Переглянути джерело

添加了Tornado相关的文档和代码

jackfrued 6 роки тому
батько
коміт
b720eb3c52
93 змінених файлів з 15339 додано та 205 видалено
  1. 196 204
      Day41-55/03.静态资源和Ajax请求.md
  2. 9 1
      Day41-55/04.表单的应用.md
  3. BIN
      Day41-55/res/show-subjects.png
  4. BIN
      Day41-55/res/show-teachers.png
  5. 140 0
      Day61-65/01.预备知识.md
  6. 377 0
      Day61-65/02.Tornado入门.md
  7. 152 0
      Day61-65/03.异步化.md
  8. 228 0
      Day61-65/04.WebSocket的应用.md
  9. 2 0
      Day61-65/05.项目实战.md
  10. 44 0
      Day61-65/code/hello-tornado/chat_handlers.py
  11. 24 0
      Day61-65/code/hello-tornado/chat_server.py
  12. 36 0
      Day61-65/code/hello-tornado/example01.py
  13. 77 0
      Day61-65/code/hello-tornado/example02.py
  14. 75 0
      Day61-65/code/hello-tornado/example03.py
  15. 42 0
      Day61-65/code/hello-tornado/example04.py
  16. 45 0
      Day61-65/code/hello-tornado/example05.py
  17. 80 0
      Day61-65/code/hello-tornado/example06.py
  18. 92 0
      Day61-65/code/hello-tornado/example07.py
  19. 30 0
      Day61-65/code/hello-tornado/example_of_aiohttp.py
  20. 40 0
      Day61-65/code/hello-tornado/example_of_asyncio.py
  21. 50 0
      Day61-65/code/hello-tornado/example_of_coroutine.py
  22. 49 0
      Day61-65/code/hello-tornado/example_of_multiprocess.py
  23. 18 0
      Day61-65/code/hello-tornado/requirements.txt
  24. 67 0
      Day61-65/code/hello-tornado/templates/chat.html
  25. 25 0
      Day61-65/code/hello-tornado/templates/login.html
  26. 17 0
      Day61-65/code/hello-tornado/templates/news.html
  27. 373 0
      Day61-65/code/project_of_tornado/assets/css/admin.css
  28. 0 0
      Day61-65/code/project_of_tornado/assets/css/amazeui.datatables.min.css
  29. 0 0
      Day61-65/code/project_of_tornado/assets/css/amazeui.min.css
  30. 1912 0
      Day61-65/code/project_of_tornado/assets/css/app.css
  31. 2056 0
      Day61-65/code/project_of_tornado/assets/css/app.less
  32. 4 0
      Day61-65/code/project_of_tornado/assets/css/fullcalendar.min.css
  33. 208 0
      Day61-65/code/project_of_tornado/assets/css/fullcalendar.print.css
  34. BIN
      Day61-65/code/project_of_tornado/assets/fonts/FontAwesome.otf
  35. BIN
      Day61-65/code/project_of_tornado/assets/fonts/fontawesome-webfont.eot
  36. BIN
      Day61-65/code/project_of_tornado/assets/fonts/fontawesome-webfont.ttf
  37. BIN
      Day61-65/code/project_of_tornado/assets/fonts/fontawesome-webfont.woff
  38. BIN
      Day61-65/code/project_of_tornado/assets/fonts/fontawesome-webfont.woff2
  39. 294 0
      Day61-65/code/project_of_tornado/assets/html/404.html
  40. 453 0
      Day61-65/code/project_of_tornado/assets/html/calendar.html
  41. 341 0
      Day61-65/code/project_of_tornado/assets/html/chart.html
  42. 619 0
      Day61-65/code/project_of_tornado/assets/html/form.html
  43. 62 0
      Day61-65/code/project_of_tornado/assets/html/login.html
  44. 70 0
      Day61-65/code/project_of_tornado/assets/html/sign-up.html
  45. 469 0
      Day61-65/code/project_of_tornado/assets/html/table-list-img.html
  46. 461 0
      Day61-65/code/project_of_tornado/assets/html/table-list.html
  47. 834 0
      Day61-65/code/project_of_tornado/assets/html/tables.html
  48. BIN
      Day61-65/code/project_of_tornado/assets/i/app-icon72x72@2x.png
  49. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/admin-chrome.png
  50. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/admin-firefox.png
  51. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/admin-ie.png
  52. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/admin-opera.png
  53. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/admin-safari.png
  54. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/adminPage.png
  55. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/blogPage.png
  56. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/landing.png
  57. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/landingPage.png
  58. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/loginPage.png
  59. BIN
      Day61-65/code/project_of_tornado/assets/i/examples/sidebarPage.png
  60. BIN
      Day61-65/code/project_of_tornado/assets/i/favicon.png
  61. BIN
      Day61-65/code/project_of_tornado/assets/i/startup-640x1096.png
  62. BIN
      Day61-65/code/project_of_tornado/assets/img/a5.png
  63. BIN
      Day61-65/code/project_of_tornado/assets/img/k.jpg
  64. BIN
      Day61-65/code/project_of_tornado/assets/img/logo.png
  65. BIN
      Day61-65/code/project_of_tornado/assets/img/logoa.png
  66. BIN
      Day61-65/code/project_of_tornado/assets/img/logob.png
  67. BIN
      Day61-65/code/project_of_tornado/assets/img/user01.png
  68. BIN
      Day61-65/code/project_of_tornado/assets/img/user02.png
  69. BIN
      Day61-65/code/project_of_tornado/assets/img/user03.png
  70. BIN
      Day61-65/code/project_of_tornado/assets/img/user04.png
  71. BIN
      Day61-65/code/project_of_tornado/assets/img/user05.png
  72. BIN
      Day61-65/code/project_of_tornado/assets/img/user06.png
  73. BIN
      Day61-65/code/project_of_tornado/assets/img/user07.png
  74. 0 0
      Day61-65/code/project_of_tornado/assets/js/amazeui.datatables.min.js
  75. 1 0
      Day61-65/code/project_of_tornado/assets/js/amazeui.min.js
  76. 370 0
      Day61-65/code/project_of_tornado/assets/js/app.js
  77. 0 0
      Day61-65/code/project_of_tornado/assets/js/dataTables.responsive.min.js
  78. 0 0
      Day61-65/code/project_of_tornado/assets/js/echarts.min.js
  79. 5 0
      Day61-65/code/project_of_tornado/assets/js/fullcalendar.min.js
  80. 3 0
      Day61-65/code/project_of_tornado/assets/js/jquery.min.js
  81. 4234 0
      Day61-65/code/project_of_tornado/assets/js/moment.js
  82. 28 0
      Day61-65/code/project_of_tornado/assets/js/theme.js
  83. 54 0
      Day61-65/code/project_of_tornado/backend_server.py
  84. 8 0
      Day61-65/code/project_of_tornado/requirements.txt
  85. 0 0
      Day61-65/code/project_of_tornado/service/__init__.py
  86. 0 0
      Day61-65/code/project_of_tornado/service/handlers/__init__.py
  87. 34 0
      Day61-65/code/project_of_tornado/service/handlers/handlers_for_charts.py
  88. 7 0
      Day61-65/code/project_of_tornado/service/handlers/handlers_for_nav.py
  89. 13 0
      Day61-65/code/project_of_tornado/service/handlers/handlers_for_tables.py
  90. 511 0
      Day61-65/code/project_of_tornado/templates/index.html
  91. BIN
      Day61-65/res/run-hello-world-app.png
  92. BIN
      Day61-65/res/websocket.png
  93. BIN
      Day61-65/res/ws_wss.png

+ 196 - 204
Day41-55/03.静态资源和Ajax请求.md

@@ -7,30 +7,108 @@
 由于之前已经详细的讲解了如何创建Django项目以及项目的相关配置,因此我们略过这部分内容,唯一需要说明的是,从上面对投票应用需求的描述中我们可以分析出三个业务实体:学科、老师和用户。学科和老师之间通常是一对多关联关系(一个学科有多个老师,一个老师通常只属于一个学科),用户因为要给老师投票,所以跟老师之间是多对多关联关系(一个用户可以给多个老师投票,一个老师也可以收到多个用户的投票)。首先修改应用下的models.py文件来定义数据模型,先给出学科和老师的模型。
 
 ```Python
+from django.db import models
 
+
+class Subject(models.Model):
+    """学科"""
+    no = models.AutoField(primary_key=True, verbose_name='编号')
+    name = models.CharField(max_length=31, verbose_name='名称')
+    intro = models.CharField(max_length=511, verbose_name='介绍')
+
+    def __str__(self):
+        return self.name
+
+    class Meta:
+        db_table = 'tb_subject'
+        verbose_name_plural = '学科'
+
+
+class Teacher(models.Model):
+    """老师"""
+    no = models.AutoField(primary_key=True, verbose_name='编号')
+    name = models.CharField(max_length=15, verbose_name='姓名')
+    gender = models.BooleanField(default=True, choices=((True, '男'), (False, '女')), verbose_name='性别')
+    birth = models.DateField(null=True, verbose_name='出生日期')
+    intro = models.CharField(max_length=511, default='', verbose_name='')
+    good_count = models.IntegerField(default=0, verbose_name='好评数')
+    bad_count = models.IntegerField(default=0, verbose_name='差评数')
+    photo = models.CharField(max_length=255, verbose_name='照片')
+    subject = models.ForeignKey(to=Subject, on_delete=models.PROTECT, db_column='sno', verbose_name='所属学科')
+
+    def __str__(self):
+        return self.name
+
+    class Meta:
+        db_table = 'tb_teacher'
+        verbose_name_plural = '老师'
 ```
 
 模型定义完成后,可以通过“生成迁移”和“执行迁移”来完成关系型数据库中二维表的创建,当然这需要提前启动数据库服务器并创建好对应的数据库,同时我们在项目中已经安装了PyMySQL而且完成了相应的配置,这些内容此处不再赘述。
 
 ```Shell
-(venv)$ python manage.py makemigrations demo
+(venv)$ python manage.py makemigrations vote
 ...
 (venv)$ python manage.py migrate
 ...
 ```
 
-完成模型迁移之后,我们可以通过下面的SQL语句来添加学科和老师的数据。
+> 注意:为了给vote应用生成迁移,需要先修改Django项目的配置文件settings.py,在INSTALLED_APPS中添加vote应用。
+
+完成模型迁移之后,我们可以通过下面的SQL语句来添加学科和老师测试的数据。
+
+```SQL
+INSERT INTO `tb_subject` (`no`,`name`,`intro`) 
+VALUES 
+(1, 'Python全栈+人工智能', 'Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。'),
+(2, 'JavaEE+分布式服务', 'Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。'),
+(3, 'HTML5大前端', 'HTML5 将成为 HTML、XHTML 以及 HTML DOM 的新标准。'),
+(4, '全栈软件测试', '在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程'),
+(5, '全链路UI/UE', '全链路要求设计师关注整个业务链中的每一个环节,将设计的价值融入每一个和用户的接触点中,让整个业务的用户体验质量得到几何级数的增长。');
+
+INSERT INTO `tb_teacher` (`no`,`name`,`gender`,`birth`,`intro`,`good_count`,`bad_count`,`photo`,`sno`) 
+VALUES 
+(1, '骆昊', 1, '1980-11-28', '10年以上软硬件产品设计、研发、架构和管理经验,2003年毕业于四川大学,四川大学Java技术俱乐部创始人,四川省优秀大学毕业生,在四川省网络通信技术重点实验室工作期间,参与了2项国家自然科学基金项目、1项中国科学院中长期研究项目和多项四川省科技攻关项目,在国际会议和国内顶级期刊上发表多篇论文(1篇被SCI收录,3篇被EI收录),大规模网络性能测量系统DMC-TS的设计者和开发者,perf-TTCN语言的发明者。国内最大程序员社区CSDN的博客专家,在Github上参与和维护了多个高质量开源项目,精通C/C++、Java、Python、R、Swift、JavaScript等编程语言,擅长OOAD、系统架构、算法设计、协议分析和网络测量,主持和参与过电子政务系统、KPI考核系统、P2P借贷平台等产品的研发,一直践行“用知识创造快乐”的教学理念,善于总结,乐于分享。', 0, 0, 'images/luohao.png', 1),
+(2, '王海飞', 1, '1993-05-24', '5年以上Python开发经验,先后参与了O2O商城、CRM系统、CMS平台、ERP系统等项目的设计与研发,曾在全国最大最专业的汽车领域相关服务网站担任Python高级研发工程师、项目经理等职务,擅长基于Python、Java、PHP等开发语言的企业级应用开发,全程参与了多个企业级应用从需求到上线所涉及的各种工作,精通Django、Flask等框架,熟悉基于微服务的企业级项目开发,拥有丰富的项目实战经验。善于用浅显易懂的方式在课堂上传授知识点,在授课过程中经常穿插企业开发的实际案例并分析其中的重点和难点,通过这种互动性极强的教学模式帮助学员找到解决问题的办法并提升学员的综合素质。', 0, 0, 'images/wangdachui.png', 1),
+(3, '余婷', 0, '1992-03-12', '5年以上移动互联网项目开发经验和教学经验,曾担任上市游戏公司高级软件研发工程师和移动端(iOS)技术负责人,参了多个企业级应用和游戏类应用的移动端开发和后台服务器开发,拥有丰富的开发经验和项目管理经验,以个人开发者和协作开发者的身份在苹果的AppStore上发布过多款App。精通Python、C、Objective-C、Swift等开发语言,熟悉iOS原生App开发、RESTful接口设计以及基于Cocos2d-x的游戏开发。授课条理清晰、细致入微,性格活泼开朗、有较强的亲和力,教学过程注重理论和实践的结合,在学员中有良好的口碑。', 0, 0, 'images/yuting.png', 1),
+(4, '肖世荣', 1, '1977-07-02', '10年以上互联网和移动互联网产品设计、研发、技术架构和项目管理经验,曾在中国移动、symbio、ajinga.com、万达信息等公司担任架构师、项目经理、技术总监等职务,长期为苹果、保时捷、耐克、沃尔玛等国际客户以及国内的政府机构提供信息化服务,主导的项目曾获得“世界科技先锋”称号,个人作品“许愿吧”曾在腾讯应用市场生活类App排名前3,拥有百万级用户群体,运营的公众号“卵石坊”是国内知名的智能穿戴设备平台。精通Python、C++、Java、Ruby、JavaScript等开发语言,主导和参与了20多个企业级项目(含国家级重大项目和互联网创新项目),涉及的领域包括政务、社交、电信、卫生和金融,有极为丰富的项目实战经验。授课深入浅出、条理清晰,善于调动学员的学习热情并帮助学员理清思路和方法。', 0, 0, 'images/xiaoshirong.png', 1),
+(5, '张无忌', 1, '1987-07-07', '出生起便在冰火岛过着原始生活,踏入中土后因中玄冥神掌命危而带病习医,忍受寒毒煎熬七年最后因福缘际会练成“九阳神功”更在之后又练成了“乾坤大挪移”等盖世武功,几乎无敌于天下。 生性随和,宅心仁厚,精通医术和药理。20岁时便凭着盖世神功当上明教教主,率领百万教众及武林群雄反抗蒙古政权元朝的高压统治,最后推翻了元朝。由于擅长乾坤大挪移神功,上课遇到问题就转移话题,属于拉不出屎怪地球没有引力的类型。', 0, 0, 'images/zhangwuji.png', 5),
+(6, '韦一笑', 1, '1975-12-15', '外号“青翼蝠王”,为明教四大护教法王之一。  身披青条子白色长袍,轻功十分了得。由于在修炼至阴至寒的“寒冰绵掌”时出了差错,经脉中郁积了至寒阴毒,只要运上内力,寒毒就会发作,如果不吸人血解毒,全身血脉就会凝结成冰,后得张无忌相助,以其高明医术配以“九阳神功”,终将寒毒驱去,摆脱了吸吮人血这一命运。由于轻功绝顶,学生一问问题就跑了。', 0, 0, 'images/weiyixiao.png', 3);
+```
+
+当然也可以直接使用Django提供的后台管理应用来添加学科和老师信息,这需要先注册模型类和模型管理类。
 
 ```SQL
+from django.contrib import admin
+from django.contrib.admin import ModelAdmin
+
+from vote.models import Teacher, Subject
+
+
+class SubjectModelAdmin(ModelAdmin):
+    """学科模型管理"""
+    list_display = ('no', 'name')
+    ordering = ('no', )
+
+
+class TeacherModelAdmin(ModelAdmin):
+    """老师模型管理"""
+    list_display = ('no', 'name', 'gender', 'birth', 'good_count', 'bad_count', 'subject')
+    ordering = ('no', )
+    search_fields = ('name', )
 
+
+admin.site.register(Subject, SubjectModelAdmin)
+admin.site.register(Teacher, TeacherModelAdmin)
 ```
 
 接下来,我们就可以修改views.py文件,通过编写视图函数先实现“学科介绍”页面。
 
 ```Python
 def show_subjects(request):
-    ctx = {'subjects_list': Subject.objects.all()}
-    return render(request, 'subject.html', ctx)
+    """查看所有学科"""
+    subjects = Subject.objects.all()
+    return render(request, 'subject.html', {'subjects': subjects})
 ```
 
 至此,我们还需要一个模板页,模板的配置以及模板页中模板语言的用法在之前已经进行过简要的介绍,如果不熟悉可以看看下面的代码,相信这并不是一件困难的事情。
@@ -41,131 +119,91 @@ def show_subjects(request):
 <head>
     <meta charset="UTF-8">
     <title>学科信息</title>
-    <style>
-        body {
-            width: 960px;
-            margin: 0 auto;
-        }
-        .sub {
-            margin: 20px 10px;
-        }
-    </style>
+    <style>/* 此处略去了层叠样式表的选择器 */</style>
 </head>
 <body>
-    <h1>学科信息</h1>
+    <h1>所有学科</h1>
     <hr>
-    {% for subject in subjects_list %}
-    <dl class="sub">
-        <dt><a href="/subjects/{{ subject.no }}">{{ subject.name }}</a></dt>
-        <dd>{{ subject.intro }}</dd>
-    </dl>
-    {% endfor %}
+    <div id="container">
+        {% for subject in subjects %}
+        <dl>
+            <dt>
+                <a href="/teachers?sno={{ subject.no }}">
+                    {{ subject.name }}
+                </a>
+            </dt>
+            <dd>{{ subject.intro }}</dd>
+        </dl>
+        {% endfor %}
+    </div>
 </body>
 </html>
 ```
 
-启动服务器,运行效果如下图所示。
-
-![](./res/runserver02.png)
-
-### 加载静态资源
-
-在上面的模板中,我们为每个学科添加了一个超链接,点击超链接可以查看该学科的讲师信息,为此我们得修改项目的urls.py文件配置一个新的URL。
+在上面的模板中,我们为每个学科添加了一个超链接,点击超链接可以查看该学科的讲师信息,为此需要再编写一个视图函数来处理查看指定学科老师信息。
 
 ```Python
-from django.contrib import admin
-from django.urls import path
-
-from demo import views
-
-urlpatterns = [
-    path('', views.show_subjects),
-    path('subjects/<int:no>', views.show_teachers),
-    path('admin/', admin.site.urls),
-]
-```
-
-Django 2.x在配置URL时可以使用如上面所示的占位符语法,而且可以指定占位符的类型,因为在查询学科讲师信息时,需要传入该学科的编号作为条件,而学科编号在定义模型时设定为`AutoField`,其本质就是`int`类型。相较于Django 1.x中使用正则表达式的命名捕获组来从URL中获取数据(如果对Django 1.x并没有什么概念,这句话可以暂时忽略不计),这种更加优雅的写法可以让我们在视图函数中直接获得学科编号,代码如下所示。
-
-```Python
-def show_teachers(request, no):
-    teachers = Teacher.objects.filter(subject__no=no)
-    ctx = {'teachers_list': teachers}
-    return render(request, 'demo/teacher.html', ctx)
+def show_teachers(request):
+    """查看指定学科的老师"""
+    try:
+        sno = int(request.GET['sno'])
+        subject = Subject.objects.get(no=sno)
+        teachers = Teacher.objects.filter(subject__no=sno)
+        context = {'subject': subject, 'teachers': teachers}
+        return render(request, 'teacher.html', context)
+    except (KeyError, ValueError, Subject.DoesNotExist):
+        return redirect('/')
 ```
 
-接下来我们可以定制“老师详情”的模板页。
+显示老师信息的模板页。
 
 ```HTML
 <!DOCTYPE html>
-{% load staticfiles %}
+{% load static %}
 <html lang="en">
 <head>
     <meta charset="UTF-8">
-    <title>讲师信息</title>
-    <style>
-        .container {
-            width: 960px;
-            margin: 0 auto;
-        }
-        .basic {
-            width: 60%;
-            float: left;
-        }
-        .potrait {
-            width: 40%;
-            float: left;
-            text-align: right;
-        }
-        hr {
-            clear: both;
-        }
-        .button {
-            display: inline-block;
-            width: 80px;
-            height: 30px;
-            background-color: red;
-            color: white;
-            font: 16px/30px Arial;
-            text-decoration: none;
-            text-align: center;
-        	margin-bottom: 10px;
-		}
-    </style>
+    <title>老师信息</title>
+    <style>/* 此处略去了层叠样式表的选择器 */</style>
 </head>
 <body>
-    {% for x in teachers_list %}
-    <div class="container">
-        <div class="basic">
-            <h1>{{ x.name }}老师</h1>
-            <p><strong>讲师简介</strong></p>
-            <p>{{ x.intro }}</p>
-            <p><strong>教学理念</strong></p>
-            <p>{{ x.motto }}</p>
-            <a href="/good/{{ x.no }}" class="button">好评({{ x.gcount }})</a>
-            <a href="/bad/{{ x.no }}" class="button">差评({{ x.bcount }})</a>
-        </div>
-        <div class="potrait">
-            {% if x.photo %}
-            <img src="{% static x.photo %}">
-            {% endif %}
+    <h1>{{ subject.name }}的老师信息</h1>
+    <hr>
+    {% if teachers %}
+    <div id="container">
+        {% for teacher in teachers %}
+        <div class="teacher">
+            <div class="photo">
+                <img src="{% static teacher.photo %}" height="140" alt="">
+            </div>
+            <div class="info">
+                <div>
+                    <span><strong>姓名:{{ teacher.name }}</strong></span>
+                    <span>性别:{{ teacher.gender | yesno:'男,女' }}</span>
+                    <span>出生日期:{{ teacher.birth }}</span>
+                </div>
+                <div class="intro">{{ teacher.intro }}</div>
+                <div class="comment">
+                    <a href="">好评({{ teacher.good_count }})</a>
+                    <a href="">差评({{ teacher.bad_count }})</a>
+                </div>
+            </div>
         </div>
-        <hr>
+        {% endfor %}
+    </div>
+    {% else %}
+    <h2>暂时没有该学科的老师信息</h2>
+    {% endif %}
+    <div class="back">
+        <a href="/">&lt;&lt;&nbsp;返回学科</a>
     </div>
-    {% endfor %}
 </body>
 </html>
 ```
 
-请注意上面的模板页面,我们在第2行和`<img>`标签中使用了加载静态资源的模板指令,通过加载静态资源的指令我们可以显示老师的头像。当然,我们还得创建放置静态资源的文件夹并在项目的配置文件中指明静态资源文件夹的所在以及静态资源的URL。
-
-```Shell
-(venv)$ mkdir static
-(venv)$ cd static
-(venv)$ mkdir css js images
-```
+### 加载静态资源
 
-首先在项目根目录下创建static文件,再进入static目录,创建css、js和images三个文件夹,分别用来放置层叠样式表、JavaScript文件和图片资源。
+在上面的模板页面中,我们使用了`<img>`标签来加载老师的照片,其中使用了引用静态资源的模板指令`{% static %}`,要使用该指令,首先要使用`{% load static %}`指令来加载静态资源,我们将这段代码放在了页码开始的位置。在上面的项目中,我们将静态资源置于名为static的文件夹中,在该文件夹下又创建了三个文件夹:css、js和images,分别用来保存外部层叠样式表、外部JavaScript文件和图片资源。为了能够找到保存静态资源的文件夹,我们还需要修改Django项目的配置文件settings.py,如下所示:
 
 ```Python
 # 此处省略上面的代码
@@ -176,135 +214,89 @@ STATIC_URL = '/static/'
 # 此处省略下面的代码
 ```
 
-接下来运行项目查看结果。
+接下来修改urls.py文件,配置用户请求的URL和视图函数的对应关系。
+
+```Python
+from django.contrib import admin
+from django.urls import path
+
+from vote import views
+
+urlpatterns = [
+    path('', views.show_subjects),
+    path('teachers/', views.show_teachers),
+    path('admin/', admin.site.urls),
+]
+```
+
+启动服务器运行项目,效果如下图所示。
+
+![](/Users/Hao/Desktop/Python-100-Days/Day41-55/res/show-subjects.png)
 
-![](./res/runserver03.png)
+![](./res/show-teachers.png)
 
 ### Ajax请求
 
-接下来就可以实现“好评”和“差评”的功能了,很明显如果能够在不刷新页面的情况下实现这两个功能会带来更好的用户体验,因此我们考虑使用[Ajax](https://zh.wikipedia.org/wiki/AJAX)来实现“好评”和“差评”。
+接下来就可以实现“好评”和“差评”的功能了,很明显如果能够在不刷新页面的情况下实现这两个功能会带来更好的用户体验,因此我们考虑使用[Ajax](https://zh.wikipedia.org/wiki/AJAX)技术来实现“好评”和“差评”,Ajax技术我们在之前的章节中已经介绍过了,此处不再赘述
 
-首先修改项目的urls.py文件,为“好评”和“差评”功能映射对应的URL,跟上面一样我们在URL中使用了占位符语法来绑定老师的编号。
+首先修改项目的urls.py文件,为“好评”和“差评”功能映射对应的URL。
 
 ```Python
 from django.contrib import admin
 from django.urls import path
 
-from demo import views
+from vote import views
 
 urlpatterns = [
-    path('', views.login),
-    path('subjects/', views.show_subjects),
-    path('subjects/<int:no>/', views.show_teachers),
-    path('good/<int:no>/', views.make_comment),
-    path('bad/<int:no>/', views.make_comment),
+    path('', views.show_subjects),
+    path('teachers/', views.show_teachers),
+    path('praise/', views.prise_or_criticize),
+    path('criticize/', views.prise_or_criticize),
     path('admin/', admin.site.urls),
 ]
 ```
 
-设计视图函数`make_comment`来支持“好评”和“差评”功能,可以通过`json`模块的`dumps`函数实现将字典转成JSON字符串并作为`HttpResponse`返回给浏览器的内容。在创建`HttpResponse`对象时,可以通过`content_type`参数来指定响应的[MIME类型](http://www.w3school.com.cn/media/media_mimeref.asp)为JSON且使用UTF-8编码(避免JSON字符串中的中文出现乱码)
+设计视图函数`praise_or_criticize`来支持“好评”和“差评”功能,该视图函数通过Django封装的JsonResponse类将字典序列化成JSON字符串作为返回给浏览器的响应内容
 
 ```Python
-def make_comment(request, no):
-    ctx = {'code': 200}
+def praise_or_criticize(request):
+    """好评"""
     try:
-        teacher = Teacher.objects.get(pk=no)
-        if request.path.startswith('/good'):
+        tno = int(request.GET['tno'])
+        teacher = Teacher.objects.get(no=tno)
+        if request.path.startswith('/prise'):
             teacher.good_count += 1
-            ctx['result'] = f'好评({teacher.gcount})'
         else:
             teacher.bad_count += 1
-            ctx['result'] = f'差评({teacher.bcount})'
         teacher.save()
-    except Teacher.DoesNotExist:
-        ctx['code'] = 404
-    return HttpResponse(json.dumps(ctx),
-                        content_type='application/json; charset=utf-8')
+        data = {'code': 200, 'hint': '操作成功'}
+    except (KeyError, ValueError, Teacher.DoseNotExist):
+        data = {'code': 404, 'hint': '操作失败'}
+    return JsonResponse(data)
 ```
 
-修改模板页引入jQuery库来实现事件处理、Ajax请求和DOM操作。
+修改显示老师信息的模板页引入jQuery库来实现事件处理、Ajax请求和DOM操作。
 
 ```HTML
-<!DOCTYPE html>
-{% load staticfiles %}
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <title>讲师信息</title>
-    <style>
-        .container {
-            width: 960px;
-            margin: 0 auto;
-        }
-        .basic {
-            width: 60%;
-            float: left;
-        }
-        .potrait {
-            width: 40%;
-            float: left;
-            text-align: right;
-        }
-        hr {
-            clear: both;
-        }
-        .button {
-            display: inline-block;
-            width: 80px;
-            height: 30px;
-            background-color: red;
-            color: white;
-            font: 16px/30px Arial;
-            text-decoration: none;
-            text-align: center;
-            margin-bottom: 10px;
-        }
-    </style>
-</head>
-<body>
-    {% for x in teachers_list %}
-    <div class="container">
-        <div class="basic">
-            <h1>{{ x.name }}老师</h1>
-            <p><strong>讲师简介</strong></p>
-            <p>{{ x.intro }}</p>
-            <p><strong>教学理念</strong></p>
-            <p>{{ x.motto }}</p>
-            <a href="/good/{{ x.no }}" class="button">好评({{ x.gcount }})</a>
-            <a href="/bad/{{ x.no }}" class="button">差评({{ x.bcount }})</a>
-        </div>
-        <div class="potrait">
-            {% if x.photo %}
-            <img src="{% static x.photo %}">
-            {% endif %}
-        </div>
-        <hr>
-    </div>
-    {% endfor %}
-    <script src="{% static 'js/jquery.min.js' %}"></script>
-    <script>
-       $(function() {
-           $('.basic .button').on('click', function(evt) {
-               evt.preventDefault();
-               var $a = $(evt.target);
-               var url = $a.attr('href');
-               $.ajax({
-                   'url': url,
-                   'type': 'get',
-                   'dataType': 'json',
-                   'success': function(json) {
-                       if (json.code == 200) {
-                           $a.text(json.result);
-                       }
-                   }
-               });
-           });
-       });
-    </script>
-</body>
-</html>
+<script src="{% static 'js/jquery.min.js' %}"></script>
+<script>
+    $(() => {
+        $('.comment>a').on('click', (evt) => {
+            evt.preventDefault();
+            let a = $(evt.target)
+            let span = a.next()
+            $.getJSON(a.attr('href'), (json) => {
+                if (json.code == 200) {
+                    span.text(parseInt(span.text()) + 1)
+                } else {
+                    alert(json.hint)
+                }
+            })
+        })
+    })
+</script>
 ```
 
 ### 小结
 
-到此,这个小项目的核心功能已然完成,在下一个章节中我们会增加用户登录和注册的功能,稍后我们还会限定登录后的用户才能进行投票操作,而且每个用户只能投出3票
+到此为止,这个投票项目的核心功能已然完成,在下一个章节中我们要求用户必须登录才能投票,没有账号的用户可以通过注册功能注册一个账号。

+ 9 - 1
Day41-55/04.表单的应用.md

@@ -1,5 +1,13 @@
 ## Django实战(04) - 表单的应用
 
-我们继续来完成上一章节中的项目,实现“用户注册”和“用户登录”的功能。Django框架中提供了对表单的封装,而且提供了多种不同的使用方式。
+我们继续来完成上一章节中的项目,实现“用户注册”和“用户登录”的功能,并限制只有登录的用户才能为老师投票。Django框架中提供了对表单的封装,而且提供了多种不同的使用方式。
+
+首先添加用户模型。
+
+```Python
+
+```
+
+
 
 

BIN
Day41-55/res/show-subjects.png


BIN
Day41-55/res/show-teachers.png


+ 140 - 0
Day61-65/01.预备知识.md

@@ -0,0 +1,140 @@
+## 预备知识
+
+### 并发编程
+
+所谓并发编程就是让程序中有多个部分能够并发或同时执行,并发编程带来的好处不言而喻,其中最为关键的两点是提升了执行效率和改善了用户体验。下面简单阐述一下Python中实现并发编程的三种方式:
+
+1. 多线程:Python中通过`threading`模块的`Thread`类并辅以`Lock`、`Condition`、`Event`、`Semaphore`和`Barrier`等类来支持多线程编程。Python解释器通过GIL(全局解释器锁)来防止多个线程同时执行本地字节码,这个锁对于CPython(Python解释器的官方实现)是必须的,因为CPython的内存管理并不是线程安全的。因为GIL的存在,Python的多线程并不能利用CPU的多核特性。
+
+2. 多进程:使用多进程可以有效的解决GIL的问题,Python中的`multiprocessing`模块提供了`Process`类来实现多进程,其他的辅助类跟`threading`模块中的类类似,由于进程间的内存是相互隔离的(操作系统对进程的保护),进程间通信(共享数据)必须使用管道、套接字等方式,这一点从编程的角度来讲是比较麻烦的,为此,Python的`multiprocessing`模块提供了一个名为`Queue`的类,它基于管道和锁机制提供了多个进程共享的队列。
+
+   ```Python
+   """
+   用下面的命令运行程序并查看执行时间,例如:
+   time python3 example06.py
+   real    0m20.657s
+   user    1m17.749s
+   sys     0m0.158s
+   使用多进程后实际执行时间为20.657秒,而用户时间1分17.749秒约为实际执行时间的4倍
+   这就证明我们的程序通过多进程使用了CPU的多核特性,而且这台计算机配置了4核的CPU
+   """
+   import concurrent.futures
+   import math
+   
+   PRIMES = [
+       1116281,
+       1297337,
+       104395303,
+       472882027,
+       533000389,
+       817504243,
+       982451653,
+       112272535095293,
+       112582705942171,
+       112272535095293,
+       115280095190773,
+       115797848077099,
+       1099726899285419
+   ] * 5
+   
+   
+   def is_prime(num):
+       """判断素数"""
+       assert num > 0
+       for i in range(2, int(math.sqrt(num)) + 1):
+           if num % i == 0:
+               return False
+       return num != 1
+   
+   
+   def main():
+       """主函数"""
+       with concurrent.futures.ProcessPoolExecutor() as executor:
+           for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
+               print('%d is prime: %s' % (number, prime))
+   
+   
+   if __name__ == '__main__':
+       main()
+   ```
+
+3. 异步编程(异步I/O):所谓异步编程是通过调度程序从任务队列中挑选任务,调度程序以交叉的形式执行这些任务,我们并不能保证任务将以某种顺序去执行,因为执行顺序取决于队列中的一项任务是否愿意将CPU处理时间让位给另一项任务。异步编程通常通过多任务协作处理的方式来实现,由于执行时间和顺序的不确定,因此需要通过钩子函数(回调函数)或者`Future`对象来获取任务执行的结果。目前我们使用的Python 3通过`asyncio`模块以及`await`和`async`关键字(Python 3.5中引入,Python 3.7中正式成为关键字)提供了对异步I/O的支持。
+
+   ```Python
+   import asyncio
+   
+   
+   async def fetch(host):
+       """从指定的站点抓取信息(协程函数)"""
+       print(f'Start fetching {host}\n')
+       # 跟服务器建立连接
+       reader, writer = await asyncio.open_connection(host, 80)
+       # 构造请求行和请求头
+       writer.write(b'GET / HTTP/1.1\r\n')
+       writer.write(f'Host: {host}\r\n'.encode())
+       writer.write(b'\r\n')
+       # 清空缓存区(发送请求)
+       await writer.drain()
+       # 接收服务器的响应(读取响应行和响应头)
+       line = await reader.readline()
+       while line != b'\r\n':
+           print(line.decode().rstrip())
+           line = await reader.readline()
+       print('\n')
+       writer.close()
+   
+   
+   def main():
+       """主函数"""
+       urls = ('www.sohu.com', 'www.douban.com', 'www.163.com')
+       # 获取系统默认的事件循环
+       loop = asyncio.get_event_loop()
+       # 用生成式语法构造一个包含多个协程对象的列表
+       tasks = [fetch(url) for url in urls]
+       # 通过asyncio模块的wait函数将协程列表包装成Task(Future子类)并等待其执行完成
+       # 通过事件循环的run_until_complete方法运行任务直到Future完成并返回它的结果
+       loop.run_until_complete(asyncio.wait(tasks))
+       loop.close()
+   
+   
+   if __name__ == '__main__':
+       main()
+   ```
+
+   > 说明:目前大多数网站都要求基于HTTPS通信,因此上面例子中的网络请求不一定能收到正常的响应,也就是说响应状态码不一定是200,有可能是3xx或者4xx。当然我们这里的重点不在于获得网站响应的内容,而是帮助大家理解`asyncio`模块以及`async`和`await`两个关键字的使用。
+
+我们对三种方式的使用场景做一个简单的总结。
+
+以下情况需要使用多线程:
+
+1. 程序需要维护许多共享的状态(尤其是可变状态),Python中的列表、字典、集合都是线程安全的,所以使用线程而不是进程维护共享状态的代价相对较小。
+2. 程序会花费大量时间在I/O操作上,没有太多并行计算的需求且不需占用太多的内存。
+
+以下情况需要使用多进程:
+
+1. 程序执行计算密集型任务(如:字节码操作、数据处理、科学计算)。
+2. 程序的输入可以并行的分成块,并且可以将运算结果合并。
+3. 程序在内存使用方面没有任何限制且不强依赖于I/O操作(如:读写文件、套接字等)。
+
+最后,如果程序不需要真正的并发性或并行性,而是更多的依赖于异步处理和回调时,异步I/O就是一种很好的选择。另一方面,当程序中有大量的等待与休眠时,也应该考虑使用异步I/O。
+
+> 扩展:关于进程,还需要做一些补充说明。首先,为了控制进程的执行,操作系统内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程使之继续执行,这种行为被称为进程切换(也叫调度)。进程切换是比较耗费资源的操作,因为在进行切换时首先要保存当前进程的上下文(内核再次唤醒该进程时所需要的状态,包括:程序计数器、状态寄存器、数据栈等),然后还要恢复准备执行的进程的上下文。正在执行的进程由于期待的某些事件未发生,如请求系统资源失败、等待某个操作完成、新数据尚未到达等原因会主动由运行状态变为阻塞状态,当进程进入阻塞状态,是不占用CPU资源的。这些知识对于理解到底选择哪种方式进行并发编程也是很重要的。
+
+### I/O模式和事件驱动
+
+对于一次I/O操作(以读操作为例),数据会先被拷贝到操作系统内核的缓冲区中,然后从操作系统内核的缓冲区拷贝到应用程序的缓冲区(这种方式称为标准I/O或缓存I/O,大多数文件系统的默认I/O都是这种方式),最后交给进程。所以说,当一个读操作发生时(写操作与之类似),它会经历两个阶段:(1)等待数据准备就绪;(2)将数据从内核拷贝到进程中。
+
+由于存在这两个阶段,因此产生了以下几种I/O模式:
+
+1. 阻塞 I/O(blocking I/O):进程发起读操作,如果内核数据尚未就绪,进程会阻塞等待数据直到内核数据就绪并拷贝到进程的内存中。
+2. 非阻塞 I/O(non-blocking I/O):进程发起读操作,如果内核数据尚未就绪,进程不阻塞而是收到内核返回的错误信息,进程收到错误信息可以再次发起读操作,一旦内核数据准备就绪,就立即将数据拷贝到了用户内存中,然后返回。
+3. 多路I/O复用( I/O multiplexing):监听多个I/O对象,当I/O对象有变化(数据就绪)的时候就通知用户进程。多路I/O复用的优势并不在于单个I/O操作能处理得更快,而是在于能处理更多的I/O操作。
+4. 异步 I/O(asynchronous I/O):进程发起读操作后就可以去做别的事情了,内核收到异步读操作后会立即返回,所以用户进程不阻塞,当内核数据准备就绪时,内核发送一个信号给用户进程,告诉它读操作完成了。
+
+通常,我们编写一个处理用户请求的服务器程序时,有以下三种方式可供选择:
+
+1. 每收到一个请求,创建一个新的进程,来处理该请求;
+2. 每收到一个请求,创建一个新的线程,来处理该请求;
+3. 每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求
+
+第1种方式实现比较简单,但由于创建进程开销比较大,会导致服务器性能比较差;第2种方式,由于要涉及到线程的同步,有可能会面临竞争、死锁等问题;第3种方式,就是所谓事件驱动的方式,它利用了多路I/O复用和异步I/O的优点,虽然代码逻辑比前面两种都复杂,但能达到最好的性能,这也是目前大多数网络服务器采用的方式。

+ 377 - 0
Day61-65/02.Tornado入门.md

@@ -0,0 +1,377 @@
+## Tornado入门
+
+### Tornado概述
+
+Python的Web框架种类繁多(比Python语言的关键字还要多),但在众多优秀的Web框架中,Tornado框架最适合用来开发需要处理长连接和应对高并发的Web应用。Tornado框架在设计之初就考虑到性能问题,通过对非阻塞I/O和epoll(Linux 2.5.44内核引入的一种多路I/O复用方式,旨在实现高性能网络服务,在BSD和macOS中是kqueue)的运用,Tornado可以处理大量的并发连接,更轻松的应对C10K(万级并发)问题,是非常理想的实时通信Web框架。
+
+> 扩展:基于线程的Web服务器产品(如:Apache)会维护一个线程池来处理用户请求,当用户请求到达时就为该请求分配一个线程,如果线程池中没有空闲线程了,那么可以通过创建新的线程来应付新的请求,但前提是系统尚有空闲的内存空间,显然这种方式很容易将服务器的空闲内存耗尽(大多数Linux发行版本中,默认的线程栈大小为8M)。想象一下,如果我们要开发一个社交类应用,这类应用中,通常需要显示实时更新的消息、对象状态的变化和各种类型的通知,那也就意味着客户端需要保持请求连接来接收服务器的各种响应,在这种情况下,服务器上的工作线程很容易被耗尽,这也就意味着新的请求很有可能无法得到响应。
+
+Tornado框架源于FriendFeed网站,在FriendFeed网站被Facebook收购之后得以开源,正式发布的日期是2009年9月10日。Tornado能让你能够快速开发高速的Web应用,如果你想编写一个可扩展的社交应用、实时分析引擎,或RESTful API,那么Tornado框架就是很好的选择。Tornado其实不仅仅是一个Web开发的框架,它还是一个高性能的事件驱动网络访问引擎,内置了高性能的HTTP服务器和客户端(支持同步和异步请求),同时还对WebSocket提供了完美的支持。
+
+了解和学习Tornado最好的资料就是它的官方文档,在[tornadoweb.org](http://www.tornadoweb.org)上面有很多不错的例子,你也可以在Github上找到Tornado的源代码和历史版本。
+
+### 5分钟上手Tornado
+
+1. 创建并激活虚拟环境。
+
+   ```Shell
+   mkdir hello-tornado
+   cd hello-tornado
+   python3 -m venv venv
+   source venv/bin/activate
+   ```
+
+2. 安装Tornado。
+
+   ```Shell
+   pip install tornado
+   ```
+
+3. 编写Web应用。
+
+   ```Python
+   """
+   example01.py
+   """
+   import tornado.ioloop
+   import tornado.web
+   
+   
+   class MainHandler(tornado.web.RequestHandler):
+   
+       def get(self):
+           self.write('<h1>Hello, world!</h1>')
+   
+   
+   def main():
+       app = tornado.web.Application(handlers=[(r'/', MainHandler), ])
+       app.listen(8888)
+       tornado.ioloop.IOLoop.current().start()
+   
+   
+   if __name__ == '__main__':
+       main()
+   ```
+
+4. 运行并访问应用。
+
+   ```Shell
+   python example01.py
+   ```
+
+   ![](./res/run-hello-world-app.png)
+
+在上面的例子中,代码example01.py通过定义一个继承自`RequestHandler`的类(`MainHandler`)来处理用户请求,当请求到达时,Tornado会实例化这个类(创建`MainHandler`对象),并调用与HTTP请求方法(GET、POST等)对应的方法,显然上面的`MainHandler`只能处理GET请求,在收到GET请求时,它会将一段HTML的内容写入到HTTP响应中。`main`函数的第1行代码创建了Tornado框架中`Application`类的实例,它代表了我们的Web应用,而创建该实例最为重要的参数就是`handlers`,该参数告知`Application`对象,当收到一个请求时应该通过哪个类的对象来处理这个请求。在上面的例子中,当通过HTTP的GET请求访问站点根路径时,就会调用`MainHandler`的`get`方法。 `main`函数的第2行代码通过`Application`对象的`listen`方法指定了监听HTTP请求的端口。`main`函数的第3行代码用于获取Tornado框架的`IOLoop`实例并启动它,该实例代表一个条件触发的I/O循环,用于持续的接收来自于客户端的请求。
+
+> 扩展:在Python 3中,`IOLoop`实例的本质就是`asyncio`的事件循环,该事件循环在非Windows系统中就是`SelectorEventLoop`对象,它基于`selectors`模块(高级I/O复用模块),会使用当前操作系统最高效的I/O复用选择器,例如在Linux环境下它使用`EpollSelector`,而在macOS和BSD环境下它使用的是`KqueueSelector`;在Python 2中,`IOLoop`直接使用`select`模块(低级I/O复用模块)的`epoll`或`kqueue`函数,如果这两种方式都不可用,则调用`select`函数实现多路I/O复用。当然,如果要支持高并发,你的系统最好能够支持epoll或者kqueue这两种多路I/O复用方式中的一种。
+
+如果希望通过命令行参数来指定Web应用的监听端口,可以对上面的代码稍作修改。
+
+```Python
+"""
+example01.py
+"""
+import tornado.ioloop
+import tornado.web
+
+from tornado.options import define, options, parse_command_line
+
+
+# 定义默认端口
+define('port', default=8000, type=int)
+
+
+class MainHandler(tornado.web.RequestHandler):
+
+    def get(self):
+        self.write('<h1>Hello, world!</h1>')
+
+
+def main():
+    # python example01.py --port=8000
+    parse_command_line()
+    app = tornado.web.Application(handlers=[(r'/', MainHandler), ])
+    app.listen(options.port)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()
+```
+
+在启动Web应用时,如果没有指定端口,将使用`define`函数中设置的默认端口8000,如果要指定端口,可以使用下面的方式来启动Web应用。
+
+```Shell
+python example01.py --port=8000
+```
+
+### 路由解析
+
+上面我们曾经提到过创建`Application`实例时需要指定`handlers`参数,这个参数非常重要,它应该是一个元组的列表,元组中的第一个元素是正则表达式,它用于匹配用户请求的资源路径;第二个元素是`RequestHandler`的子类。在刚才的例子中,我们只在`handlers`列表中放置了一个元组,事实上我们可以放置多个元组来匹配不同的请求(资源路径),而且可以使用正则表达式的捕获组来获取匹配的内容并将其作为参数传入到`get`、`post`这些方法中。
+
+```Python
+"""
+example02.py
+"""
+import os
+import random
+
+import tornado.ioloop
+import tornado.web
+
+from tornado.options import define, options, parse_command_line
+
+
+# 定义默认端口
+define('port', default=8000, type=int)
+
+
+class SayingHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self):
+        sayings = [
+            '世上没有绝望的处境,只有对处境绝望的人',
+            '人生的道路在态度的岔口一分为二,从此通向成功或失败',
+            '所谓措手不及,不是说没有时间准备,而是有时间的时候没有准备',
+            '那些你认为不靠谱的人生里,充满你没有勇气做的事',
+            '在自己喜欢的时间里,按照自己喜欢的方式,去做自己喜欢做的事,这便是自由',
+            '有些人不属于自己,但是遇见了也弥足珍贵'
+        ]
+        # 渲染index.html模板页
+        self.render('index.html', message=random.choice(sayings))
+
+
+class WeatherHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self, city):
+        # Tornado框架会自动处理百分号编码的问题
+        weathers = {
+            '北京': {'temperature': '-4~4', 'pollution': '195 中度污染'},
+            '成都': {'temperature': '3~9', 'pollution': '53 良'},
+            '深圳': {'temperature': '20~25', 'pollution': '25 优'},
+            '广州': {'temperature': '18~23', 'pollution': '56 良'},
+            '上海': {'temperature': '6~8', 'pollution': '65 良'}
+        }
+        if city in weathers:
+            self.render('weather.html', city=city, weather=weathers[city])
+        else:
+            self.render('index.html', message=f'没有{city}的天气信息')
+
+
+class ErrorHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self):
+        # 重定向到指定的路径
+        self.redirect('/saying')
+
+
+def main():
+    """主函数"""
+    parse_command_line()
+    app = tornado.web.Application(
+        # handlers是按列表中的顺序依次进行匹配的
+        handlers=[
+            (r'/saying/?', SayingHandler),
+            (r'/weather/([^/]{2,})/?', WeatherHandler),
+            (r'/.+', ErrorHandler),
+        ],
+        # 通过template_path参数设置模板页的路径
+        template_path=os.path.join(os.path.dirname(__file__), 'templates')
+    )
+    app.listen(options.port)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()
+```
+
+模板页index.html。
+
+```HTML
+<!-- index.html -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta charset="utf-8">
+	<title>Tornado基础</title>
+</head>
+<body>
+	<h1>{{message}}</h1>
+</body>
+</html>
+```
+
+模板页weather.html。
+
+```HTML
+<!-- weather.html -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta charset="utf-8">
+	<title>Tornado基础</title>
+</head>
+<body>
+	<h1>{{city}}</h1>
+	<hr>
+	<h2>温度:{{weather['temperature']}}摄氏度</h2>
+	<h2>污染指数:{{weather['pollution']}}</h2>
+</body>
+</html>
+```
+
+Tornado的模板语法与其他的Web框架中使用的模板语法并没有什么实质性的区别,而且目前的Web应用开发更倡导使用前端渲染的方式来减轻服务器的负担,所以这里我们并不对模板语法和后端渲染进行深入的讲解。
+
+### 请求处理器
+
+通过上面的代码可以看出,`RequestHandler`是处理用户请求的核心类,通过重写`get`、`post`、`put`、`delete`等方法可以处理不同类型的HTTP请求,除了这些方法之外,`RequestHandler`还实现了很多重要的方法,下面是部分方法的列表:
+
+1. `get_argument` / `get_arguments` / `get_body_argument` / `get_body_arguments` / `get_query_arugment` / `get_query_arguments`:获取请求参数。
+2. `set_status` / `send_error` / `set_header` / `add_header` / `clear_header` / `clear`:操作状态码和响应头。
+3. `write` / `flush` / `finish` / `write_error`:和输出相关的方法。
+4. `render` / `render_string`:渲染模板。
+5. `redirect`:请求重定向。
+6. `get_cookie` / `set_cookie` / `get_secure_cookie` / `set_secure_cookie` / `create_signed_value` / `clear_cookie` / `clear_all_cookies`:操作Cookie。
+
+我们用上面讲到的这些方法来完成下面的需求,访问页面时,如果Cookie中没有读取到用户信息则要求用户填写个人信息,如果从Cookie中读取到用户信息则直接显示用户信息。
+
+```Python
+"""
+example03.py
+"""
+import os
+import re
+
+import tornado.ioloop
+import tornado.web
+
+from tornado.options import define, options, parse_command_line
+
+
+# 定义默认端口
+define('port', default=8000, type=int)
+
+users = {}
+
+
+class User(object):
+    """用户"""
+
+    def __init__(self, nickname, gender, birthday):
+        self.nickname = nickname
+        self.gender = gender
+        self.birthday = birthday
+
+
+class MainHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self):
+        # 从Cookie中读取用户昵称
+        nickname = self.get_cookie('nickname')
+        if nickname in users:
+            self.render('userinfo.html', user=users[nickname])
+        else:
+            self.render('userform.html', hint='请填写个人信息')
+
+
+class UserHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def post(self):
+        # 从表单参数中读取用户昵称、性别和生日信息
+        nickname = self.get_body_argument('nickname').strip()
+        gender = self.get_body_argument('gender')
+        birthday = self.get_body_argument('birthday')
+        # 检查用户昵称是否有效
+        if not re.fullmatch(r'\w{6,20}', nickname):
+            self.render('userform.html', hint='请输入有效的昵称')
+        elif nickname in users:
+            self.render('userform.html', hint='昵称已经被使用过')
+        else:
+            users[nickname] = User(nickname, gender, birthday)
+            # 将用户昵称写入Cookie并设置有效期为7天
+            self.set_cookie('nickname', nickname, expires_days=7)
+            self.render('userinfo.html', user=users[nickname])
+
+
+def main():
+    """主函数"""
+    parse_command_line()
+    app = tornado.web.Application(
+        handlers=[
+            (r'/', MainHandler), (r'/register', UserHandler)
+        ],
+        template_path=os.path.join(os.path.dirname(__file__), 'templates')
+    )
+    app.listen(options.port)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()
+```
+
+模板页userform.html。
+
+```HTML
+<!-- userform.html -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Tornado基础</title>
+	<style>
+		.em { color: red; }
+	</style>
+</head>
+<body>
+    <h1>填写用户信息</h1>
+    <hr>
+	<p class="em">{{hint}}</p>
+    <form action="/register" method="post">
+		<p>
+			<label>昵称:</label>
+			<input type="text" name="nickname">
+			(字母数字下划线,6-20个字符)
+		</p>
+		<p>
+			<label>性别:</label>
+			<input type="radio" name="gender" value="男" checked>男
+			<input type="radio" name="gender" value="女">女
+		</p>
+		<p>
+			<label>生日:</label>
+			<input type="date" name="birthday" value="1990-01-01">
+		</p>
+		<p>
+			<input type="submit" value="确定">
+		</p>
+	</form>
+</body>
+</html>
+```
+
+模板页userinfo.html。
+
+```HTML
+<!-- userinfo.html -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Tornado基础</title>
+</head>
+<body>
+    <h1>用户信息</h1>
+    <hr>
+    <h2>昵称:{{user.nickname}}</h2>
+    <h2>性别:{{user.gender}}</h2>
+    <h2>出生日期:{{user.birthday}}</h2>
+</body>
+</html>
+```

+ 152 - 0
Day61-65/03.异步化.md

@@ -0,0 +1,152 @@
+## 异步化
+
+在前面的例子中,我们并没有对`RequestHandler`中的`get`或`post`方法进行异步处理,这就意味着,一旦在`get`或`post`方法中出现了耗时间的操作,不仅仅是当前请求被阻塞,按照Tornado框架的工作模式,其他的请求也会被阻塞,所以我们需要对耗时间的操作进行异步化处理。
+
+在Tornado稍早一些的版本中,可以用装饰器实现请求方法的异步化或协程化来解决这个问题。
+
+- 给`RequestHandler`的请求处理函数添加`@tornado.web.asynchronous`装饰器,如下所示:
+
+  ```Python
+  class AsyncReqHandler(RequestHandler):
+      
+      @tornado.web.asynchronous
+      def get(self):
+         http = httpclient.AsyncHTTPClient()
+         http.fetch("http://example.com/", self._on_download)
+  
+      def _on_download(self, response):
+         do_something_with_response(response)
+         self.render("template.html")
+  ```
+
+- 给`RequestHandler`的请求处理函数添加`@tornado.gen.coroutine`装饰器,如下所示:
+
+  ```Python
+  class GenAsyncHandler(RequestHandler):
+      
+      @tornado.gen.coroutine
+      def get(self):
+          http_client = AsyncHTTPClient()
+          response = yield http_client.fetch("http://example.com")
+          do_something_with_response(response)
+          self.render("template.html")
+  ```
+
+- 使用`@return_future`装饰器,如下所示:
+
+  ```Python
+  @return_future
+  def future_func(arg1, arg2, callback):
+      # Do stuff (possibly asynchronous)
+      callback(result)
+  
+  async def caller():
+      await future_func(arg1, arg2)
+  ```
+
+在Tornado 5.x版本中,这几个装饰器都被标记为**deprcated**(过时),我们可以通过Python 3.5中引入的`async`和`await`(在Python 3.7中已经成为正式的关键字)来达到同样的效果。当然,要实现异步化还得靠其他的支持异步操作的三方库来支持,如果请求处理函数中用到了不支持异步操作的三方库,就需要靠自己写包装类来支持异步化。
+
+下面的代码演示了在读写数据库时如何实现请求处理的异步化。我们用到的数据库建表语句如下所示:
+
+```SQL
+create database hrs default charset utf8;
+
+use hrs;
+
+/* 创建部门表 */
+create table tb_dept
+(
+    dno     int not null comment '部门编号',
+    dname   varchar(10) not null comment '部门名称',
+    dloc    varchar(20) not null comment '部门所在地',
+    primary key (dno)
+);
+
+insert into tb_dept values
+    (10, '会计部', '北京'),
+    (20, '研发部', '成都'),
+    (30, '销售部', '重庆'),
+    (40, '运维部', '深圳');
+```
+
+我们通过下面的代码实现了查询和新增部门两个操作。
+
+```Python
+import json
+
+import aiomysql
+import tornado
+import tornado.web
+
+from tornado.ioloop import IOLoop
+from tornado.options import define, parse_command_line, options
+
+define('port', default=8000, type=int)
+
+
+async def connect_mysql():
+    return await aiomysql.connect(
+        host='120.77.222.217',
+        port=3306,
+        db='hrs',
+        user='root',
+        password='123456',
+    )
+
+
+class HomeHandler(tornado.web.RequestHandler):
+
+    async def get(self, no):
+        async with self.settings['mysql'].cursor(aiomysql.DictCursor) as cursor:
+            await cursor.execute("select * from tb_dept where dno=%s", (no, ))
+            if cursor.rowcount == 0:
+                self.finish(json.dumps({
+                    'code': 20001,
+                    'mesg': f'没有编号为{no}的部门'
+                }))
+                return
+            row = await cursor.fetchone()
+            self.finish(json.dumps(row))
+
+    async def post(self, *args, **kwargs):
+        no = self.get_argument('no')
+        name = self.get_argument('name')
+        loc = self.get_argument('loc')
+        conn = self.settings['mysql']
+        try:
+            async with conn.cursor() as cursor:
+                await cursor.execute('insert into tb_dept values (%s, %s, %s)',
+                                     (no, name, loc))
+            await conn.commit()
+        except aiomysql.MySQLError:
+            self.finish(json.dumps({
+                'code': 20002,
+                'mesg': '添加部门失败请确认部门信息'
+            }))
+        else:
+            self.set_status(201)
+            self.finish()
+
+
+def make_app(config):
+    return tornado.web.Application(
+        handlers=[(r'/api/depts/(.*)', HomeHandler), ],
+        **config
+    )
+
+
+def main():
+    parse_command_line()
+    app = make_app({
+        'debug': True,
+        'mysql': IOLoop.current().run_sync(connect_mysql)
+    })
+    app.listen(options.port)
+    IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()
+```
+
+上面的代码中,我们用到了`aiomysql`这个三方库,它基于`pymysql`封装,实现了对MySQL操作的异步化。操作Redis可以使用`aioredis`,访问MongoDB可以使用`motor`,这些都是支持异步操作的三方库。

+ 228 - 0
Day61-65/04.WebSocket的应用.md

@@ -0,0 +1,228 @@
+## WebSocket的应用
+
+Tornado的异步特性使其非常适合处理高并发的业务,同时也适合那些需要在客户端和服务器之间维持长连接的业务。传统的基于HTTP协议的Web应用,服务器和客户端(浏览器)的通信只能由客户端发起,这种单向请求注定了如果服务器有连续的状态变化,客户端(浏览器)是很难得知的。事实上,今天的很多Web应用都需要服务器主动向客户端(浏览器)发送数据,我们将这种通信方式称之为“推送”。过去很长一段时间,程序员都是用定时轮询(Polling)或长轮询(Long Polling)等方式来实现“推送”,但是这些都不是真正意义上的“推送”,而且浪费资源且效率低下。在HTML5时代,可以通过一种名为WebSocket的技术在服务器和客户端(浏览器)之间维持传输数据的长连接,这种方式可以实现真正的“推送”服务。
+
+### WebSocket简介
+
+WebSocket 协议在2008年诞生,2011年成为国际标准([RFC 6455](https://tools.ietf.org/html/rfc6455)),现在的浏览器都能够支持它,它可以实现浏览器和服务器之间的全双工通信。我们之前学习或了解过Python的Socket编程,通过Socket编程,可以基于TCP或UDP进行数据传输;而WebSocket与之类似,只不过它是基于HTTP来实现通信握手,使用TCP来进行数据传输。WebSocket的出现打破了HTTP请求和响应只能一对一通信的模式,也改变了服务器只能被动接受客户端请求的状况。目前有很多Web应用是需要服务器主动向客户端发送信息的,例如股票信息的网站可能需要向浏览器发送股票涨停通知,社交网站可能需要向用户发送好友上线提醒或聊天信息。
+
+![](./res/websocket.png)
+
+WebSocket的特点如下所示:
+
+1. 建立在TCP协议之上,服务器端的实现比较容易。
+2. 与HTTP协议有着良好的兼容性,默认端口是80(WS)和443(WSS),通信握手阶段采用HTTP协议,能通过各种 HTTP 代理服务器(不容易被防火墙阻拦)。
+3. 数据格式比较轻量,性能开销小,通信高效。
+4. 可以发送文本,也可以发送二进制数据。
+5. 没有同源策略的限制,客户端(浏览器)可以与任意服务器通信。
+
+![](./res/ws_wss.png)
+
+### WebSocket服务器端编程
+
+Tornado框架中有一个`tornado.websocket.WebSocketHandler`类专门用于处理来自WebSocket的请求,通过继承该类并重写`open`、`on_message`、`on_close` 等方法来处理WebSocket通信,下面我们对`WebSocketHandler`的核心方法做一个简单的介绍。
+
+1. `open(*args, **kwargs)`方法:建立新的WebSocket连接后,Tornado框架会调用该方法,该方法的参数与`RequestHandler`的`get`方法的参数类似,这也就意味着在`open`方法中可以执行获取请求参数、读取Cookie信息这样的操作。
+
+2. `on_message(message)`方法:建立WebSocket之后,当收到来自客户端的消息时,Tornado框架会调用该方法,这样就可以对收到的消息进行对应的处理,必须重写这个方法。
+
+3. `on_close()`方法:当WebSocket被关闭时,Tornado框架会调用该方法,在该方法中可以通过`close_code`和`close_reason`了解关闭的原因。
+
+4. `write_message(message, binary=False)`方法:将指定的消息通过WebSocket发送给客户端,可以传递utf-8字符序列或者字节序列,如果message是一个字典,将会执行JSON序列化。正常情况下,该方法会返回一个`Future`对象;如果WebSocket被关闭了,将引发`WebSocketClosedError`。
+
+5. `set_nodelay(value)`方法:默认情况下,因为TCP的Nagle算法会导致短小的消息被延迟发送,在考虑到交互性的情况下就要通过将该方法的参数设置为`True`来避免延迟。
+
+6. `close(code=None, reason=None)`方法:主动关闭WebSocket,可以指定状态码(详见[RFC 6455 7.4.1节](https://tools.ietf.org/html/rfc6455#section-7.4.1))和原因。
+
+### WebSocket客户端编程
+
+1. 创建WebSocket对象。
+
+   ```JavaScript
+   var webSocket = new WebSocket('ws://localhost:8000/ws');
+   ```
+
+   >说明:webSocket对象的readyState属性表示该对象当前状态,取值为CONNECTING-正在连接,OPEN-连接成功可以通信,CLOSING-正在关闭,CLOSED-已经关闭。
+
+2. 编写回调函数。
+
+   ```JavaScript
+   webSocket.onopen = function(evt) { webSocket.send('...'); };
+   webSocket.onmessage = function(evt) { console.log(evt.data); };
+   webSocket.onclose = function(evt) {};
+   webSocket.onerror = function(evt) {};
+   ```
+
+   > 说明:如果要绑定多个事件回调函数,可以用addEventListener方法。另外,通过事件对象的data属性获得的数据可能是字符串,也有可能是二进制数据,可以通过webSocket对象的binaryType属性(blob、arraybuffer)或者通过typeof、instanceof运算符检查类型进行判定。
+
+### 项目:Web聊天室
+
+```Python
+"""
+handlers.py - 用户登录和聊天的处理器
+"""
+import tornado.web
+import tornado.websocket
+
+nicknames = set()
+connections = {}
+
+
+class LoginHandler(tornado.web.RequestHandler):
+
+    def get(self):
+        self.render('login.html', hint='')
+
+    def post(self):
+        nickname = self.get_argument('nickname')
+        if nickname in nicknames:
+            self.render('login.html', hint='昵称已被使用,请更换昵称')
+        self.set_secure_cookie('nickname', nickname)
+        self.render('chat.html')
+
+
+class ChatHandler(tornado.websocket.WebSocketHandler):
+
+    def open(self):
+        nickname = self.get_secure_cookie('nickname').decode()
+        nicknames.add(nickname)
+        for conn in connections.values():
+            conn.write_message(f'~~~{nickname}进入了聊天室~~~')
+        connections[nickname] = self
+
+    def on_message(self, message):
+        nickname = self.get_secure_cookie('nickname').decode()
+        for conn in connections.values():
+            if conn is not self:
+                conn.write_message(f'{nickname}说:{message}')
+
+    def on_close(self):
+        nickname = self.get_secure_cookie('nickname').decode()
+        del connections[nickname]
+        nicknames.remove(nickname)
+        for conn in connections.values():
+            conn.write_message(f'~~~{nickname}离开了聊天室~~~')
+
+```
+
+```Python
+"""
+run_chat_server.py - 聊天服务器
+"""
+import os
+
+import tornado.web
+import tornado.ioloop
+
+from handlers import LoginHandler, ChatHandler
+
+
+if __name__ == '__main__':
+    app = tornado.web.Application(
+        handlers=[(r'/login', LoginHandler), (r'/chat', ChatHandler)],
+        template_path=os.path.join(os.path.dirname(__file__), 'templates'),
+        static_path=os.path.join(os.path.dirname(__file__), 'static'),
+        cookie_secret='MWM2MzEyOWFlOWRiOWM2MGMzZThhYTk0ZDNlMDA0OTU=',
+    )
+    app.listen(8888)
+    tornado.ioloop.IOLoop.current().start()
+```
+
+```HTML
+<!-- login.html -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>Tornado聊天室</title>
+    <style>
+        .hint { color: red; font-size: 0.8em; }
+    </style>
+</head>
+<body>
+    <div>
+        <div id="container">
+            <h1>进入聊天室</h1>
+            <hr>
+            <p class="hint">{{hint}}</p>
+            <form method="post" action="/login">
+                <label>昵称:</label>
+                <input type="text" placeholder="请输入你的昵称" name="nickname">
+                <button type="submit">登录</button>
+            </form>
+        </div>
+    </div>
+</body>
+</html>
+```
+
+```HTML
+<!-- chat.html -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Tornado聊天室</title>
+</head>
+<body>
+    <h1>聊天室</h1>
+    <hr>
+    <div>
+        <textarea id="contents" rows="20" cols="120" readonly></textarea>
+    </div>
+    <div class="send">
+        <input type="text" id="content" size="50">
+        <input type="button" id="send" value="发送">
+    </div>
+    <p>
+        <a id="quit" href="javascript:void(0);">退出聊天室</a>
+    </p>
+    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
+    <script>
+        $(function() {
+            // 将内容追加到指定的文本区
+            function appendContent($ta, message) {
+                var contents = $ta.val();
+                contents += '\n' + message;
+                $ta.val(contents);
+                $ta[0].scrollTop = $ta[0].scrollHeight;
+            }
+            // 通过WebSocket发送消息
+            function sendMessage() {
+                message = $('#content').val().trim();
+                if (message.length > 0) {
+                    ws.send(message);
+                    appendContent($('#contents'), '我说:' + message);
+                    $('#content').val('');
+                }
+            }
+            // 创建WebSocket对象
+            var ws= new WebSocket('ws://localhost:8888/chat');
+            // 连接建立后执行的回调函数
+            ws.onopen = function(evt) {
+                $('#contents').val('~~~欢迎您进入聊天室~~~');
+            };
+            // 收到消息后执行的回调函数
+            ws.onmessage = function(evt) {
+                appendContent($('#contents'), evt.data);
+            };
+            // 为发送按钮绑定点击事件回调函数
+            $('#send').on('click', sendMessage);
+            // 为文本框绑定按下回车事件回调函数
+            $('#content').on('keypress', function(evt) {
+                keycode = evt.keyCode || evt.which;
+                if (keycode == 13) {
+                    sendMessage();
+                }
+            });
+            // 为退出聊天室超链接绑定点击事件回调函数
+            $('#quit').on('click', function(evt) {
+                ws.close();
+                location.href = '/login';
+            });
+        });
+    </script>
+</body>
+</html>
+```
+

+ 2 - 0
Day61-65/05.项目实战.md

@@ -0,0 +1,2 @@
+## 项目实战
+

+ 44 - 0
Day61-65/code/hello-tornado/chat_handlers.py

@@ -0,0 +1,44 @@
+"""
+handlers.py - 用户登录和聊天的处理器
+"""
+import tornado.web
+import tornado.websocket
+
+nicknames = set()
+connections = {}
+
+
+class LoginHandler(tornado.web.RequestHandler):
+
+    def get(self):
+        self.render('login.html', hint='')
+
+    def post(self):
+        nickname = self.get_argument('nickname')
+        if nickname in nicknames:
+            self.render('login.html', hint='昵称已被使用,请更换昵称')
+        self.set_secure_cookie('nickname', nickname)
+        self.render('chat.html')
+
+
+class ChatHandler(tornado.websocket.WebSocketHandler):
+
+    def open(self):
+        nickname = self.get_secure_cookie('nickname').decode()
+        nicknames.add(nickname)
+        for conn in connections.values():
+            conn.write_message(f'~~~{nickname}进入了聊天室~~~')
+        connections[nickname] = self
+
+    def on_message(self, message):
+        nickname = self.get_secure_cookie('nickname').decode()
+        for conn in connections.values():
+            if conn is not self:
+                conn.write_message(f'{nickname}说:{message}')
+
+    def on_close(self):
+        nickname = self.get_secure_cookie('nickname').decode()
+        del connections[nickname]
+        nicknames.remove(nickname)
+        for conn in connections.values():
+            conn.write_message(f'~~~{nickname}离开了聊天室~~~')

+ 24 - 0
Day61-65/code/hello-tornado/chat_server.py

@@ -0,0 +1,24 @@
+"""
+chat_server.py - 聊天服务器
+"""
+import os
+
+import tornado.web
+import tornado.ioloop
+
+from chat_handlers import LoginHandler, ChatHandler
+
+
+def main():
+    app = tornado.web.Application(
+        handlers=[(r'/login', LoginHandler), (r'/chat', ChatHandler)],
+        template_path=os.path.join(os.path.dirname(__file__), 'templates'),
+        static_path=os.path.join(os.path.dirname(__file__), 'static'),
+        cookie_secret='MWM2MzEyOWFlOWRiOWM2MGMzZThhYTk0ZDNlMDA0OTU=',
+    )
+    app.listen(8888)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()

+ 36 - 0
Day61-65/code/hello-tornado/example01.py

@@ -0,0 +1,36 @@
+"""
+example01.py - 五分钟上手Tornado
+"""
+import tornado.ioloop
+import tornado.web
+
+from tornado.options import define, options, parse_command_line
+
+# 定义默认端口
+define('port', default=8000, type=int)
+
+
+class MainHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self):
+        # 向客户端(浏览器)写入内容
+        self.write('<h1>Hello, world!</h1>')
+
+
+def main():
+    """主函数"""
+    # 解析命令行参数,例如:
+    # python example01.py --port 8888
+    parse_command_line()
+    # 创建了Tornado框架中Application类的实例并指定handlers参数
+    # Application实例代表了我们的Web应用,handlers代表了路由解析
+    app = tornado.web.Application(handlers=[(r'/', MainHandler), ])
+    # 指定了监听HTTP请求的TCP端口(默认8000,也可以通过命令行参数指定)
+    app.listen(options.port)
+    # 获取Tornado框架的IOLoop实例并启动它(默认启动asyncio的事件循环)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()

+ 77 - 0
Day61-65/code/hello-tornado/example02.py

@@ -0,0 +1,77 @@
+"""
+example02.py - 路由解析
+"""
+import os
+import random
+
+import tornado.ioloop
+import tornado.web
+
+from tornado.options import define, options, parse_command_line
+
+
+# 定义默认端口
+define('port', default=8000, type=int)
+
+
+class SayingHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self):
+        sayings = [
+            '世上没有绝望的处境,只有对处境绝望的人',
+            '人生的道路在态度的岔口一分为二,从此通向成功或失败',
+            '所谓措手不及,不是说没有时间准备,而是有时间的时候没有准备',
+            '那些你认为不靠谱的人生里,充满你没有勇气做的事',
+            '在自己喜欢的时间里,按照自己喜欢的方式,去做自己喜欢做的事,这便是自由',
+            '有些人不属于自己,但是遇见了也弥足珍贵'
+        ]
+        # 渲染index.html模板页
+        self.render('index.html', message=random.choice(sayings))
+
+
+class WeatherHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self, city):
+        # Tornado框架会自动处理百分号编码的问题
+        weathers = {
+            '北京': {'temperature': '-4~4', 'pollution': '195 中度污染'},
+            '成都': {'temperature': '3~9', 'pollution': '53 良'},
+            '深圳': {'temperature': '20~25', 'pollution': '25 优'},
+            '广州': {'temperature': '18~23', 'pollution': '56 良'},
+            '上海': {'temperature': '6~8', 'pollution': '65 良'}
+        }
+        if city in weathers:
+            self.render('weather.html', city=city, weather=weathers[city])
+        else:
+            self.render('index.html', message=f'没有{city}的天气信息')
+
+
+class ErrorHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self):
+        # 重定向到指定的路径
+        self.redirect('/saying')
+
+
+def main():
+    """主函数"""
+    parse_command_line()
+    app = tornado.web.Application(
+        # handlers是按列表中的顺序依次进行匹配的
+        handlers=[
+            (r'/saying/?', SayingHandler),
+            (r'/weather/([^/]{2,})/?', WeatherHandler),
+            (r'/.+', ErrorHandler),
+        ],
+        # 通过template_path参数设置模板页的路径
+        template_path=os.path.join(os.path.dirname(__file__), 'templates')
+    )
+    app.listen(options.port)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()

+ 75 - 0
Day61-65/code/hello-tornado/example03.py

@@ -0,0 +1,75 @@
+"""
+example03.py - RequestHandler解析
+"""
+import os
+import re
+
+import tornado.ioloop
+import tornado.web
+
+from tornado.options import define, options, parse_command_line
+
+
+# 定义默认端口
+define('port', default=8000, type=int)
+
+users = {}
+
+
+class User(object):
+    """用户"""
+
+    def __init__(self, nickname, gender, birthday):
+        self.nickname = nickname
+        self.gender = gender
+        self.birthday = birthday
+
+
+class MainHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self):
+        # 从Cookie中读取用户昵称
+        nickname = self.get_cookie('nickname')
+        if nickname in users:
+            self.render('userinfo.html', user=users[nickname])
+        else:
+            self.render('userform.html', hint='请填写个人信息')
+
+
+class UserHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def post(self):
+        # 从表单参数中读取用户昵称、性别和生日信息
+        nickname = self.get_body_argument('nickname').strip()
+        gender = self.get_body_argument('gender')
+        birthday = self.get_body_argument('birthday')
+        # 检查用户昵称是否有效
+        if not re.fullmatch(r'\w{6,20}', nickname):
+            self.render('userform.html', hint='请输入有效的昵称')
+        elif nickname in users:
+            self.render('userform.html', hint='昵称已经被使用过')
+        else:
+            users[nickname] = User(nickname, gender, birthday)
+            # 将用户昵称写入Cookie并设置有效期为7天
+            self.set_cookie('nickname', nickname, expires_days=7)
+            self.render('userinfo.html', user=users[nickname])
+
+
+def main():
+    """主函数"""
+    parse_command_line()
+    app = tornado.web.Application(
+        handlers=[
+            (r'/', MainHandler),
+            (r'/register', UserHandler),
+        ],
+        template_path=os.path.join(os.path.dirname(__file__), 'templates'),
+    )
+    app.listen(options.port)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()

+ 42 - 0
Day61-65/code/hello-tornado/example04.py

@@ -0,0 +1,42 @@
+"""
+example04.py - 同步请求的例子
+"""
+import json
+import os
+
+import requests
+import tornado.gen
+import tornado.ioloop
+import tornado.web
+import tornado.websocket
+import tornado.httpclient
+from tornado.options import define, options, parse_command_line
+
+define('port', default=8888, type=int)
+
+REQ_URL = 'http://api.tianapi.com/guonei/'
+API_KEY = '772a81a51ae5c780251b1f98ea431b84'
+
+
+class MainHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    def get(self):
+        resp = requests.get(f'{REQ_URL}?key={API_KEY}')
+        newslist = json.loads(resp.text)['newslist']
+        self.render('news.html', newslist=newslist)
+
+
+def main():
+    """主函数"""
+    parse_command_line()
+    app = tornado.web.Application(
+        handlers=[(r'/', MainHandler), ],
+        template_path=os.path.join(os.path.dirname(__file__), 'templates'),
+    )
+    app.listen(options.port)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()

+ 45 - 0
Day61-65/code/hello-tornado/example05.py

@@ -0,0 +1,45 @@
+"""
+example05.py - 异步请求的例子
+"""
+import aiohttp
+import json
+import os
+
+import tornado.gen
+import tornado.ioloop
+import tornado.web
+import tornado.websocket
+import tornado.httpclient
+from tornado.options import define, options, parse_command_line
+
+define('port', default=8888, type=int)
+
+REQ_URL = 'http://api.tianapi.com/guonei/'
+API_KEY = '772a81a51ae5c780251b1f98ea431b84'
+
+
+class MainHandler(tornado.web.RequestHandler):
+    """自定义请求处理器"""
+
+    async def get(self):
+        async with aiohttp.ClientSession() as session:
+            resp = await session.get(f'{REQ_URL}?key={API_KEY}')
+            json_str = await resp.text()
+            print(json_str)
+            newslist = json.loads(json_str)['newslist']
+            self.render('news.html', newslist=newslist)
+
+
+def main():
+    """主函数"""
+    parse_command_line()
+    app = tornado.web.Application(
+        handlers=[(r'/', MainHandler), ],
+        template_path=os.path.join(os.path.dirname(__file__), 'templates'),
+    )
+    app.listen(options.port)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()

+ 80 - 0
Day61-65/code/hello-tornado/example06.py

@@ -0,0 +1,80 @@
+"""
+example06.py - 异步操作MySQL
+"""
+import json
+
+import aiomysql
+import tornado
+import tornado.web
+
+from tornado.ioloop import IOLoop
+from tornado.options import define, parse_command_line, options
+
+define('port', default=8888, type=int)
+
+
+async def connect_mysql():
+    return await aiomysql.connect(
+        host='120.77.222.217',
+        port=3306,
+        db='hrs',
+        charset='utf8',
+        use_unicode=True,
+        user='root',
+        password='123456',
+    )
+
+
+class HomeHandler(tornado.web.RequestHandler):
+
+    async def get(self, no):
+        async with self.settings['mysql'].cursor(aiomysql.DictCursor) as cursor:
+            await cursor.execute("select * from tb_dept where dno=%s", (no, ))
+            if cursor.rowcount == 0:
+                self.finish(json.dumps({
+                    'code': 20001,
+                    'mesg': f'没有编号为{no}的部门'
+                }))
+                return
+            row = await cursor.fetchone()
+            self.finish(json.dumps(row))
+
+    async def post(self, *args, **kwargs):
+        no = self.get_argument('no')
+        name = self.get_argument('name')
+        loc = self.get_argument('loc')
+        conn = self.settings['mysql']
+        try:
+            async with conn.cursor() as cursor:
+                await cursor.execute('insert into tb_dept values (%s, %s, %s)',
+                                     (no, name, loc))
+            await conn.commit()
+        except aiomysql.MySQLError:
+            self.finish(json.dumps({
+                'code': 20002,
+                'mesg': '添加部门失败请确认部门信息'
+            }))
+        else:
+            self.set_status(201)
+            self.finish()
+
+
+def make_app(config):
+    return tornado.web.Application(
+        handlers=[(r'/api/depts/(.*)', HomeHandler), ],
+        **config
+    )
+
+
+def main():
+    parse_command_line()
+    app = make_app({
+        'debug': True,
+        'mysql': IOLoop.current().run_sync(connect_mysql)
+    })
+    app.listen(options.port)
+    IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()

+ 92 - 0
Day61-65/code/hello-tornado/example07.py

@@ -0,0 +1,92 @@
+"""
+example07.py - 将非异步的三方库封装为异步调用
+"""
+import asyncio
+import concurrent
+import json
+
+import tornado
+import tornado.web
+import pymysql
+
+from pymysql import connect
+from pymysql.cursors import DictCursor
+
+from tornado.ioloop import IOLoop
+from tornado.options import define, parse_command_line, options
+from tornado.platform.asyncio import AnyThreadEventLoopPolicy
+
+define('port', default=8888, type=int)
+
+
+def get_mysql_connection():
+    return connect(
+        host='120.77.222.217',
+        port=3306,
+        db='hrs',
+        charset='utf8',
+        use_unicode=True,
+        user='root',
+        password='123456',
+    )
+
+
+class HomeHandler(tornado.web.RequestHandler):
+    executor = concurrent.futures.ThreadPoolExecutor(max_workers=10)
+
+    async def get(self, no):
+        return await self._get(no)
+
+    @tornado.concurrent.run_on_executor
+    def _get(self, no):
+        con = get_mysql_connection()
+        try:
+            with con.cursor(DictCursor) as cursor:
+                cursor.execute("select * from tb_dept where dno=%s", (no, ))
+                if cursor.rowcount == 0:
+                    self.finish(json.dumps({
+                        'code': 20001,
+                        'mesg': f'没有编号为{no}的部门'
+                    }))
+                    return
+                row = cursor.fetchone()
+                self.finish(json.dumps(row))
+        finally:
+            con.close()
+
+    async def post(self, *args, **kwargs):
+        return await self._post(*args, **kwargs)
+
+    @tornado.concurrent.run_on_executor
+    def _post(self, *args, **kwargs):
+        no = self.get_argument('no')
+        name = self.get_argument('name')
+        loc = self.get_argument('loc')
+        conn = get_mysql_connection()
+        try:
+            with conn.cursor() as cursor:
+                cursor.execute('insert into tb_dept values (%s, %s, %s)',
+                               (no, name, loc))
+            conn.commit()
+        except pymysql.MySQLError:
+            self.finish(json.dumps({
+                'code': 20002,
+                'mesg': '添加部门失败请确认部门信息'
+            }))
+        else:
+            self.set_status(201)
+            self.finish()
+
+
+def main():
+    asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
+    parse_command_line()
+    app = tornado.web.Application(
+        handlers=[(r'/api/depts/(.*)', HomeHandler), ]
+    )
+    app.listen(options.port)
+    IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()

+ 30 - 0
Day61-65/code/hello-tornado/example_of_aiohttp.py

@@ -0,0 +1,30 @@
+import asyncio
+import re
+
+import aiohttp
+
+PATTERN = re.compile(r'\<title\>(?P<title>.*)\<\/title\>')
+
+
+async def show_title(url):
+    async with aiohttp.ClientSession() as session:
+        resp = await session.get(url, ssl=False)
+        html = await resp.text()
+        print(PATTERN.search(html).group('title'))
+
+
+def main():
+    urls = ('https://www.python.org/',
+            'https://git-scm.com/',
+            'https://www.jd.com/',
+            'https://www.taobao.com/',
+            'https://www.douban.com/')
+    # asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
+    # 获取事件循环()
+    loop = asyncio.get_event_loop()
+    tasks = [show_title(url) for url in urls]
+    loop.run_until_complete(asyncio.wait(tasks))
+
+
+if __name__ == '__main__':
+    main()

+ 40 - 0
Day61-65/code/hello-tornado/example_of_asyncio.py

@@ -0,0 +1,40 @@
+import asyncio
+
+
+async def fetch(host):
+    """从指定的站点抓取信息(协程函数)"""
+    print(f'Start fetching {host}\n')
+    # 跟服务器建立连接
+    reader, writer = await asyncio.open_connection(host, 80)
+    # 构造请求行和请求头
+    writer.write(b'GET / HTTP/1.1\r\n')
+    writer.write(f'Host: {host}\r\n'.encode())
+    writer.write(b'\r\n')
+    # 清空缓存区(发送请求)
+    await writer.drain()
+    # 接收服务器的响应(读取响应行和响应头)
+    line = await reader.readline()
+    while line != b'\r\n':
+        print(line.decode().rstrip())
+        line = await reader.readline()
+    print('\n')
+    writer.close()
+
+
+def main():
+    """主函数"""
+    urls = ('www.sohu.com', 'www.douban.com', 'www.163.com')
+    # 获取系统默认的事件循环
+    loop = asyncio.get_event_loop()
+    # 用生成式语法构造一个包含多个协程对象的列表
+    tasks = [fetch(url) for url in urls]
+    # 通过asyncio模块的wait函数将协程列表包装成Task(Future子类)并等待其执行完成
+    # 通过事件循环的run_until_complete方法运行任务直到Future完成并返回它的结果
+    futures = asyncio.wait(tasks)
+    print(futures, type(futures))
+    loop.run_until_complete(futures)
+    loop.close()
+
+
+if __name__ == '__main__':
+    main()

+ 50 - 0
Day61-65/code/hello-tornado/example_of_coroutine.py

@@ -0,0 +1,50 @@
+"""
+协程(coroutine)- 可以在需要时进行切换的相互协作的子程序
+"""
+import asyncio
+
+from example_of_multiprocess import is_prime
+
+
+def num_generator(m, n):
+    """指定范围的数字生成器"""
+    for num in range(m, n + 1):
+        print(f'generate number: {num}')
+        yield num
+
+
+async def prime_filter(m, n):
+    """素数过滤器"""
+    primes = []
+    for i in num_generator(m, n):
+        if is_prime(i):
+            print('Prime =>', i)
+            primes.append(i)
+
+        await asyncio.sleep(0.001)
+    return tuple(primes)
+
+
+async def square_mapper(m, n):
+    """平方映射器"""
+    squares = []
+    for i in num_generator(m, n):
+        print('Square =>', i * i)
+        squares.append(i * i)
+
+        await asyncio.sleep(0.001)
+    return squares
+
+
+def main():
+    """主函数"""
+    loop = asyncio.get_event_loop()
+    start, end = 1, 100
+    futures = asyncio.gather(prime_filter(start, end), square_mapper(start, end))
+    futures.add_done_callback(lambda x: print(x.result()))
+    loop.run_until_complete(futures)
+    loop.close()
+
+
+if __name__ == '__main__':
+    main()

+ 49 - 0
Day61-65/code/hello-tornado/example_of_multiprocess.py

@@ -0,0 +1,49 @@
+"""
+用下面的命令运行程序并查看执行时间,例如:
+time python3 example05.py
+real    0m20.657s
+user    1m17.749s
+sys     0m0.158s
+使用多进程后实际执行时间为20.657秒,而用户时间1分17.749秒约为实际执行时间的4倍
+这就证明我们的程序通过多进程使用了CPU的多核特性,而且这台计算机配置了4核的CPU
+"""
+import concurrent.futures
+import math
+
+PRIMES = [
+    1116281,
+    1297337,
+    104395303,
+    472882027,
+    533000389,
+    817504243,
+    982451653,
+    112272535095293,
+    112582705942171,
+    112272535095293,
+    115280095190773,
+    115797848077099,
+    1099726899285419
+] * 5
+
+
+def is_prime(num):
+    """判断素数"""
+    assert num > 0
+    if num % 2 == 0:
+        return False
+    for i in range(3, int(math.sqrt(num)) + 1, 2):
+        if num % i == 0:
+            return False
+    return num != 1
+
+
+def main():
+    """主函数"""
+    with concurrent.futures.ProcessPoolExecutor() as executor:
+        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
+            print('%d is prime: %s' % (number, prime))
+
+
+if __name__ == '__main__':
+    main()

+ 18 - 0
Day61-65/code/hello-tornado/requirements.txt

@@ -0,0 +1,18 @@
+aiohttp==3.5.4
+aiomysql==0.0.20
+asn1crypto==0.24.0
+async-timeout==3.0.1
+attrs==19.1.0
+certifi==2019.3.9
+cffi==1.12.2
+chardet==3.0.4
+cryptography==2.6.1
+idna==2.8
+multidict==4.5.2
+pycparser==2.19
+PyMySQL==0.9.2
+requests==2.21.0
+six==1.12.0
+tornado==5.1.1
+urllib3==1.24.1
+yarl==1.3.0

+ 67 - 0
Day61-65/code/hello-tornado/templates/chat.html

@@ -0,0 +1,67 @@
+<!-- chat.html -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Tornado聊天室</title>
+</head>
+<body>
+    <h1>聊天室</h1>
+    <hr>
+    <div>
+        <textarea id="contents" rows="20" cols="120" readonly></textarea>
+    </div>
+    <div class="send">
+        <input type="text" id="content" size="50">
+        <input type="button" id="send" value="发送">
+    </div>
+    <p>
+        <a id="quit" href="javascript:void(0);">退出聊天室</a>
+    </p>
+    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
+    <script>
+        $(function() {
+            // 将内容追加到指定的文本区
+            function appendContent($ta, message) {
+                var contents = $ta.val();
+                contents += '\n' + message;
+                $ta.val(contents);
+                $ta[0].scrollTop = $ta[0].scrollHeight;
+            }
+            // 通过WebSocket发送消息
+            function sendMessage() {
+                message = $('#content').val().trim();
+                if (message.length > 0) {
+                    ws.send(message);
+                    appendContent($('#contents'), '我说:' + message);
+                    $('#content').val('');
+                }
+            }
+            // 创建WebSocket对象
+            var ws= new WebSocket('ws://localhost:8888/chat');
+            // 连接建立后执行的回调函数
+            ws.onopen = function(evt) {
+                $('#contents').val('~~~欢迎您进入聊天室~~~');
+            };
+            // 收到消息后执行的回调函数
+            ws.onmessage = function(evt) {
+                appendContent($('#contents'), evt.data);
+            };
+            // 为发送按钮绑定点击事件回调函数
+            $('#send').on('click', sendMessage);
+            // 为文本框绑定按下回车事件回调函数
+            $('#content').on('keypress', function(evt) {
+                keycode = evt.keyCode || evt.which;
+                if (keycode == 13) {
+                    sendMessage();
+                }
+            });
+            // 为退出聊天室超链接绑定点击事件回调函数
+            $('#quit').on('click', function(evt) {
+                ws.close();
+                location.href = '/login';
+            });
+        });
+    </script>
+</body>
+</html>

+ 25 - 0
Day61-65/code/hello-tornado/templates/login.html

@@ -0,0 +1,25 @@
+<!-- login.html -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>Tornado聊天室</title>
+    <style>
+        .hint { color: red; font-size: 0.8em; }
+    </style>
+</head>
+<body>
+    <div>
+        <div id="container">
+            <h1>进入聊天室</h1>
+            <hr>
+            <p class="hint">{{hint}}</p>
+            <form method="post" action="/login">
+                <label>昵称:</label>
+                <input type="text" placeholder="请输入你的昵称" name="nickname">
+                <button type="submit">登录</button>
+            </form>
+        </div>
+    </div>
+</body>
+</html>

+ 17 - 0
Day61-65/code/hello-tornado/templates/news.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>新闻列表</title>
+</head>
+<body>
+    <h1>新闻列表</h1>
+    <hr>
+    {% for news in newslist %}
+    <div>
+        <img src="{{news['picUrl']}}" alt="">
+        <p>{{news['title']}}</p>
+    </div>
+    {% end %}
+</body>
+</html>

+ 373 - 0
Day61-65/code/project_of_tornado/assets/css/admin.css

@@ -0,0 +1,373 @@
+/**
+ * admin.css
+ */
+
+
+/*
+ fixed-layout 固定头部和边栏布局
+*/
+
+html,
+body {
+  height: 100%;
+  overflow: hidden;
+}
+
+ul {
+  margin-top: 0;
+}
+
+.admin-icon-yellow {
+  color: #ffbe40;
+}
+
+.admin-header {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: 1500;
+  font-size: 1.4rem;
+  margin-bottom: 0;
+}
+
+.admin-header-list a:hover :after {
+  content: none;
+}
+
+.admin-main {
+  position: relative;
+  height: 100%;
+  padding-top: 51px;
+  background: #f3f3f3;
+}
+
+.admin-menu {
+  position: fixed;
+  z-index: 10;
+  bottom: 30px;
+  right: 20px;
+}
+
+.admin-sidebar {
+  width: 260px;
+  min-height: 100%;
+  float: left;
+  border-right: 1px solid #cecece;
+}
+
+.admin-sidebar.am-active {
+  z-index: 1600;
+}
+
+.admin-sidebar-list {
+  margin-bottom: 0;
+}
+
+.admin-sidebar-list li a {
+  color: #5c5c5c;
+  padding-left: 24px;
+}
+
+.admin-sidebar-list li:first-child {
+  border-top: none;
+}
+
+.admin-sidebar-sub {
+  margin-top: 0;
+  margin-bottom: 0;
+  box-shadow: 0 16px 8px -15px #e2e2e2 inset;
+  background: #ececec;
+  padding-left: 24px;
+}
+
+.admin-sidebar-sub li:first-child {
+  border-top: 1px solid #dedede;
+}
+
+.admin-sidebar-panel {
+  margin: 10px;
+}
+
+.admin-content {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-box-orient: vertical;
+  -webkit-box-direction: normal;
+  -webkit-flex-direction: column;
+  -ms-flex-direction: column;
+  flex-direction: column;
+  background: #fff;
+}
+
+.admin-content,
+.admin-sidebar {
+  height: 100%;
+  overflow-x: hidden;
+  overflow-y: scroll;
+  -webkit-overflow-scrolling: touch;
+}
+
+.admin-content-body {
+  -webkit-box-flex: 1;
+  -webkit-flex: 1 0 auto;
+  -ms-flex: 1 0 auto;
+  flex: 1 0 auto;
+}
+
+.admin-content-footer {
+  font-size: 85%;
+  color: #777;
+}
+
+.admin-content-list {
+  border: 1px solid #e9ecf1;
+  margin-top: 0;
+}
+
+.admin-content-list li {
+  border: 1px solid #e9ecf1;
+  border-width: 0 1px;
+  margin-left: -1px;
+}
+
+.admin-content-list li:first-child {
+  border-left: none;
+}
+
+.admin-content-list li:last-child {
+  border-right: none;
+}
+
+.admin-content-table a {
+  color: #535353;
+}
+.admin-content-file {
+  margin-bottom: 0;
+  color: #666;
+}
+
+.admin-content-file p {
+  margin: 0 0 5px 0;
+  font-size: 1.4rem;
+}
+
+.admin-content-file li {
+  padding: 10px 0;
+}
+
+.admin-content-file li:first-child {
+  border-top: none;
+}
+
+.admin-content-file li:last-child {
+  border-bottom: none;
+}
+
+.admin-content-file li .am-progress {
+  margin-bottom: 4px;
+}
+
+.admin-content-file li .am-progress-bar {
+  line-height: 14px;
+}
+
+.admin-content-task {
+  margin-bottom: 0;
+}
+
+.admin-content-task li {
+  padding: 5px 0;
+  border-color: #eee;
+}
+
+.admin-content-task li:first-child {
+  border-top: none;
+}
+
+.admin-content-task li:last-child {
+  border-bottom: none;
+}
+
+.admin-task-meta {
+  font-size: 1.2rem;
+  color: #999;
+}
+
+.admin-task-bd {
+  font-size: 1.4rem;
+  margin-bottom: 5px;
+}
+
+.admin-content-comment {
+  margin-bottom: 0;
+}
+
+.admin-content-comment .am-comment-bd {
+  font-size: 1.4rem;
+}
+
+.admin-content-pagination {
+  margin-bottom: 0;
+}
+.admin-content-pagination li a {
+  padding: 4px 8px;
+}
+
+@media only screen and (min-width: 641px) {
+  .admin-sidebar {
+    display: block;
+    position: static;
+    background: none;
+  }
+
+  .admin-offcanvas-bar {
+    position: static;
+    width: auto;
+    background: none;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+    overflow-y: visible;
+    min-height: 100%;
+  }
+  .admin-offcanvas-bar:after {
+    content: none;
+  }
+}
+
+@media only screen and (max-width: 640px) {
+  .admin-sidebar {
+    width: inherit;
+  }
+
+  .admin-offcanvas-bar {
+    background: #f3f3f3;
+  }
+
+  .admin-offcanvas-bar:after {
+    background: #BABABA;
+  }
+
+  .admin-sidebar-list a:hover, .admin-sidebar-list a:active{
+    -webkit-transition: background-color .3s ease;
+    -moz-transition: background-color .3s ease;
+    -ms-transition: background-color .3s ease;
+    -o-transition: background-color .3s ease;
+    transition: background-color .3s ease;
+    background: #E4E4E4;
+  }
+
+  .admin-content-list li {
+    padding: 10px;
+    border-width: 1px 0;
+    margin-top: -1px;
+  }
+
+  .admin-content-list li:first-child {
+    border-top: none;
+  }
+
+  .admin-content-list li:last-child {
+    border-bottom: none;
+  }
+
+  .admin-form-text {
+    text-align: left !important;
+  }
+
+}
+
+/*
+* user.html css
+*/
+.user-info {
+  margin-bottom: 15px;
+}
+
+.user-info .am-progress {
+  margin-bottom: 4px;
+}
+
+.user-info p {
+  margin: 5px;
+}
+
+.user-info-order {
+  font-size: 1.4rem;
+}
+
+/*
+* errorLog.html css
+*/
+
+.error-log .am-pre-scrollable {
+  max-height: 40rem;
+}
+
+/*
+* table.html css
+*/
+
+.table-main {
+  font-size: 1.4rem;
+  padding: .5rem;
+}
+
+.table-main button {
+  background: #fff;
+}
+
+.table-check {
+  width: 30px;
+}
+
+.table-id {
+  width: 50px;
+}
+
+@media only screen and (max-width: 640px) {
+  .table-select {
+    margin-top: 10px;
+    margin-left: 5px;
+  }
+}
+
+/*
+gallery.html css
+*/
+
+.gallery-list li {
+  padding: 10px;
+}
+
+.gallery-list a {
+  color: #666;
+}
+
+.gallery-list a:hover {
+  color: #3bb4f2;
+}
+
+.gallery-title {
+  margin-top: 6px;
+  font-size: 1.4rem;
+}
+
+.gallery-desc {
+  font-size: 1.2rem;
+  margin-top: 4px;
+}
+
+/*
+ 404.html css
+*/
+
+.page-404 {
+  background: #fff;
+  border: none;
+  width: 200px;
+  margin: 0 auto;
+}

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
Day61-65/code/project_of_tornado/assets/css/amazeui.datatables.min.css


Різницю між файлами не показано, бо вона завелика
+ 0 - 0
Day61-65/code/project_of_tornado/assets/css/amazeui.min.css


+ 1912 - 0
Day61-65/code/project_of_tornado/assets/css/app.css

@@ -0,0 +1,1912 @@
+ul,
+li {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+header {
+  z-index: 1200;
+  position: relative;
+}
+.tpl-header-logo {
+  width: 240px;
+  height: 57px;
+  display: table;
+  text-align: center;
+  position: relative;
+  z-index: 1300;
+}
+.tpl-header-logo a {
+  display: table-cell;
+  vertical-align: middle;
+}
+.tpl-header-logo img {
+  width: 170px;
+}
+.tpl-header-fluid {
+  margin-left: 240px;
+  height: 56px;
+  padding-left: 20px;
+  padding-right: 20px;
+}
+.tpl-header-switch-button {
+  margin-top: 0px;
+  margin-bottom: 0px;
+  float: left;
+  color: #cfcfcf;
+  margin-left: -20px;
+  margin-right: 0;
+  border: 0;
+  border-radius: 0;
+  padding: 0px 22px;
+  font-size: 22px;
+  line-height: 55px;
+}
+.tpl-header-switch-button:hover {
+  outline: none;
+}
+.tpl-header-search-form {
+  height: 54px;
+  line-height: 52px;
+  margin-left: 10px;
+}
+.tpl-header-search-box,
+.tpl-header-search-btn {
+  transition: all 0.4s ease-in-out;
+  color: #848c90;
+  background: none;
+  border: none;
+  outline: none;
+}
+.tpl-header-search-box {
+  font-size: 14px;
+}
+.tpl-header-search-box:hover,
+.tpl-header-search-box:active {
+  color: #fff;
+}
+.tpl-header-search-btn {
+  font-size: 15px;
+}
+.tpl-header-search-btn:hover,
+.tpl-header-search-btn:active {
+  color: #fff;
+}
+.tpl-header-navbar {
+  color: #fff;
+}
+.tpl-header-navbar li {
+  float: left;
+}
+.tpl-header-navbar a {
+  line-height: 56px;
+  display: block;
+  padding: 0 16px;
+  position: relative;
+}
+.tpl-header-navbar a .item-feed-badge {
+  position: absolute;
+  top: 9px;
+  left: 25px;
+}
+ul.tpl-dropdown-content {
+  padding: 10px;
+  margin-top: 0;
+  width: 300px;
+  background-color: #2f3638;
+  border: 1px solid #525e62;
+  border-radius: 0;
+}
+ul.tpl-dropdown-content li {
+  float: none;
+}
+ul.tpl-dropdown-content:before,
+ul.tpl-dropdown-content:after {
+  display: none;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-title {
+  font-size: 12px;
+  float: left;
+  color: rgba(255, 255, 255, 0.7);
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-time {
+  float: right;
+  text-align: right;
+  color: rgba(255, 255, 255, 0.7);
+  font-size: 11px;
+  width: 50px;
+  margin-left: 10px;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications:last-child .tpl-dropdown-menu-notifications-item {
+  text-align: center;
+  border: none;
+  font-size: 12px;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications:last-child .tpl-dropdown-menu-notifications-item i {
+  margin-left: -6px;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages:last-child .tpl-dropdown-menu-messages-item {
+  text-align: center;
+  border: none;
+  font-size: 12px;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages:last-child .tpl-dropdown-menu-messages-item i {
+  margin-left: -6px;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item,
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item {
+  padding: 12px;
+  color: #fff;
+  line-height: 20px;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item:hover,
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item:hover,
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item:focus,
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item:focus {
+  background-color: #465154;
+  color: #fff;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item .menu-messages-ico,
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item .menu-messages-ico {
+  line-height: initial;
+  float: left;
+  width: 35px;
+  height: 35px;
+  border-radius: 50%;
+  margin-right: 10px;
+  margin-top: 6px;
+  overflow: hidden;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item .menu-messages-ico img,
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item .menu-messages-ico img {
+  width: 100%;
+  height: auto;
+  vertical-align: middle;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item .menu-messages-time,
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item .menu-messages-time {
+  float: right;
+  text-align: right;
+  color: rgba(255, 255, 255, 0.7);
+  font-size: 11px;
+  width: 40px;
+  margin-left: 10px;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item .menu-messages-content,
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item .menu-messages-content {
+  display: block;
+  font-size: 13px;
+  margin-left: 45px;
+  margin-right: 50px;
+}
+ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item .menu-messages-content .menu-messages-content-time,
+ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item .menu-messages-content .menu-messages-content-time {
+  margin-top: 3px;
+  color: rgba(255, 255, 255, 0.7);
+  font-size: 11px;
+}
+.am-dimmer {
+  z-index: 1200;
+}
+.am-modal {
+  z-index: 1300;
+}
+.am-datepicker-dropdown {
+  z-index: 1400;
+}
+.tpl-skiner {
+  transition: all 0.4s ease-in-out;
+  position: fixed;
+  z-index: 10000;
+  right: -130px;
+  top: 65px;
+}
+.tpl-skiner.active {
+  right: 0px;
+}
+.tpl-skiner-content {
+  background: rgba(0, 0, 0, 0.7);
+  width: 130px;
+  padding: 15px;
+  border-radius: 4px 0 0 4px;
+  overflow: hidden;
+}
+.fc-content .am-icon-close {
+  position: absolute;
+  right: 0;
+  top: 0px;
+}
+.tpl-skiner-toggle {
+  position: absolute;
+  top: 5px;
+  left: -40px;
+  width: 40px;
+  color: #969a9b;
+  font-size: 20px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  background: rgba(0, 0, 0, 0.7);
+  cursor: pointer;
+  border-top-left-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+.tpl-skiner-content-title {
+  margin: 0;
+  margin-bottom: 4px;
+  padding-bottom: 4px;
+  font-size: 16px;
+  text-transform: uppercase;
+  color: #fff;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
+}
+.tpl-skiner-content-bar {
+  padding-top: 10px;
+}
+.tpl-skiner-content-bar .skiner-color {
+  transition: all 0.4s ease-in-out;
+  float: left;
+  width: 25px;
+  height: 25px;
+  margin-right: 10px;
+  cursor: pointer;
+}
+.tpl-skiner-content-bar .skiner-white {
+  background: #fff;
+  border: 2px solid #eee;
+}
+.tpl-skiner-content-bar .skiner-black {
+  background: #000;
+  border: 2px solid #222;
+}
+.sub-active {
+  color: #fff!important;
+}
+.left-sidebar {
+  transition: all 0.4s ease-in-out;
+  width: 240px;
+  min-height: 100%;
+  padding-top: 57px;
+  position: absolute;
+  z-index: 1104;
+  top: 0;
+  left: 0px;
+}
+.left-sidebar.xs-active {
+  left: 0px;
+}
+.left-sidebar.active {
+  left: -240px;
+}
+.tpl-sidebar-user-panel {
+  padding: 22px;
+  padding-top: 28px;
+}
+.tpl-user-panel-profile-picture {
+  border-radius: 50%;
+  width: 82px;
+  height: 82px;
+  margin-bottom: 10px;
+  overflow: hidden;
+}
+.tpl-user-panel-profile-picture img {
+  width: auto;
+  height: 82px;
+  vertical-align: middle;
+}
+.tpl-user-panel-status-icon {
+  margin-right: 2px;
+}
+.user-panel-logged-in-text {
+  display: block;
+  color: #cfcfcf;
+  font-size: 14px;
+}
+.tpl-user-panel-action-link {
+  color: #6d787c;
+  font-size: 12px;
+}
+.tpl-user-panel-action-link:hover {
+  color: #a2aaad;
+}
+.sidebar-nav {
+  list-style-type: none;
+  padding: 0;
+  margin: 0;
+}
+.sidebar-nav-sub {
+  display: none;
+}
+.sidebar-nav-sub .sidebar-nav-link {
+  font-size: 12px;
+  padding-left: 30px;
+}
+.sidebar-nav-sub .sidebar-nav-link a {
+  font-size: 12px;
+  padding-left: 0;
+}
+.sidebar-nav-sub .sidebar-nav-link-logo {
+  margin-right: 8px;
+  width: 20px;
+  font-size: 16px;
+}
+.sidebar-nav-sub-ico-rotate {
+  -webkit-transform: rotate(180deg);
+  transform: rotate(180deg);
+  -webkit-transition: all 300ms;
+  transition: all 300ms;
+}
+.sidebar-nav-link-logo-ico {
+  margin-top: 5px;
+}
+.sidebar-nav-heading {
+  padding: 24px 17px;
+  font-size: 15px;
+  font-weight: 500;
+}
+.sidebar-nav-heading-info {
+  font-size: 12px;
+  color: #868E8E;
+  padding-left: 10px;
+}
+.sidebar-nav-link-logo {
+  margin-right: 8px;
+  width: 20px;
+  font-size: 16px;
+}
+.sidebar-nav-link {
+  color: #fff;
+}
+.sidebar-nav-link a {
+  display: block;
+  color: #868E8E;
+  padding: 10px 17px;
+  border-left: #282d2f 3px solid;
+  font-size: 14px;
+  cursor: pointer;
+}
+.sidebar-nav-link a.active {
+  cursor: pointer;
+  border-left: #1CA2CE 3px solid;
+  color: #fff;
+}
+.sidebar-nav-link a:hover {
+  color: #fff;
+}
+.tpl-content-wrapper {
+  transition: all 0.4s ease-in-out;
+  position: relative;
+  margin-left: 240px;
+  z-index: 1101;
+  min-height: 922px;
+  border-bottom-left-radius: 3px;
+}
+.tpl-content-wrapper.xs-active {
+  margin-left: 240px;
+}
+.tpl-content-wrapper.active {
+  margin-left: 0;
+}
+.page-header {
+  background: #424b4f;
+  margin-top: 0;
+  margin-bottom: 0;
+  padding: 40px 0;
+  border-bottom: 0;
+}
+.container-fluid {
+  margin-top: 0;
+  margin-bottom: 0;
+  padding: 40px 0;
+  border-bottom: 0;
+  padding-left: 20px;
+  padding-right: 20px;
+}
+.row {
+  margin-right: -10px;
+  margin-left: -10px;
+}
+.page-header-description {
+  margin-top: 4px;
+  margin-bottom: 0;
+  font-size: 14px;
+  color: #e6e6e6;
+}
+.page-header-heading {
+  font-size: 20px;
+  font-weight: 400;
+}
+.page-header-heading .page-header-heading-ico {
+  font-size: 28px;
+  position: relative;
+  top: 3px;
+}
+.page-header-heading small {
+  font-weight: normal;
+  line-height: 1;
+  color: #B3B3B3;
+}
+.page-header-button {
+  transition: all 0.4s ease-in-out;
+  opacity: 0.3;
+  float: right;
+  outline: none;
+  border: 1px solid #fff;
+  padding: 16px 36px;
+  font-size: 23px;
+  line-height: 23px;
+  border-radius: 0;
+  padding-top: 14px;
+  color: #fff;
+  background-color: rgba(0, 0, 0, 0);
+  font-weight: 500;
+}
+.page-header-button:hover {
+  background-color: #ffffff;
+  color: #333;
+  opacity: 1;
+}
+.widget {
+  width: 100%;
+  min-height: 148px;
+  margin-bottom: 20px;
+  border-radius: 0;
+  position: relative;
+}
+.widget-head {
+  width: 100%;
+  padding: 15px;
+}
+.widget-title {
+  font-size: 14px;
+}
+.widget-fluctuation-period-text {
+  display: inline-block;
+  font-size: 16px;
+  line-height: 20px;
+  margin-bottom: 9px;
+}
+.widget-body {
+  padding: 13px 15px;
+  width: 100%;
+}
+.row-content {
+  padding: 20px;
+}
+.widget-fluctuation-description-text {
+  margin-top: 4px;
+  display: block;
+  font-size: 12px;
+  line-height: 13px;
+}
+.widget-fluctuation-description-amount {
+  display: block;
+  font-size: 20px;
+  line-height: 22px;
+}
+.widget-statistic-header {
+  position: relative;
+  z-index: 35;
+  display: block;
+  font-size: 14px;
+  text-transform: uppercase;
+  margin-bottom: 8px;
+}
+.widget-body-md {
+  height: 200px;
+}
+.widget-body-lg {
+  min-height: 330px;
+}
+.widget-margin-bottom-lg {
+  margin-bottom: 20px;
+}
+.tpl-table-black-operation a {
+  display: inline-block;
+  padding: 5px 6px;
+  font-size: 12px;
+  line-height: 12px;
+}
+.tpl-switch input[type="checkbox"] {
+  position: absolute;
+  opacity: 0;
+  width: 50px;
+  height: 20px;
+}
+.tpl-switch input[type="checkbox"].ios-switch + div {
+  vertical-align: middle;
+  width: 40px;
+  height: 20px;
+  border-radius: 999px;
+  background-color: rgba(0, 0, 0, 0.1);
+  -webkit-transition-duration: .4s;
+  -webkit-transition-property: background-color, box-shadow;
+  margin-top: 6px;
+}
+.tpl-switch input[type="checkbox"].ios-switch:checked + div {
+  width: 40px;
+  background-position: 0 0;
+  background-color: #36c6d3;
+}
+.tpl-switch input[type="checkbox"].tinyswitch.ios-switch + div {
+  width: 34px;
+  height: 18px;
+}
+.tpl-switch input[type="checkbox"].bigswitch.ios-switch + div {
+  width: 50px;
+  height: 25px;
+}
+.tpl-switch input[type="checkbox"].green.ios-switch:checked + div {
+  background-color: #00e359;
+  border: 1px solid #00a23f;
+  box-shadow: inset 0 0 0 10px #00e359;
+}
+.tpl-switch input[type="checkbox"].ios-switch + div > div {
+  float: left;
+  width: 18px;
+  height: 18px;
+  border-radius: inherit;
+  background: #ffffff;
+  -webkit-transition-timing-function: cubic-bezier(0.54, 1.85, 0.5, 1);
+  -webkit-transition-duration: 0.4s;
+  -webkit-transition-property: transform, background-color, box-shadow;
+  -moz-transition-timing-function: cubic-bezier(0.54, 1.85, 0.5, 1);
+  -moz-transition-duration: 0.4s;
+  -moz-transition-property: transform, background-color;
+  pointer-events: none;
+  margin-top: 1px;
+  margin-left: 1px;
+}
+.tpl-switch input[type="checkbox"].ios-switch:checked + div > div {
+  -webkit-transform: translate3d(20px, 0, 0);
+  -moz-transform: translate3d(20px, 0, 0);
+  background-color: #ffffff;
+}
+.tpl-switch input[type="checkbox"].tinyswitch.ios-switch + div > div {
+  width: 16px;
+  height: 16px;
+  margin-top: 1px;
+}
+.tpl-switch input[type="checkbox"].tinyswitch.ios-switch:checked + div > div {
+  -webkit-transform: translate3d(16px, 0, 0);
+  -moz-transform: translate3d(16px, 0, 0);
+  box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3), 0px 0px 0 1px #0850ac;
+}
+.tpl-switch input[type="checkbox"].bigswitch.ios-switch + div > div {
+  width: 23px;
+  height: 23px;
+  margin-top: 1px;
+}
+.tpl-switch input[type="checkbox"].bigswitch.ios-switch:checked + div > div {
+  -webkit-transform: translate3d(25px, 0, 0);
+  -moz-transform: translate3d(16px, 0, 0);
+}
+.tpl-switch input[type="checkbox"].green.ios-switch:checked + div > div {
+  box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3), 0 0 0 1px #00a23f;
+}
+.tpl-page-state {
+  width: 100%;
+}
+.tpl-page-state-title {
+  font-size: 40px;
+  font-weight: bold;
+}
+.tpl-page-state-content {
+  padding: 10px 0;
+}
+.tpl-login {
+  width: 100%;
+}
+.tpl-login-logo {
+  max-width: 159px;
+  height: 205px;
+  margin: 0 auto;
+  margin-bottom: 20px;
+}
+.tpl-login-title {
+  width: 100%;
+  font-size: 24px;
+}
+.tpl-login-content {
+  width: 300px;
+  margin: 12% auto 0;
+}
+.tpl-login-remember-me {
+  color: #B3B3B3;
+  font-size: 14px;
+}
+.tpl-login-remember-me label {
+  position: relative;
+  top: -2px;
+}
+.tpl-login-content-info {
+  color: #B3B3B3;
+  font-size: 14px;
+}
+.cl-p {
+  padding: 0!important;
+}
+.tpl-table-line-img {
+  max-width: 100px;
+  padding: 2px;
+}
+.tpl-table-list-select {
+  text-align: right;
+}
+.fc-button-group,
+.fc button {
+  display: block;
+}
+.theme-white {
+  background: #e9ecf3;
+}
+.theme-white .sidebar-nav-sub .sidebar-nav-link-logo {
+  margin-left: 10px;
+}
+.theme-white .tpl-header-search-box:hover,
+.theme-white .tpl-header-search-box:active .tpl-error-title {
+  color: #848c90;
+}
+.theme-white .tpl-error-title-info {
+  line-height: 30px;
+  font-size: 21px;
+  margin-top: 20px;
+  text-align: center;
+  color: #dce2ec;
+}
+.theme-white .tpl-error-btn {
+  background: #03a9f3;
+  border: 1px solid #03a9f3;
+  border-radius: 30px;
+  padding: 6px 20px 8px;
+}
+.theme-white .tpl-error-content {
+  margin-top: 20px;
+  margin-bottom: 20px;
+  font-size: 16px;
+  text-align: center;
+  color: #96a2b4;
+}
+.theme-white .tpl-calendar-box {
+  background: #fff;
+  border-radius: 4px;
+  padding: 20px;
+}
+.theme-white .tpl-calendar-box .fc-event {
+  border-radius: 0;
+  background: #03a9f3;
+  border: 1px solid #14b0f6;
+}
+.theme-white .tpl-calendar-box .fc-axis {
+  color: #868E8E;
+}
+.theme-white .tpl-calendar-box .fc-unthemed .fc-today {
+  background: #eee;
+}
+.theme-white .tpl-calendar-box .fc-more {
+  color: #868E8E;
+}
+.theme-white .tpl-calendar-box .fc th.fc-widget-header {
+  background: #32c5d2!important;
+  color: #ffffff;
+  font-size: 14px;
+  line-height: 20px;
+  padding: 7px 0px;
+  text-transform: uppercase;
+  border: none!important;
+}
+.theme-white .tpl-calendar-box .fc th.fc-widget-header a {
+  color: #fff;
+}
+.theme-white .tpl-calendar-box .fc-center h2 {
+  color: #868E8E;
+}
+.theme-white .tpl-calendar-box .fc-state-default {
+  background-image: none;
+  background: #fff;
+  font-size: 14px;
+  color: #868E8E;
+}
+.theme-white .tpl-calendar-box .fc th,
+.theme-white .tpl-calendar-box .fc td,
+.theme-white .tpl-calendar-box .fc hr,
+.theme-white .tpl-calendar-box .fc thead,
+.theme-white .tpl-calendar-box .fc tbody,
+.theme-white .tpl-calendar-box .fc-row {
+  border-color: #eee!important;
+}
+.theme-white .tpl-calendar-box .fc-day-number {
+  color: #868E8E;
+  padding-right: 6px;
+}
+.theme-white .tpl-calendar-box .fc th {
+  color: #868E8E;
+  font-weight: normal;
+  font-size: 14px;
+  padding: 6px 0;
+}
+.theme-white .tpl-login-logo {
+  background: url(../img/logoa.png) center no-repeat;
+}
+.theme-white .sub-active {
+  color: #23abf0!important;
+}
+.theme-white .tpl-table-line-img {
+  border: 1px solid #ddd;
+}
+.theme-white .tpl-pagination .am-disabled a,
+.theme-white .tpl-pagination li a {
+  color: #23abf0;
+  border-radius: 3px;
+  padding: 6px 12px;
+}
+.theme-white .tpl-pagination .am-active a {
+  background: #23abf0;
+  color: #fff;
+  border: 1px solid #23abf0;
+  padding: 6px 12px;
+}
+.theme-white .tpl-login-btn {
+  background-color: #32c5d2;
+  border: none;
+  padding: 10px 16px;
+  font-size: 14px;
+  line-height: 14px;
+  outline: none;
+}
+.theme-white .tpl-login-btn:hover,
+.theme-white .tpl-login-btn:active {
+  background: #22b2e1;
+  color: #fff;
+}
+.theme-white .tpl-login-title {
+  color: #697882;
+}
+.theme-white .tpl-login-title strong {
+  color: #39bae4;
+}
+.theme-white .tpl-login-content {
+  width: 500px;
+  padding: 40px 40px 25px;
+  background-color: #fff;
+  border-radius: 4px;
+}
+.theme-white .tpl-form-line-form,
+.theme-white .tpl-form-border-form {
+  padding-top: 20px;
+}
+.theme-white .tpl-form-border-form input[type=number]:focus,
+.theme-white .tpl-form-border-form input[type=search]:focus,
+.theme-white .tpl-form-border-form input[type=text]:focus,
+.theme-white .tpl-form-border-form input[type=password]:focus,
+.theme-white .tpl-form-border-form input[type=datetime]:focus,
+.theme-white .tpl-form-border-form input[type=datetime-local]:focus,
+.theme-white .tpl-form-border-form input[type=date]:focus,
+.theme-white .tpl-form-border-form input[type=month]:focus,
+.theme-white .tpl-form-border-form input[type=time]:focus,
+.theme-white .tpl-form-border-form input[type=week]:focus,
+.theme-white .tpl-form-border-form input[type=email]:focus,
+.theme-white .tpl-form-border-form input[type=url]:focus,
+.theme-white .tpl-form-border-form input[type=tel]:focus,
+.theme-white .tpl-form-border-form input[type=color]:focus,
+.theme-white .tpl-form-border-form select:focus,
+.theme-white .tpl-form-border-form textarea:focus,
+.theme-white .am-form-field:focus {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.theme-white .tpl-form-border-form input[type=number],
+.theme-white .tpl-form-border-form input[type=search],
+.theme-white .tpl-form-border-form input[type=text],
+.theme-white .tpl-form-border-form input[type=password],
+.theme-white .tpl-form-border-form input[type=datetime],
+.theme-white .tpl-form-border-form input[type=datetime-local],
+.theme-white .tpl-form-border-form input[type=date],
+.theme-white .tpl-form-border-form input[type=month],
+.theme-white .tpl-form-border-form input[type=time],
+.theme-white .tpl-form-border-form input[type=week],
+.theme-white .tpl-form-border-form input[type=email],
+.theme-white .tpl-form-border-form input[type=url],
+.theme-white .tpl-form-border-form input[type=tel],
+.theme-white .tpl-form-border-form input[type=color],
+.theme-white .tpl-form-border-form select,
+.theme-white .tpl-form-border-form textarea,
+.theme-white .am-form-field {
+  display: block;
+  width: 100%;
+  padding: 6px 12px;
+  line-height: 1.42857;
+  color: #4d6b8a;
+  background-color: #fff;
+  background-image: none;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  background: 0 0;
+  border: 0;
+  border: 1px solid #c2cad8;
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  -ms-border-radius: 0;
+  text-indent: .5em;
+  -o-border-radius: 0;
+  border-radius: 0;
+  color: #555;
+  box-shadow: none;
+  padding-left: 0;
+  padding-right: 0;
+  font-size: 14px;
+}
+.theme-white .tpl-form-border-form .am-checkbox,
+.theme-white .tpl-form-border-form .am-checkbox-inline,
+.theme-white .tpl-form-border-form .am-form-label,
+.theme-white .tpl-form-border-form .am-radio,
+.theme-white .tpl-form-border-form .am-radio-inline {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+.theme-white .tpl-form-border-form .am-form-group:after {
+  clear: both;
+}
+.theme-white .tpl-form-border-form .am-form-group:after,
+.theme-white .tpl-form-border-form .am-form-group:before {
+  content: " ";
+  display: table;
+}
+.theme-white .tpl-form-border-form .am-form-label {
+  padding-top: 5px;
+  font-size: 16px;
+  color: #888;
+  font-weight: inherit;
+  text-align: right;
+}
+.theme-white .tpl-form-border-form .am-form-group {
+  /*padding: 20px 0;*/
+}
+.theme-white .tpl-form-border-form .am-form-label .tpl-form-line-small-title {
+  color: #999;
+  font-size: 12px;
+}
+.theme-white .tpl-form-line-form input[type=number]:focus,
+.theme-white .tpl-form-line-form input[type=search]:focus,
+.theme-white .tpl-form-line-form input[type=text]:focus,
+.theme-white .tpl-form-line-form input[type=password]:focus,
+.theme-white .tpl-form-line-form input[type=datetime]:focus,
+.theme-white .tpl-form-line-form input[type=datetime-local]:focus,
+.theme-white .tpl-form-line-form input[type=date]:focus,
+.theme-white .tpl-form-line-form input[type=month]:focus,
+.theme-white .tpl-form-line-form input[type=time]:focus,
+.theme-white .tpl-form-line-form input[type=week]:focus,
+.theme-white .tpl-form-line-form input[type=email]:focus,
+.theme-white .tpl-form-line-form input[type=url]:focus,
+.theme-white .tpl-form-line-form input[type=tel]:focus,
+.theme-white .tpl-form-line-form input[type=color]:focus,
+.theme-white .tpl-form-line-form select:focus,
+.theme-white .tpl-form-line-form textarea:focus,
+.theme-white .am-form-field:focus {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.theme-white .tpl-form-line-form input[type=number],
+.theme-white .tpl-form-line-form input[type=search],
+.theme-white .tpl-form-line-form input[type=text],
+.theme-white .tpl-form-line-form input[type=password],
+.theme-white .tpl-form-line-form input[type=datetime],
+.theme-white .tpl-form-line-form input[type=datetime-local],
+.theme-white .tpl-form-line-form input[type=date],
+.theme-white .tpl-form-line-form input[type=month],
+.theme-white .tpl-form-line-form input[type=time],
+.theme-white .tpl-form-line-form input[type=week],
+.theme-white .tpl-form-line-form input[type=email],
+.theme-white .tpl-form-line-form input[type=url],
+.theme-white .tpl-form-line-form input[type=tel],
+.theme-white .tpl-form-line-form input[type=color],
+.theme-white .tpl-form-line-form select,
+.theme-white .tpl-form-line-form textarea,
+.theme-white .am-form-field {
+  display: block;
+  width: 100%;
+  padding: 6px 12px;
+  line-height: 1.42857;
+  color: #4d6b8a;
+  background-color: #fff;
+  background-image: none;
+  border: 1px solid #c2cad8;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  background: 0 0;
+  border: 0;
+  border-bottom: 1px solid #c2cad8;
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  -ms-border-radius: 0;
+  -o-border-radius: 0;
+  border-radius: 0;
+  color: #555;
+  box-shadow: none;
+  padding-left: 0;
+  padding-right: 0;
+  font-size: 14px;
+}
+.theme-white .tpl-form-line-form .am-checkbox,
+.theme-white .tpl-form-line-form .am-checkbox-inline,
+.theme-white .tpl-form-line-form .am-form-label,
+.theme-white .tpl-form-line-form .am-radio,
+.theme-white .tpl-form-line-form .am-radio-inline {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+.theme-white .tpl-form-line-form .am-form-group:after {
+  clear: both;
+}
+.theme-white .tpl-form-line-form .am-form-group:after,
+.theme-white .tpl-form-line-form .am-form-group:before {
+  content: " ";
+  display: table;
+}
+.theme-white .tpl-form-line-form .am-form-label {
+  padding-top: 5px;
+  font-size: 16px;
+  color: #888;
+  font-weight: inherit;
+  text-align: right;
+}
+.theme-white .tpl-form-line-form .am-form-group {
+  /*padding: 20px 0;*/
+}
+.theme-white .tpl-form-line-form .am-form-label .tpl-form-line-small-title {
+  color: #999;
+  font-size: 12px;
+}
+.theme-white .tpl-table-black-operation a {
+  border: 1px solid #36c6d3;
+  color: #36c6d3;
+}
+.theme-white .tpl-table-black-operation a:hover {
+  background: #36c6d3;
+  color: #fff;
+}
+.theme-white .tpl-table-black-operation a.tpl-table-black-operation-del {
+  border: 1px solid #e7505a;
+  color: #e7505a;
+}
+.theme-white .tpl-table-black-operation a.tpl-table-black-operation-del:hover {
+  background: #e7505a;
+  color: #fff;
+}
+.theme-white .tpl-amendment-echarts {
+  left: -17px;
+}
+.theme-white .tpl-user-card {
+  border: 1px solid #3598dc;
+  border-top: 2px solid #3598dc;
+  background: #3598dc;
+  color: #ffffff;
+  border-radius: 4px;
+}
+.theme-white .tpl-user-card-title {
+  font-size: 26px;
+  margin-top: 0;
+  font-weight: 300;
+  margin-top: 25px;
+  margin-bottom: 10px;
+}
+.theme-white .achievement-subheading {
+  font-size: 12px;
+  margin-top: 0;
+  margin-bottom: 15px;
+}
+.theme-white .achievement-image {
+  border-radius: 50%;
+  margin-bottom: 22px;
+}
+.theme-white .achievement-description {
+  margin: 0;
+  font-size: 12px;
+}
+.theme-white .tpl-table-black {
+  color: #838FA1;
+}
+.theme-white .tpl-table-black thead > tr > th {
+  font-size: 14px;
+  padding: 6px;
+}
+.theme-white .tpl-table-black tbody > tr > td {
+  font-size: 14px;
+  padding: 7px 6px;
+}
+.theme-white .tpl-table-black tfoot > tr > th {
+  font-size: 14px;
+  padding: 6px 0;
+}
+.theme-white .am-progress {
+  height: 12px;
+}
+.theme-white .am-progress-title {
+  font-size: 14px;
+  margin-bottom: 8px;
+}
+.theme-white .widget-fluctuation-tpl-btn {
+  margin-top: 6px;
+  display: block;
+  color: #fff;
+  font-size: 12px;
+  padding: 8px 14px;
+  outline: none;
+  background-color: #e7505a;
+  border: 1px solid #e7505a;
+}
+.theme-white .widget-fluctuation-tpl-btn:hover {
+  background: transparent;
+  color: #e7505a;
+}
+.theme-white .widget-fluctuation-description-text {
+  color: #c5cacd;
+}
+.theme-white .widget-fluctuation-period-text {
+  color: #838FA1;
+}
+.theme-white .text-success {
+  color: #5eb95e;
+}
+.theme-white .widget-head {
+  border-bottom: 1px solid #eef1f5;
+}
+.theme-white .widget-function a {
+  color: #838FA1;
+}
+.theme-white .widget-function a:hover {
+  color: #a7bdcd;
+}
+.theme-white .widget {
+  padding: 10px 20px 13px;
+  background-color: #fff;
+  border-radius: 4px;
+  color: #838FA1;
+}
+.theme-white .widget-title {
+  font-size: 16px;
+}
+.theme-white .widget-primary {
+  min-height: 174px;
+  border: 1px solid #32c5d2;
+  border-top: 2px solid #32c5d2;
+  background: #32c5d2;
+  color: #ffffff;
+  padding: 12px 17px;
+  padding-left: 22px;
+}
+.theme-white .widget-statistic-icon {
+  position: absolute;
+  z-index: 30;
+  right: 30px;
+  top: 24px;
+  font-size: 70px;
+  color: #46cad6;
+}
+.theme-white .widget-statistic-description {
+  position: relative;
+  z-index: 35;
+  display: block;
+  font-size: 14px;
+  line-height: 14px;
+  padding-top: 8px;
+  color: #fff;
+}
+.theme-white .widget-statistic-value {
+  position: relative;
+  z-index: 35;
+  font-weight: 300;
+  display: block;
+  color: #fff;
+  font-size: 46px;
+  line-height: 46px;
+  margin-bottom: 8px;
+}
+.theme-white .widget-statistic-header {
+  padding-top: 18px;
+  color: #fff;
+}
+.theme-white .widget-purple {
+  padding: 12px 17px;
+  border: 1px solid #8E44AD;
+  border-top: 2px solid #8E44AD;
+  background: #8E44AD;
+  color: #ffffff;
+  min-height: 174px;
+}
+.theme-white .widget-purple .widget-statistic-icon {
+  color: #9956b5;
+}
+.theme-white .widget-purple .widget-statistic-header {
+  color: #ded5e7;
+}
+.theme-white .widget-purple .widget-statistic-description {
+  color: #ded5e7;
+}
+.theme-white .page-header-button {
+  opacity: .8;
+  border: 1px solid #32c5d2;
+  background: #32c5d2;
+  color: #fff;
+}
+.theme-white .page-header-button:hover {
+  opacity: 1;
+}
+.theme-white .page-header-description {
+  color: #666;
+}
+.theme-white .page-header-heading {
+  color: #666;
+}
+.theme-white ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item .menu-messages-content .menu-messages-content-time {
+  color: #96a5aa;
+}
+.theme-white ul.tpl-dropdown-content {
+  background: #fff;
+  border: 1px solid #ddd;
+}
+.theme-white ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item,
+.theme-white ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item {
+  border-bottom: 1px solid #eee;
+  color: #999;
+}
+.theme-white ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item:hover,
+.theme-white ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item:hover {
+  background-color: #f5f5f5;
+}
+.theme-white ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-item .tpl-dropdown-menu-notifications-time,
+.theme-white ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item .tpl-dropdown-menu-notifications-time {
+  color: #999;
+}
+.theme-white ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item:hover {
+  background-color: #f5f5f5;
+}
+.theme-white ul.tpl-dropdown-content .tpl-dropdown-menu-notifications-title {
+  color: #999;
+}
+.theme-white .sidebar-nav-link a {
+  border-left: #fff 3px solid;
+}
+.theme-white .sidebar-nav-link a:hover {
+  background: #f2f6f9;
+  color: #868E8E;
+  border-left: #3bb4f2 3px solid;
+}
+.theme-white .sidebar-nav-link a.active {
+  background: #f2f6f9;
+  color: #868E8E;
+  border-left: #3bb4f2 3px solid;
+}
+.theme-white .sidebar-nav-heading {
+  color: #999;
+  border-bottom: 1px solid #eee;
+}
+.theme-white .tpl-sidebar-user-panel {
+  background: #fff;
+  border-bottom: 1px solid #eee;
+}
+.theme-white .tpl-content-wrapper {
+  background: #e9ecf3;
+}
+.theme-white .tpl-header-fluid {
+  background: #fff;
+  border-top: 1px solid #eee;
+}
+.theme-white .tpl-header-logo {
+  background: #fff;
+  border-bottom: 1px solid #eee;
+}
+.theme-white .tpl-header-switch-button {
+  background: #fff;
+  border-right: 1px solid #eee;
+  border-left: 1px solid #eee;
+}
+.theme-white .tpl-header-switch-button:hover {
+  background: #fff;
+  color: #999;
+}
+.theme-white .tpl-header-navbar a {
+  color: #999;
+}
+.theme-white .tpl-header-navbar a:hover {
+  color: #999;
+}
+.theme-white .left-sidebar {
+  background: #fff;
+}
+.theme-white .widget-color-green {
+  border: 1px solid #32c5d2;
+  border-top: 2px solid #32c5d2;
+  background: #32c5d2;
+  color: #ffffff;
+}
+.theme-white .widget-color-green .widget-fluctuation-period-text {
+  color: #fff;
+}
+.theme-white .widget-color-green .widget-head {
+  border-bottom: 1px solid #2bb8c4;
+}
+.theme-white .widget-color-green .widget-fluctuation-description-text {
+  color: #bbe7f6;
+}
+.theme-white .widget-color-green .widget-function a {
+  color: #42bde5;
+}
+.theme-white .widget-color-green .widget-function a:hover {
+  color: #fff;
+}
+.theme-black {
+  background-color: #282d2f;
+}
+.theme-black .tpl-am-model-bd {
+  background: #424b4f;
+}
+.theme-black .tpl-model-dialog {
+  background: #424b4f;
+}
+.theme-black .tpl-error-title {
+  font-size: 210px;
+  line-height: 220px;
+  color: #868E8E;
+}
+.theme-black .tpl-error-title-info {
+  line-height: 30px;
+  font-size: 21px;
+  margin-top: 20px;
+  text-align: center;
+  color: #868E8E;
+}
+.theme-black .tpl-error-btn {
+  background: #03a9f3;
+  border: 1px solid #03a9f3;
+  border-radius: 30px;
+  padding: 6px 20px 8px;
+}
+.theme-black .tpl-error-content {
+  margin-top: 20px;
+  margin-bottom: 20px;
+  font-size: 16px;
+  text-align: center;
+  color: #cfcfcf;
+}
+.theme-black .tpl-calendar-box {
+  background: #424b4f;
+  padding: 20px;
+}
+.theme-black .tpl-calendar-box .fc-button {
+  border-radius: 0;
+  box-shadow: 0;
+}
+.theme-black .tpl-calendar-box .fc-event {
+  border-radius: 0;
+  background: #03a9f3;
+}
+.theme-black .tpl-calendar-box .fc-axis {
+  color: #fff;
+}
+.theme-black .tpl-calendar-box .fc-unthemed .fc-today {
+  background: #3a4144;
+}
+.theme-black .tpl-calendar-box .fc-more {
+  color: #fff;
+}
+.theme-black .tpl-calendar-box .fc th.fc-widget-header {
+  background: #9675ce!important;
+  color: #ffffff;
+  font-size: 14px;
+  line-height: 20px;
+  padding: 7px 0px;
+  text-transform: uppercase;
+  border: none!important;
+}
+.theme-black .tpl-calendar-box .fc th.fc-widget-header a {
+  color: #fff;
+}
+.theme-black .tpl-calendar-box .fc-center h2 {
+  color: #fff;
+}
+.theme-black .tpl-calendar-box .fc-state-default {
+  background-image: none;
+  background: #fff;
+  font-size: 14px;
+}
+.theme-black .tpl-calendar-box .fc th,
+.theme-black .tpl-calendar-box .fc td,
+.theme-black .tpl-calendar-box .fc hr,
+.theme-black .tpl-calendar-box .fc thead,
+.theme-black .tpl-calendar-box .fc tbody,
+.theme-black .tpl-calendar-box .fc-row {
+  border-color: rgba(120, 130, 140, 0.4) !important;
+}
+.theme-black .tpl-calendar-box .fc-day-number {
+  color: #868E8E;
+  padding-right: 6px;
+}
+.theme-black .tpl-calendar-box .fc th {
+  color: #868E8E;
+  font-weight: normal;
+  font-size: 14px;
+  padding: 6px 0;
+}
+.theme-black .tpl-login-logo {
+  background: url(../img/logob.png) center no-repeat;
+}
+.theme-black .tpl-table-line-img {
+  max-width: 100px;
+  padding: 2px;
+  border: none;
+}
+.theme-black .tpl-table-list-field {
+  border: none;
+}
+.theme-black .tpl-table-list-select .am-dropdown-content {
+  color: #888;
+}
+.theme-black .tpl-table-list-select .am-selected-btn {
+  border: 1px solid rgba(255, 255, 255, 0.2);
+  color: #fff;
+}
+.theme-black .tpl-table-list-select .am-btn-default.am-active,
+.theme-black .tpl-table-list-select .am-btn-default:active,
+.theme-black .tpl-table-list-select .am-dropdown.am-active .am-btn-default.am-dropdown-toggle {
+  border: 1px solid rgba(255, 255, 255, 0.2);
+  color: #fff;
+  background: #5d6468;
+}
+.theme-black .tpl-pagination .am-disabled a,
+.theme-black .tpl-pagination li a {
+  color: #fff;
+  padding: 6px 12px;
+  background: #3f4649;
+  border: none;
+}
+.theme-black .tpl-pagination .am-active a {
+  background: #167fa1;
+  color: #fff;
+  border: 1px solid #167fa1;
+  padding: 6px 12px;
+}
+.theme-black .tpl-login-btn {
+  border: 1px solid #b5b5b5;
+  background-color: rgba(0, 0, 0, 0);
+  padding: 10px 16px;
+  font-size: 14px;
+  line-height: 14px;
+  color: #b5b5b5;
+}
+.theme-black .tpl-login-btn:hover,
+.theme-black .tpl-login-btn:active {
+  background: #b5b5b5;
+  color: #fff;
+}
+.theme-black .tpl-login-title {
+  color: #fff;
+}
+.theme-black .tpl-login-title strong {
+  color: #39bae4;
+}
+.theme-black .tpl-form-line-form,
+.theme-black .tpl-form-border-form {
+  padding-top: 20px;
+}
+.theme-black .tpl-form-line-form .am-btn-default,
+.theme-black .tpl-form-border-form .am-btn-default {
+  color: #fff;
+  border: 1px solid rgba(255, 255, 255, 0.2);
+}
+.theme-black .tpl-form-line-form .am-selected-text,
+.theme-black .tpl-form-border-form .am-selected-text {
+  color: #888;
+}
+.theme-black .tpl-form-border-form input[type=number]:focus,
+.theme-black .tpl-form-border-form input[type=search]:focus,
+.theme-black .tpl-form-border-form input[type=text]:focus,
+.theme-black .tpl-form-border-form input[type=password]:focus,
+.theme-black .tpl-form-border-form input[type=datetime]:focus,
+.theme-black .tpl-form-border-form input[type=datetime-local]:focus,
+.theme-black .tpl-form-border-form input[type=date]:focus,
+.theme-black .tpl-form-border-form input[type=month]:focus,
+.theme-black .tpl-form-border-form input[type=time]:focus,
+.theme-black .tpl-form-border-form input[type=week]:focus,
+.theme-black .tpl-form-border-form input[type=email]:focus,
+.theme-black .tpl-form-border-form input[type=url]:focus,
+.theme-black .tpl-form-border-form input[type=tel]:focus,
+.theme-black .tpl-form-border-form input[type=color]:focus,
+.theme-black .tpl-form-border-form select:focus,
+.theme-black .tpl-form-border-form textarea:focus,
+.theme-black .am-form-field:focus {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.theme-black .tpl-form-border-form input[type=number],
+.theme-black .tpl-form-border-form input[type=search],
+.theme-black .tpl-form-border-form input[type=text],
+.theme-black .tpl-form-border-form input[type=password],
+.theme-black .tpl-form-border-form input[type=datetime],
+.theme-black .tpl-form-border-form input[type=datetime-local],
+.theme-black .tpl-form-border-form input[type=date],
+.theme-black .tpl-form-border-form input[type=month],
+.theme-black .tpl-form-border-form input[type=time],
+.theme-black .tpl-form-border-form input[type=week],
+.theme-black .tpl-form-border-form input[type=email],
+.theme-black .tpl-form-border-form input[type=url],
+.theme-black .tpl-form-border-form input[type=tel],
+.theme-black .tpl-form-border-form input[type=color],
+.theme-black .tpl-form-border-form select,
+.theme-black .tpl-form-border-form textarea,
+.theme-black .am-form-field {
+  display: block;
+  width: 100%;
+  padding: 6px 12px;
+  line-height: 1.42857;
+  color: #4d6b8a;
+  background-color: #fff;
+  background-image: none;
+  border: 1px solid #c2cad8;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  background: 0 0;
+  border: 0;
+  text-indent: .5em;
+  border: 1px solid rgba(255, 255, 255, 0.2);
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  -ms-border-radius: 0;
+  -o-border-radius: 0;
+  border-radius: 0;
+  color: #fff;
+  box-shadow: none;
+  padding-left: 0;
+  padding-right: 0;
+  font-size: 14px;
+}
+.theme-black .tpl-form-border-form .am-checkbox,
+.theme-black .tpl-form-border-form .am-checkbox-inline,
+.theme-black .tpl-form-border-form .am-form-label,
+.theme-black .tpl-form-border-form .am-radio,
+.theme-black .tpl-form-border-form .am-radio-inline {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+.theme-black .tpl-form-border-form .am-form-group:after {
+  clear: both;
+}
+.theme-black .tpl-form-border-form .am-form-group:after,
+.theme-black .tpl-form-border-form .am-form-group:before {
+  content: " ";
+  display: table;
+}
+.theme-black .tpl-form-border-form .am-form-label {
+  padding-top: 5px;
+  font-size: 16px;
+  color: #fff;
+  font-weight: inherit;
+  text-align: right;
+}
+.theme-black .tpl-form-border-form .am-form-group {
+  /*padding: 20px 0;*/
+}
+.theme-black .tpl-form-border-form .am-form-label .tpl-form-line-small-title {
+  color: #999;
+  font-size: 12px;
+}
+.theme-black .tpl-form-line-form input[type=number]:focus,
+.theme-black .tpl-form-line-form input[type=search]:focus,
+.theme-black .tpl-form-line-form input[type=text]:focus,
+.theme-black .tpl-form-line-form input[type=password]:focus,
+.theme-black .tpl-form-line-form input[type=datetime]:focus,
+.theme-black .tpl-form-line-form input[type=datetime-local]:focus,
+.theme-black .tpl-form-line-form input[type=date]:focus,
+.theme-black .tpl-form-line-form input[type=month]:focus,
+.theme-black .tpl-form-line-form input[type=time]:focus,
+.theme-black .tpl-form-line-form input[type=week]:focus,
+.theme-black .tpl-form-line-form input[type=email]:focus,
+.theme-black .tpl-form-line-form input[type=url]:focus,
+.theme-black .tpl-form-line-form input[type=tel]:focus,
+.theme-black .tpl-form-line-form input[type=color]:focus,
+.theme-black .tpl-form-line-form select:focus,
+.theme-black .tpl-form-line-form textarea:focus,
+.theme-black .am-form-field:focus {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.theme-black .tpl-form-line-form input[type=number],
+.theme-black .tpl-form-line-form input[type=search],
+.theme-black .tpl-form-line-form input[type=text],
+.theme-black .tpl-form-line-form input[type=password],
+.theme-black .tpl-form-line-form input[type=datetime],
+.theme-black .tpl-form-line-form input[type=datetime-local],
+.theme-black .tpl-form-line-form input[type=date],
+.theme-black .tpl-form-line-form input[type=month],
+.theme-black .tpl-form-line-form input[type=time],
+.theme-black .tpl-form-line-form input[type=week],
+.theme-black .tpl-form-line-form input[type=email],
+.theme-black .tpl-form-line-form input[type=url],
+.theme-black .tpl-form-line-form input[type=tel],
+.theme-black .tpl-form-line-form input[type=color],
+.theme-black .tpl-form-line-form select,
+.theme-black .tpl-form-line-form textarea,
+.theme-black .am-form-field {
+  display: block;
+  width: 100%;
+  padding: 6px 12px;
+  line-height: 1.42857;
+  color: #4d6b8a;
+  background-color: #fff;
+  background-image: none;
+  border: 1px solid #c2cad8;
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+  background: 0 0;
+  border: 0;
+  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
+  -webkit-border-radius: 0;
+  -moz-border-radius: 0;
+  -ms-border-radius: 0;
+  -o-border-radius: 0;
+  border-radius: 0;
+  color: #fff;
+  box-shadow: none;
+  padding-left: 0;
+  padding-right: 0;
+  font-size: 14px;
+}
+.theme-black .tpl-form-line-form .am-checkbox,
+.theme-black .tpl-form-line-form .am-checkbox-inline,
+.theme-black .tpl-form-line-form .am-form-label,
+.theme-black .tpl-form-line-form .am-radio,
+.theme-black .tpl-form-line-form .am-radio-inline {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+.theme-black .tpl-form-line-form .am-form-group:after {
+  clear: both;
+}
+.theme-black .tpl-form-line-form .am-form-group:after,
+.theme-black .tpl-form-line-form .am-form-group:before {
+  content: " ";
+  display: table;
+}
+.theme-black .tpl-form-line-form .am-form-label {
+  padding-top: 5px;
+  font-size: 16px;
+  color: #fff;
+  font-weight: inherit;
+  text-align: right;
+}
+.theme-black .tpl-form-line-form .am-form-group {
+  /*padding: 20px 0;*/
+}
+.theme-black .tpl-form-line-form .am-form-label .tpl-form-line-small-title {
+  color: #999;
+  font-size: 12px;
+}
+.theme-black .tpl-table-black-operation a {
+  border: 1px solid #7b878d;
+  color: #7b878d;
+}
+.theme-black .tpl-table-black-operation a:hover {
+  background: #7b878d;
+  color: #fff;
+}
+.theme-black .tpl-table-black-operation a.tpl-table-black-operation-del {
+  border: 1px solid #f35842;
+  color: #f35842;
+}
+.theme-black .tpl-table-black-operation a.tpl-table-black-operation-del:hover {
+  background: #f35842;
+  color: #fff;
+}
+.theme-black .am-table-bordered {
+  border: 1px solid #666d70;
+}
+.theme-black .am-table-bordered > tbody > tr > td,
+.theme-black .am-table-bordered > tbody > tr > th,
+.theme-black .am-table-bordered > tfoot > tr > td,
+.theme-black .am-table-bordered > tfoot > tr > th,
+.theme-black .am-table-bordered > thead > tr > td,
+.theme-black .am-table-bordered > thead > tr > th {
+  border: 1px solid #666d70;
+}
+.theme-black .am-table-bordered > thead + tbody > tr:first-child > td,
+.theme-black .am-table-bordered > thead + tbody > tr:first-child > th {
+  border: 1px solid #666d70;
+}
+.theme-black .am-table-striped > tbody > tr:nth-child(odd) > td,
+.theme-black .am-table-striped > tbody > tr:nth-child(odd) > th {
+  background-color: #5d6468;
+}
+.theme-black .tpl-table-black {
+  color: #fff;
+}
+.theme-black .tpl-table-black thead > tr > th {
+  font-size: 14px;
+  padding: 6px;
+  border-bottom: 1px solid #666d70;
+}
+.theme-black .tpl-table-black tbody > tr > td {
+  font-size: 14px;
+  padding: 7px 6px;
+  border-top: 1px solid #666d70;
+}
+.theme-black .tpl-table-black tfoot > tr > th {
+  font-size: 14px;
+  padding: 6px 0;
+}
+.theme-black .tpl-user-card {
+  border: 1px solid #11627d;
+  border-top: 2px solid #105f79;
+  background: #1786aa;
+  color: #ffffff;
+}
+.theme-black .tpl-user-card-title {
+  font-size: 26px;
+  margin-top: 0;
+  font-weight: 300;
+  margin-top: 25px;
+  margin-bottom: 10px;
+}
+.theme-black .achievement-subheading {
+  font-size: 12px;
+  margin-top: 0;
+  margin-bottom: 15px;
+}
+.theme-black .achievement-image {
+  border-radius: 50%;
+  margin-bottom: 22px;
+}
+.theme-black .achievement-description {
+  margin: 0;
+  font-size: 12px;
+}
+.theme-black .am-progress {
+  height: 12px;
+  margin-bottom: 14px;
+  background: rgba(0, 0, 0, 0.15);
+}
+.theme-black .am-progress-title {
+  font-size: 14px;
+  margin-bottom: 8px;
+}
+.theme-black .am-progress-title-more {
+  color: #a1a8ab;
+}
+.theme-black .widget-fluctuation-tpl-btn {
+  margin-top: 6px;
+  display: block;
+  color: #fff;
+  font-size: 12px;
+  padding: 5px 10px;
+  outline: none;
+  background-color: rgba(255, 255, 255, 0);
+  border: 1px solid #fff;
+}
+.theme-black .widget-fluctuation-tpl-btn:hover {
+  background: #fff;
+  color: #4b5357;
+}
+.theme-black .widget-fluctuation-description-text {
+  color: #c5cacd;
+}
+.theme-black .text-success {
+  color: #08ed72;
+}
+.theme-black .widget-fluctuation-period-text {
+  color: #fff;
+}
+.theme-black .widget-head {
+  border-bottom: 1px solid #3f4649;
+}
+.theme-black .widget-function a {
+  color: #7b878d;
+}
+.theme-black .widget-function a:hover {
+  color: #fff;
+}
+.theme-black .widget {
+  border: 1px solid #33393c;
+  border-top: 2px solid #313639;
+  background: #4b5357;
+  color: #ffffff;
+}
+.theme-black .widget-primary {
+  border: 1px solid #11627d;
+  border-top: 2px solid #105f79;
+  background: #1786aa;
+  color: #ffffff;
+  padding: 12px 17px;
+}
+.theme-black .widget-statistic-icon {
+  position: absolute;
+  z-index: 30;
+  right: 30px;
+  top: 0px;
+  font-size: 70px;
+  color: #1b9eca;
+}
+.theme-black .widget-statistic-description {
+  position: relative;
+  z-index: 35;
+  display: block;
+  font-size: 14px;
+  line-height: 14px;
+  padding-top: 8px;
+  color: #9cdcf2;
+}
+.theme-black .widget-statistic-value {
+  position: relative;
+  z-index: 35;
+  font-weight: 300;
+  display: block;
+  color: #fff;
+  font-size: 46px;
+  line-height: 46px;
+  margin-bottom: 8px;
+}
+.theme-black .widget-statistic-header {
+  color: #9cdcf2;
+}
+.theme-black .widget-purple {
+  padding: 12px 17px;
+  border: 1px solid #5e4578;
+  border-top: 2px solid #5c4375;
+  background: #785799;
+  color: #ffffff;
+}
+.theme-black .widget-purple .widget-statistic-icon {
+  color: #8a6aaa;
+}
+.theme-black .widget-purple .widget-statistic-header {
+  color: #ded5e7;
+}
+.theme-black .widget-purple .widget-statistic-description {
+  color: #ded5e7;
+}
+.theme-black .page-header-description {
+  color: #e6e6e6;
+}
+.theme-black .page-header-heading {
+  color: #666;
+}
+.theme-black .container-fluid {
+  background: #424b4f;
+}
+.theme-black .page-header-heading {
+  color: #fff;
+}
+.theme-black .sidebar-nav-heading {
+  color: #fff;
+}
+.theme-black .tpl-sidebar-user-panel {
+  background: #1f2224;
+  border-bottom: 1px solid #1f2224;
+}
+.theme-black .tpl-content-wrapper {
+  background: #3a4144;
+}
+.theme-black .tpl-header-fluid {
+  background: #2f3638;
+}
+.theme-black .sidebar-nav-link a.active {
+  background: #232829;
+}
+.theme-black .sidebar-nav-link a:hover {
+  background: #232829;
+}
+.theme-black .tpl-header-switch-button {
+  background: #2f3638;
+  border-right: 1px solid #282d2f;
+}
+.theme-black .tpl-header-switch-button:hover {
+  background: #282d2f;
+  color: #fff;
+}
+.theme-black .tpl-header-navbar a {
+  color: #cfcfcf;
+}
+.theme-black .tpl-header-navbar a:hover {
+  color: #fff;
+}
+.theme-black .left-sidebar {
+  padding-top: 56px;
+  background: #282d2f;
+}
+.theme-black .widget-color-green {
+  border: 1px solid #11627d;
+  border-top: 2px solid #105f79;
+  background: #1786aa;
+  color: #ffffff;
+}
+.theme-black .widget-color-green .widget-head {
+  border-bottom: 1px solid #147494;
+}
+.theme-black .widget-color-green .widget-fluctuation-description-text {
+  color: #bbe7f6;
+}
+.theme-black .widget-color-green .widget-function a {
+  color: #42bde5;
+}
+.theme-black .widget-color-green .widget-function a:hover {
+  color: #fff;
+}
+@media screen and (max-width: 1024px) {
+  .tpl-index-settings-button {
+    display: none;
+  }
+  .theme-black .left-sidebar {
+    padding-top: 111px;
+  }
+  .left-sidebar {
+    padding-top: 111px;
+  }
+  .tpl-content-wrapper {
+    margin-left: 0;
+  }
+  .tpl-header-logo {
+    float: none;
+    width: 100%;
+  }
+  .tpl-header-navbar-welcome {
+    display: none;
+  }
+  .tpl-sidebar-user-panel {
+    border-top: 1px solid #eee;
+  }
+  .tpl-header-fluid {
+    border-top: none;
+    margin-left: 0;
+  }
+  .theme-white .tpl-header-fluid {
+    border-top: none;
+  }
+  .theme-black .tpl-sidebar-user-panel {
+    border-top: 1px solid #1f2224;
+  }
+}
+@media screen and (min-width: 641px) {
+  [class*=am-u-] {
+    padding-left: 10px;
+    padding-right: 10px;
+  }
+}
+@media screen and (max-width: 641px) {
+  .theme-white .tpl-error-title,
+  .theme-black .tpl-error-title {
+    font-size: 130px;
+    line-height: 140px;
+  }
+  .theme-white .tpl-login-title {
+    font-size: 20px;
+  }
+  .theme-white .tpl-login-content {
+    width: 86%;
+    padding: 22px 30px 25px;
+  }
+  .tpl-header-search {
+    display: none;
+  }
+  ul.tpl-dropdown-content {
+    position: fixed;
+    width: 100%;
+    left: 0;
+    top: 112px;
+    right: 0;
+  }
+}

+ 2056 - 0
Day61-65/code/project_of_tornado/assets/css/app.less

@@ -0,0 +1,2056 @@
+ul,li {
+    list-style: none;
+    padding: 0;
+    margin: 0;
+}
+
+a {
+    
+}
+
+header {
+    z-index: 1200;
+    position: relative;
+}
+.tpl-header-logo {
+    width: 240px;
+    height: 57px;
+    display: table;
+    text-align:center;
+    position: relative;
+    z-index: 1300;
+
+    a {
+        display:table-cell;
+        vertical-align:middle;
+    }
+
+    img {
+        width:170px;
+    }
+}
+
+
+.tpl-header-fluid {
+    margin-left: 240px;
+    height: 56px;
+    
+    padding-left: 20px;
+    padding-right: 20px;
+}
+
+
+.tpl-header-switch-button {
+
+    margin-top: 0px;
+    margin-bottom: 0px;
+    float: left;
+    color: #cfcfcf;
+    margin-left: -20px;
+    margin-right: 0;
+    border: 0;
+    border-radius: 0;
+    padding: 0px 22px;
+    font-size: 22px;
+    line-height: 55px;
+    
+    &:hover {
+      
+        outline: none;
+    }
+}
+
+
+.tpl-header-search-form {
+    height: 54px;
+    line-height: 52px;
+    margin-left: 10px;
+
+}
+.tpl-header-search-box , .tpl-header-search-btn {
+    transition: all 0.4s ease-in-out;
+    color: #848c90;
+    background: none;
+    border: none;
+    outline: none;
+}
+
+.tpl-header-search-box {
+    font-size: 14px;
+
+    &:hover,&:active {
+        color: #fff;
+    }
+}
+
+.tpl-header-search-btn {
+    font-size: 15px;
+
+    &:hover,&:active {
+        color: #fff;
+    }
+}
+
+.tpl-header-navbar {
+    color: #fff;
+    li {
+        float: left;
+    }
+    a {
+        line-height: 56px;
+        display: block;
+        padding: 0 16px;
+        position: relative;
+
+
+        &:hover {
+
+        }
+        
+        .item-feed-badge {
+            position: absolute;
+            top: 9px;
+            left: 25px;
+        }
+    }
+}
+
+ul.tpl-dropdown-content {
+    padding: 10px;
+    margin-top: 0;
+    width: 300px;
+    background-color: #2f3638;
+    border: 1px solid #525e62;
+    border-radius: 0;
+
+    li {
+        float:none;
+    }
+
+    &:before , &:after {
+        display: none;
+    }
+}
+
+
+ul.tpl-dropdown-content {
+
+
+    .tpl-dropdown-menu-notifications {
+        
+    }
+
+    .tpl-dropdown-menu-notifications-title {
+        font-size: 12px;
+        float: left;
+        color: rgba(255, 255, 255, 0.7);
+    }
+
+    .tpl-dropdown-menu-notifications-time {
+         float: right;
+        text-align: right;
+        color: rgba(255, 255, 255, 0.7);
+        font-size: 11px;
+        width: 50px;
+        margin-left: 10px;
+    }
+
+    .tpl-dropdown-menu-notifications:last-child .tpl-dropdown-menu-notifications-item {
+            text-align: center;
+            border: none;
+            font-size: 12px;
+            i {
+                margin-left: -6px;
+            }
+    }
+
+    .tpl-dropdown-menu-messages:last-child .tpl-dropdown-menu-messages-item {
+            text-align: center;
+            border: none;
+            font-size: 12px;
+            i {
+                margin-left: -6px;
+            }
+    }
+    .tpl-dropdown-menu-notifications-item , .tpl-dropdown-menu-messages-item {
+        padding: 12px;
+        color: #fff;
+        line-height: 20px;
+        border-bottom: 1px solid rgba(255, 255, 255, 0.15);
+
+        &:hover , &:focus {
+                background-color: #465154;
+                color: #fff;
+        }
+
+        
+
+        .menu-messages-ico {
+            line-height: initial;
+            float: left;
+            width: 35px;
+            height: 35px;
+            border-radius: 50%;
+            margin-right: 10px;
+            margin-top: 6px;
+            overflow: hidden;
+
+            img {
+                width: 100%;
+                height: auto;
+                vertical-align: middle;
+            }
+        }
+
+        .menu-messages-time {
+            float: right;
+            text-align: right;
+            color: rgba(255, 255, 255, 0.7);
+            font-size: 11px;
+            width: 40px;
+            margin-left: 10px;
+
+            
+        }
+
+        .menu-messages-content {
+            display: block;
+            font-size: 13px;
+            margin-left: 45px;
+            margin-right: 50px;
+
+            .menu-messages-content-title {
+
+            }
+
+            .menu-messages-content-time {
+                margin-top: 3px;
+                color: rgba(255, 255, 255, 0.7);
+                font-size: 11px;
+            }
+        }
+
+       
+    }
+}
+
+.am-dimmer {
+    z-index: 1200;
+}
+.am-modal {
+    z-index: 1300;
+}
+.am-datepicker-dropdown {
+    z-index: 1400;
+}
+
+.tpl-skiner {
+    transition: all 0.4s ease-in-out;
+    position: fixed;
+    z-index: 10000;
+    right: -130px;
+    top: 65px;
+}
+
+.tpl-skiner.active {
+    right: 0px;
+}
+.tpl-skiner-content {
+    background: rgba(0, 0, 0, 0.7);
+    width: 130px;
+    padding: 15px;
+    border-radius: 4px 0 0 4px;
+    overflow: hidden;
+}
+
+.fc-content .am-icon-close {
+    position: absolute;
+    right: 0;
+    top: 0px;
+}
+.tpl-skiner-toggle {
+    position: absolute;
+    top: 5px;
+    left: -40px;
+    width: 40px;
+    color:#969a9b;
+    font-size: 20px;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+    background: rgba(0, 0, 0, 0.7);
+    cursor: pointer;
+    border-top-left-radius: 4px;
+    border-bottom-left-radius: 4px;
+
+}
+.tpl-skiner-content-title {
+    margin: 0;
+    margin-bottom: 4px;
+    padding-bottom: 4px;
+    font-size: 16px;
+    text-transform: uppercase;
+    color:#fff;
+    border-bottom: 1px solid rgba(255, 255, 255, 0.3);
+}
+
+.tpl-skiner-content-bar {
+    padding-top: 10px;
+    .skiner-color {
+        transition: all 0.4s ease-in-out;
+        float: left;
+        width: 25px;
+        height: 25px;
+        margin-right: 10px;
+        cursor: pointer;
+    }
+    .skiner-white {
+        background: #fff;
+        border: 2px solid #eee;
+    }
+
+    .skiner-black {
+        background: #000;
+        border: 2px solid #222;
+    }
+}
+
+.sub-active {
+    color:#fff!important;
+}
+.left-sidebar {
+        transition: all 0.4s ease-in-out;
+    width: 240px;
+    min-height: 100%;
+    padding-top: 57px;
+    position: absolute;
+    z-index: 1104;
+    top: 0;
+    left: 0px;
+    &.xs-active {
+        left:0px;
+    }
+    &.active {
+        left:-240px;
+    }
+    
+}
+.tpl-sidebar-user-panel {
+    padding: 22px;
+    padding-top: 28px;
+}
+
+.tpl-user-panel-slide-toggleable {
+
+}
+
+.tpl-user-panel-profile-picture {
+    border-radius: 50%;
+    width: 82px;
+    height: 82px;
+    margin-bottom: 10px;
+    overflow: hidden;
+
+    img {
+        width: auto;
+        height: 82px;
+        vertical-align: middle;
+    }
+}
+.tpl-user-panel-status-icon {
+        margin-right: 2px;
+}
+.user-panel-logged-in-text {
+    display: block;
+
+    color:#cfcfcf;
+    font-size: 14px;
+}
+.tpl-user-panel-action-link {
+    color: #6d787c;
+    font-size: 12px;
+    &:hover {
+        color: #a2aaad;
+    }
+}
+
+.sidebar-nav {
+    list-style-type: none;
+    padding: 0;
+    margin: 0;
+}
+
+.sidebar-nav-sub {
+    display: none;
+    .sidebar-nav-link {
+        font-size: 12px;
+        padding-left: 30px;
+    a {
+        font-size: 12px;
+        padding-left: 0;
+    }
+    }
+
+    .sidebar-nav-link-logo {
+            margin-right: 8px;
+    width: 20px;
+    font-size: 16px;
+    }
+}
+
+.sidebar-nav-sub-ico-rotate{
+    -webkit-transform: rotate(180deg);
+    transform: rotate(180deg);
+    -webkit-transition: all 300ms;
+    transition: all 300ms;
+}
+.sidebar-nav-link-logo-ico {
+    margin-top: 5px;
+}
+.sidebar-nav-heading {
+    padding: 24px 17px;
+    font-size: 15px;
+    font-weight: 500;
+}
+.sidebar-nav-heading-info {
+    font-size: 12px;
+    color:#868E8E;
+    padding-left: 10px;
+}
+.sidebar-nav-link-logo {
+    margin-right: 8px;
+    width: 20px;
+    font-size: 16px;
+}
+.sidebar-nav-link {
+ 
+    color: #fff;
+
+    a {
+        display: block;
+        color: #868E8E;
+        padding: 10px 17px;
+        border-left: #282d2f 3px solid;
+        font-size: 14px;
+        cursor: pointer;
+
+        &.active {
+            cursor: pointer;
+            border-left: #1CA2CE 3px solid;
+            color: #fff;
+            
+        }
+
+        &:hover {
+            color: #fff;
+        }
+    }
+}
+
+.tpl-content-wrapper {
+    transition: all 0.4s ease-in-out;
+    position: relative;
+    margin-left: 240px;
+    z-index: 1101;
+    min-height: 922px;
+    border-bottom-left-radius: 3px;
+    &.xs-active {
+        margin-left: 240px;
+    }
+    &.active {
+        margin-left: 0;
+    }
+}
+
+.page-header {
+    background: #424b4f;
+    margin-top: 0;
+    margin-bottom: 0;
+    padding: 40px 0;
+    border-bottom: 0;
+}
+
+.container-fluid {
+    margin-top: 0;
+    margin-bottom: 0;
+    padding: 40px 0;
+    border-bottom: 0;
+        padding-left: 20px;
+    padding-right: 20px;
+}
+
+.row {
+    margin-right: -10px;
+    margin-left: -10px;
+}
+
+.page-header-description {
+    margin-top: 4px;
+    margin-bottom: 0;
+    font-size: 14px;
+    color: #e6e6e6;
+}
+.page-header-heading {
+    font-size: 20px;
+    font-weight: 400;
+    .page-header-heading-ico {
+        font-size: 28px;
+        position: relative;
+        top: 3px;
+    }
+    small {
+            font-weight: normal;
+    line-height: 1;
+    color: #B3B3B3;
+    }
+}
+
+.page-header-button {
+    transition: all 0.4s ease-in-out;
+    opacity: 0.3;
+    font-weight: 500;
+    border-radius: 0;
+    float: right;
+    outline: none;
+    border: 1px solid #fff;
+    padding: 16px 36px;
+    font-size: 23px;
+    line-height: 23px;
+    border-radius: 0;
+    padding-top: 14px;
+    color: #fff;
+    background-color: rgba(0, 0, 0, 0);
+    font-weight: 500;
+
+    &:hover {
+        background-color: #ffffff;
+        color: #333;
+        opacity: 1;
+    }
+}
+.widget {
+    width: 100%;
+        min-height: 148px;
+    margin-bottom: 20px;
+    border-radius: 0;
+    position: relative;
+}
+
+.widget-head {
+    width: 100%;
+    padding: 15px;
+}
+
+.widget-title  {
+    font-size: 14px;
+}
+.widget-function {
+      
+}
+.widget-fluctuation-period-text {
+    display: inline-block;
+    font-size: 16px;
+    line-height: 20px;
+    margin-bottom: 9px;
+}
+.widget-body {
+    padding: 13px 15px;
+    width: 100%;
+}
+.row-content {
+    padding: 20px;
+}
+
+.widget-fluctuation-description-text{
+margin-top: 4px;
+    display: block;
+    font-size: 12px;
+    line-height: 13px;
+    }
+
+.text-success {
+
+}
+.widget-fluctuation-tpl-btn {
+
+}
+.widget-fluctuation-description-amount {
+    display: block;
+    font-size: 20px;
+    line-height: 22px;
+}
+
+.widget-primary {
+
+}
+
+.widget-statistic-header {
+    position: relative;
+    z-index: 35;
+    display: block;
+    font-size: 14px;
+    text-transform: uppercase;
+    margin-bottom: 8px;
+}
+ .widget-body-md {
+      height: 200px;
+  }
+.widget-body-lg {
+    min-height: 330px;
+    // height: 330px;
+}
+.widget-margin-bottom-lg {
+    margin-bottom: 20px;
+}
+
+.tpl-table-black-operation {
+
+}
+
+
+.tpl-table-black-operation {
+    a {
+        display: inline-block;
+        padding: 5px 6px;
+        font-size: 12px;
+        line-height: 12px;
+    }
+}
+.tpl-switch input[type="checkbox"] {
+        position: absolute;
+        opacity: 0;
+        width: 50px;
+    height: 20px;
+    }
+
+    
+    .tpl-switch input[type="checkbox"].ios-switch + div {
+        vertical-align: middle;
+        width: 40px;
+        height: 20px;
+
+        border-radius: 999px;
+        background-color: rgba(0, 0, 0, 0.1);
+        -webkit-transition-duration: .4s;
+        -webkit-transition-property: background-color, box-shadow;
+
+        margin-top: 6px;
+    }
+
+    
+    .tpl-switch input[type="checkbox"].ios-switch:checked + div {
+        width: 40px;
+        background-position: 0 0;
+        background-color: #36c6d3;
+
+
+    }
+
+    
+    .tpl-switch input[type="checkbox"].tinyswitch.ios-switch + div {
+        width: 34px;
+        height: 18px;
+    }
+
+    
+    .tpl-switch input[type="checkbox"].bigswitch.ios-switch + div {
+        width: 50px;
+        height: 25px;
+    }
+
+    
+    .tpl-switch input[type="checkbox"].green.ios-switch:checked + div {
+        background-color: #00e359;
+        border: 1px solid rgba(0, 162, 63, 1);
+        box-shadow: inset 0 0 0 10px rgba(0, 227, 89, 1);
+    }
+
+    
+    .tpl-switch input[type="checkbox"].ios-switch + div > div {
+        float: left;
+        width: 18px;
+        height: 18px;
+        border-radius: inherit;
+        background: #ffffff;
+        -webkit-transition-timing-function: cubic-bezier(.54, 1.85, .5, 1);
+        -webkit-transition-duration: 0.4s;
+        -webkit-transition-property: transform, background-color, box-shadow;
+        -moz-transition-timing-function: cubic-bezier(.54, 1.85, .5, 1);
+        -moz-transition-duration: 0.4s;
+        -moz-transition-property: transform, background-color;
+  
+        pointer-events: none;
+        margin-top: 1px;
+        margin-left: 1px;
+    }
+
+    
+    .tpl-switch input[type="checkbox"].ios-switch:checked + div > div {
+        -webkit-transform: translate3d(20px, 0, 0);
+        -moz-transform: translate3d(20px, 0, 0);
+        background-color: #ffffff;
+  
+    }
+
+    
+    .tpl-switch input[type="checkbox"].tinyswitch.ios-switch + div > div {
+        width: 16px;
+        height: 16px;
+        margin-top: 1px;
+    }
+
+    
+    .tpl-switch input[type="checkbox"].tinyswitch.ios-switch:checked + div > div {
+        -webkit-transform: translate3d(16px, 0, 0);
+        -moz-transform: translate3d(16px, 0, 0);
+        box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3), 0px 0px 0 1px rgba(8, 80, 172, 1);
+    }
+
+    
+    .tpl-switch input[type="checkbox"].bigswitch.ios-switch + div > div {
+        width: 23px;
+        height: 23px;
+        margin-top: 1px;
+    }
+
+    
+    .tpl-switch input[type="checkbox"].bigswitch.ios-switch:checked + div > div {
+        -webkit-transform: translate3d(25px, 0, 0);
+        -moz-transform: translate3d(16px, 0, 0);
+   
+    }
+
+    
+    .tpl-switch input[type="checkbox"].green.ios-switch:checked + div > div {
+        box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(0, 162, 63, 1);
+    }
+
+
+
+.tpl-page-state {
+    width: 100%;
+}
+
+.tpl-page-state-title {
+    font-size: 40px;
+    font-weight: bold;
+}
+
+.tpl-page-state-content {
+    padding: 10px 0;
+}
+
+.tpl-login {
+   width: 100%; 
+}
+
+.tpl-login-logo {
+    max-width: 159px;
+    height: 205px;
+    margin: 0 auto;
+    margin-bottom: 20px;
+}
+.tpl-login-title {
+    width: 100%;
+    font-size: 24px;
+}
+.tpl-login-content {
+    width: 300px;
+    margin: 12% auto 0;
+}
+.tpl-login-remember-me {
+    color: #B3B3B3;
+    font-size: 14px;
+
+        label {
+            position: relative;
+            top: -2px;
+        }
+}
+.tpl-login-content-info {
+    color: #B3B3B3;
+    font-size: 14px;
+}
+
+.tpl-pagination {
+
+}
+
+.cl-p {
+    padding: 0!important;
+}
+.tpl-table-line-img {
+    max-width: 100px;
+    padding: 2px;
+}
+.tpl-table-list-select {
+        text-align:right;
+    }
+.fc-button-group, .fc button {
+    display: block;
+}
+
+.theme-white {
+
+    .sidebar-nav-sub {
+        .sidebar-nav-link-logo {
+            margin-left: 10px;
+        }
+    }
+    .tpl-header-search-box:hover, .tpl-header-search-box:active
+    .tpl-error-title {
+
+        color: #848c90;
+    }
+    .tpl-error-title-info {
+        line-height: 30px;
+    font-size: 21px;
+    margin-top: 20px;
+            text-align: center;
+            color: #dce2ec;
+    }
+    .tpl-error-btn {
+        background: #03a9f3;
+    border: 1px solid #03a9f3;
+    border-radius: 30px;
+    padding: 6px 20px 8px;
+    }
+    .tpl-error-content {
+        margin-top: 20px;
+        margin-bottom: 20px;
+        font-size: 16px;
+        text-align: center;
+        color: #96a2b4;
+    }
+.tpl-calendar-box {
+        background: #fff;
+        border-radius: 4px;
+        padding: 20px;
+        .fc-event {
+            border-radius: 0;
+            background: #03a9f3;
+            border: 1px solid #14b0f6;
+        }
+        .fc-axis {
+            color: #868E8E;
+        }
+        .fc-unthemed .fc-today {
+            background: #eee;
+        }
+        .fc-more {
+            color: #868E8E;
+        }
+
+        .fc th.fc-widget-header {
+                background: #32c5d2!important;
+
+    color: #ffffff;
+    font-size: 14px;
+    line-height: 20px;
+    padding: 7px 0px;
+    text-transform: uppercase;
+    border:none!important;
+    a {
+        color: #fff;
+    }
+        }
+ 
+        .fc-center {
+            h2 {
+                color:#868E8E;
+            }
+        }
+        .fc-state-default {
+            background-image: none;
+            background: #fff;
+            font-size: 14px;
+            color: #868E8E;
+}
+        .fc th, .fc td, .fc hr, .fc thead, .fc tbody, .fc-row {
+            // background: rgba(0, 0, 0, 0)!important;
+                border-color: #eee!important;
+        }
+        .fc-day-number {
+            color: #868E8E;
+            padding-right: 6px;
+        }
+        .fc th {
+            color: #868E8E;
+            font-weight: normal;
+            font-size: 14px;
+            padding: 6px 0;
+        }
+    }
+
+    .tpl-login-logo {
+        background: url(../img/logoa.png) center no-repeat;
+        
+    }
+    .sub-active {
+
+        color:#23abf0!important;
+    }
+.tpl-table-line-img {
+    border: 1px solid #ddd;
+}
+.tpl-pagination .am-disabled a , .tpl-pagination li a {
+    color: #23abf0;
+    border-radius: 3px;
+    padding: 6px 12px;
+}
+
+.tpl-pagination .am-active a{
+    background: #23abf0;color: #fff;
+    border: 1px solid #23abf0;
+    padding: 6px 12px;
+}
+
+   
+.tpl-login-btn {
+    background-color:#32c5d2;
+    border: none;
+    padding: 10px 16px;
+    font-size: 14px;
+    line-height: 14px;
+    outline: none;
+
+    &:hover,&:active {
+        background: #22b2e1;
+        color:#fff;
+    }
+
+}
+.tpl-login-title {
+      color: #697882;
+    strong {
+        color: #39bae4;
+    }
+}
+   .tpl-login-content{
+       width: 500px;
+    padding: 40px 40px 25px;
+    background-color: #fff;
+    border-radius: 4px;
+   }
+    
+  .tpl-form-line-form , .tpl-form-border-form {
+        padding-top: 20px;
+  }
+
+
+.tpl-form-border-form input[type=number]:focus, .tpl-form-border-form input[type=search]:focus, .tpl-form-border-form input[type=text]:focus, .tpl-form-border-form input[type=password]:focus, .tpl-form-border-form input[type=datetime]:focus, .tpl-form-border-form input[type=datetime-local]:focus, .tpl-form-border-form input[type=date]:focus, .tpl-form-border-form input[type=month]:focus, .tpl-form-border-form input[type=time]:focus, .tpl-form-border-form input[type=week]:focus, .tpl-form-border-form input[type=email]:focus, .tpl-form-border-form input[type=url]:focus, .tpl-form-border-form input[type=tel]:focus, .tpl-form-border-form input[type=color]:focus, .tpl-form-border-form select:focus, .tpl-form-border-form textarea:focus, .am-form-field:focus{
+          -webkit-box-shadow: none;
+    box-shadow: none;
+  }
+.tpl-form-border-form input[type=number], .tpl-form-border-form input[type=search], .tpl-form-border-form input[type=text], .tpl-form-border-form input[type=password], .tpl-form-border-form input[type=datetime], .tpl-form-border-form input[type=datetime-local], .tpl-form-border-form input[type=date], .tpl-form-border-form input[type=month], .tpl-form-border-form input[type=time], .tpl-form-border-form input[type=week], .tpl-form-border-form input[type=email], .tpl-form-border-form input[type=url], .tpl-form-border-form input[type=tel], .tpl-form-border-form input[type=color], .tpl-form-border-form select, .tpl-form-border-form textarea, .am-form-field {
+        display: block;
+    width: 100%;
+
+    padding: 6px 12px;
+    font-size: 14px;
+    line-height: 1.42857;
+    color: #4d6b8a;
+    background-color: #fff;
+    background-image: none;
+    border: 1px solid #c2cad8;
+    border-radius: 4px;
+    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    -webkit-transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    -o-transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    background: 0 0;
+    border: 0;
+    border: 1px solid #c2cad8;
+    -webkit-border-radius: 0;
+    -moz-border-radius: 0;
+    -ms-border-radius: 0;
+    text-indent: .5em;
+    -o-border-radius: 0;
+    border-radius: 0;
+    color: #555;
+    box-shadow: none;
+    padding-left: 0;
+    padding-right: 0;
+    font-size: 14px;
+}
+
+.tpl-form-border-form .am-checkbox, .tpl-form-border-form .am-checkbox-inline, .tpl-form-border-form .am-form-label, .tpl-form-border-form .am-radio, .tpl-form-border-form .am-radio-inline{
+    margin-top: 0;
+    margin-bottom: 0;
+
+}
+
+.tpl-form-border-form .am-form-group:after {
+    clear: both;
+}
+.tpl-form-border-form .am-form-group:after, .tpl-form-border-form .am-form-group:before {
+content: " ";
+    display: table;
+
+}
+.tpl-form-border-form  .am-form-label{    
+    padding-top: 5px;
+font-size: 16px;
+color: #888;
+font-weight: inherit;
+text-align: right;
+}
+.tpl-form-border-form  .am-form-group {
+    /*padding: 20px 0;*/
+
+}
+.tpl-form-border-form  .am-form-label .tpl-form-line-small-title {
+    color: #999;
+    font-size: 12px;
+}
+
+  .tpl-form-line-form input[type=number]:focus, .tpl-form-line-form input[type=search]:focus, .tpl-form-line-form input[type=text]:focus, .tpl-form-line-form input[type=password]:focus, .tpl-form-line-form input[type=datetime]:focus, .tpl-form-line-form input[type=datetime-local]:focus, .tpl-form-line-form input[type=date]:focus, .tpl-form-line-form input[type=month]:focus, .tpl-form-line-form input[type=time]:focus, .tpl-form-line-form input[type=week]:focus, .tpl-form-line-form input[type=email]:focus, .tpl-form-line-form input[type=url]:focus, .tpl-form-line-form input[type=tel]:focus, .tpl-form-line-form input[type=color]:focus, .tpl-form-line-form select:focus, .tpl-form-line-form textarea:focus, .am-form-field:focus{
+          -webkit-box-shadow: none;
+    box-shadow: none;
+  }
+.tpl-form-line-form input[type=number], .tpl-form-line-form input[type=search], .tpl-form-line-form input[type=text], .tpl-form-line-form input[type=password], .tpl-form-line-form input[type=datetime], .tpl-form-line-form input[type=datetime-local], .tpl-form-line-form input[type=date], .tpl-form-line-form input[type=month], .tpl-form-line-form input[type=time], .tpl-form-line-form input[type=week], .tpl-form-line-form input[type=email], .tpl-form-line-form input[type=url], .tpl-form-line-form input[type=tel], .tpl-form-line-form input[type=color], .tpl-form-line-form select, .tpl-form-line-form textarea, .am-form-field {
+        display: block;
+    width: 100%;
+
+    padding: 6px 12px;
+    font-size: 14px;
+    line-height: 1.42857;
+    color: #4d6b8a;
+    background-color: #fff;
+    background-image: none;
+    border: 1px solid #c2cad8;
+    border-radius: 4px;
+    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    -webkit-transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    -o-transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    background: 0 0;
+    border: 0;
+    border-bottom: 1px solid #c2cad8;
+    -webkit-border-radius: 0;
+    -moz-border-radius: 0;
+    -ms-border-radius: 0;
+    -o-border-radius: 0;
+    border-radius: 0;
+    color: #555;
+    box-shadow: none;
+    padding-left: 0;
+    padding-right: 0;
+    font-size: 14px;
+}
+
+.tpl-form-line-form .am-checkbox, .tpl-form-line-form .am-checkbox-inline, .tpl-form-line-form .am-form-label, .tpl-form-line-form .am-radio, .tpl-form-line-form .am-radio-inline{
+    margin-top: 0;
+    margin-bottom: 0;
+
+}
+
+.tpl-form-line-form .am-form-group:after {
+    clear: both;
+}
+.tpl-form-line-form .am-form-group:after, .tpl-form-line-form .am-form-group:before {
+content: " ";
+    display: table;
+
+}
+.tpl-form-line-form  .am-form-label{    
+    padding-top: 5px;
+font-size: 16px;
+color: #888;
+font-weight: inherit;
+text-align: right;
+}
+.tpl-form-line-form  .am-form-group {
+    /*padding: 20px 0;*/
+
+}
+.tpl-form-line-form  .am-form-label .tpl-form-line-small-title {
+    color: #999;
+    font-size: 12px;
+}
+
+    .tpl-table-black-operation {
+    a {
+        border: 1px solid #36c6d3;
+        color:#36c6d3;
+        &:hover {
+            background: #36c6d3;
+            color:#fff;
+        }
+    }
+    a.tpl-table-black-operation-del {
+        border: 1px solid #e7505a;
+        color:#e7505a;
+        &:hover {
+            background: #e7505a;
+            color:#fff;
+        }
+    }
+}
+    .tpl-amendment-echarts {
+            left: -17px;
+    }
+   .tpl-user-card {
+        border: 1px solid #3598dc;
+        border-top: 2px solid #3598dc;
+        background: #3598dc;
+        color: #ffffff;
+        border-radius: 4px;
+    }
+          .tpl-user-card-title {
+        font-size: 26px;
+        margin-top: 0;
+        font-weight: 300;
+        margin-top: 25px;
+        margin-bottom: 10px;
+    }
+    .achievement-subheading {
+        font-size: 12px;
+        margin-top: 0;
+        margin-bottom: 15px;
+    }
+     .achievement-image {
+             border-radius: 50%;
+    margin-bottom: 22px;
+     }
+     .achievement-description {
+             margin: 0;
+    font-size: 12px;
+     }
+
+           .tpl-table-black {
+            color: #838FA1;
+
+        thead>tr>th {
+            font-size: 14px;
+            padding: 6px;
+        }
+        tbody>tr>td {
+            font-size: 14px;
+            padding: 7px 6px;
+
+        }
+        tfoot>tr>th {
+            font-size: 14px;
+            padding: 6px 0;
+        }
+    }
+
+
+     .am-progress {
+          height: 12px;
+     }
+    .am-progress-title {
+        font-size: 14px;
+         margin-bottom: 8px;
+    }
+    .am-progress-title-more {
+
+    }
+      .widget-fluctuation-tpl-btn {
+       margin-top: 6px;
+       display: block;
+        color: #fff;
+        font-size: 12px;
+            padding: 8px 14px;
+            outline: none;
+    background-color: #e7505a;
+    border: 1px solid #e7505a;
+            &:hover {
+                background:transparent;
+                color:#e7505a;
+            }
+
+    }
+    .widget-fluctuation-description-text{
+color: #c5cacd;
+    }
+    background: #e9ecf3;
+    .widget-fluctuation-period-text {
+        color:#838FA1;
+    }
+.text-success {
+       color: #5eb95e;
+}
+    .widget-head {
+         border-bottom: 1px solid #eef1f5;
+}
+   .widget-function {
+       a {
+            color: #838FA1;
+        &:hover {
+            color:#a7bdcd;
+        }
+       }
+   
+    }
+    .widget  {
+        padding: 10px 20px 13px;
+        background-color: #fff;
+        border-radius: 4px;
+            color: #838FA1;
+            
+    }
+    .widget-title {
+        font-size: 16px;
+    }
+
+    .widget-primary {
+       
+        min-height: 174px;
+    border: 1px solid #32c5d2;
+    border-top: 2px solid #32c5d2;
+    background: #32c5d2;
+    color: #ffffff;
+        padding: 12px 17px;
+         padding-left: 22px;
+}
+.widget-statistic-body {
+
+}
+.widget-statistic-icon {
+    position: absolute;
+    z-index: 30;
+    right: 30px;
+    top: 24px;
+    font-size: 70px;
+    color: #46cad6;
+}
+.widget-statistic-description {
+    position: relative;
+    z-index: 35;
+    display: block;
+    font-size: 14px;
+    line-height: 14px;
+    padding-top: 8px;
+        color: #fff;
+}
+.widget-statistic-value {
+    position: relative;
+    z-index: 35;
+    font-weight: 300;
+    display: block;
+    color: #fff;
+    font-size: 46px;
+    line-height: 46px;
+    margin-bottom: 8px;
+}
+.widget-statistic-header {
+    padding-top: 18px;
+    color: #fff;
+}
+.widget-purple {
+        padding: 12px 17px;
+        border: 1px solid #8E44AD;
+    border-top: 2px solid #8E44AD;
+    background: #8E44AD;
+    color: #ffffff;
+        min-height: 174px;
+     .widget-statistic-icon {
+             color: #9956b5;
+     }
+    .widget-statistic-header {
+        color: #ded5e7;
+    }
+    .widget-statistic-description {
+            color: #ded5e7;
+    }
+}
+    .page-header-button {
+        opacity: .8;
+        border: 1px solid #32c5d2;
+        background: #32c5d2;
+        color:#fff;
+        &:hover {
+            opacity: 1;
+        }
+    }
+       .page-header-description {
+       color: #666;
+   }
+    .page-header-heading {
+        color: #666;
+    }
+    .container-fluid {
+    
+    }
+    ul.tpl-dropdown-content .tpl-dropdown-menu-messages-item .menu-messages-content .menu-messages-content-time {
+    color: #96a5aa;
+    }
+    ul.tpl-dropdown-content {
+        background: #fff;
+        border: 1px solid #ddd;
+    .tpl-dropdown-menu-notifications-item , .tpl-dropdown-menu-messages-item {
+        border-bottom: 1px solid #eee;
+        color:#999;
+            
+            &:hover{
+                    background-color: #f5f5f5;
+            }
+        .tpl-dropdown-menu-notifications-time {
+            color: #999;
+        }
+    }
+        .tpl-dropdown-menu-messages-item:hover {
+                background-color: #f5f5f5;
+        }
+
+        .tpl-dropdown-menu-notifications-title {
+            color:#999;
+        }
+
+        
+    }
+    .sidebar-nav-link {
+        a {
+            border-left: #fff 3px solid;
+        }
+        a:hover {
+
+            background: #f2f6f9;
+    color: #868E8E;
+    border-left: #3bb4f2 3px solid;
+        }
+    }
+
+    .sidebar-nav-link a.active {
+            background: #f2f6f9;
+            color:  #868E8E;
+            border-left: #3bb4f2 3px solid;
+    }
+   .sidebar-nav-heading {
+       color: #999;
+       border-bottom: 1px solid #eee;
+   }
+    .tpl-sidebar-user-panel {
+        background: #fff;
+        border-bottom: 1px solid #eee;
+    }
+.tpl-content-wrapper {
+       background: #e9ecf3;
+   }
+    .tpl-header-fluid {
+    background: #fff;
+    border-top: 1px solid #eee;
+}
+    .tpl-header-logo {
+     background: #fff;
+     border-bottom: 1px solid #eee;
+}
+
+.tpl-header-switch-button {
+    background: #fff;
+    border-right: 1px solid #eee;
+    border-left: 1px solid #eee;
+    &:hover {
+        background: #fff;
+        color: #999;
+    }
+}
+     .tpl-header-navbar {
+        a {
+            color:#999;
+
+            &:hover {
+                color: #999;
+            }
+        }
+    }
+    .left-sidebar {
+        background: #fff;
+    }
+
+  .widget-color-green {
+        border: 1px solid #32c5d2;
+    border-top: 2px solid #32c5d2;
+    background: #32c5d2;
+    color: #ffffff;
+    .widget-fluctuation-period-text {
+        color:#fff;
+    }
+    .widget-head {
+        border-bottom: 1px solid #2bb8c4;
+    }
+    .widget-fluctuation-description-text {
+        color:#bbe7f6;
+    }
+    .widget-function {
+        a {
+            color:#42bde5;
+            &:hover {
+                color: #fff;
+            }
+        }
+    }
+    }
+
+
+
+}
+
+
+.theme-black {
+
+    .tpl-am-model-bd {
+        background: #424b4f;
+    }
+    .tpl-model-dialog {
+        background: #424b4f;
+    }
+     .tpl-error-title {
+        font-size: 210px;
+        line-height: 220px;
+        color: #868E8E;
+    }
+    .tpl-error-title-info {
+        line-height: 30px;
+    font-size: 21px;
+    margin-top: 20px;
+            text-align: center;
+            color: #868E8E;
+    }
+    .tpl-error-btn {
+        background: #03a9f3;
+    border: 1px solid #03a9f3;
+    border-radius: 30px;
+    padding: 6px 20px 8px;
+    }
+    .tpl-error-content {
+        margin-top: 20px;
+        margin-bottom: 20px;
+        font-size: 16px;
+        text-align: center;
+        color: #cfcfcf;
+    }
+    .tpl-calendar-box {
+        background: #424b4f;
+        padding: 20px;
+        .fc-button {
+            border-radius: 0;
+            box-shadow:0;
+        }
+        .fc-event {
+            border-radius: 0;
+            background: #03a9f3;
+        }
+        .fc-axis {
+            color: #fff;
+        }
+        .fc-unthemed .fc-today {
+            background: #3a4144;
+        }
+        .fc-more {
+            color: #fff;
+        }
+        .fc th.fc-widget-header {
+                background: #9675ce!important;
+    color: #ffffff;
+    font-size: 14px;
+    line-height: 20px;
+    padding: 7px 0px;
+    text-transform: uppercase;
+    border:none!important;
+    a {
+        color: #fff;
+    }
+        }
+ 
+        .fc-center {
+            h2 {
+                color:#fff;
+            }
+        }
+        .fc-state-default {
+            background-image: none;
+            background: #fff;
+            font-size: 14px;
+}
+        .fc th, .fc td, .fc hr, .fc thead, .fc tbody, .fc-row {
+            // background: rgba(0, 0, 0, 0)!important;
+                border-color: rgba(120, 130, 140, 0.4) !important;
+        }
+        .fc-day-number {
+            color: #868E8E;
+            padding-right: 6px;
+        }
+        .fc th {
+            color: #868E8E;
+            font-weight: normal;
+            font-size: 14px;
+            padding: 6px 0;
+        }
+    }
+   .tpl-login-logo {
+        background: url(../img/logob.png) center no-repeat;
+        
+    }
+    .tpl-table-line-img {
+    max-width: 100px;
+    padding: 2px;
+border: none;
+}
+   .tpl-table-list-field {
+       border: none;
+   }
+    .tpl-table-list-select {
+   
+        .am-dropdown-content {
+            color:#888;
+        }
+        .am-selected-btn {
+                border:1px solid rgba(255, 255, 255, 0.2);
+                color:#fff;
+        }
+
+        .am-btn-default.am-active, .am-btn-default:active, .am-dropdown.am-active .am-btn-default.am-dropdown-toggle {
+            border:1px solid rgba(255, 255, 255, 0.2);
+                color:#fff;
+                background: #5d6468;
+        }
+    }
+.tpl-pagination .am-disabled a , .tpl-pagination li a {
+    color: #fff;
+    padding: 6px 12px;
+    background: #3f4649;
+    border: none;
+}
+
+.tpl-pagination .am-active a{
+    background: #167fa1;color: #fff;
+    border: 1px solid #167fa1;
+    padding: 6px 12px;
+}
+
+.tpl-login-btn {
+    border: 1px solid #b5b5b5;
+    background-color: rgba(0, 0, 0, 0);
+    padding: 10px 16px;
+    font-size: 14px;
+    line-height: 14px;
+    color:#b5b5b5;
+
+    &:hover,&:active {
+        background: #b5b5b5;
+        color:#fff;
+    }
+
+}
+.tpl-login-title {
+    color:#fff;
+    strong {
+        color: #39bae4;
+    }
+}
+
+
+
+
+ .tpl-form-line-form , .tpl-form-border-form {
+        padding-top: 20px;
+
+        .am-btn-default {
+            color:#fff;
+            border: 1px solid rgba(255, 255, 255, 0.2);
+           
+        }
+         .am-selected-text {
+                color:#888;
+            }
+  }
+  .tpl-form-border-form input[type=number]:focus, .tpl-form-border-form input[type=search]:focus, .tpl-form-border-form input[type=text]:focus, .tpl-form-border-form input[type=password]:focus, .tpl-form-border-form input[type=datetime]:focus, .tpl-form-border-form input[type=datetime-local]:focus, .tpl-form-border-form input[type=date]:focus, .tpl-form-border-form input[type=month]:focus, .tpl-form-border-form input[type=time]:focus, .tpl-form-border-form input[type=week]:focus, .tpl-form-border-form input[type=email]:focus, .tpl-form-border-form input[type=url]:focus, .tpl-form-border-form input[type=tel]:focus, .tpl-form-border-form input[type=color]:focus, .tpl-form-border-form select:focus, .tpl-form-border-form textarea:focus, .am-form-field:focus{
+          -webkit-box-shadow: none;
+    box-shadow: none;
+  }
+.tpl-form-border-form input[type=number], .tpl-form-border-form input[type=search], .tpl-form-border-form input[type=text], .tpl-form-border-form input[type=password], .tpl-form-border-form input[type=datetime], .tpl-form-border-form input[type=datetime-local], .tpl-form-border-form input[type=date], .tpl-form-border-form input[type=month], .tpl-form-border-form input[type=time], .tpl-form-border-form input[type=week], .tpl-form-border-form input[type=email], .tpl-form-border-form input[type=url], .tpl-form-border-form input[type=tel], .tpl-form-border-form input[type=color], .tpl-form-border-form select, .tpl-form-border-form textarea, .am-form-field {
+        display: block;
+    width: 100%;
+
+    padding: 6px 12px;
+    font-size: 14px;
+    line-height: 1.42857;
+    color: #4d6b8a;
+    background-color: #fff;
+    background-image: none;
+    border: 1px solid #c2cad8;
+    border-radius: 4px;
+    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    -webkit-transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    -o-transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    background: 0 0;
+    border: 0;
+    text-indent: .5em;
+    border: 1px solid rgba(255, 255, 255, 0.2);
+    -webkit-border-radius: 0;
+    -moz-border-radius: 0;
+    -ms-border-radius: 0;
+    -o-border-radius: 0;
+    border-radius: 0;
+    color: #fff;
+    box-shadow: none;
+    padding-left: 0;
+    padding-right: 0;
+    font-size: 14px;
+}
+
+.tpl-form-border-form .am-checkbox, .tpl-form-border-form .am-checkbox-inline, .tpl-form-border-form .am-form-label, .tpl-form-border-form .am-radio, .tpl-form-border-form .am-radio-inline{
+    margin-top: 0;
+    margin-bottom: 0;
+
+}
+
+.tpl-form-border-form .am-form-group:after {
+    clear: both;
+}
+.tpl-form-border-form .am-form-group:after, .tpl-form-border-form .am-form-group:before {
+content: " ";
+    display: table;
+
+}
+.tpl-form-border-form  .am-form-label{    
+    padding-top: 5px;
+font-size: 16px;
+color: #fff;
+font-weight: inherit;
+text-align: right;
+}
+.tpl-form-border-form  .am-form-group {
+    /*padding: 20px 0;*/
+
+}
+.tpl-form-border-form  .am-form-label .tpl-form-line-small-title {
+    color: #999;
+    font-size: 12px;
+}
+
+
+
+
+
+
+  .tpl-form-line-form input[type=number]:focus, .tpl-form-line-form input[type=search]:focus, .tpl-form-line-form input[type=text]:focus, .tpl-form-line-form input[type=password]:focus, .tpl-form-line-form input[type=datetime]:focus, .tpl-form-line-form input[type=datetime-local]:focus, .tpl-form-line-form input[type=date]:focus, .tpl-form-line-form input[type=month]:focus, .tpl-form-line-form input[type=time]:focus, .tpl-form-line-form input[type=week]:focus, .tpl-form-line-form input[type=email]:focus, .tpl-form-line-form input[type=url]:focus, .tpl-form-line-form input[type=tel]:focus, .tpl-form-line-form input[type=color]:focus, .tpl-form-line-form select:focus, .tpl-form-line-form textarea:focus, .am-form-field:focus{
+          -webkit-box-shadow: none;
+    box-shadow: none;
+  }
+.tpl-form-line-form input[type=number], .tpl-form-line-form input[type=search], .tpl-form-line-form input[type=text], .tpl-form-line-form input[type=password], .tpl-form-line-form input[type=datetime], .tpl-form-line-form input[type=datetime-local], .tpl-form-line-form input[type=date], .tpl-form-line-form input[type=month], .tpl-form-line-form input[type=time], .tpl-form-line-form input[type=week], .tpl-form-line-form input[type=email], .tpl-form-line-form input[type=url], .tpl-form-line-form input[type=tel], .tpl-form-line-form input[type=color], .tpl-form-line-form select, .tpl-form-line-form textarea, .am-form-field {
+        display: block;
+    width: 100%;
+
+    padding: 6px 12px;
+    font-size: 14px;
+    line-height: 1.42857;
+    color: #4d6b8a;
+    background-color: #fff;
+    background-image: none;
+    border: 1px solid #c2cad8;
+    border-radius: 4px;
+    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
+    -webkit-transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    -o-transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    transition: border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;
+    background: 0 0;
+    border: 0;
+    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
+    -webkit-border-radius: 0;
+    -moz-border-radius: 0;
+    -ms-border-radius: 0;
+    -o-border-radius: 0;
+    border-radius: 0;
+    color: #fff;
+    box-shadow: none;
+    padding-left: 0;
+    padding-right: 0;
+    font-size: 14px;
+}
+
+.tpl-form-line-form .am-checkbox, .tpl-form-line-form .am-checkbox-inline, .tpl-form-line-form .am-form-label, .tpl-form-line-form .am-radio, .tpl-form-line-form .am-radio-inline{
+    margin-top: 0;
+    margin-bottom: 0;
+
+}
+
+.tpl-form-line-form .am-form-group:after {
+    clear: both;
+}
+.tpl-form-line-form .am-form-group:after, .tpl-form-line-form .am-form-group:before {
+content: " ";
+    display: table;
+
+}
+.tpl-form-line-form  .am-form-label{    
+    padding-top: 5px;
+font-size: 16px;
+color: #fff;
+font-weight: inherit;
+text-align: right;
+}
+
+
+
+.tpl-form-line-form  .am-form-group {
+    /*padding: 20px 0;*/
+
+}
+.tpl-form-line-form  .am-form-label .tpl-form-line-small-title {
+    color: #999;
+    font-size: 12px;
+}
+   
+   background-color: #282d2f;
+   
+ .tpl-table-black-operation {
+    a {
+        border: 1px solid #7b878d;
+        color:#7b878d;
+        &:hover {
+            background: #7b878d;
+            color:#fff;
+        }
+    }
+    a.tpl-table-black-operation-del {
+        border: 1px solid #f35842;
+        color:#f35842;
+        &:hover {
+            background: #f35842;
+            color:#fff;
+        }
+    }
+}
+    .am-table-bordered {
+        border: 1px solid #666d70;
+    }
+    .am-table-bordered>tbody>tr>td, .am-table-bordered>tbody>tr>th, .am-table-bordered>tfoot>tr>td, .am-table-bordered>tfoot>tr>th, .am-table-bordered>thead>tr>td, .am-table-bordered>thead>tr>th {
+        border: 1px solid #666d70;
+    }
+
+    .am-table-bordered>thead+tbody>tr:first-child>td, .am-table-bordered>thead+tbody>tr:first-child>th {
+         border: 1px solid #666d70;
+    }
+
+    .am-table-striped>tbody>tr:nth-child(odd)>td, .am-table-striped>tbody>tr:nth-child(odd)>th {
+        background-color: #5d6468;
+    }
+    .tpl-table-black {
+        color:#fff;
+
+        thead>tr>th {
+            font-size: 14px;
+            padding: 6px;
+            border-bottom: 1px solid #666d70;
+        }
+        tbody>tr>td {
+            font-size: 14px;
+            padding: 7px 6px;
+                border-top: 1px solid #666d70;
+        }
+        tfoot>tr>th {
+            font-size: 14px;
+            padding: 6px 0;
+        }
+    }
+   .tpl-user-card {
+        border: 1px solid #11627d;
+        border-top: 2px solid #105f79;
+        background: #1786aa;
+        color: #ffffff;
+    }
+          .tpl-user-card-title {
+        font-size: 26px;
+        margin-top: 0;
+        font-weight: 300;
+        margin-top: 25px;
+        margin-bottom: 10px;
+    }
+    .achievement-subheading {
+        font-size: 12px;
+        margin-top: 0;
+        margin-bottom: 15px;
+    }
+     .achievement-image {
+             border-radius: 50%;
+    margin-bottom: 22px;
+     }
+     .achievement-description {
+             margin: 0;
+    font-size: 12px;
+     }
+
+
+
+    .am-progress {
+        height: 12px;
+        margin-bottom: 14px;
+              background: rgba(0, 0, 0, 0.15);
+    }
+   .am-progress-title {
+        font-size: 14px;
+        margin-bottom: 8px;
+    }
+    .am-progress-title-more {
+            color: #a1a8ab;
+    }
+   .widget-fluctuation-tpl-btn {
+       margin-top: 6px;
+       display: block;
+        color: #fff;
+        font-size: 12px;
+            padding: 5px 10px;
+            outline: none;
+    background-color: rgba(255, 255, 255, 0);
+    border: 1px solid #fff;
+            &:hover {
+                background: #fff;
+                color:#4b5357;
+            }
+
+    }
+.widget-fluctuation-description-text{
+color: #c5cacd;
+    }
+
+   .text-success {
+    color: #08ed72;
+}
+.widget-fluctuation-period-text {
+      color:#fff;   
+    }
+
+    .widget-head {
+    border-bottom: 1px solid #3f4649;
+}
+   .widget-function {
+       a {
+            color:#7b878d;
+        &:hover {
+            color:#fff;
+        }
+       }
+   
+    }
+    .widget  {
+         border: 1px solid #33393c;
+    border-top: 2px solid #313639;
+    background: #4b5357;
+    color: #ffffff;
+    }
+      .widget-primary {
+    border: 1px solid #11627d;
+    border-top: 2px solid #105f79;
+    background: #1786aa;
+    color: #ffffff;
+        padding: 12px 17px;
+}
+.widget-statistic-body {
+
+}
+.widget-statistic-icon {
+    position: absolute;
+    z-index: 30;
+    right: 30px;
+    top: 0px;
+    font-size: 70px;
+    color: #1b9eca;
+}
+.widget-statistic-description {
+    position: relative;
+    z-index: 35;
+    display: block;
+    font-size: 14px;
+    line-height: 14px;
+    padding-top: 8px;
+        color: #9cdcf2;
+}
+.widget-statistic-value {
+    position: relative;
+    z-index: 35;
+    font-weight: 300;
+    display: block;
+    color: #fff;
+    font-size: 46px;
+    line-height: 46px;
+    margin-bottom: 8px;
+}
+.widget-statistic-header {
+    color: #9cdcf2;
+}
+
+.widget-purple {
+        padding: 12px 17px;
+        border: 1px solid #5e4578;
+    border-top: 2px solid #5c4375;
+    background: #785799;
+    color: #ffffff;
+     .widget-statistic-icon {
+             color: #8a6aaa;
+     }
+    .widget-statistic-header {
+        color: #ded5e7;
+    }
+    .widget-statistic-description {
+            color: #ded5e7;
+    }
+}
+   .page-header-description {
+       color: #e6e6e6;
+   }
+   .page-header-heading {
+        color: #666;
+    }
+    .container-fluid {
+        background: #424b4f;
+    }
+   .page-header-heading {
+       color: #fff;
+   }
+   .sidebar-nav-heading {
+       color:#fff;
+   }
+   .tpl-sidebar-user-panel {
+    background: #1f2224;
+    border-bottom: 1px solid #1f2224;
+}
+   .tpl-content-wrapper {
+       background: #3a4144;
+   }
+       .tpl-header-fluid {
+    background: #2f3638;
+
+}
+
+    .sidebar-nav-link {
+        a.active {
+            background: #232829;
+        }
+        a:hover {
+
+         background: #232829;
+        }
+    }
+
+.tpl-header-switch-button {
+    background: #2f3638;
+    border-right: 1px solid #282d2f;
+    &:hover {
+        background: #282d2f;
+        color: #fff;
+    }
+}
+        .tpl-header-navbar {
+        a {
+            color:#cfcfcf;
+
+            &:hover {
+                color: #fff;
+            }
+        }
+    } 
+    .left-sidebar {
+        padding-top: 56px;
+        background: #282d2f;
+    }
+
+    .widget-color-green {
+        border: 1px solid #11627d;
+    border-top: 2px solid #105f79;
+    background: #1786aa;
+    color: #ffffff;
+    .widget-head {
+        border-bottom: 1px solid #147494;
+    }
+    .widget-fluctuation-description-text {
+        color:#bbe7f6;
+    }
+    .widget-function {
+        a {
+            color:#42bde5;
+            &:hover {
+                color: #fff;
+            }
+        }
+    }
+    }
+}
+
+
+
+@media screen and (max-width: 1024px) {
+    .tpl-index-settings-button {
+        display: none;
+    }
+
+    .theme-black .left-sidebar {
+        padding-top: 111px;
+    }
+    .left-sidebar {
+        padding-top: 111px;
+    }
+    .tpl-content-wrapper {
+        margin-left: 0
+    }
+    .tpl-header-logo {
+        float:none;
+        width: 100%;
+    }
+    .tpl-header-navbar-welcome {
+        display: none;
+    }
+
+    .tpl-sidebar-user-panel {
+        border-top: 1px solid #eee;
+    }
+    .tpl-header-fluid {
+        border-top: none;
+        margin-left: 0;
+    }
+
+    .theme-white .tpl-header-fluid {
+        border-top: none;
+    }
+    .theme-black .tpl-sidebar-user-panel {
+        border-top: 1px solid #1f2224;
+    }
+}
+
+@media screen and (min-width: 641px) {
+     [class*=am-u-] {
+        padding-left: 10px;
+        padding-right: 10px;
+}
+}
+@media screen and (max-width: 641px) {
+
+     .theme-white , .theme-black {
+         .tpl-error-title {
+        font-size: 130px;
+        line-height: 140px;
+
+    }
+     }
+     .theme-white {
+         
+         .tpl-login-title {
+             font-size: 20px;
+         }
+        .tpl-login-content{
+            width: 86%;
+                padding: 22px 30px 25px;
+        }
+    }
+
+
+  
+    .tpl-header-search {
+        display: none;
+    }
+    ul.tpl-dropdown-content {
+        position: fixed;
+        width: 100%;
+        left: 0;
+        top: 112px;
+        right: 0;
+    }
+}

Різницю між файлами не показано, бо вона завелика
+ 4 - 0
Day61-65/code/project_of_tornado/assets/css/fullcalendar.min.css


+ 208 - 0
Day61-65/code/project_of_tornado/assets/css/fullcalendar.print.css

@@ -0,0 +1,208 @@
+/*!
+ * FullCalendar v0.0.0 Print Stylesheet
+ * Docs & License: http://fullcalendar.io/
+ * (c) 2016 Adam Shaw
+ */
+
+/*
+ * Include this stylesheet on your page to get a more printer-friendly calendar.
+ * When including this stylesheet, use the media='print' attribute of the <link> tag.
+ * Make sure to include this stylesheet IN ADDITION to the regular fullcalendar.css.
+ */
+
+.fc {
+	max-width: 100% !important;
+}
+
+
+/* Global Event Restyling
+--------------------------------------------------------------------------------------------------*/
+
+.fc-event {
+	background: #fff !important;
+	color: #000 !important;
+	page-break-inside: avoid;
+}
+
+.fc-event .fc-resizer {
+	display: none;
+}
+
+
+/* Table & Day-Row Restyling
+--------------------------------------------------------------------------------------------------*/
+
+.fc th,
+.fc td,
+.fc hr,
+.fc thead,
+.fc tbody,
+.fc-row {
+	border-color: #ccc !important;
+	background: #fff !important;
+}
+
+/* kill the overlaid, absolutely-positioned components */
+/* common... */
+.fc-bg,
+.fc-bgevent-skeleton,
+.fc-highlight-skeleton,
+.fc-helper-skeleton,
+/* for timegrid. within cells within table skeletons... */
+.fc-bgevent-container,
+.fc-business-container,
+.fc-highlight-container,
+.fc-helper-container {
+	display: none;
+}
+
+/* don't force a min-height on rows (for DayGrid) */
+.fc tbody .fc-row {
+	height: auto !important; /* undo height that JS set in distributeHeight */
+	min-height: 0 !important; /* undo the min-height from each view's specific stylesheet */
+}
+
+.fc tbody .fc-row .fc-content-skeleton {
+	position: static; /* undo .fc-rigid */
+	padding-bottom: 0 !important; /* use a more border-friendly method for this... */
+}
+
+.fc tbody .fc-row .fc-content-skeleton tbody tr:last-child td { /* only works in newer browsers */
+	padding-bottom: 1em; /* ...gives space within the skeleton. also ensures min height in a way */
+}
+
+.fc tbody .fc-row .fc-content-skeleton table {
+	/* provides a min-height for the row, but only effective for IE, which exaggerates this value,
+	   making it look more like 3em. for other browers, it will already be this tall */
+	height: 1em;
+}
+
+
+/* Undo month-view event limiting. Display all events and hide the "more" links
+--------------------------------------------------------------------------------------------------*/
+
+.fc-more-cell,
+.fc-more {
+	display: none !important;
+}
+
+.fc tr.fc-limited {
+	display: table-row !important;
+}
+
+.fc td.fc-limited {
+	display: table-cell !important;
+}
+
+.fc-popover {
+	display: none; /* never display the "more.." popover in print mode */
+}
+
+
+/* TimeGrid Restyling
+--------------------------------------------------------------------------------------------------*/
+
+/* undo the min-height 100% trick used to fill the container's height */
+.fc-time-grid {
+	min-height: 0 !important;
+}
+
+/* don't display the side axis at all ("all-day" and time cells) */
+.fc-agenda-view .fc-axis {
+	display: none;
+}
+
+/* don't display the horizontal lines */
+.fc-slats,
+.fc-time-grid hr { /* this hr is used when height is underused and needs to be filled */
+	display: none !important; /* important overrides inline declaration */
+}
+
+/* let the container that holds the events be naturally positioned and create real height */
+.fc-time-grid .fc-content-skeleton {
+	position: static;
+}
+
+/* in case there are no events, we still want some height */
+.fc-time-grid .fc-content-skeleton table {
+	height: 4em;
+}
+
+/* kill the horizontal spacing made by the event container. event margins will be done below */
+.fc-time-grid .fc-event-container {
+	margin: 0 !important;
+}
+
+
+/* TimeGrid *Event* Restyling
+--------------------------------------------------------------------------------------------------*/
+
+/* naturally position events, vertically stacking them */
+.fc-time-grid .fc-event {
+	position: static !important;
+	margin: 3px 2px !important;
+}
+
+/* for events that continue to a future day, give the bottom border back */
+.fc-time-grid .fc-event.fc-not-end {
+	border-bottom-width: 1px !important;
+}
+
+/* indicate the event continues via "..." text */
+.fc-time-grid .fc-event.fc-not-end:after {
+	content: "...";
+}
+
+/* for events that are continuations from previous days, give the top border back */
+.fc-time-grid .fc-event.fc-not-start {
+	border-top-width: 1px !important;
+}
+
+/* indicate the event is a continuation via "..." text */
+.fc-time-grid .fc-event.fc-not-start:before {
+	content: "...";
+}
+
+/* time */
+
+/* undo a previous declaration and let the time text span to a second line */
+.fc-time-grid .fc-event .fc-time {
+	white-space: normal !important;
+}
+
+/* hide the the time that is normally displayed... */
+.fc-time-grid .fc-event .fc-time span {
+	display: none;
+}
+
+/* ...replace it with a more verbose version (includes AM/PM) stored in an html attribute */
+.fc-time-grid .fc-event .fc-time:after {
+	content: attr(data-full);
+}
+
+
+/* Vertical Scroller & Containers
+--------------------------------------------------------------------------------------------------*/
+
+/* kill the scrollbars and allow natural height */
+.fc-scroller,
+.fc-day-grid-container,    /* these divs might be assigned height, which we need to cleared */
+.fc-time-grid-container {  /* */
+	overflow: visible !important;
+	height: auto !important;
+}
+
+/* kill the horizontal border/padding used to compensate for scrollbars */
+.fc-row {
+	border: 0 !important;
+	margin: 0 !important;
+}
+
+
+/* Button Controls
+--------------------------------------------------------------------------------------------------*/
+
+.fc-button-group,
+.fc button {
+	display: none; /* don't display any button-related controls */
+}

BIN
Day61-65/code/project_of_tornado/assets/fonts/FontAwesome.otf


BIN
Day61-65/code/project_of_tornado/assets/fonts/fontawesome-webfont.eot


BIN
Day61-65/code/project_of_tornado/assets/fonts/fontawesome-webfont.ttf


BIN
Day61-65/code/project_of_tornado/assets/fonts/fontawesome-webfont.woff


BIN
Day61-65/code/project_of_tornado/assets/fonts/fontawesome-webfont.woff2


+ 294 - 0
Day61-65/code/project_of_tornado/assets/html/404.html

@@ -0,0 +1,294 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Amaze UI Admin index Examples</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp"/>
+    <link rel="icon" type="image/png" href="../i/favicon.png">
+    <link rel="apple-touch-icon-precomposed" href="../i/app-icon72x72@2x.png">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI"/>
+    <script src="../js/echarts.min.js"></script>
+    <link rel="stylesheet" href="../css/amazeui.min.css"/>
+    <link rel="stylesheet" href="../css/amazeui.datatables.min.css"/>
+    <link rel="stylesheet" href="../css/app.css">
+    <script src="../js/jquery.min.js"></script>
+
+</head>
+
+<body data-type="widgets">
+<script src="../js/theme.js"></script>
+<div class="am-g tpl-g">
+    <!-- 头部 -->
+    <header>
+        <!-- logo -->
+        <div class="am-fl tpl-header-logo">
+            <a href="javascript:;"><img src="../img/logo.png" alt=""></a>
+        </div>
+        <!-- 右侧内容 -->
+        <div class="tpl-header-fluid">
+            <!-- 侧边切换 -->
+            <div class="am-fl tpl-header-switch-button am-icon-list">
+                    <span>
+
+                </span>
+            </div>
+            <!-- 搜索 -->
+            <div class="am-fl tpl-header-search">
+                <form class="tpl-header-search-form" action="javascript:;">
+                    <button class="tpl-header-search-btn am-icon-search"></button>
+                    <input class="tpl-header-search-box" type="text" placeholder="搜索内容...">
+                </form>
+            </div>
+            <!-- 其它功能-->
+            <div class="am-fr tpl-header-navbar">
+                <ul>
+                    <!-- 欢迎语 -->
+                    <li class="am-text-sm tpl-header-navbar-welcome">
+                        <a href="javascript:;">欢迎你, <span>Amaze UI</span> </a>
+                    </li>
+
+                    <!-- 新邮件 -->
+                    <li class="am-dropdown tpl-dropdown" data-am-dropdown>
+                        <a href="javascript:;" class="am-dropdown-toggle tpl-dropdown-toggle" data-am-dropdown-toggle>
+                            <i class="am-icon-envelope"></i>
+                            <span class="am-badge am-badge-success am-round item-feed-badge">4</span>
+                        </a>
+                        <!-- 弹出列表 -->
+                        <ul class="am-dropdown-content tpl-dropdown-content">
+                            <li class="tpl-dropdown-menu-messages">
+                                <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                    <div class="menu-messages-ico">
+                                        <img src="../img/user04.png" alt="">
+                                    </div>
+                                    <div class="menu-messages-time">
+                                        3小时前
+                                    </div>
+                                    <div class="menu-messages-content">
+                                        <div class="menu-messages-content-title">
+                                            <i class="am-icon-circle-o am-text-success"></i>
+                                            <span>夕风色</span>
+                                        </div>
+                                        <div class="am-text-truncate"> Amaze UI 的诞生,依托于 GitHub 及其他技术社区上一些优秀的资源;Amaze UI
+                                            的成长,则离不开用户的支持。
+                                        </div>
+                                        <div class="menu-messages-content-time">2016-09-21 下午 16:40</div>
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-messages">
+                                <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                    <div class="menu-messages-ico">
+                                        <img src="../img/user02.png" alt="">
+                                    </div>
+                                    <div class="menu-messages-time">
+                                        5天前
+                                    </div>
+                                    <div class="menu-messages-content">
+                                        <div class="menu-messages-content-title">
+                                            <i class="am-icon-circle-o am-text-warning"></i>
+                                            <span>禁言小张</span>
+                                        </div>
+                                        <div class="am-text-truncate"> 为了能最准确的传达所描述的问题, 建议你在反馈时附上演示,方便我们理解。</div>
+                                        <div class="menu-messages-content-time">2016-09-16 上午 09:23</div>
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-messages">
+                                <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                    <i class="am-icon-circle-o"></i> 进入列表…
+                                </a>
+                            </li>
+                        </ul>
+                    </li>
+
+                    <!-- 新提示 -->
+                    <li class="am-dropdown" data-am-dropdown>
+                        <a href="javascript:;" class="am-dropdown-toggle" data-am-dropdown-toggle>
+                            <i class="am-icon-bell"></i>
+                            <span class="am-badge am-badge-warning am-round item-feed-badge">5</span>
+                        </a>
+                        <!-- 弹出列表 -->
+                        <ul class="am-dropdown-content tpl-dropdown-content">
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <div class="tpl-dropdown-menu-notifications-title">
+                                        <i class="am-icon-line-chart"></i>
+                                        <span> 有6笔新的销售订单</span>
+                                    </div>
+                                    <div class="tpl-dropdown-menu-notifications-time">
+                                        12分钟前
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <div class="tpl-dropdown-menu-notifications-title">
+                                        <i class="am-icon-star"></i>
+                                        <span> 有3个来自人事部的消息</span>
+                                    </div>
+                                    <div class="tpl-dropdown-menu-notifications-time">
+                                        30分钟前
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <div class="tpl-dropdown-menu-notifications-title">
+                                        <i class="am-icon-folder-o"></i>
+                                        <span> 上午开会记录存档</span>
+                                    </div>
+                                    <div class="tpl-dropdown-menu-notifications-time">
+                                        1天前
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <i class="am-icon-bell"></i> 进入列表…
+                                </a>
+                            </li>
+                        </ul>
+                    </li>
+
+                    <!-- 退出 -->
+                    <li class="am-text-sm">
+                        <a href="javascript:;">
+                            <span class="am-icon-sign-out"></span> 退出
+                        </a>
+                    </li>
+                </ul>
+            </div>
+        </div>
+
+    </header>
+    <!-- 风格切换 -->
+    <div class="tpl-skiner">
+        <div class="tpl-skiner-toggle am-icon-cog">
+        </div>
+        <div class="tpl-skiner-content">
+            <div class="tpl-skiner-content-title">
+                选择主题
+            </div>
+            <div class="tpl-skiner-content-bar">
+                <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                <span class="skiner-color skiner-black" data-color="theme-black"></span>
+            </div>
+        </div>
+    </div>
+    <!-- 侧边导航栏 -->
+    <div class="left-sidebar">
+        <!-- 用户信息 -->
+        <div class="tpl-sidebar-user-panel">
+            <div class="tpl-user-panel-slide-toggleable">
+                <div class="tpl-user-panel-profile-picture">
+                    <img src="../img/user04.png" alt="">
+                </div>
+                <span class="user-panel-logged-in-text">
+              <i class="am-icon-circle-o am-text-success tpl-user-panel-status-icon"></i>
+              禁言小张
+          </span>
+                <a href="javascript:;" class="tpl-user-panel-action-link"> <span class="am-icon-pencil"></span> 账号设置</a>
+            </div>
+        </div>
+
+        <!-- 菜单 -->
+        <ul class="sidebar-nav">
+            <li class="sidebar-nav-heading">Components <span class="sidebar-nav-heading-info"> 附加组件</span></li>
+            <li class="sidebar-nav-link">
+                <a href="/">
+                    <i class="am-icon-home sidebar-nav-link-logo"></i> 首页
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/tables.html">
+                    <i class="am-icon-table sidebar-nav-link-logo"></i> 表格
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/calendar.html">
+                    <i class="am-icon-calendar sidebar-nav-link-logo"></i> 日历
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/form.html">
+                    <i class="am-icon-wpforms sidebar-nav-link-logo"></i> 表单
+
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/chart.html">
+                    <i class="am-icon-bar-chart sidebar-nav-link-logo"></i> 图表
+
+                </a>
+            </li>
+            <li class="sidebar-nav-heading">Page<span class="sidebar-nav-heading-info"> 常用页面</span></li>
+            <li class="sidebar-nav-link">
+                <a href="javascript:;" class="sidebar-nav-sub-title">
+                    <i class="am-icon-table sidebar-nav-link-logo"></i> 数据列表
+                    <span class="am-icon-chevron-down am-fr am-margin-right-sm sidebar-nav-sub-ico"></span>
+                </a>
+                <ul class="sidebar-nav sidebar-nav-sub">
+                    <li class="sidebar-nav-link">
+                        <a href="../html/table-list.html">
+                            <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 文字列表
+                        </a>
+                    </li>
+                    <li class="sidebar-nav-link">
+                        <a href="../html/table-list-img.html">
+                            <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 图文列表
+                        </a>
+                    </li>
+                </ul>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="/signup">
+                    <i class="am-icon-clone sidebar-nav-link-logo"></i> 注册
+                    <span class="am-badge am-badge-secondary sidebar-nav-link-logo-ico am-round am-fr am-margin-right-sm">6</span>
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="/login">
+                    <i class="am-icon-key sidebar-nav-link-logo"></i> 登录
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="/page404" class="active">
+                    <i class="am-icon-tv sidebar-nav-link-logo"></i> 404错误
+                </a>
+            </li>
+
+        </ul>
+    </div>
+
+    <!-- 内容区域 -->
+    <div class="tpl-content-wrapper">
+        <div class="row-content am-cf">
+            <div class="widget am-cf">
+                <div class="widget-body">
+                    <div class="tpl-page-state">
+                        <div class="tpl-page-state-title am-text-center tpl-error-title">404</div>
+                        <div class="tpl-error-title-info">Page Not Found</div>
+                        <div class="tpl-page-state-content tpl-error-content">
+
+                            <p>对不起,没有找到您所需要的页面,可能是URL不确定,或者页面已被移除。</p>
+                            <a href="/" class="am-btn am-btn-secondary am-radius tpl-error-btn">Back Home</a></div>
+
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+</div>
+<script src="../js/amazeui.min.js"></script>
+<script src="../js/amazeui.datatables.min.js"></script>
+<script src="../js/dataTables.responsive.min.js"></script>
+<script src="../js/app.js"></script>
+</body>
+</html>

+ 453 - 0
Day61-65/code/project_of_tornado/assets/html/calendar.html

@@ -0,0 +1,453 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Amaze UI Admin index Examples</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp" />
+    <link rel="icon" type="image/png" href="../i/favicon.png">
+    <link rel="apple-touch-icon-precomposed" href="../i/app-icon72x72@2x.png">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI" />
+    <link rel="stylesheet" href="../css/amazeui.min.css" />
+    <link rel="stylesheet" href="../css/fullcalendar.min.css" />
+    <link rel="stylesheet" href="../css/fullcalendar.print.css" media='print' />
+    <link rel="stylesheet" href="../css/app.css">
+    <script src="../js/jquery.min.js"></script>
+
+</head>
+
+<body data-type="widgets">
+    <script src="../js/theme.js"></script>
+    <div class="am-g tpl-g">
+        <!-- 头部 -->
+        <header>
+            <!-- logo -->
+            <div class="am-fl tpl-header-logo">
+                <a href="javascript:;"><img src="../img/logo.png" alt=""></a>
+            </div>
+            <!-- 右侧内容 -->
+            <div class="tpl-header-fluid">
+                <!-- 侧边切换 -->
+                <div class="am-fl tpl-header-switch-button am-icon-list">
+                    <span>
+
+                </span>
+                </div>
+                <!-- 搜索 -->
+                <div class="am-fl tpl-header-search">
+                    <form class="tpl-header-search-form" action="javascript:;">
+                        <button class="tpl-header-search-btn am-icon-search"></button>
+                        <input class="tpl-header-search-box" type="text" placeholder="搜索内容...">
+                    </form>
+                </div>
+                <!-- 其它功能-->
+                <div class="am-fr tpl-header-navbar">
+                    <ul>
+                        <!-- 欢迎语 -->
+                        <li class="am-text-sm tpl-header-navbar-welcome">
+                            <a href="javascript:;">欢迎你, <span>Amaze UI</span> </a>
+                        </li>
+
+                        <!-- 新邮件 -->
+                        <li class="am-dropdown tpl-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle tpl-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-envelope"></i>
+                                <span class="am-badge am-badge-success am-round item-feed-badge">4</span>
+                            </a>
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="../img/user04.png" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            3小时前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-success"></i>
+                                                <span>夕风色</span>
+                                            </div>
+                                            <div class="am-text-truncate"> Amaze UI 的诞生,依托于 GitHub 及其他技术社区上一些优秀的资源;Amaze UI 的成长,则离不开用户的支持。 </div>
+                                            <div class="menu-messages-content-time">2016-09-21 下午 16:40</div>
+                                        </div>
+                                    </a>
+                                </li>
+
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="../img/user02.png" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            5天前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-warning"></i>
+                                                <span>禁言小张</span>
+                                            </div>
+                                            <div class="am-text-truncate"> 为了能最准确的传达所描述的问题, 建议你在反馈时附上演示,方便我们理解。 </div>
+                                            <div class="menu-messages-content-time">2016-09-16 上午 09:23</div>
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <i class="am-icon-circle-o"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+
+                        <!-- 新提示 -->
+                        <li class="am-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-bell"></i>
+                                <span class="am-badge am-badge-warning am-round item-feed-badge">5</span>
+                            </a>
+
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-line-chart"></i>
+                                            <span> 有6笔新的销售订单</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            12分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-star"></i>
+                                            <span> 有3个来自人事部的消息</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            30分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-folder-o"></i>
+                                            <span> 上午开会记录存档</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            1天前
+                                        </div>
+                                    </a>
+                                </li>
+
+
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <i class="am-icon-bell"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+
+                        <!-- 退出 -->
+                        <li class="am-text-sm">
+                            <a href="javascript:;">
+                                <span class="am-icon-sign-out"></span> 退出
+                            </a>
+                        </li>
+                    </ul>
+                </div>
+            </div>
+
+        </header>
+        <!-- 风格切换 -->
+        <div class="tpl-skiner">
+            <div class="tpl-skiner-toggle am-icon-cog">
+            </div>
+            <div class="tpl-skiner-content">
+                <div class="tpl-skiner-content-title">
+                    选择主题
+                </div>
+                <div class="tpl-skiner-content-bar">
+                    <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                    <span class="skiner-color skiner-black" data-color="theme-black"></span>
+                </div>
+            </div>
+        </div>
+        <!-- 侧边导航栏 -->
+        <div class="left-sidebar">
+            <!-- 用户信息 -->
+            <div class="tpl-sidebar-user-panel">
+                <div class="tpl-user-panel-slide-toggleable">
+                    <div class="tpl-user-panel-profile-picture">
+                        <img src="../img/user04.png" alt="">
+                    </div>
+                    <span class="user-panel-logged-in-text">
+              <i class="am-icon-circle-o am-text-success tpl-user-panel-status-icon"></i>
+              禁言小张
+          </span>
+                    <a href="javascript:;" class="tpl-user-panel-action-link"> <span class="am-icon-pencil"></span> 账号设置</a>
+                </div>
+            </div>
+
+
+            <!-- 菜单 -->
+            <ul class="sidebar-nav">
+                <li class="sidebar-nav-heading">Components <span class="sidebar-nav-heading-info"> 附加组件</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="/">
+                        <i class="am-icon-home sidebar-nav-link-logo"></i> 首页
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/tables.html">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 表格
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/calendar.html" class="active">
+                        <i class="am-icon-calendar sidebar-nav-link-logo"></i> 日历
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/form.html">
+                        <i class="am-icon-wpforms sidebar-nav-link-logo"></i> 表单
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/chart.html">
+                        <i class="am-icon-bar-chart sidebar-nav-link-logo"></i> 图表
+                    </a>
+                </li>
+
+                <li class="sidebar-nav-heading">Page<span class="sidebar-nav-heading-info"> 常用页面</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="javascript:;" class="sidebar-nav-sub-title">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 数据列表
+                        <span class="am-icon-chevron-down am-fr am-margin-right-sm sidebar-nav-sub-ico"></span>
+                    </a>
+                    <ul class="sidebar-nav sidebar-nav-sub">
+                        <li class="sidebar-nav-link">
+                            <a href="../html/table-list.html">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 文字列表
+                            </a>
+                        </li>
+
+                        <li class="sidebar-nav-link">
+                            <a href="../html/table-list-img.html">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 图文列表
+                            </a>
+                        </li>
+                    </ul>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/signup">
+                        <i class="am-icon-clone sidebar-nav-link-logo"></i> 注册
+                        <span class="am-badge am-badge-secondary sidebar-nav-link-logo-ico am-round am-fr am-margin-right-sm">6</span>
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/login">
+                        <i class="am-icon-key sidebar-nav-link-logo"></i> 登录
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/page404">
+                        <i class="am-icon-tv sidebar-nav-link-logo"></i> 404错误
+                    </a>
+                </li>
+
+            </ul>
+        </div>
+
+        <!-- 内容区域 -->
+        <div class="tpl-content-wrapper">
+            <div class="row-content am-cf">
+                <div class="tpl-calendar-box">
+                    <div id="calendar"></div>
+                </div>
+
+            </div>
+        </div>
+    </div>
+    </div>
+
+
+    <!-- 弹出层 -->
+
+    <div class="am-modal am-modal-no-btn" id="calendar-edit-box">
+        <div class="am-modal-dialog tpl-model-dialog">
+            <div class="am-modal-hd">
+                <a href="javascript: void(0)" class="am-close edit-box-close am-close-spin" data-am-modal-close>&times;</a>
+            </div>
+            <div class="am-modal-bd tpl-am-model-bd am-cf">
+
+                <form class="am-form tpl-form-border-form">
+                    <div class="am-form-group am-u-sm-12">
+                        <label for="user-name" class="am-u-sm-12 am-form-label am-text-left">标题 <span class="tpl-form-line-small-title">Title</span></label>
+                        <div class="am-u-sm-12">
+                            <input type="text" class="tpl-form-input am-margin-top-xs calendar-edit-box-title" id="user-name" placeholder="" disabled>
+                        </div>
+                    </div>
+
+
+
+
+
+
+
+                </form>
+
+            </div>
+        </div>
+    </div>
+    <script src="../js/moment.js"></script>
+    <script src="../js/amazeui.min.js"></script>
+    <script src="../js/fullcalendar.min.js"></script>
+    <script src="../js/app.js"></script>
+    <script>
+        $(document).ready(function() {
+            var editBox = $('#calendar-edit-box');
+
+            $('.edit-box-close').on('click', function() {
+                $('#calendar').fullCalendar('unselect');
+            })
+            $('#calendar').fullCalendar({
+
+                header: {
+                    left: 'prev,next today',
+                    center: 'title',
+                    right: 'month,agendaWeek,agendaDay'
+                },
+
+                monthNames: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
+                monthNamesShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
+                dayNames: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
+                dayNamesShort: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
+                today: ["今天"],
+                firstDay: 1,
+                buttonText: {
+                    today: '本月',
+                    month: '月',
+                    week: '周',
+                    day: '日',
+                    prev: '上一月',
+                    next: '下一月'
+                },
+                defaultDate: '2016-09-12',
+                lang: 'zh-cn',
+                navLinks: true, // can click day/week names to navigate views
+                selectable: true,
+                selectHelper: true,
+                select: function(start, end) {
+                    var title = prompt('填写你的记录的:');
+                    var eventData;
+                    if (title) {
+                        eventData = {
+                            title: title,
+                            start: start,
+                            end: end
+                        };
+                        $('#calendar').fullCalendar('renderEvent', eventData, true); // stick? = true
+                    }
+                    $('#calendar').fullCalendar('unselect');
+
+
+
+                },
+                editable: true,
+                eventLimit: true, // allow "more" link when too many events
+                eventClick: function(event, jsEvent, view) {
+
+                    // event.source.events[0].title = '222223333'
+                    // 修改数据
+                    // 标题
+                    $('.calendar-edit-box-title').val(event.title)
+
+
+
+                    //  弹出框
+                    editBox.modal();
+
+
+
+
+
+                },
+                events: [{
+                    id: 1,
+                    title: '给她抱抱 叫她包包 喂她吃饱 给她买包',
+                    start: '2016-09-01',
+                    end: '2016-09-10'
+                }, {
+                    id: 2,
+                    title: '给她抱抱',
+                    start: '2016-09-07',
+                    end: '2016-09-10'
+                }, {
+                    id: 3,
+                    title: '叫她包包',
+                    start: '2016-09-09',
+                    end: '2016-09-10'
+                }, {
+                    id: 4,
+                    title: '喂她吃饱',
+                    start: '2016-09-16',
+                    end: '2016-09-10'
+                }, {
+                    id: 5,
+                    title: '喂她吃饱',
+                    start: '2016-09-11',
+                    end: '2016-09-13'
+                }, {
+                    id: 6,
+                    title: '喂她吃饱',
+                    start: '2016-09-12',
+                    end: '2016-09-12'
+                }, {
+                    id: 7,
+                    title: '喂她吃饱',
+                    start: '2016-09-12',
+                    end: '2016-09-12'
+                }, {
+                    id: 8,
+                    title: '喂她吃饱',
+                    start: '2016-09-12',
+                    end: '2016-09-12'
+                }, {
+                    id: 9,
+                    title: '喂她吃饱',
+                    start: '2016-09-12',
+                    end: '2016-09-12'
+                }, {
+                    id: 10,
+                    title: '喂她吃饱',
+                    start: '2016-09-12',
+                    end: '2016-09-12'
+                }, {
+                    id: 11,
+                    title: 'Birthday Party',
+                    start: '2016-09-13',
+                    end: '2016-09-12'
+                }, {
+                    id: 12,
+                    title: 'Click for Google',
+                    start: '2016-09-28',
+                    end: '2016-09-12'
+                }]
+            });
+
+        });
+    </script>
+</body>
+
+</html>

+ 341 - 0
Day61-65/code/project_of_tornado/assets/html/chart.html

@@ -0,0 +1,341 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Amaze UI Admin index Examples</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp" />
+    <link rel="icon" type="image/png" href="../i/favicon.png">
+    <link rel="apple-touch-icon-precomposed" href="../i/app-icon72x72@2x.png">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI" />
+    <script src="../js/echarts.min.js"></script>
+    <link rel="stylesheet" href="../css/amazeui.min.css" />
+    <link rel="stylesheet" href="../css/amazeui.datatables.min.css" />
+    <link rel="stylesheet" href="../css/app.css">
+    <script src="../js/jquery.min.js"></script>
+</head>
+<body data-type="chart">
+    <script src="../js/theme.js"></script>
+    <div class="am-g tpl-g">
+        <!-- 头部 -->
+        <header>
+            <!-- logo -->
+            <div class="am-fl tpl-header-logo">
+                <a href="javascript:;"><img src="../img/logo.png" alt=""></a>
+            </div>
+            <!-- 右侧内容 -->
+            <div class="tpl-header-fluid">
+                <!-- 侧边切换 -->
+                <div class="am-fl tpl-header-switch-button am-icon-list">
+                    <span>
+
+                </span>
+                </div>
+                <!-- 搜索 -->
+                <div class="am-fl tpl-header-search">
+                    <form class="tpl-header-search-form" action="javascript:;">
+                        <button class="tpl-header-search-btn am-icon-search"></button>
+                        <input class="tpl-header-search-box" type="text" placeholder="搜索内容...">
+                    </form>
+                </div>
+                <!-- 其它功能-->
+                <div class="am-fr tpl-header-navbar">
+                    <ul>
+                        <!-- 欢迎语 -->
+                        <li class="am-text-sm tpl-header-navbar-welcome">
+                            <a href="javascript:;">欢迎你, <span>Amaze UI</span> </a>
+                        </li>
+
+                        <!-- 新邮件 -->
+                        <li class="am-dropdown tpl-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle tpl-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-envelope"></i>
+                                <span class="am-badge am-badge-success am-round item-feed-badge">4</span>
+                            </a>
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="../img/user04.png" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            3小时前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-success"></i>
+                                                <span>夕风色</span>
+                                            </div>
+                                            <div class="am-text-truncate"> Amaze UI 的诞生,依托于 GitHub 及其他技术社区上一些优秀的资源;Amaze UI 的成长,则离不开用户的支持。 </div>
+                                            <div class="menu-messages-content-time">2016-09-21 下午 16:40</div>
+                                        </div>
+                                    </a>
+                                </li>
+
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="../img/user02.png" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            5天前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-warning"></i>
+                                                <span>禁言小张</span>
+                                            </div>
+                                            <div class="am-text-truncate"> 为了能最准确的传达所描述的问题, 建议你在反馈时附上演示,方便我们理解。 </div>
+                                            <div class="menu-messages-content-time">2016-09-16 上午 09:23</div>
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <i class="am-icon-circle-o"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+
+                        <!-- 新提示 -->
+                        <li class="am-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-bell"></i>
+                                <span class="am-badge am-badge-warning am-round item-feed-badge">5</span>
+                            </a>
+
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-line-chart"></i>
+                                            <span> 有6笔新的销售订单</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            12分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-star"></i>
+                                            <span> 有3个来自人事部的消息</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            30分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-folder-o"></i>
+                                            <span> 上午开会记录存档</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            1天前
+                                        </div>
+                                    </a>
+                                </li>
+
+
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <i class="am-icon-bell"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+
+                        <!-- 退出 -->
+                        <li class="am-text-sm">
+                            <a href="javascript:;">
+                                <span class="am-icon-sign-out"></span> 退出
+                            </a>
+                        </li>
+                    </ul>
+                </div>
+            </div>
+
+        </header>
+        <!-- 风格切换 -->
+        <div class="tpl-skiner">
+            <div class="tpl-skiner-toggle am-icon-cog">
+            </div>
+            <div class="tpl-skiner-content">
+                <div class="tpl-skiner-content-title">
+                    选择主题
+                </div>
+                <div class="tpl-skiner-content-bar">
+                    <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                    <span class="skiner-color skiner-black" data-color="theme-black"></span>
+                </div>
+            </div>
+        </div>
+        <!-- 侧边导航栏 -->
+        <div class="left-sidebar">
+            <!-- 用户信息 -->
+            <div class="tpl-sidebar-user-panel">
+                <div class="tpl-user-panel-slide-toggleable">
+                    <div class="tpl-user-panel-profile-picture">
+                        <img src="../img/user04.png" alt="">
+                    </div>
+                    <span class="user-panel-logged-in-text">
+              <i class="am-icon-circle-o am-text-success tpl-user-panel-status-icon"></i>
+              禁言小张
+          </span>
+                    <a href="javascript:;" class="tpl-user-panel-action-link"> <span class="am-icon-pencil"></span> 账号设置</a>
+                </div>
+            </div>
+
+            <!-- 菜单 -->
+            <ul class="sidebar-nav">
+                <li class="sidebar-nav-heading">Components <span class="sidebar-nav-heading-info"> 附加组件</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="/">
+                        <i class="am-icon-home sidebar-nav-link-logo"></i> 首页
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/tables.html">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 表格
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/calendar.html">
+                        <i class="am-icon-calendar sidebar-nav-link-logo"></i> 日历
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/form.html">
+                        <i class="am-icon-wpforms sidebar-nav-link-logo"></i> 表单
+
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/chart.html" class="active">
+                        <i class="am-icon-bar-chart sidebar-nav-link-logo"></i> 图表
+
+                    </a>
+                </li>
+
+                <li class="sidebar-nav-heading">Page<span class="sidebar-nav-heading-info"> 常用页面</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="javascript:;" class="sidebar-nav-sub-title">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 数据列表
+                        <span class="am-icon-chevron-down am-fr am-margin-right-sm sidebar-nav-sub-ico"></span>
+                    </a>
+                    <ul class="sidebar-nav sidebar-nav-sub">
+                        <li class="sidebar-nav-link">
+                            <a href="../html/table-list.html">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 文字列表
+                            </a>
+                        </li>
+
+                        <li class="sidebar-nav-link">
+                            <a href="../html/table-list-img.html">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 图文列表
+                            </a>
+                        </li>
+                    </ul>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/signup">
+                        <i class="am-icon-clone sidebar-nav-link-logo"></i> 注册
+                        <span class="am-badge am-badge-secondary sidebar-nav-link-logo-ico am-round am-fr am-margin-right-sm">6</span>
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/login">
+                        <i class="am-icon-key sidebar-nav-link-logo"></i> 登录
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/page404">
+                        <i class="am-icon-tv sidebar-nav-link-logo"></i> 404错误
+                    </a>
+                </li>
+
+            </ul>
+        </div>
+
+        <!-- 内容区域 -->
+        <div class="tpl-content-wrapper">
+
+            <div class="container-fluid am-cf">
+                <div class="row">
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-9">
+                        <div class="page-header-heading"><span class="am-icon-home page-header-heading-icon"></span> 图表 <small>Amaze UI</small></div>
+                        <p class="page-header-description">图表组件使用的是 <a href="http://echarts.baidu.com">百度图表echarts</a>。</p>
+                    </div>
+                    <div class="am-u-lg-3 tpl-index-settings-button">
+                        <button type="button" class="page-header-button"><span class="am-icon-paint-brush"></span> 设置</button>
+                    </div>
+                </div>
+
+            </div>
+
+            <div class="row-content am-cf">
+                <div class="widget am-cf">
+                    <div class="widget-head am-cf">
+                        <div class="widget-title am-fl">折线</div>
+                        <div class="widget-function am-fr">
+                            <a href="javascript:;" class="am-icon-cog"></a>
+                        </div>
+                    </div>
+                    <div class="widget-body am-fr">
+                        <div style="height: 400px" class="" id="tpl-echarts-A">
+
+                        </div>
+                    </div>
+                </div>
+
+
+                <div class="widget am-cf">
+                    <div class="widget-head am-cf">
+                        <div class="widget-title am-fl">雷达</div>
+                        <div class="widget-function am-fr">
+                            <a href="javascript:;" class="am-icon-cog"></a>
+                        </div>
+                    </div>
+                    <div class="widget-body am-fr">
+                        <div style="height: 400px" id="tpl-echarts-B">
+
+                        </div>
+                    </div>
+                </div>
+
+
+                <div class="widget am-cf">
+                    <div class="widget-head am-cf">
+                        <div class="widget-title am-fl">折线柱图</div>
+                        <div class="widget-function am-fr">
+                            <a href="javascript:;" class="am-icon-cog"></a>
+                        </div>
+                    </div>
+                    <div class="widget-body am-fr">
+                        <div style="height: 400px" id="tpl-echarts-C">
+
+                        </div>
+                    </div>
+                </div>
+
+            </div>
+        </div>
+    </div>
+    </div>
+    <script src="../js/amazeui.min.js"></script>
+    <script src="../js/amazeui.datatables.min.js"></script>
+    <script src="../js/dataTables.responsive.min.js"></script>
+    <script src="../js/app.js"></script>
+    <!-- 说明:通过WebSocket获取服务器推送数据的代码在app.js中 -->
+</body>
+</html>

+ 619 - 0
Day61-65/code/project_of_tornado/assets/html/form.html

@@ -0,0 +1,619 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Amaze UI Admin index Examples</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp" />
+    <link rel="icon" type="image/png" href="../i/favicon.png">
+    <link rel="apple-touch-icon-precomposed" href="../i/app-icon72x72@2x.png">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI" />
+    <script src="../js/echarts.min.js"></script>
+    <link rel="stylesheet" href="../css/amazeui.min.css" />
+    <link rel="stylesheet" href="../css/amazeui.datatables.min.css" />
+    <link rel="stylesheet" href="../css/app.css">
+    <script src="../js/jquery.min.js"></script>
+
+</head>
+
+<body data-type="widgets">
+    <script src="../js/theme.js"></script>
+    <div class="am-g tpl-g">
+        <!-- 头部 -->
+        <header>
+            <!-- logo -->
+            <div class="am-fl tpl-header-logo">
+                <a href="javascript:;"><img src="../img/logo.png" alt=""></a>
+            </div>
+            <!-- 右侧内容 -->
+            <div class="tpl-header-fluid">
+                <!-- 侧边切换 -->
+                <div class="am-fl tpl-header-switch-button am-icon-list">
+                    <span>
+
+                </span>
+                </div>
+                <!-- 搜索 -->
+                <div class="am-fl tpl-header-search">
+                    <form class="tpl-header-search-form" action="javascript:;">
+                        <button class="tpl-header-search-btn am-icon-search"></button>
+                        <input class="tpl-header-search-box" type="text" placeholder="搜索内容...">
+                    </form>
+                </div>
+                <!-- 其它功能-->
+                <div class="am-fr tpl-header-navbar">
+                    <ul>
+                        <!-- 欢迎语 -->
+                        <li class="am-text-sm tpl-header-navbar-welcome">
+                            <a href="javascript:;">欢迎你, <span>Amaze UI</span> </a>
+                        </li>
+
+                        <!-- 新邮件 -->
+                        <li class="am-dropdown tpl-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle tpl-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-envelope"></i>
+                                <span class="am-badge am-badge-success am-round item-feed-badge">4</span>
+                            </a>
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="../img/user04.png" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            3小时前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-success"></i>
+                                                <span>夕风色</span>
+                                            </div>
+                                            <div class="am-text-truncate"> Amaze UI 的诞生,依托于 GitHub 及其他技术社区上一些优秀的资源;Amaze UI 的成长,则离不开用户的支持。 </div>
+                                            <div class="menu-messages-content-time">2016-09-21 下午 16:40</div>
+                                        </div>
+                                    </a>
+                                </li>
+
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="../img/user02.png" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            5天前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-warning"></i>
+                                                <span>禁言小张</span>
+                                            </div>
+                                            <div class="am-text-truncate"> 为了能最准确的传达所描述的问题, 建议你在反馈时附上演示,方便我们理解。 </div>
+                                            <div class="menu-messages-content-time">2016-09-16 上午 09:23</div>
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <i class="am-icon-circle-o"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+
+                        <!-- 新提示 -->
+                        <li class="am-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-bell"></i>
+                                <span class="am-badge am-badge-warning am-round item-feed-badge">5</span>
+                            </a>
+
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-line-chart"></i>
+                                            <span> 有6笔新的销售订单</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            12分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-star"></i>
+                                            <span> 有3个来自人事部的消息</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            30分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-folder-o"></i>
+                                            <span> 上午开会记录存档</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            1天前
+                                        </div>
+                                    </a>
+                                </li>
+
+
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <i class="am-icon-bell"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+
+                        <!-- 退出 -->
+                        <li class="am-text-sm">
+                            <a href="javascript:;">
+                                <span class="am-icon-sign-out"></span> 退出
+                            </a>
+                        </li>
+                    </ul>
+                </div>
+            </div>
+
+        </header>
+        <!-- 风格切换 -->
+        <div class="tpl-skiner">
+            <div class="tpl-skiner-toggle am-icon-cog">
+            </div>
+            <div class="tpl-skiner-content">
+                <div class="tpl-skiner-content-title">
+                    选择主题
+                </div>
+                <div class="tpl-skiner-content-bar">
+                    <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                    <span class="skiner-color skiner-black" data-color="theme-black"></span>
+                </div>
+            </div>
+        </div>
+        <!-- 侧边导航栏 -->
+        <div class="left-sidebar">
+            <!-- 用户信息 -->
+            <div class="tpl-sidebar-user-panel">
+                <div class="tpl-user-panel-slide-toggleable">
+                    <div class="tpl-user-panel-profile-picture">
+                        <img src="../img/user04.png" alt="">
+                    </div>
+                    <span class="user-panel-logged-in-text">
+              <i class="am-icon-circle-o am-text-success tpl-user-panel-status-icon"></i>
+              禁言小张
+          </span>
+                    <a href="javascript:;" class="tpl-user-panel-action-link"> <span class="am-icon-pencil"></span> 账号设置</a>
+                </div>
+            </div>
+
+            <!-- 菜单 -->
+            <ul class="sidebar-nav">
+                <li class="sidebar-nav-heading">Components <span class="sidebar-nav-heading-info"> 附加组件</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="/">
+                        <i class="am-icon-home sidebar-nav-link-logo"></i> 首页
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/tables.html">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 表格
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/calendar.html">
+                        <i class="am-icon-calendar sidebar-nav-link-logo"></i> 日历
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/form.html" class="active">
+                        <i class="am-icon-wpforms sidebar-nav-link-logo"></i> 表单
+
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/chart.html">
+                        <i class="am-icon-bar-chart sidebar-nav-link-logo"></i> 图表
+
+                    </a>
+                </li>
+
+                <li class="sidebar-nav-heading">Page<span class="sidebar-nav-heading-info"> 常用页面</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="javascript:;" class="sidebar-nav-sub-title">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 数据列表
+                        <span class="am-icon-chevron-down am-fr am-margin-right-sm sidebar-nav-sub-ico"></span>
+                    </a>
+                    <ul class="sidebar-nav sidebar-nav-sub">
+                        <li class="sidebar-nav-link">
+                            <a href="../html/table-list.html">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 文字列表
+                            </a>
+                        </li>
+
+                        <li class="sidebar-nav-link">
+                            <a href="../html/table-list-img.html">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 图文列表
+                            </a>
+                        </li>
+                    </ul>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/signup">
+                        <i class="am-icon-clone sidebar-nav-link-logo"></i> 注册
+                        <span class="am-badge am-badge-secondary sidebar-nav-link-logo-ico am-round am-fr am-margin-right-sm">6</span>
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/login">
+                        <i class="am-icon-key sidebar-nav-link-logo"></i> 登录
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/page404">
+                        <i class="am-icon-tv sidebar-nav-link-logo"></i> 404错误
+                    </a>
+                </li>
+
+            </ul>
+        </div>
+
+        <!-- 内容区域 -->
+        <div class="tpl-content-wrapper">
+
+            <div class="container-fluid am-cf">
+                <div class="row">
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-9">
+                        <div class="page-header-heading"><span class="am-icon-home page-header-heading-icon"></span> 表单 <small>Amaze UI</small></div>
+                        <p class="page-header-description">Amaze UI 有许多不同的表格可用。</p>
+                    </div>
+                    <div class="am-u-lg-3 tpl-index-settings-button">
+                        <button type="button" class="page-header-button"><span class="am-icon-paint-brush"></span> 设置</button>
+                    </div>
+                </div>
+
+            </div>
+
+            <div class="row-content am-cf">
+
+
+                <div class="row">
+
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-12">
+                        <div class="widget am-cf">
+                            <div class="widget-head am-cf">
+                                <div class="widget-title am-fl">线条表单</div>
+                                <div class="widget-function am-fr">
+                                    <a href="javascript:;" class="am-icon-cog"></a>
+                                </div>
+                            </div>
+                            <div class="widget-body am-fr">
+
+                                <form class="am-form tpl-form-line-form">
+                                    <div class="am-form-group">
+                                        <label for="user-name" class="am-u-sm-3 am-form-label">标题 <span class="tpl-form-line-small-title">Title</span></label>
+                                        <div class="am-u-sm-9">
+                                            <input type="text" class="tpl-form-input" id="user-name" placeholder="请输入标题文字">
+                                            <small>请填写标题文字10-20字左右。</small>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-email" class="am-u-sm-3 am-form-label">发布时间 <span class="tpl-form-line-small-title">Time</span></label>
+                                        <div class="am-u-sm-9">
+                                            <input type="text" class="am-form-field tpl-form-no-bg" placeholder="发布时间" data-am-datepicker="" readonly="">
+                                            <small>发布时间为必填</small>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-phone" class="am-u-sm-3 am-form-label">作者 <span class="tpl-form-line-small-title">Author</span></label>
+                                        <div class="am-u-sm-9">
+                                            <select data-am-selected="{searchBox: 1}" style="display: none;">
+  <option value="a">-The.CC</option>
+  <option value="b">夕风色</option>
+  <option value="o">Orange</option>
+</select>
+
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label class="am-u-sm-3 am-form-label">SEO关键字 <span class="tpl-form-line-small-title">SEO</span></label>
+                                        <div class="am-u-sm-9">
+                                            <input type="text" placeholder="输入SEO关键字">
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-weibo" class="am-u-sm-3 am-form-label">封面图 <span class="tpl-form-line-small-title">Images</span></label>
+                                        <div class="am-u-sm-9">
+                                            <div class="am-form-group am-form-file">
+                                                <div class="tpl-form-file-img">
+                                                    <img src="../img/a5.png" alt="">
+                                                </div>
+                                                <button type="button" class="am-btn am-btn-danger am-btn-sm">
+    <i class="am-icon-cloud-upload"></i> 添加封面图片</button>
+                                                <input id="doc-form-file" type="file" multiple="">
+                                            </div>
+
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-weibo" class="am-u-sm-3 am-form-label">添加分类 <span class="tpl-form-line-small-title">Type</span></label>
+                                        <div class="am-u-sm-9">
+                                            <input type="text" id="user-weibo" placeholder="请添加分类用点号隔开">
+                                            <div>
+
+                                            </div>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-intro" class="am-u-sm-3 am-form-label">隐藏文章</label>
+                                        <div class="am-u-sm-9">
+                                            <div class="tpl-switch">
+                                                <input type="checkbox" class="ios-switch bigswitch tpl-switch-btn" checked="">
+                                                <div class="tpl-switch-btn-view">
+                                                    <div>
+                                                    </div>
+                                                </div>
+                                            </div>
+
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-intro" class="am-u-sm-3 am-form-label">文章内容</label>
+                                        <div class="am-u-sm-9">
+                                            <textarea class="" rows="10" id="user-intro" placeholder="请输入文章内容"></textarea>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <div class="am-u-sm-9 am-u-sm-push-3">
+                                            <button type="button" class="am-btn am-btn-primary tpl-btn-bg-color-success ">提交</button>
+                                        </div>
+                                    </div>
+                                </form>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-12">
+                        <div class="widget am-cf">
+                            <div class="widget-head am-cf">
+                                <div class="widget-title am-fl">边框表单</div>
+                                <div class="widget-function am-fr">
+                                    <a href="javascript:;" class="am-icon-cog"></a>
+                                </div>
+                            </div>
+                            <div class="widget-body am-fr">
+
+                                <form class="am-form tpl-form-border-form tpl-form-border-br">
+                                    <div class="am-form-group">
+                                        <label for="user-name" class="am-u-sm-3 am-form-label">标题 <span class="tpl-form-line-small-title">Title</span></label>
+                                        <div class="am-u-sm-9">
+                                            <input type="text" class="tpl-form-input" id="user-name" placeholder="请输入标题文字">
+                                            <small>请填写标题文字10-20字左右。</small>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-email" class="am-u-sm-3 am-form-label">发布时间 <span class="tpl-form-line-small-title">Time</span></label>
+                                        <div class="am-u-sm-9">
+                                            <input type="text" class="am-form-field tpl-form-no-bg" placeholder="发布时间" data-am-datepicker="" readonly="">
+                                            <small>发布时间为必填</small>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-phone" class="am-u-sm-3 am-form-label">作者 <span class="tpl-form-line-small-title">Author</span></label>
+                                        <div class="am-u-sm-9">
+                                            <select data-am-selected="{searchBox: 1}" style="display: none;">
+  <option value="a">-The.CC</option>
+  <option value="b">夕风色</option>
+  <option value="o">Orange</option>
+</select>
+
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label class="am-u-sm-3 am-form-label">SEO关键字 <span class="tpl-form-line-small-title">SEO</span></label>
+                                        <div class="am-u-sm-9">
+                                            <input type="text" placeholder="输入SEO关键字">
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-weibo" class="am-u-sm-3 am-form-label">封面图 <span class="tpl-form-line-small-title">Images</span></label>
+                                        <div class="am-u-sm-9">
+                                            <div class="am-form-group am-form-file">
+                                                <div class="tpl-form-file-img">
+                                                    <img src="../img/a5.png" alt="">
+                                                </div>
+                                                <button type="button" class="am-btn am-btn-danger am-btn-sm">
+    <i class="am-icon-cloud-upload"></i> 添加封面图片</button>
+                                                <input id="doc-form-file" type="file" multiple="">
+                                            </div>
+
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-weibo" class="am-u-sm-3 am-form-label">添加分类 <span class="tpl-form-line-small-title">Type</span></label>
+                                        <div class="am-u-sm-9">
+                                            <input type="text" id="user-weibo" placeholder="请添加分类用点号隔开">
+                                            <div>
+
+                                            </div>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-intro" class="am-u-sm-3 am-form-label">隐藏文章</label>
+                                        <div class="am-u-sm-9">
+                                            <div class="tpl-switch">
+                                                <input type="checkbox" class="ios-switch bigswitch tpl-switch-btn" checked="">
+                                                <div class="tpl-switch-btn-view">
+                                                    <div>
+                                                    </div>
+                                                </div>
+                                            </div>
+
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-intro" class="am-u-sm-3 am-form-label">文章内容</label>
+                                        <div class="am-u-sm-9">
+                                            <textarea class="" rows="10" id="user-intro" placeholder="请输入文章内容"></textarea>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <div class="am-u-sm-9 am-u-sm-push-3">
+                                            <button type="button" class="am-btn am-btn-primary tpl-btn-bg-color-success ">提交</button>
+                                        </div>
+                                    </div>
+                                </form>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row">
+
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-12">
+                        <div class="widget am-cf">
+                            <div class="widget-head am-cf">
+                                <div class="widget-title am-fl">换行边框</div>
+                                <div class="widget-function am-fr">
+                                    <a href="javascript:;" class="am-icon-cog"></a>
+                                </div>
+                            </div>
+                            <div class="widget-body am-fr">
+
+                                <form class="am-form tpl-form-border-form">
+                                    <div class="am-form-group">
+                                        <label for="user-name" class="am-u-sm-12 am-form-label am-text-left">标题 <span class="tpl-form-line-small-title">Title</span></label>
+                                        <div class="am-u-sm-12">
+                                            <input type="text" class="tpl-form-input am-margin-top-xs" id="user-name" placeholder="请输入标题文字">
+                                            <small>请填写标题文字10-20字左右。</small>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-email" class="am-u-sm-12 am-form-label am-text-left">发布时间 <span class="tpl-form-line-small-title">Time</span></label>
+                                        <div class="am-u-sm-12">
+                                            <input type="text" class="am-form-field tpl-form-no-bg am-margin-top-xs" placeholder="发布时间" data-am-datepicker="" readonly="">
+                                            <small>发布时间为必填</small>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-phone" class="am-u-sm-12 am-form-label am-text-left">作者 <span class="tpl-form-line-small-title">Author</span></label>
+                                        <div class="am-u-sm-12  am-margin-top-xs">
+                                            <select data-am-selected="{searchBox: 1}" style="display: none;">
+  <option value="a">-The.CC</option>
+  <option value="b">夕风色</option>
+  <option value="o">Orange</option>
+</select>
+
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label class="am-u-sm-12 am-form-label  am-text-left">SEO关键字 <span class="tpl-form-line-small-title">SEO</span></label>
+                                        <div class="am-u-sm-12">
+                                            <input type="text" class="am-margin-top-xs" placeholder="输入SEO关键字">
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-weibo" class="am-u-sm-12 am-form-label  am-text-left">封面图 <span class="tpl-form-line-small-title">Images</span></label>
+                                        <div class="am-u-sm-12 am-margin-top-xs">
+                                            <div class="am-form-group am-form-file">
+                                                <div class="tpl-form-file-img">
+                                                    <img src="../img/a5.png" alt="">
+                                                </div>
+                                                <button type="button" class="am-btn am-btn-danger am-btn-sm ">
+    <i class="am-icon-cloud-upload"></i> 添加封面图片</button>
+                                                <input id="doc-form-file" type="file" multiple="">
+                                            </div>
+
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-weibo" class="am-u-sm-12 am-form-label  am-text-left">添加分类 <span class="tpl-form-line-small-title">Type</span></label>
+                                        <div class="am-u-sm-12">
+                                            <input type="text" id="user-weibo" class="am-margin-top-xs" placeholder="请添加分类用点号隔开">
+                                            <div>
+
+                                            </div>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-intro" class="am-u-sm-12 am-form-label  am-text-left">隐藏文章</label>
+                                        <div class="am-u-sm-12">
+                                            <div class="tpl-switch">
+                                                <input type="checkbox" class="ios-switch bigswitch tpl-switch-btn am-margin-top-xs" checked="">
+                                                <div class="tpl-switch-btn-view">
+                                                    <div>
+                                                    </div>
+                                                </div>
+                                            </div>
+
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <label for="user-intro" class="am-u-sm-12 am-form-label  am-text-left">文章内容</label>
+                                        <div class="am-u-sm-12 am-margin-top-xs">
+                                            <textarea class="" rows="10" id="user-intro" placeholder="请输入文章内容"></textarea>
+                                        </div>
+                                    </div>
+
+                                    <div class="am-form-group">
+                                        <div class="am-u-sm-12 am-u-sm-push-12">
+                                            <button type="button" class="am-btn am-btn-primary tpl-btn-bg-color-success ">提交</button>
+                                        </div>
+                                    </div>
+                                </form>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+
+            </div>
+        </div>
+    </div>
+    </div>
+    <script src="../js/amazeui.min.js"></script>
+    <script src="../js/amazeui.datatables.min.js"></script>
+    <script src="../js/dataTables.responsive.min.js"></script>
+    <script src="../js/app.js"></script>
+
+</body>
+
+</html>

+ 62 - 0
Day61-65/code/project_of_tornado/assets/html/login.html

@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Amaze UI Admin index Examples</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp" />
+    <link rel="icon" type="image/png" href="../i/favicon.png">
+    <link rel="apple-touch-icon-precomposed" href="../i/app-icon72x72@2x.png">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI" />
+    <link rel="stylesheet" href="../css/amazeui.min.css" />
+    <link rel="stylesheet" href="../css/amazeui.datatables.min.css" />
+    <link rel="stylesheet" href="../css/app.css">
+    <script src="../js/jquery.min.js"></script>
+</head>
+<body data-type="login">
+    <script src="../js/theme.js"></script>
+    <div class="am-g tpl-g">
+        <!-- 风格切换 -->
+        <div class="tpl-skiner">
+            <div class="tpl-skiner-toggle am-icon-cog">
+            </div>
+            <div class="tpl-skiner-content">
+                <div class="tpl-skiner-content-title">
+                    选择主题
+                </div>
+                <div class="tpl-skiner-content-bar">
+                    <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                    <span class="skiner-color skiner-black" data-color="theme-black"></span>
+                </div>
+            </div>
+        </div>
+        <div class="tpl-login">
+            <div class="tpl-login-content">
+                <div class="tpl-login-logo"></div>
+                <form class="am-form tpl-form-line-form">
+                    <div class="am-form-group">
+                        <input type="text" class="tpl-form-input" id="user-name" placeholder="请输入账号">
+                    </div>
+                    <div class="am-form-group">
+                        <input type="password" class="tpl-form-input" id="user-name" placeholder="请输入密码">
+                    </div>
+                    <div class="am-form-group tpl-login-remember-me">
+                        <input id="remember-me" type="checkbox">
+                        <label for="remember-me">记住密码</label>
+                    </div>
+                    <div class="am-form-group">
+                        <button type="button" class="am-btn am-btn-primary  am-btn-block tpl-btn-bg-color-success  tpl-login-btn">提交</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+    <script src="../js/amazeui.min.js"></script>
+    <script src="../js/app.js"></script>
+</body>
+</html>

+ 70 - 0
Day61-65/code/project_of_tornado/assets/html/sign-up.html

@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Amaze UI Admin index Examples</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp"/>
+    <link rel="icon" type="image/png" href="../i/favicon.png">
+    <link rel="apple-touch-icon-precomposed" href="../i/app-icon72x72@2x.png">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI"/>
+    <link rel="stylesheet" href="../css/amazeui.min.css"/>
+    <link rel="stylesheet" href="../css/amazeui.datatables.min.css"/>
+    <link rel="stylesheet" href="../css/app.css">
+    <script src="../js/jquery.min.js"></script>
+</head>
+<body data-type="login">
+<script src="../js/theme.js"></script>
+<div class="am-g tpl-g">
+    <!-- 风格切换 -->
+    <div class="tpl-skiner">
+        <div class="tpl-skiner-toggle am-icon-cog">
+        </div>
+        <div class="tpl-skiner-content">
+            <div class="tpl-skiner-content-title">
+                选择主题
+            </div>
+            <div class="tpl-skiner-content-bar">
+                <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                <span class="skiner-color skiner-black" data-color="theme-black"></span>
+            </div>
+        </div>
+    </div>
+    <div class="tpl-login">
+        <div class="tpl-login-content">
+            <div class="tpl-login-title">注册用户</div>
+            <span class="tpl-login-content-info">创建一个新的用户</span>
+            <form class="am-form tpl-form-line-form">
+                <div class="am-form-group">
+                    <input type="text" class="tpl-form-input" id="user-name" placeholder="邮箱">
+                </div>
+                <div class="am-form-group">
+                    <input type="text" class="tpl-form-input" id="user-name" placeholder="用户名">
+                </div>
+                <div class="am-form-group">
+                    <input type="password" class="tpl-form-input" id="user-name" placeholder="请输入密码">
+                </div>
+                <div class="am-form-group">
+                    <input type="password" class="tpl-form-input" id="user-name" placeholder="再次输入密码">
+                </div>
+                <div class="am-form-group tpl-login-remember-me">
+                    <input id="remember-me" type="checkbox">
+                    <label for="remember-me">我已阅读并同意 <a href="javascript:;">《用户注册协议》</a></label>
+                </div>
+                <div class="am-form-group">
+                    <button type="button"
+                            class="am-btn am-btn-primary  am-btn-block tpl-btn-bg-color-success  tpl-login-btn">提交
+                    </button>
+                </div>
+            </form>
+        </div>
+    </div>
+</div>
+<script src="../js/amazeui.min.js"></script>
+<script src="../js/app.js"></script>
+</body>
+</html>

+ 469 - 0
Day61-65/code/project_of_tornado/assets/html/table-list-img.html

@@ -0,0 +1,469 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Amaze UI Admin index Examples</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp" />
+    <link rel="icon" type="image/png" href="../i/favicon.png">
+    <link rel="apple-touch-icon-precomposed" href="../i/app-icon72x72@2x.png">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI" />
+    <link rel="stylesheet" href="../css/amazeui.min.css" />
+    <link rel="stylesheet" href="../css/amazeui.datatables.min.css" />
+    <link rel="stylesheet" href="../css/app.css">
+    <script src="../js/jquery.min.js"></script>
+
+</head>
+
+<body data-type="widgets">
+    <script src="../js/theme.js"></script>
+    <div class="am-g tpl-g">
+        <!-- 头部 -->
+        <header>
+            <!-- logo -->
+            <div class="am-fl tpl-header-logo">
+                <a href="javascript:;"><img src="../img/logo.png" alt=""></a>
+            </div>
+            <!-- 右侧内容 -->
+            <div class="tpl-header-fluid">
+                <!-- 侧边切换 -->
+                <div class="am-fl tpl-header-switch-button am-icon-list">
+                    <span>
+
+                </span>
+                </div>
+                <!-- 搜索 -->
+                <div class="am-fl tpl-header-search">
+                    <form class="tpl-header-search-form" action="javascript:;">
+                        <button class="tpl-header-search-btn am-icon-search"></button>
+                        <input class="tpl-header-search-box" type="text" placeholder="搜索内容...">
+                    </form>
+                </div>
+                <!-- 其它功能-->
+                <div class="am-fr tpl-header-navbar">
+                    <ul>
+                        <!-- 欢迎语 -->
+                        <li class="am-text-sm tpl-header-navbar-welcome">
+                            <a href="javascript:;">欢迎你, <span>Amaze UI</span> </a>
+                        </li>
+
+                        <!-- 新邮件 -->
+                        <li class="am-dropdown tpl-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle tpl-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-envelope"></i>
+                                <span class="am-badge am-badge-success am-round item-feed-badge">4</span>
+                            </a>
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="../img/user04.png" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            3小时前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-success"></i>
+                                                <span>夕风色</span>
+                                            </div>
+                                            <div class="am-text-truncate"> Amaze UI 的诞生,依托于 GitHub 及其他技术社区上一些优秀的资源;Amaze UI 的成长,则离不开用户的支持。 </div>
+                                            <div class="menu-messages-content-time">2016-09-21 下午 16:40</div>
+                                        </div>
+                                    </a>
+                                </li>
+
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="../img/user02.png" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            5天前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-warning"></i>
+                                                <span>禁言小张</span>
+                                            </div>
+                                            <div class="am-text-truncate"> 为了能最准确的传达所描述的问题, 建议你在反馈时附上演示,方便我们理解。 </div>
+                                            <div class="menu-messages-content-time">2016-09-16 上午 09:23</div>
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <i class="am-icon-circle-o"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+
+                        <!-- 新提示 -->
+                        <li class="am-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-bell"></i>
+                                <span class="am-badge am-badge-warning am-round item-feed-badge">5</span>
+                            </a>
+
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-line-chart"></i>
+                                            <span> 有6笔新的销售订单</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            12分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-star"></i>
+                                            <span> 有3个来自人事部的消息</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            30分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-folder-o"></i>
+                                            <span> 上午开会记录存档</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            1天前
+                                        </div>
+                                    </a>
+                                </li>
+
+
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <i class="am-icon-bell"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+
+                        <!-- 退出 -->
+                        <li class="am-text-sm">
+                            <a href="javascript:;">
+                                <span class="am-icon-sign-out"></span> 退出
+                            </a>
+                        </li>
+                    </ul>
+                </div>
+            </div>
+
+        </header>
+        <!-- 风格切换 -->
+        <div class="tpl-skiner">
+            <div class="tpl-skiner-toggle am-icon-cog">
+            </div>
+            <div class="tpl-skiner-content">
+                <div class="tpl-skiner-content-title">
+                    选择主题
+                </div>
+                <div class="tpl-skiner-content-bar">
+                    <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                    <span class="skiner-color skiner-black" data-color="theme-black"></span>
+                </div>
+            </div>
+        </div>
+        <!-- 侧边导航栏 -->
+        <div class="left-sidebar">
+            <!-- 用户信息 -->
+            <div class="tpl-sidebar-user-panel">
+                <div class="tpl-user-panel-slide-toggleable">
+                    <div class="tpl-user-panel-profile-picture">
+                        <img src="../img/user04.png" alt="">
+                    </div>
+                    <span class="user-panel-logged-in-text">
+                        <i class="am-icon-circle-o am-text-success tpl-user-panel-status-icon"></i>
+                        禁言小张
+                    </span>
+                    <a href="javascript:;" class="tpl-user-panel-action-link"> <span class="am-icon-pencil"></span> 账号设置</a>
+                </div>
+            </div>
+            <!-- 菜单 -->
+            <ul class="sidebar-nav">
+                <li class="sidebar-nav-heading">Components <span class="sidebar-nav-heading-info"> 附加组件</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="/">
+                        <i class="am-icon-home sidebar-nav-link-logo"></i> 首页
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/tables.html">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 表格
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/calendar.html">
+                        <i class="am-icon-calendar sidebar-nav-link-logo"></i> 日历
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/form.html">
+                        <i class="am-icon-wpforms sidebar-nav-link-logo"></i> 表单
+
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="../html/chart.html">
+                        <i class="am-icon-bar-chart sidebar-nav-link-logo"></i> 图表
+
+                    </a>
+                </li>
+
+                <li class="sidebar-nav-heading">Page<span class="sidebar-nav-heading-info"> 常用页面</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="javascript:;" class="sidebar-nav-sub-title active">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 数据列表
+                        <span class="am-icon-chevron-down am-fr am-margin-right-sm sidebar-nav-sub-ico sidebar-nav-sub-ico-rotate"></span>
+                    </a>
+                    <ul class="sidebar-nav sidebar-nav-sub" style="display: block;">
+                        <li class="sidebar-nav-link">
+                            <a href="../html/table-list.html">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 文字列表
+                            </a>
+                        </li>
+
+                        <li class="sidebar-nav-link">
+                            <a href="../html/table-list-img.html" class="sub-active">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 图文列表
+                            </a>
+                        </li>
+                    </ul>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/signup">
+                        <i class="am-icon-clone sidebar-nav-link-logo"></i> 注册
+                        <span class="am-badge am-badge-secondary sidebar-nav-link-logo-ico am-round am-fr am-margin-right-sm">6</span>
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/login">
+                        <i class="am-icon-key sidebar-nav-link-logo"></i> 登录
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="/page404">
+                        <i class="am-icon-tv sidebar-nav-link-logo"></i> 404错误
+                    </a>
+                </li>
+
+            </ul>
+        </div>
+        <!-- 内容区域 -->
+        <div class="tpl-content-wrapper">
+            <div class="row-content am-cf">
+                <div class="row">
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-12">
+                        <div class="widget am-cf">
+                            <div class="widget-head am-cf">
+                                <div class="widget-title  am-cf">文章列表</div>
+
+
+                            </div>
+                            <div class="widget-body  am-fr">
+
+                                <div class="am-u-sm-12 am-u-md-6 am-u-lg-6">
+                                    <div class="am-form-group">
+                                        <div class="am-btn-toolbar">
+                                            <div class="am-btn-group am-btn-group-xs">
+                                                <button type="button" class="am-btn am-btn-default am-btn-success"><span class="am-icon-plus"></span> 新增</button>
+                                                <button type="button" class="am-btn am-btn-default am-btn-secondary"><span class="am-icon-save"></span> 保存</button>
+                                                <button type="button" class="am-btn am-btn-default am-btn-warning"><span class="am-icon-archive"></span> 审核</button>
+                                                <button type="button" class="am-btn am-btn-default am-btn-danger"><span class="am-icon-trash-o"></span> 删除</button>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="am-u-sm-12 am-u-md-6 am-u-lg-3">
+                                    <div class="am-form-group tpl-table-list-select">
+                                        <select data-am-selected="{btnSize: 'sm'}">
+              <option value="option1">所有类别</option>
+              <option value="option2">IT业界</option>
+              <option value="option3">数码产品</option>
+              <option value="option3">笔记本电脑</option>
+              <option value="option3">平板电脑</option>
+              <option value="option3">只能手机</option>
+              <option value="option3">超极本</option>
+            </select>
+                                    </div>
+                                </div>
+                                <div class="am-u-sm-12 am-u-md-12 am-u-lg-3">
+                                    <div class="am-input-group am-input-group-sm tpl-form-border-form cl-p">
+                                        <input type="text" class="am-form-field ">
+                                        <span class="am-input-group-btn">
+            <button class="am-btn  am-btn-default am-btn-success tpl-table-list-field am-icon-search" type="button"></button>
+          </span>
+                                    </div>
+                                </div>
+
+                                <div class="am-u-sm-12">
+                                    <table width="100%" class="am-table am-table-compact am-table-striped tpl-table-black ">
+                                        <thead>
+                                            <tr>
+                                                <th>文章缩略图</th>
+                                                <th>文章标题</th>
+                                                <th>作者</th>
+                                                <th>时间</th>
+                                                <th>操作</th>
+                                            </tr>
+                                        </thead>
+                                        <tbody>
+                                            <tr class="gradeX">
+                                                <td>
+                                                    <img src="../img/k.jpg" class="tpl-table-line-img" alt="">
+                                                </td>
+                                                <td class="am-text-middle">Amaze UI 模式窗口</td>
+                                                <td class="am-text-middle">张鹏飞</td>
+                                                <td class="am-text-middle">2016-09-26</td>
+                                                <td class="am-text-middle">
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            <tr class="even gradeC">
+                                                <td>
+                                                    <img src="../img/k.jpg" class="tpl-table-line-img" alt="">
+                                                </td>
+                                                <td class="am-text-middle">有适配微信小程序的计划吗</td>
+                                                <td class="am-text-middle">天纵之人</td>
+                                                <td class="am-text-middle">2016-09-26</td>
+                                                <td class="am-text-middle">
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            <tr class="gradeX">
+                                                <td>
+                                                    <img src="../img/k.jpg" class="tpl-table-line-img" alt="">
+                                                </td>
+                                                <td class="am-text-middle">请问有没有amazeui 分享插件</td>
+                                                <td class="am-text-middle">王宽师</td>
+                                                <td class="am-text-middle">2016-09-26</td>
+                                                <td class="am-text-middle">
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            <tr class="even gradeC">
+                                                <td>
+                                                    <img src="../img/k.jpg" class="tpl-table-line-img" alt="">
+                                                </td>
+                                                <td class="am-text-middle">关于input输入框的问题</td>
+                                                <td class="am-text-middle">着迷</td>
+                                                <td class="am-text-middle">2016-09-26</td>
+                                                <td class="am-text-middle">
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            <tr class="even gradeC">
+                                                <td>
+                                                    <img src="../img/k.jpg" class="tpl-table-line-img" alt="">
+                                                </td>
+                                                <td class="am-text-middle">有没有发现官网上的下载包不好用</td>
+                                                <td class="am-text-middle">醉里挑灯看键</td>
+                                                <td class="am-text-middle">2016-09-26</td>
+                                                <td class="am-text-middle">
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+
+                                            <tr class="even gradeC">
+                                                <td>
+                                                    <img src="../img/k.jpg" class="tpl-table-line-img" alt="">
+                                                </td>
+                                                <td class="am-text-middle">我建议WEB版本文件引入问题</td>
+                                                <td class="am-text-middle">罢了</td>
+                                                <td class="am-text-middle">2016-09-26</td>
+                                                <td class="am-text-middle">
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            <!-- more data -->
+                                        </tbody>
+                                    </table>
+                                </div>
+                                <div class="am-u-lg-12 am-cf">
+
+                                    <div class="am-fr">
+                                        <ul class="am-pagination tpl-pagination">
+                                            <li class="am-disabled"><a href="#">«</a></li>
+                                            <li class="am-active"><a href="#">1</a></li>
+                                            <li><a href="#">2</a></li>
+                                            <li><a href="#">3</a></li>
+                                            <li><a href="#">4</a></li>
+                                            <li><a href="#">5</a></li>
+                                            <li><a href="#">»</a></li>
+                                        </ul>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    </div>
+    <script src="../js/amazeui.min.js"></script>
+    <script src="../js/app.js"></script>
+
+</body>
+
+</html>

+ 461 - 0
Day61-65/code/project_of_tornado/assets/html/table-list.html

@@ -0,0 +1,461 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Amaze UI Admin index Examples</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp"/>
+    <link rel="icon" type="image/png" href="../i/favicon.png">
+    <link rel="apple-touch-icon-precomposed" href="../i/app-icon72x72@2x.png">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI"/>
+    <script src="../js/echarts.min.js"></script>
+    <link rel="stylesheet" href="../css/amazeui.min.css"/>
+    <link rel="stylesheet" href="../css/amazeui.datatables.min.css"/>
+    <link rel="stylesheet" href="../css/app.css">
+    <script src="../js/jquery.min.js"></script>
+
+</head>
+
+<body data-type="widgets">
+<script src="../js/theme.js"></script>
+<div class="am-g tpl-g">
+    <!-- 头部 -->
+    <header>
+        <!-- logo -->
+        <div class="am-fl tpl-header-logo">
+            <a href="javascript:;"><img src="../img/logo.png" alt=""></a>
+        </div>
+        <!-- 右侧内容 -->
+        <div class="tpl-header-fluid">
+            <!-- 侧边切换 -->
+            <div class="am-fl tpl-header-switch-button am-icon-list">
+                    <span>
+
+                </span>
+            </div>
+            <!-- 搜索 -->
+            <div class="am-fl tpl-header-search">
+                <form class="tpl-header-search-form" action="javascript:;">
+                    <button class="tpl-header-search-btn am-icon-search"></button>
+                    <input class="tpl-header-search-box" type="text" placeholder="搜索内容...">
+                </form>
+            </div>
+            <!-- 其它功能-->
+            <div class="am-fr tpl-header-navbar">
+                <ul>
+                    <!-- 欢迎语 -->
+                    <li class="am-text-sm tpl-header-navbar-welcome">
+                        <a href="javascript:;">欢迎你, <span>Amaze UI</span> </a>
+                    </li>
+
+                    <!-- 新邮件 -->
+                    <li class="am-dropdown tpl-dropdown" data-am-dropdown>
+                        <a href="javascript:;" class="am-dropdown-toggle tpl-dropdown-toggle" data-am-dropdown-toggle>
+                            <i class="am-icon-envelope"></i>
+                            <span class="am-badge am-badge-success am-round item-feed-badge">4</span>
+                        </a>
+                        <!-- 弹出列表 -->
+                        <ul class="am-dropdown-content tpl-dropdown-content">
+                            <li class="tpl-dropdown-menu-messages">
+                                <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                    <div class="menu-messages-ico">
+                                        <img src="../img/user04.png" alt="">
+                                    </div>
+                                    <div class="menu-messages-time">
+                                        3小时前
+                                    </div>
+                                    <div class="menu-messages-content">
+                                        <div class="menu-messages-content-title">
+                                            <i class="am-icon-circle-o am-text-success"></i>
+                                            <span>夕风色</span>
+                                        </div>
+                                        <div class="am-text-truncate"> Amaze UI 的诞生,依托于 GitHub 及其他技术社区上一些优秀的资源;Amaze UI
+                                            的成长,则离不开用户的支持。
+                                        </div>
+                                        <div class="menu-messages-content-time">2016-09-21 下午 16:40</div>
+                                    </div>
+                                </a>
+                            </li>
+
+                            <li class="tpl-dropdown-menu-messages">
+                                <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                    <div class="menu-messages-ico">
+                                        <img src="../img/user02.png" alt="">
+                                    </div>
+                                    <div class="menu-messages-time">
+                                        5天前
+                                    </div>
+                                    <div class="menu-messages-content">
+                                        <div class="menu-messages-content-title">
+                                            <i class="am-icon-circle-o am-text-warning"></i>
+                                            <span>禁言小张</span>
+                                        </div>
+                                        <div class="am-text-truncate"> 为了能最准确的传达所描述的问题, 建议你在反馈时附上演示,方便我们理解。</div>
+                                        <div class="menu-messages-content-time">2016-09-16 上午 09:23</div>
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-messages">
+                                <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                    <i class="am-icon-circle-o"></i> 进入列表…
+                                </a>
+                            </li>
+                        </ul>
+                    </li>
+
+                    <!-- 新提示 -->
+                    <li class="am-dropdown" data-am-dropdown>
+                        <a href="javascript:;" class="am-dropdown-toggle" data-am-dropdown-toggle>
+                            <i class="am-icon-bell"></i>
+                            <span class="am-badge am-badge-warning am-round item-feed-badge">5</span>
+                        </a>
+
+                        <!-- 弹出列表 -->
+                        <ul class="am-dropdown-content tpl-dropdown-content">
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <div class="tpl-dropdown-menu-notifications-title">
+                                        <i class="am-icon-line-chart"></i>
+                                        <span> 有6笔新的销售订单</span>
+                                    </div>
+                                    <div class="tpl-dropdown-menu-notifications-time">
+                                        12分钟前
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <div class="tpl-dropdown-menu-notifications-title">
+                                        <i class="am-icon-star"></i>
+                                        <span> 有3个来自人事部的消息</span>
+                                    </div>
+                                    <div class="tpl-dropdown-menu-notifications-time">
+                                        30分钟前
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <div class="tpl-dropdown-menu-notifications-title">
+                                        <i class="am-icon-folder-o"></i>
+                                        <span> 上午开会记录存档</span>
+                                    </div>
+                                    <div class="tpl-dropdown-menu-notifications-time">
+                                        1天前
+                                    </div>
+                                </a>
+                            </li>
+
+
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <i class="am-icon-bell"></i> 进入列表…
+                                </a>
+                            </li>
+                        </ul>
+                    </li>
+
+                    <!-- 退出 -->
+                    <li class="am-text-sm">
+                        <a href="javascript:;">
+                            <span class="am-icon-sign-out"></span> 退出
+                        </a>
+                    </li>
+                </ul>
+            </div>
+        </div>
+
+    </header>
+    <!-- 风格切换 -->
+    <div class="tpl-skiner">
+        <div class="tpl-skiner-toggle am-icon-cog">
+        </div>
+        <div class="tpl-skiner-content">
+            <div class="tpl-skiner-content-title">
+                选择主题
+            </div>
+            <div class="tpl-skiner-content-bar">
+                <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                <span class="skiner-color skiner-black" data-color="theme-black"></span>
+            </div>
+        </div>
+    </div>
+    <!-- 侧边导航栏 -->
+    <div class="left-sidebar">
+        <!-- 用户信息 -->
+        <div class="tpl-sidebar-user-panel">
+            <div class="tpl-user-panel-slide-toggleable">
+                <div class="tpl-user-panel-profile-picture">
+                    <img src="../img/user04.png" alt="">
+                </div>
+                <span class="user-panel-logged-in-text"><i class="am-icon-circle-o am-text-success tpl-user-panel-status-icon"></i>
+                禁言小张
+                </span>
+                <a href="javascript:;" class="tpl-user-panel-action-link"> <span class="am-icon-pencil"></span> 账号设置</a>
+            </div>
+        </div>
+        <!-- 菜单 -->
+        <ul class="sidebar-nav">
+            <li class="sidebar-nav-heading">Components <span class="sidebar-nav-heading-info"> 附加组件</span></li>
+            <li class="sidebar-nav-link">
+                <a href="/">
+                    <i class="am-icon-home sidebar-nav-link-logo"></i> 首页
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/tables.html">
+                    <i class="am-icon-table sidebar-nav-link-logo"></i> 表格
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/calendar.html">
+                    <i class="am-icon-calendar sidebar-nav-link-logo"></i> 日历
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/form.html">
+                    <i class="am-icon-wpforms sidebar-nav-link-logo"></i> 表单
+
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/chart.html">
+                    <i class="am-icon-bar-chart sidebar-nav-link-logo"></i> 图表
+
+                </a>
+            </li>
+            <li class="sidebar-nav-heading">Page<span class="sidebar-nav-heading-info"> 常用页面</span></li>
+            <li class="sidebar-nav-link">
+                <a href="javascript:;" class="sidebar-nav-sub-title active">
+                    <i class="am-icon-table sidebar-nav-link-logo"></i> 数据列表
+                    <span class="am-icon-chevron-down am-fr am-margin-right-sm sidebar-nav-sub-ico sidebar-nav-sub-ico-rotate"></span>
+                </a>
+                <ul class="sidebar-nav sidebar-nav-sub" style="display: block;">
+                    <li class="sidebar-nav-link">
+                        <a href="../html/table-list.html" class="sub-active">
+                            <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 文字列表
+                        </a>
+                    </li>
+                    <li class="sidebar-nav-link">
+                        <a href="../html/table-list-img.html">
+                            <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 图文列表
+                        </a>
+                    </li>
+                </ul>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="/signup">
+                    <i class="am-icon-clone sidebar-nav-link-logo"></i> 注册
+                    <span class="am-badge am-badge-secondary sidebar-nav-link-logo-ico am-round am-fr am-margin-right-sm">6</span>
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="/login">
+                    <i class="am-icon-key sidebar-nav-link-logo"></i> 登录
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="/page404">
+                    <i class="am-icon-tv sidebar-nav-link-logo"></i> 404错误
+                </a>
+            </li>
+        </ul>
+    </div>
+    <!-- 内容区域 -->
+    <div class="tpl-content-wrapper">
+        <div class="row-content am-cf">
+            <div class="row">
+                <div class="am-u-sm-12 am-u-md-12 am-u-lg-12">
+                    <div class="widget am-cf">
+                        <div class="widget-head am-cf">
+                            <div class="widget-title  am-cf">文章列表</div>
+
+
+                        </div>
+                        <div class="widget-body  am-fr">
+
+                            <div class="am-u-sm-12 am-u-md-6 am-u-lg-6">
+                                <div class="am-form-group">
+                                    <div class="am-btn-toolbar">
+                                        <div class="am-btn-group am-btn-group-xs">
+                                            <button type="button" class="am-btn am-btn-default am-btn-success"><span
+                                                    class="am-icon-plus"></span> 新增
+                                            </button>
+                                            <button type="button" class="am-btn am-btn-default am-btn-secondary"><span
+                                                    class="am-icon-save"></span> 保存
+                                            </button>
+                                            <button type="button" class="am-btn am-btn-default am-btn-warning"><span
+                                                    class="am-icon-archive"></span> 审核
+                                            </button>
+                                            <button type="button" class="am-btn am-btn-default am-btn-danger"><span
+                                                    class="am-icon-trash-o"></span> 删除
+                                            </button>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="am-u-sm-12 am-u-md-6 am-u-lg-3">
+                                <div class="am-form-group tpl-table-list-select">
+                                    <select data-am-selected="{btnSize: 'sm'}">
+                                        <option value="option1">所有类别</option>
+                                        <option value="option2">IT业界</option>
+                                        <option value="option3">数码产品</option>
+                                        <option value="option3">笔记本电脑</option>
+                                        <option value="option3">平板电脑</option>
+                                        <option value="option3">只能手机</option>
+                                        <option value="option3">超极本</option>
+                                    </select>
+                                </div>
+                            </div>
+                            <div class="am-u-sm-12 am-u-md-12 am-u-lg-3">
+                                <div class="am-input-group am-input-group-sm tpl-form-border-form cl-p">
+                                    <input type="text" class="am-form-field ">
+                                    <span class="am-input-group-btn">
+            <button class="am-btn  am-btn-default am-btn-success tpl-table-list-field am-icon-search"
+                    type="button"></button>
+          </span>
+                                </div>
+                            </div>
+
+                            <div class="am-u-sm-12">
+                                <table width="100%" class="am-table am-table-compact am-table-striped tpl-table-black "
+                                       id="example-r">
+                                    <thead>
+                                    <tr>
+                                        <th>文章标题</th>
+                                        <th>作者</th>
+                                        <th>时间</th>
+                                        <th>操作</th>
+                                    </tr>
+                                    </thead>
+                                    <tbody>
+                                    <tr class="gradeX">
+                                        <td>Amaze UI 模式窗口</td>
+                                        <td>张鹏飞</td>
+                                        <td>2016-09-26</td>
+                                        <td>
+                                            <div class="tpl-table-black-operation">
+                                                <a href="javascript:;">
+                                                    <i class="am-icon-pencil"></i> 编辑
+                                                </a>
+                                                <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                    <i class="am-icon-trash"></i> 删除
+                                                </a>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                    <tr class="even gradeC">
+                                        <td>有适配微信小程序的计划吗</td>
+                                        <td>天纵之人</td>
+                                        <td>2016-09-26</td>
+                                        <td>
+                                            <div class="tpl-table-black-operation">
+                                                <a href="javascript:;">
+                                                    <i class="am-icon-pencil"></i> 编辑
+                                                </a>
+                                                <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                    <i class="am-icon-trash"></i> 删除
+                                                </a>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                    <tr class="gradeX">
+                                        <td>请问有没有amazeui 分享插件</td>
+                                        <td>王宽师</td>
+                                        <td>2016-09-26</td>
+                                        <td>
+                                            <div class="tpl-table-black-operation">
+                                                <a href="javascript:;">
+                                                    <i class="am-icon-pencil"></i> 编辑
+                                                </a>
+                                                <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                    <i class="am-icon-trash"></i> 删除
+                                                </a>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                    <tr class="even gradeC">
+                                        <td>关于input输入框的问题</td>
+                                        <td>着迷</td>
+                                        <td>2016-09-26</td>
+                                        <td>
+                                            <div class="tpl-table-black-operation">
+                                                <a href="javascript:;">
+                                                    <i class="am-icon-pencil"></i> 编辑
+                                                </a>
+                                                <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                    <i class="am-icon-trash"></i> 删除
+                                                </a>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                    <tr class="even gradeC">
+                                        <td>有没有发现官网上的下载包不好用</td>
+                                        <td>醉里挑灯看键</td>
+                                        <td>2016-09-26</td>
+                                        <td>
+                                            <div class="tpl-table-black-operation">
+                                                <a href="javascript:;">
+                                                    <i class="am-icon-pencil"></i> 编辑
+                                                </a>
+                                                <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                    <i class="am-icon-trash"></i> 删除
+                                                </a>
+                                            </div>
+                                        </td>
+                                    </tr>
+
+                                    <tr class="even gradeC">
+                                        <td>我建议WEB版本文件引入问题</td>
+                                        <td>罢了</td>
+                                        <td>2016-09-26</td>
+                                        <td>
+                                            <div class="tpl-table-black-operation">
+                                                <a href="javascript:;">
+                                                    <i class="am-icon-pencil"></i> 编辑
+                                                </a>
+                                                <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                    <i class="am-icon-trash"></i> 删除
+                                                </a>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                    <!-- more data -->
+                                    </tbody>
+                                </table>
+                            </div>
+                            <div class="am-u-lg-12 am-cf">
+
+                                <div class="am-fr">
+                                    <ul class="am-pagination tpl-pagination">
+                                        <li class="am-disabled"><a href="#">«</a></li>
+                                        <li class="am-active"><a href="#">1</a></li>
+                                        <li><a href="#">2</a></li>
+                                        <li><a href="#">3</a></li>
+                                        <li><a href="#">4</a></li>
+                                        <li><a href="#">5</a></li>
+                                        <li><a href="#">»</a></li>
+                                    </ul>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+</div>
+<script src="../js/amazeui.min.js"></script>
+<script src="../js/amazeui.datatables.min.js"></script>
+<script src="../js/dataTables.responsive.min.js"></script>
+<script src="../js/app.js"></script>
+
+</body>
+
+</html>

+ 834 - 0
Day61-65/code/project_of_tornado/assets/html/tables.html

@@ -0,0 +1,834 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>Amaze UI Admin index Examples</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp">
+    <link rel="icon" type="image/png" href="../i/favicon.png">
+    <link rel="apple-touch-icon-precomposed" href="../i/app-icon72x72@2x.png">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI">
+    <script src="../js/echarts.min.js"></script>
+    <link rel="stylesheet" href="../css/amazeui.min.css">
+    <link rel="stylesheet" href="../css/amazeui.datatables.min.css">
+    <link rel="stylesheet" href="../css/app.css">
+    <script src="../js/jquery.min.js"></script>
+</head>
+<body data-type="widgets">
+<script src="../js/theme.js"></script>
+<div class="am-g tpl-g">
+    <!-- 头部 -->
+    <header>
+        <!-- logo -->
+        <div class="am-fl tpl-header-logo">
+            <a href="javascript:;"><img src="../img/logo.png" alt=""></a>
+        </div>
+        <!-- 右侧内容 -->
+        <div class="tpl-header-fluid">
+            <!-- 侧边切换 -->
+            <div class="am-fl tpl-header-switch-button am-icon-list">
+                    <span>
+
+                </span>
+            </div>
+            <!-- 搜索 -->
+            <div class="am-fl tpl-header-search">
+                <form class="tpl-header-search-form" action="javascript:;">
+                    <button class="tpl-header-search-btn am-icon-search"></button>
+                    <input class="tpl-header-search-box" type="text" placeholder="搜索内容...">
+                </form>
+            </div>
+            <!-- 其它功能-->
+            <div class="am-fr tpl-header-navbar">
+                <ul>
+                    <!-- 欢迎语 -->
+                    <li class="am-text-sm tpl-header-navbar-welcome">
+                        <a href="javascript:;">欢迎你, <span>Amaze UI</span> </a>
+                    </li>
+                    <!-- 新邮件 -->
+                    <li class="am-dropdown tpl-dropdown" data-am-dropdown>
+                        <a href="javascript:;" class="am-dropdown-toggle tpl-dropdown-toggle" data-am-dropdown-toggle>
+                            <i class="am-icon-envelope"></i>
+                            <span class="am-badge am-badge-success am-round item-feed-badge">4</span>
+                        </a>
+                        <!-- 弹出列表 -->
+                        <ul class="am-dropdown-content tpl-dropdown-content">
+                            <li class="tpl-dropdown-menu-messages">
+                                <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                    <div class="menu-messages-ico">
+                                        <img src="../img/user04.png" alt="">
+                                    </div>
+                                    <div class="menu-messages-time">
+                                        3小时前
+                                    </div>
+                                    <div class="menu-messages-content">
+                                        <div class="menu-messages-content-title">
+                                            <i class="am-icon-circle-o am-text-success"></i>
+                                            <span>夕风色</span>
+                                        </div>
+                                        <div class="am-text-truncate"> Amaze UI 的诞生,依托于 GitHub 及其他技术社区上一些优秀的资源;Amaze UI
+                                            的成长,则离不开用户的支持。
+                                        </div>
+                                        <div class="menu-messages-content-time">2016-09-21 下午 16:40</div>
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-messages">
+                                <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                    <div class="menu-messages-ico">
+                                        <img src="../img/user02.png" alt="">
+                                    </div>
+                                    <div class="menu-messages-time">
+                                        5天前
+                                    </div>
+                                    <div class="menu-messages-content">
+                                        <div class="menu-messages-content-title">
+                                            <i class="am-icon-circle-o am-text-warning"></i>
+                                            <span>禁言小张</span>
+                                        </div>
+                                        <div class="am-text-truncate"> 为了能最准确的传达所描述的问题, 建议你在反馈时附上演示,方便我们理解。</div>
+                                        <div class="menu-messages-content-time">2016-09-16 上午 09:23</div>
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-messages">
+                                <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                    <i class="am-icon-circle-o"></i> 进入列表…
+                                </a>
+                            </li>
+                        </ul>
+                    </li>
+
+                    <!-- 新提示 -->
+                    <li class="am-dropdown" data-am-dropdown>
+                        <a href="javascript:;" class="am-dropdown-toggle" data-am-dropdown-toggle>
+                            <i class="am-icon-bell"></i>
+                            <span class="am-badge am-badge-warning am-round item-feed-badge">5</span>
+                        </a>
+
+                        <!-- 弹出列表 -->
+                        <ul class="am-dropdown-content tpl-dropdown-content">
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <div class="tpl-dropdown-menu-notifications-title">
+                                        <i class="am-icon-line-chart"></i>
+                                        <span> 有6笔新的销售订单</span>
+                                    </div>
+                                    <div class="tpl-dropdown-menu-notifications-time">
+                                        12分钟前
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <div class="tpl-dropdown-menu-notifications-title">
+                                        <i class="am-icon-star"></i>
+                                        <span> 有3个来自人事部的消息</span>
+                                    </div>
+                                    <div class="tpl-dropdown-menu-notifications-time">
+                                        30分钟前
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <div class="tpl-dropdown-menu-notifications-title">
+                                        <i class="am-icon-folder-o"></i>
+                                        <span> 上午开会记录存档</span>
+                                    </div>
+                                    <div class="tpl-dropdown-menu-notifications-time">
+                                        1天前
+                                    </div>
+                                </a>
+                            </li>
+                            <li class="tpl-dropdown-menu-notifications">
+                                <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                    <i class="am-icon-bell"></i> 进入列表…
+                                </a>
+                            </li>
+                        </ul>
+                    </li>
+
+                    <!-- 退出 -->
+                    <li class="am-text-sm">
+                        <a href="javascript:;">
+                            <span class="am-icon-sign-out"></span> 退出
+                        </a>
+                    </li>
+                </ul>
+            </div>
+        </div>
+
+    </header>
+    <!-- 风格切换 -->
+    <div class="tpl-skiner">
+        <div class="tpl-skiner-toggle am-icon-cog">
+        </div>
+        <div class="tpl-skiner-content">
+            <div class="tpl-skiner-content-title">
+                选择主题
+            </div>
+            <div class="tpl-skiner-content-bar">
+                <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                <span class="skiner-color skiner-black" data-color="theme-black"></span>
+            </div>
+        </div>
+    </div>
+    <!-- 侧边导航栏 -->
+    <div class="left-sidebar">
+        <!-- 用户信息 -->
+        <div class="tpl-sidebar-user-panel">
+            <div class="tpl-user-panel-slide-toggleable">
+                <div class="tpl-user-panel-profile-picture">
+                    <img src="../img/user04.png" alt="">
+                </div>
+                <span class="user-panel-logged-in-text">
+              <i class="am-icon-circle-o am-text-success tpl-user-panel-status-icon"></i>
+              禁言小张
+          </span>
+                <a href="javascript:;" class="tpl-user-panel-action-link"> <span class="am-icon-pencil"></span> 账号设置</a>
+            </div>
+        </div>
+        <!-- 菜单 -->
+        <ul class="sidebar-nav">
+            <li class="sidebar-nav-heading">Components <span class="sidebar-nav-heading-info"> 附加组件</span></li>
+            <li class="sidebar-nav-link">
+                <a href="/">
+                    <i class="am-icon-home sidebar-nav-link-logo"></i> 首页
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/tables.html" class="active">
+                    <i class="am-icon-table sidebar-nav-link-logo"></i> 表格
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/calendar.html">
+                    <i class="am-icon-calendar sidebar-nav-link-logo"></i> 日历
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/form.html">
+                    <i class="am-icon-wpforms sidebar-nav-link-logo"></i> 表单
+
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="../html/chart.html">
+                    <i class="am-icon-bar-chart sidebar-nav-link-logo"></i> 图表
+
+                </a>
+            </li>
+
+            <li class="sidebar-nav-heading">Page<span class="sidebar-nav-heading-info"> 常用页面</span></li>
+            <li class="sidebar-nav-link">
+                <a href="javascript:;" class="sidebar-nav-sub-title">
+                    <i class="am-icon-table sidebar-nav-link-logo"></i> 数据列表
+                    <span class="am-icon-chevron-down am-fr am-margin-right-sm sidebar-nav-sub-ico"></span>
+                </a>
+                <ul class="sidebar-nav sidebar-nav-sub">
+                    <li class="sidebar-nav-link">
+                        <a href="../html/table-list.html">
+                            <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 文字列表
+                        </a>
+                    </li>
+
+                    <li class="sidebar-nav-link">
+                        <a href="../html/table-list-img.html">
+                            <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 图文列表
+                        </a>
+                    </li>
+                </ul>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="/signup">
+                    <i class="am-icon-clone sidebar-nav-link-logo"></i> 注册
+                    <span class="am-badge am-badge-secondary sidebar-nav-link-logo-ico am-round am-fr am-margin-right-sm">6</span>
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="/login">
+                    <i class="am-icon-key sidebar-nav-link-logo"></i> 登录
+                </a>
+            </li>
+            <li class="sidebar-nav-link">
+                <a href="/page404">
+                    <i class="am-icon-tv sidebar-nav-link-logo"></i> 404错误
+                </a>
+            </li>
+
+        </ul>
+    </div>
+    <!-- 内容区域 -->
+    <div class="tpl-content-wrapper">
+        <div class="container-fluid am-cf">
+            <div class="row">
+                <div class="am-u-sm-12 am-u-md-12 am-u-lg-9">
+                    <div class="page-header-heading"><span class="am-icon-home page-header-heading-icon"></span> 表格
+                        <small>Amaze UI</small>
+                    </div>
+                    <p class="page-header-description">Amaze UI 有许多不同的表格可用。</p>
+                </div>
+                <div class="am-u-lg-3 tpl-index-settings-button">
+                    <button type="button" class="page-header-button"><span class="am-icon-paint-brush"></span> 设置
+                    </button>
+                </div>
+            </div>
+        </div>
+        <div class="row-content am-cf">
+            <div class="row">
+                <div class="am-u-sm-12 am-u-md-12 am-u-lg-6">
+                    <div class="widget am-cf">
+                        <div class="widget-head am-cf">
+                            <div class="widget-title am-fl">滚动条表格</div>
+                            <div class="widget-function am-fr">
+                                <a href="javascript:;" class="am-icon-cog"></a>
+                            </div>
+                        </div>
+                        <div class="widget-body  widget-body-lg am-fr">
+                            <div class="am-scrollable-horizontal ">
+                                <table width="100%" class="am-table am-table-compact am-text-nowrap tpl-table-black "
+                                       id="example-r">
+                                    <thead>
+                                    <tr>
+                                        <th>工号</th>
+                                        <th>姓名</th>
+                                        <th>职位</th>
+                                        <th>月薪</th>
+                                        <th>自我介绍</th>
+                                    </tr>
+                                    </thead>
+                                    <tbody id="emp-data-row">
+                                    <tr v-for="emp in emps">
+                                        <td>{{ emp.no }}</td>
+                                        <td>{{ emp.name }}</td>
+                                        <td>{{ emp.job }}</td>
+                                        <td>{{ emp.sal }}</td>
+                                        <td>{{ emp.intro }}</td>
+                                        <td>
+                                            <div class="tpl-table-black-operation">
+                                                <a href="javascript:;">
+                                                    <i class="am-icon-pencil"></i> 编辑
+                                                </a>
+                                                <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                    <i class="am-icon-trash"></i> 删除
+                                                </a>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                    </tbody>
+                                </table>
+                            </div>
+
+                        </div>
+                    </div>
+                </div>
+
+                <div class="am-u-sm-12 am-u-md-12 am-u-lg-6">
+                    <div class="widget am-cf">
+                        <div class="widget-head am-cf">
+                            <div class="widget-title am-fl">自适应表格</div>
+                            <div class="widget-function am-fr">
+                                <a href="javascript:;" class="am-icon-cog"></a>
+                            </div>
+                        </div>
+                        <div class="widget-body  widget-body-lg am-fr">
+                            <table width="100%" class="am-table am-table-compact tpl-table-black " id="example-r">
+                                <thead>
+                                <tr>
+                                    <th>文章标题</th>
+                                    <th>作者</th>
+                                    <th>时间</th>
+                                    <th>操作</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                <tr class="gradeX">
+                                    <td>Amaze UI 模式窗口</td>
+                                    <td>张鹏飞</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>有适配微信小程序的计划吗</td>
+                                    <td>天纵之人</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="gradeX">
+                                    <td>请问有没有amazeui 分享插件</td>
+                                    <td>王宽师</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>关于input输入框的问题</td>
+                                    <td>着迷</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>有没有发现官网上的下载包不好用</td>
+                                    <td>醉里挑灯看键</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+
+                                <tr class="even gradeC">
+                                    <td>我建议WEB版本文件引入问题</td>
+                                    <td>罢了</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="row">
+                <div class="am-u-sm-12 am-u-md-12 am-u-lg-6">
+                    <div class="widget am-cf">
+                        <div class="widget-head am-cf">
+                            <div class="widget-title am-fl">基本边框</div>
+                            <div class="widget-function am-fr">
+                                <a href="javascript:;" class="am-icon-cog"></a>
+                            </div>
+                        </div>
+                        <div class="widget-body  widget-body-lg am-fr">
+
+                            <table width="100%" class="am-table am-table-compact am-table-bordered tpl-table-black "
+                                   id="example-r">
+                                <thead>
+                                <tr>
+                                    <th>文章标题</th>
+                                    <th>作者</th>
+                                    <th>时间</th>
+                                    <th>操作</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                <tr class="gradeX">
+                                    <td>Amaze UI 模式窗口</td>
+                                    <td>张鹏飞</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>有适配微信小程序的计划吗</td>
+                                    <td>天纵之人</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="gradeX">
+                                    <td>请问有没有amazeui 分享插件</td>
+                                    <td>王宽师</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>关于input输入框的问题</td>
+                                    <td>着迷</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>有没有发现官网上的下载包不好用</td>
+                                    <td>醉里挑灯看键</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+
+                                <tr class="even gradeC">
+                                    <td>我建议WEB版本文件引入问题</td>
+                                    <td>罢了</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <!-- more data -->
+                                </tbody>
+                            </table>
+
+                        </div>
+                    </div>
+                </div>
+
+                <div class="am-u-sm-12 am-u-md-12 am-u-lg-6">
+                    <div class="widget am-cf">
+                        <div class="widget-head am-cf">
+                            <div class="widget-title am-fl">圆角斑马线边框</div>
+                            <div class="widget-function am-fr">
+                                <a href="javascript:;" class="am-icon-cog"></a>
+                            </div>
+                        </div>
+                        <div class="widget-body  widget-body-lg am-fr">
+
+                            <table width="100%"
+                                   class="am-table am-table-compact am-table-bordered am-table-radius am-table-striped tpl-table-black "
+                                   id="example-r">
+                                <thead>
+                                <tr>
+                                    <th>文章标题</th>
+                                    <th>作者</th>
+                                    <th>时间</th>
+                                    <th>操作</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                <tr class="gradeX">
+                                    <td>Amaze UI 模式窗口</td>
+                                    <td>张鹏飞</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>有适配微信小程序的计划吗</td>
+                                    <td>天纵之人</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="gradeX">
+                                    <td>请问有没有amazeui 分享插件</td>
+                                    <td>王宽师</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>关于input输入框的问题</td>
+                                    <td>着迷</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>有没有发现官网上的下载包不好用</td>
+                                    <td>醉里挑灯看键</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+
+                                <tr class="even gradeC">
+                                    <td>我建议WEB版本文件引入问题</td>
+                                    <td>罢了</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <!-- more data -->
+                                </tbody>
+                            </table>
+
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="row">
+                <div class="am-u-sm-12 am-u-md-12 am-u-lg-12">
+                    <div class="widget am-cf">
+                        <div class="widget-head am-cf">
+                            <div class="widget-title am-fl">斑马线</div>
+                            <div class="widget-function am-fr">
+                                <a href="javascript:;" class="am-icon-cog"></a>
+                            </div>
+                        </div>
+                        <div class="widget-body  widget-body-lg am-fr">
+
+                            <table width="100%" class="am-table am-table-compact am-table-striped tpl-table-black "
+                                   id="example-r">
+                                <thead>
+                                <tr>
+                                    <th>文章标题</th>
+                                    <th>作者</th>
+                                    <th>时间</th>
+                                    <th>操作</th>
+                                </tr>
+                                </thead>
+                                <tbody>
+                                <tr class="gradeX">
+                                    <td>Amaze UI 模式窗口</td>
+                                    <td>张鹏飞</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>有适配微信小程序的计划吗</td>
+                                    <td>天纵之人</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="gradeX">
+                                    <td>请问有没有amazeui 分享插件</td>
+                                    <td>王宽师</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>关于input输入框的问题</td>
+                                    <td>着迷</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr class="even gradeC">
+                                    <td>有没有发现官网上的下载包不好用</td>
+                                    <td>醉里挑灯看键</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+
+                                <tr class="even gradeC">
+                                    <td>我建议WEB版本文件引入问题</td>
+                                    <td>罢了</td>
+                                    <td>2016-09-26</td>
+                                    <td>
+                                        <div class="tpl-table-black-operation">
+                                            <a href="javascript:;">
+                                                <i class="am-icon-pencil"></i> 编辑
+                                            </a>
+                                            <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                <i class="am-icon-trash"></i> 删除
+                                            </a>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <!-- more data -->
+                                </tbody>
+                            </table>
+
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+</div>
+<script src="../js/amazeui.min.js"></script>
+<script src="../js/amazeui.datatables.min.js"></script>
+<script src="../js/dataTables.responsive.min.js"></script>
+<script src="../js/app.js"></script>
+<script src="https://cdn.bootcss.com/vue/2.6.9/vue.min.js"></script>
+<script>
+    fetch('/api/emps')
+        .then(resp => resp.json())
+        .then(function(data) {
+            var app = new Vue({
+                'el': '#emp-data-row',
+                data: {
+                    emps: data
+                }
+            });
+        });
+</script>
+</body>
+</html>

BIN
Day61-65/code/project_of_tornado/assets/i/app-icon72x72@2x.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/admin-chrome.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/admin-firefox.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/admin-ie.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/admin-opera.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/admin-safari.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/adminPage.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/blogPage.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/landing.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/landingPage.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/loginPage.png


BIN
Day61-65/code/project_of_tornado/assets/i/examples/sidebarPage.png


BIN
Day61-65/code/project_of_tornado/assets/i/favicon.png


BIN
Day61-65/code/project_of_tornado/assets/i/startup-640x1096.png


BIN
Day61-65/code/project_of_tornado/assets/img/a5.png


BIN
Day61-65/code/project_of_tornado/assets/img/k.jpg


BIN
Day61-65/code/project_of_tornado/assets/img/logo.png


BIN
Day61-65/code/project_of_tornado/assets/img/logoa.png


BIN
Day61-65/code/project_of_tornado/assets/img/logob.png


BIN
Day61-65/code/project_of_tornado/assets/img/user01.png


BIN
Day61-65/code/project_of_tornado/assets/img/user02.png


BIN
Day61-65/code/project_of_tornado/assets/img/user03.png


BIN
Day61-65/code/project_of_tornado/assets/img/user04.png


BIN
Day61-65/code/project_of_tornado/assets/img/user05.png


BIN
Day61-65/code/project_of_tornado/assets/img/user06.png


BIN
Day61-65/code/project_of_tornado/assets/img/user07.png


Різницю між файлами не показано, бо вона завелика
+ 0 - 0
Day61-65/code/project_of_tornado/assets/js/amazeui.datatables.min.js


Різницю між файлами не показано, бо вона завелика
+ 1 - 0
Day61-65/code/project_of_tornado/assets/js/amazeui.min.js


+ 370 - 0
Day61-65/code/project_of_tornado/assets/js/app.js

@@ -0,0 +1,370 @@
+$(function() {
+    // 读取body data-type 判断是哪个页面然后执行相应页面方法,方法在下面。
+    var dataType = $('body').attr('data-type');
+    console.log(dataType);
+    for (key in pageData) {
+        if (key == dataType) {
+            pageData[key]();
+        }
+    }
+    //     // 判断用户是否已有自己选择的模板风格
+    //    if(storageLoad('SelcetColor')){
+    //      $('body').attr('class',storageLoad('SelcetColor').Color)
+    //    }else{
+    //        storageSave(saveSelectColor);
+    //        $('body').attr('class','theme-black')
+    //    }
+
+    autoLeftNav();
+    $(window).resize(function() {
+        autoLeftNav();
+        console.log($(window).width())
+    });
+
+    //    if(storageLoad('SelcetColor')){
+
+    //     }else{
+    //       storageSave(saveSelectColor);
+    //     }
+})
+
+
+// 页面数据
+var pageData = {
+    // ===============================================
+    // 首页
+    // ===============================================
+    'index': function indexData() {
+        $('#example-r').DataTable({
+
+            bInfo: false, //页脚信息
+            dom: 'ti'
+        });
+
+
+        // ==========================
+        // 百度图表A http://echarts.baidu.com/
+        // ==========================
+
+        var echartsA = echarts.init(document.getElementById('tpl-echarts'));
+        option = {
+            tooltip: {
+                trigger: 'axis'
+            },
+            grid: {
+                top: '3%',
+                left: '3%',
+                right: '4%',
+                bottom: '3%',
+                containLabel: true
+            },
+            xAxis: [{
+                type: 'category',
+                boundaryGap: false,
+                data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
+            }],
+            yAxis: [{
+                type: 'value'
+            }],
+            textStyle: {
+                color: '#838FA1'
+            },
+            series: [{
+                name: '邮件营销',
+                type: 'line',
+                stack: '总量',
+                areaStyle: { normal: {} },
+                data: [120, 132, 101, 134, 90],
+                itemStyle: {
+                    normal: {
+                        color: '#1cabdb',
+                        borderColor: '#1cabdb',
+                        borderWidth: '2',
+                        borderType: 'solid',
+                        opacity: '1'
+                    },
+                    emphasis: {
+
+                    }
+                }
+            }]
+        };
+        echartsA.setOption(option);
+    },
+    // ===============================================
+    // 图表页
+    // ===============================================
+    'chart': function chartData() {
+        // ==========================
+        // 百度图表A http://echarts.baidu.com/
+        // ==========================
+
+        var echartsC = echarts.init(document.getElementById('tpl-echarts-C'));
+
+
+        optionC = {
+            tooltip: {
+                trigger: 'axis'
+            },
+
+            legend: {
+                data: ['蒸发量', '降水量', '平均温度']
+            },
+            xAxis: [{
+                type: 'category',
+                data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
+            }],
+            yAxis: [{
+                    type: 'value',
+                    name: '水量',
+                    min: 0,
+                    max: 250,
+                    interval: 50,
+                    axisLabel: {
+                        formatter: '{value} ml'
+                    }
+                },
+                {
+                    type: 'value',
+                    name: '温度',
+                    min: 0,
+                    max: 25,
+                    interval: 5,
+                    axisLabel: {
+                        formatter: '{value} °C'
+                    }
+                }
+            ],
+            series: [{
+                    name: '蒸发量',
+                    type: 'bar',
+                    data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
+                },
+                {
+                    name: '降水量',
+                    type: 'bar',
+                    data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
+                },
+                {
+                    name: '平均温度',
+                    type: 'line',
+                    yAxisIndex: 1,
+                    data: [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
+                }
+            ]
+        };
+
+        echartsC.setOption(optionC);
+
+        var echartsB = echarts.init(document.getElementById('tpl-echarts-B'));
+        optionB = {
+            tooltip: {
+                trigger: 'axis'
+            },
+            legend: {
+                x: 'center',
+                data: ['某软件', '某主食手机', '某水果手机', '降水量', '蒸发量']
+            },
+            radar: [{
+                    indicator: [
+                        { text: '品牌', max: 100 },
+                        { text: '内容', max: 100 },
+                        { text: '可用性', max: 100 },
+                        { text: '功能', max: 100 }
+                    ],
+                    center: ['25%', '40%'],
+                    radius: 80
+                },
+                {
+                    indicator: [
+                        { text: '外观', max: 100 },
+                        { text: '拍照', max: 100 },
+                        { text: '系统', max: 100 },
+                        { text: '性能', max: 100 },
+                        { text: '屏幕', max: 100 }
+                    ],
+                    radius: 80,
+                    center: ['50%', '60%'],
+                },
+                {
+                    indicator: (function() {
+                        var res = [];
+                        for (var i = 1; i <= 12; i++) {
+                            res.push({ text: i + '月', max: 100 });
+                        }
+                        return res;
+                    })(),
+                    center: ['75%', '40%'],
+                    radius: 80
+                }
+            ],
+            series: [{
+                    type: 'radar',
+                    tooltip: {
+                        trigger: 'item'
+                    },
+                    itemStyle: { normal: { areaStyle: { type: 'default' } } },
+                    data: [{
+                        value: [60, 73, 85, 40],
+                        name: '某软件'
+                    }]
+                },
+                {
+                    type: 'radar',
+                    radarIndex: 1,
+                    data: [{
+                            value: [85, 90, 90, 95, 95],
+                            name: '某主食手机'
+                        },
+                        {
+                            value: [95, 80, 95, 90, 93],
+                            name: '某水果手机'
+                        }
+                    ]
+                },
+                {
+                    type: 'radar',
+                    radarIndex: 2,
+                    itemStyle: { normal: { areaStyle: { type: 'default' } } },
+                    data: [{
+                            name: '降水量',
+                            value: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 75.6, 82.2, 48.7, 18.8, 6.0, 2.3],
+                        },
+                        {
+                            name: '蒸发量',
+                            value: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 35.6, 62.2, 32.6, 20.0, 6.4, 3.3]
+                        }
+                    ]
+                }
+            ]
+        };
+        echartsB.setOption(optionB);
+        var echartsA = echarts.init(document.getElementById('tpl-echarts-A'));
+        option = {
+            tooltip: {
+                trigger: 'axis',
+            },
+            legend: {
+                data: ['邮件', '媒体', '资源']
+            },
+            grid: {
+                left: '3%',
+                right: '4%',
+                bottom: '3%',
+                containLabel: true
+            },
+            xAxis: [{
+                type: 'category',
+                boundaryGap: true,
+                data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
+            }],
+
+            yAxis: [{
+                type: 'value'
+            }],
+            series: [
+                {
+                    name: '邮件',
+                    type: 'line',
+                    stack: '总量',
+                    areaStyle: { normal: {} },
+                    data: [120, 132, 101, 134, 90, 230, 210],
+                    itemStyle: {
+                        normal: {
+                            color: '#59aea2'
+                        },
+                        emphasis: {
+
+                        }
+                    }
+                },
+                {
+                    name: '媒体',
+                    type: 'line',
+                    stack: '总量',
+                    areaStyle: { normal: {} },
+                    data: [220, 182, 191, 234, 290, 330, 310],
+                    itemStyle: {
+                        normal: {
+                            color: '#e7505a'
+                        }
+                    }
+                },
+                {
+                    name: '资源',
+                    type: 'line',
+                    stack: '总量',
+                    areaStyle: { normal: {} },
+                    data: [150, 232, 201, 154, 190, 330, 410],
+                    itemStyle: {
+                        normal: {
+                            color: '#32c5d2'
+                        }
+                    }
+                }
+            ]
+        };
+
+        // 通过WebSocket获取数据并刷新图表
+        var ws = new WebSocket('ws://localhost:8888/ws/charts');
+        ws.onmessage = function(evt) {
+            var array = JSON.parse(evt.data);
+            for (var i = 0; i < array.length; ++i) {
+                option.series[i].data = array[i];
+            }
+            echartsA.setOption(option);
+        };
+    }
+}
+
+
+// 风格切换
+
+$('.tpl-skiner-toggle').on('click', function() {
+    $('.tpl-skiner').toggleClass('active');
+})
+
+$('.tpl-skiner-content-bar').find('span').on('click', function() {
+    $('body').attr('class', $(this).attr('data-color'))
+    saveSelectColor.Color = $(this).attr('data-color');
+    // 保存选择项
+    storageSave(saveSelectColor);
+
+})
+
+
+
+
+// 侧边菜单开关
+
+
+function autoLeftNav() {
+    $('.tpl-header-switch-button').on('click', function() {
+        if ($('.left-sidebar').is('.active')) {
+            if ($(window).width() > 1024) {
+                $('.tpl-content-wrapper').removeClass('active');
+            }
+            $('.left-sidebar').removeClass('active');
+        } else {
+
+            $('.left-sidebar').addClass('active');
+            if ($(window).width() > 1024) {
+                $('.tpl-content-wrapper').addClass('active');
+            }
+        }
+    })
+
+    if ($(window).width() < 1024) {
+        $('.left-sidebar').addClass('active');
+    } else {
+        $('.left-sidebar').removeClass('active');
+    }
+}
+
+
+// 侧边菜单
+$('.sidebar-nav-sub-title').on('click', function() {
+    $(this).siblings('.sidebar-nav-sub').slideToggle(80)
+        .end()
+        .find('.sidebar-nav-sub-ico').toggleClass('sidebar-nav-sub-ico-rotate');
+})

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
Day61-65/code/project_of_tornado/assets/js/dataTables.responsive.min.js


Різницю між файлами не показано, бо вона завелика
+ 0 - 0
Day61-65/code/project_of_tornado/assets/js/echarts.min.js


Різницю між файлами не показано, бо вона завелика
+ 5 - 0
Day61-65/code/project_of_tornado/assets/js/fullcalendar.min.js


Різницю між файлами не показано, бо вона завелика
+ 3 - 0
Day61-65/code/project_of_tornado/assets/js/jquery.min.js


+ 4234 - 0
Day61-65/code/project_of_tornado/assets/js/moment.js

@@ -0,0 +1,4234 @@
+//! moment.js
+//! version : 2.15.1
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+
+;(function (global, factory) {
+    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+    typeof define === 'function' && define.amd ? define(factory) :
+    global.moment = factory()
+}(this, function () { 'use strict';
+
+    var hookCallback;
+
+    function utils_hooks__hooks () {
+        return hookCallback.apply(null, arguments);
+    }
+
+    // This is done to register the method called with moment()
+    // without creating circular dependencies.
+    function setHookCallback (callback) {
+        hookCallback = callback;
+    }
+
+    function isArray(input) {
+        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
+    }
+
+    function isObject(input) {
+        // IE8 will treat undefined and null as object if it wasn't for
+        // input != null
+        return input != null && Object.prototype.toString.call(input) === '[object Object]';
+    }
+
+    function isObjectEmpty(obj) {
+        var k;
+        for (k in obj) {
+            // even if its not own property I'd still call it non-empty
+            return false;
+        }
+        return true;
+    }
+
+    function isDate(input) {
+        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
+    }
+
+    function map(arr, fn) {
+        var res = [], i;
+        for (i = 0; i < arr.length; ++i) {
+            res.push(fn(arr[i], i));
+        }
+        return res;
+    }
+
+    function hasOwnProp(a, b) {
+        return Object.prototype.hasOwnProperty.call(a, b);
+    }
+
+    function extend(a, b) {
+        for (var i in b) {
+            if (hasOwnProp(b, i)) {
+                a[i] = b[i];
+            }
+        }
+
+        if (hasOwnProp(b, 'toString')) {
+            a.toString = b.toString;
+        }
+
+        if (hasOwnProp(b, 'valueOf')) {
+            a.valueOf = b.valueOf;
+        }
+
+        return a;
+    }
+
+    function create_utc__createUTC (input, format, locale, strict) {
+        return createLocalOrUTC(input, format, locale, strict, true).utc();
+    }
+
+    function defaultParsingFlags() {
+        // We need to deep clone this object.
+        return {
+            empty           : false,
+            unusedTokens    : [],
+            unusedInput     : [],
+            overflow        : -2,
+            charsLeftOver   : 0,
+            nullInput       : false,
+            invalidMonth    : null,
+            invalidFormat   : false,
+            userInvalidated : false,
+            iso             : false,
+            parsedDateParts : [],
+            meridiem        : null
+        };
+    }
+
+    function getParsingFlags(m) {
+        if (m._pf == null) {
+            m._pf = defaultParsingFlags();
+        }
+        return m._pf;
+    }
+
+    var some;
+    if (Array.prototype.some) {
+        some = Array.prototype.some;
+    } else {
+        some = function (fun) {
+            var t = Object(this);
+            var len = t.length >>> 0;
+
+            for (var i = 0; i < len; i++) {
+                if (i in t && fun.call(this, t[i], i, t)) {
+                    return true;
+                }
+            }
+
+            return false;
+        };
+    }
+
+    function valid__isValid(m) {
+        if (m._isValid == null) {
+            var flags = getParsingFlags(m);
+            var parsedParts = some.call(flags.parsedDateParts, function (i) {
+                return i != null;
+            });
+            var isNowValid = !isNaN(m._d.getTime()) &&
+                flags.overflow < 0 &&
+                !flags.empty &&
+                !flags.invalidMonth &&
+                !flags.invalidWeekday &&
+                !flags.nullInput &&
+                !flags.invalidFormat &&
+                !flags.userInvalidated &&
+                (!flags.meridiem || (flags.meridiem && parsedParts));
+
+            if (m._strict) {
+                isNowValid = isNowValid &&
+                    flags.charsLeftOver === 0 &&
+                    flags.unusedTokens.length === 0 &&
+                    flags.bigHour === undefined;
+            }
+
+            if (Object.isFrozen == null || !Object.isFrozen(m)) {
+                m._isValid = isNowValid;
+            }
+            else {
+                return isNowValid;
+            }
+        }
+        return m._isValid;
+    }
+
+    function valid__createInvalid (flags) {
+        var m = create_utc__createUTC(NaN);
+        if (flags != null) {
+            extend(getParsingFlags(m), flags);
+        }
+        else {
+            getParsingFlags(m).userInvalidated = true;
+        }
+
+        return m;
+    }
+
+    function isUndefined(input) {
+        return input === void 0;
+    }
+
+    // Plugins that add properties should also add the key here (null value),
+    // so we can properly clone ourselves.
+    var momentProperties = utils_hooks__hooks.momentProperties = [];
+
+    function copyConfig(to, from) {
+        var i, prop, val;
+
+        if (!isUndefined(from._isAMomentObject)) {
+            to._isAMomentObject = from._isAMomentObject;
+        }
+        if (!isUndefined(from._i)) {
+            to._i = from._i;
+        }
+        if (!isUndefined(from._f)) {
+            to._f = from._f;
+        }
+        if (!isUndefined(from._l)) {
+            to._l = from._l;
+        }
+        if (!isUndefined(from._strict)) {
+            to._strict = from._strict;
+        }
+        if (!isUndefined(from._tzm)) {
+            to._tzm = from._tzm;
+        }
+        if (!isUndefined(from._isUTC)) {
+            to._isUTC = from._isUTC;
+        }
+        if (!isUndefined(from._offset)) {
+            to._offset = from._offset;
+        }
+        if (!isUndefined(from._pf)) {
+            to._pf = getParsingFlags(from);
+        }
+        if (!isUndefined(from._locale)) {
+            to._locale = from._locale;
+        }
+
+        if (momentProperties.length > 0) {
+            for (i in momentProperties) {
+                prop = momentProperties[i];
+                val = from[prop];
+                if (!isUndefined(val)) {
+                    to[prop] = val;
+                }
+            }
+        }
+
+        return to;
+    }
+
+    var updateInProgress = false;
+
+    // Moment prototype object
+    function Moment(config) {
+        copyConfig(this, config);
+        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
+        // Prevent infinite loop in case updateOffset creates new moment
+        // objects.
+        if (updateInProgress === false) {
+            updateInProgress = true;
+            utils_hooks__hooks.updateOffset(this);
+            updateInProgress = false;
+        }
+    }
+
+    function isMoment (obj) {
+        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
+    }
+
+    function absFloor (number) {
+        if (number < 0) {
+            // -0 -> 0
+            return Math.ceil(number) || 0;
+        } else {
+            return Math.floor(number);
+        }
+    }
+
+    function toInt(argumentForCoercion) {
+        var coercedNumber = +argumentForCoercion,
+            value = 0;
+
+        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
+            value = absFloor(coercedNumber);
+        }
+
+        return value;
+    }
+
+    // compare two arrays, return the number of differences
+    function compareArrays(array1, array2, dontConvert) {
+        var len = Math.min(array1.length, array2.length),
+            lengthDiff = Math.abs(array1.length - array2.length),
+            diffs = 0,
+            i;
+        for (i = 0; i < len; i++) {
+            if ((dontConvert && array1[i] !== array2[i]) ||
+                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
+                diffs++;
+            }
+        }
+        return diffs + lengthDiff;
+    }
+
+    function warn(msg) {
+        if (utils_hooks__hooks.suppressDeprecationWarnings === false &&
+                (typeof console !==  'undefined') && console.warn) {
+            console.warn('Deprecation warning: ' + msg);
+        }
+    }
+
+    function deprecate(msg, fn) {
+        var firstTime = true;
+
+        return extend(function () {
+            if (utils_hooks__hooks.deprecationHandler != null) {
+                utils_hooks__hooks.deprecationHandler(null, msg);
+            }
+            if (firstTime) {
+                var args = [];
+                var arg;
+                for (var i = 0; i < arguments.length; i++) {
+                    arg = '';
+                    if (typeof arguments[i] === 'object') {
+                        arg += '\n[' + i + '] ';
+                        for (var key in arguments[0]) {
+                            arg += key + ': ' + arguments[0][key] + ', ';
+                        }
+                        arg = arg.slice(0, -2); // Remove trailing comma and space
+                    } else {
+                        arg = arguments[i];
+                    }
+                    args.push(arg);
+                }
+                warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
+                firstTime = false;
+            }
+            return fn.apply(this, arguments);
+        }, fn);
+    }
+
+    var deprecations = {};
+
+    function deprecateSimple(name, msg) {
+        if (utils_hooks__hooks.deprecationHandler != null) {
+            utils_hooks__hooks.deprecationHandler(name, msg);
+        }
+        if (!deprecations[name]) {
+            warn(msg);
+            deprecations[name] = true;
+        }
+    }
+
+    utils_hooks__hooks.suppressDeprecationWarnings = false;
+    utils_hooks__hooks.deprecationHandler = null;
+
+    function isFunction(input) {
+        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
+    }
+
+    function locale_set__set (config) {
+        var prop, i;
+        for (i in config) {
+            prop = config[i];
+            if (isFunction(prop)) {
+                this[i] = prop;
+            } else {
+                this['_' + i] = prop;
+            }
+        }
+        this._config = config;
+        // Lenient ordinal parsing accepts just a number in addition to
+        // number + (possibly) stuff coming from _ordinalParseLenient.
+        this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source);
+    }
+
+    function mergeConfigs(parentConfig, childConfig) {
+        var res = extend({}, parentConfig), prop;
+        for (prop in childConfig) {
+            if (hasOwnProp(childConfig, prop)) {
+                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
+                    res[prop] = {};
+                    extend(res[prop], parentConfig[prop]);
+                    extend(res[prop], childConfig[prop]);
+                } else if (childConfig[prop] != null) {
+                    res[prop] = childConfig[prop];
+                } else {
+                    delete res[prop];
+                }
+            }
+        }
+        for (prop in parentConfig) {
+            if (hasOwnProp(parentConfig, prop) &&
+                    !hasOwnProp(childConfig, prop) &&
+                    isObject(parentConfig[prop])) {
+                // make sure changes to properties don't modify parent config
+                res[prop] = extend({}, res[prop]);
+            }
+        }
+        return res;
+    }
+
+    function Locale(config) {
+        if (config != null) {
+            this.set(config);
+        }
+    }
+
+    var keys;
+
+    if (Object.keys) {
+        keys = Object.keys;
+    } else {
+        keys = function (obj) {
+            var i, res = [];
+            for (i in obj) {
+                if (hasOwnProp(obj, i)) {
+                    res.push(i);
+                }
+            }
+            return res;
+        };
+    }
+
+    var defaultCalendar = {
+        sameDay : '[Today at] LT',
+        nextDay : '[Tomorrow at] LT',
+        nextWeek : 'dddd [at] LT',
+        lastDay : '[Yesterday at] LT',
+        lastWeek : '[Last] dddd [at] LT',
+        sameElse : 'L'
+    };
+
+    function locale_calendar__calendar (key, mom, now) {
+        var output = this._calendar[key] || this._calendar['sameElse'];
+        return isFunction(output) ? output.call(mom, now) : output;
+    }
+
+    var defaultLongDateFormat = {
+        LTS  : 'h:mm:ss A',
+        LT   : 'h:mm A',
+        L    : 'MM/DD/YYYY',
+        LL   : 'MMMM D, YYYY',
+        LLL  : 'MMMM D, YYYY h:mm A',
+        LLLL : 'dddd, MMMM D, YYYY h:mm A'
+    };
+
+    function longDateFormat (key) {
+        var format = this._longDateFormat[key],
+            formatUpper = this._longDateFormat[key.toUpperCase()];
+
+        if (format || !formatUpper) {
+            return format;
+        }
+
+        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
+            return val.slice(1);
+        });
+
+        return this._longDateFormat[key];
+    }
+
+    var defaultInvalidDate = 'Invalid date';
+
+    function invalidDate () {
+        return this._invalidDate;
+    }
+
+    var defaultOrdinal = '%d';
+    var defaultOrdinalParse = /\d{1,2}/;
+
+    function ordinal (number) {
+        return this._ordinal.replace('%d', number);
+    }
+
+    var defaultRelativeTime = {
+        future : 'in %s',
+        past   : '%s ago',
+        s  : 'a few seconds',
+        m  : 'a minute',
+        mm : '%d minutes',
+        h  : 'an hour',
+        hh : '%d hours',
+        d  : 'a day',
+        dd : '%d days',
+        M  : 'a month',
+        MM : '%d months',
+        y  : 'a year',
+        yy : '%d years'
+    };
+
+    function relative__relativeTime (number, withoutSuffix, string, isFuture) {
+        var output = this._relativeTime[string];
+        return (isFunction(output)) ?
+            output(number, withoutSuffix, string, isFuture) :
+            output.replace(/%d/i, number);
+    }
+
+    function pastFuture (diff, output) {
+        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
+        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
+    }
+
+    var aliases = {};
+
+    function addUnitAlias (unit, shorthand) {
+        var lowerCase = unit.toLowerCase();
+        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
+    }
+
+    function normalizeUnits(units) {
+        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
+    }
+
+    function normalizeObjectUnits(inputObject) {
+        var normalizedInput = {},
+            normalizedProp,
+            prop;
+
+        for (prop in inputObject) {
+            if (hasOwnProp(inputObject, prop)) {
+                normalizedProp = normalizeUnits(prop);
+                if (normalizedProp) {
+                    normalizedInput[normalizedProp] = inputObject[prop];
+                }
+            }
+        }
+
+        return normalizedInput;
+    }
+
+    var priorities = {};
+
+    function addUnitPriority(unit, priority) {
+        priorities[unit] = priority;
+    }
+
+    function getPrioritizedUnits(unitsObj) {
+        var units = [];
+        for (var u in unitsObj) {
+            units.push({unit: u, priority: priorities[u]});
+        }
+        units.sort(function (a, b) {
+            return a.priority - b.priority;
+        });
+        return units;
+    }
+
+    function makeGetSet (unit, keepTime) {
+        return function (value) {
+            if (value != null) {
+                get_set__set(this, unit, value);
+                utils_hooks__hooks.updateOffset(this, keepTime);
+                return this;
+            } else {
+                return get_set__get(this, unit);
+            }
+        };
+    }
+
+    function get_set__get (mom, unit) {
+        return mom.isValid() ?
+            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
+    }
+
+    function get_set__set (mom, unit, value) {
+        if (mom.isValid()) {
+            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
+        }
+    }
+
+    // MOMENTS
+
+    function stringGet (units) {
+        units = normalizeUnits(units);
+        if (isFunction(this[units])) {
+            return this[units]();
+        }
+        return this;
+    }
+
+
+    function stringSet (units, value) {
+        if (typeof units === 'object') {
+            units = normalizeObjectUnits(units);
+            var prioritized = getPrioritizedUnits(units);
+            for (var i = 0; i < prioritized.length; i++) {
+                this[prioritized[i].unit](units[prioritized[i].unit]);
+            }
+        } else {
+            units = normalizeUnits(units);
+            if (isFunction(this[units])) {
+                return this[units](value);
+            }
+        }
+        return this;
+    }
+
+    function zeroFill(number, targetLength, forceSign) {
+        var absNumber = '' + Math.abs(number),
+            zerosToFill = targetLength - absNumber.length,
+            sign = number >= 0;
+        return (sign ? (forceSign ? '+' : '') : '-') +
+            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
+    }
+
+    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;
+
+    var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
+
+    var formatFunctions = {};
+
+    var formatTokenFunctions = {};
+
+    // token:    'M'
+    // padded:   ['MM', 2]
+    // ordinal:  'Mo'
+    // callback: function () { this.month() + 1 }
+    function addFormatToken (token, padded, ordinal, callback) {
+        var func = callback;
+        if (typeof callback === 'string') {
+            func = function () {
+                return this[callback]();
+            };
+        }
+        if (token) {
+            formatTokenFunctions[token] = func;
+        }
+        if (padded) {
+            formatTokenFunctions[padded[0]] = function () {
+                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
+            };
+        }
+        if (ordinal) {
+            formatTokenFunctions[ordinal] = function () {
+                return this.localeData().ordinal(func.apply(this, arguments), token);
+            };
+        }
+    }
+
+    function removeFormattingTokens(input) {
+        if (input.match(/\[[\s\S]/)) {
+            return input.replace(/^\[|\]$/g, '');
+        }
+        return input.replace(/\\/g, '');
+    }
+
+    function makeFormatFunction(format) {
+        var array = format.match(formattingTokens), i, length;
+
+        for (i = 0, length = array.length; i < length; i++) {
+            if (formatTokenFunctions[array[i]]) {
+                array[i] = formatTokenFunctions[array[i]];
+            } else {
+                array[i] = removeFormattingTokens(array[i]);
+            }
+        }
+
+        return function (mom) {
+            var output = '', i;
+            for (i = 0; i < length; i++) {
+                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
+            }
+            return output;
+        };
+    }
+
+    // format date using native date object
+    function formatMoment(m, format) {
+        if (!m.isValid()) {
+            return m.localeData().invalidDate();
+        }
+
+        format = expandFormat(format, m.localeData());
+        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
+
+        return formatFunctions[format](m);
+    }
+
+    function expandFormat(format, locale) {
+        var i = 5;
+
+        function replaceLongDateFormatTokens(input) {
+            return locale.longDateFormat(input) || input;
+        }
+
+        localFormattingTokens.lastIndex = 0;
+        while (i >= 0 && localFormattingTokens.test(format)) {
+            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
+            localFormattingTokens.lastIndex = 0;
+            i -= 1;
+        }
+
+        return format;
+    }
+
+    var match1         = /\d/;            //       0 - 9
+    var match2         = /\d\d/;          //      00 - 99
+    var match3         = /\d{3}/;         //     000 - 999
+    var match4         = /\d{4}/;         //    0000 - 9999
+    var match6         = /[+-]?\d{6}/;    // -999999 - 999999
+    var match1to2      = /\d\d?/;         //       0 - 99
+    var match3to4      = /\d\d\d\d?/;     //     999 - 9999
+    var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
+    var match1to3      = /\d{1,3}/;       //       0 - 999
+    var match1to4      = /\d{1,4}/;       //       0 - 9999
+    var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999
+
+    var matchUnsigned  = /\d+/;           //       0 - inf
+    var matchSigned    = /[+-]?\d+/;      //    -inf - inf
+
+    var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
+    var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
+
+    var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
+
+    // any word (or two) characters or numbers including two/three word month in arabic.
+    // includes scottish gaelic two word and hyphenated months
+    var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
+
+
+    var regexes = {};
+
+    function addRegexToken (token, regex, strictRegex) {
+        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
+            return (isStrict && strictRegex) ? strictRegex : regex;
+        };
+    }
+
+    function getParseRegexForToken (token, config) {
+        if (!hasOwnProp(regexes, token)) {
+            return new RegExp(unescapeFormat(token));
+        }
+
+        return regexes[token](config._strict, config._locale);
+    }
+
+    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
+    function unescapeFormat(s) {
+        return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
+            return p1 || p2 || p3 || p4;
+        }));
+    }
+
+    function regexEscape(s) {
+        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+    }
+
+    var tokens = {};
+
+    function addParseToken (token, callback) {
+        var i, func = callback;
+        if (typeof token === 'string') {
+            token = [token];
+        }
+        if (typeof callback === 'number') {
+            func = function (input, array) {
+                array[callback] = toInt(input);
+            };
+        }
+        for (i = 0; i < token.length; i++) {
+            tokens[token[i]] = func;
+        }
+    }
+
+    function addWeekParseToken (token, callback) {
+        addParseToken(token, function (input, array, config, token) {
+            config._w = config._w || {};
+            callback(input, config._w, config, token);
+        });
+    }
+
+    function addTimeToArrayFromToken(token, input, config) {
+        if (input != null && hasOwnProp(tokens, token)) {
+            tokens[token](input, config._a, config, token);
+        }
+    }
+
+    var YEAR = 0;
+    var MONTH = 1;
+    var DATE = 2;
+    var HOUR = 3;
+    var MINUTE = 4;
+    var SECOND = 5;
+    var MILLISECOND = 6;
+    var WEEK = 7;
+    var WEEKDAY = 8;
+
+    var indexOf;
+
+    if (Array.prototype.indexOf) {
+        indexOf = Array.prototype.indexOf;
+    } else {
+        indexOf = function (o) {
+            // I know
+            var i;
+            for (i = 0; i < this.length; ++i) {
+                if (this[i] === o) {
+                    return i;
+                }
+            }
+            return -1;
+        };
+    }
+
+    function daysInMonth(year, month) {
+        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
+    }
+
+    // FORMATTING
+
+    addFormatToken('M', ['MM', 2], 'Mo', function () {
+        return this.month() + 1;
+    });
+
+    addFormatToken('MMM', 0, 0, function (format) {
+        return this.localeData().monthsShort(this, format);
+    });
+
+    addFormatToken('MMMM', 0, 0, function (format) {
+        return this.localeData().months(this, format);
+    });
+
+    // ALIASES
+
+    addUnitAlias('month', 'M');
+
+    // PRIORITY
+
+    addUnitPriority('month', 8);
+
+    // PARSING
+
+    addRegexToken('M',    match1to2);
+    addRegexToken('MM',   match1to2, match2);
+    addRegexToken('MMM',  function (isStrict, locale) {
+        return locale.monthsShortRegex(isStrict);
+    });
+    addRegexToken('MMMM', function (isStrict, locale) {
+        return locale.monthsRegex(isStrict);
+    });
+
+    addParseToken(['M', 'MM'], function (input, array) {
+        array[MONTH] = toInt(input) - 1;
+    });
+
+    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
+        var month = config._locale.monthsParse(input, token, config._strict);
+        // if we didn't find a month name, mark the date as invalid.
+        if (month != null) {
+            array[MONTH] = month;
+        } else {
+            getParsingFlags(config).invalidMonth = input;
+        }
+    });
+
+    // LOCALES
+
+    var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/;
+    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
+    function localeMonths (m, format) {
+        if (!m) {
+            return this._months;
+        }
+        return isArray(this._months) ? this._months[m.month()] :
+            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
+    }
+
+    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
+    function localeMonthsShort (m, format) {
+        if (!m) {
+            return this._monthsShort;
+        }
+        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
+            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
+    }
+
+    function units_month__handleStrictParse(monthName, format, strict) {
+        var i, ii, mom, llc = monthName.toLocaleLowerCase();
+        if (!this._monthsParse) {
+            // this is not used
+            this._monthsParse = [];
+            this._longMonthsParse = [];
+            this._shortMonthsParse = [];
+            for (i = 0; i < 12; ++i) {
+                mom = create_utc__createUTC([2000, i]);
+                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
+                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
+            }
+        }
+
+        if (strict) {
+            if (format === 'MMM') {
+                ii = indexOf.call(this._shortMonthsParse, llc);
+                return ii !== -1 ? ii : null;
+            } else {
+                ii = indexOf.call(this._longMonthsParse, llc);
+                return ii !== -1 ? ii : null;
+            }
+        } else {
+            if (format === 'MMM') {
+                ii = indexOf.call(this._shortMonthsParse, llc);
+                if (ii !== -1) {
+                    return ii;
+                }
+                ii = indexOf.call(this._longMonthsParse, llc);
+                return ii !== -1 ? ii : null;
+            } else {
+                ii = indexOf.call(this._longMonthsParse, llc);
+                if (ii !== -1) {
+                    return ii;
+                }
+                ii = indexOf.call(this._shortMonthsParse, llc);
+                return ii !== -1 ? ii : null;
+            }
+        }
+    }
+
+    function localeMonthsParse (monthName, format, strict) {
+        var i, mom, regex;
+
+        if (this._monthsParseExact) {
+            return units_month__handleStrictParse.call(this, monthName, format, strict);
+        }
+
+        if (!this._monthsParse) {
+            this._monthsParse = [];
+            this._longMonthsParse = [];
+            this._shortMonthsParse = [];
+        }
+
+        // TODO: add sorting
+        // Sorting makes sure if one month (or abbr) is a prefix of another
+        // see sorting in computeMonthsParse
+        for (i = 0; i < 12; i++) {
+            // make the regex if we don't have it already
+            mom = create_utc__createUTC([2000, i]);
+            if (strict && !this._longMonthsParse[i]) {
+                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
+                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
+            }
+            if (!strict && !this._monthsParse[i]) {
+                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
+                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
+            }
+            // test the regex
+            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
+                return i;
+            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
+                return i;
+            } else if (!strict && this._monthsParse[i].test(monthName)) {
+                return i;
+            }
+        }
+    }
+
+    // MOMENTS
+
+    function setMonth (mom, value) {
+        var dayOfMonth;
+
+        if (!mom.isValid()) {
+            // No op
+            return mom;
+        }
+
+        if (typeof value === 'string') {
+            if (/^\d+$/.test(value)) {
+                value = toInt(value);
+            } else {
+                value = mom.localeData().monthsParse(value);
+                // TODO: Another silent failure?
+                if (typeof value !== 'number') {
+                    return mom;
+                }
+            }
+        }
+
+        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
+        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
+        return mom;
+    }
+
+    function getSetMonth (value) {
+        if (value != null) {
+            setMonth(this, value);
+            utils_hooks__hooks.updateOffset(this, true);
+            return this;
+        } else {
+            return get_set__get(this, 'Month');
+        }
+    }
+
+    function getDaysInMonth () {
+        return daysInMonth(this.year(), this.month());
+    }
+
+    var defaultMonthsShortRegex = matchWord;
+    function monthsShortRegex (isStrict) {
+        if (this._monthsParseExact) {
+            if (!hasOwnProp(this, '_monthsRegex')) {
+                computeMonthsParse.call(this);
+            }
+            if (isStrict) {
+                return this._monthsShortStrictRegex;
+            } else {
+                return this._monthsShortRegex;
+            }
+        } else {
+            if (!hasOwnProp(this, '_monthsShortRegex')) {
+                this._monthsShortRegex = defaultMonthsShortRegex;
+            }
+            return this._monthsShortStrictRegex && isStrict ?
+                this._monthsShortStrictRegex : this._monthsShortRegex;
+        }
+    }
+
+    var defaultMonthsRegex = matchWord;
+    function monthsRegex (isStrict) {
+        if (this._monthsParseExact) {
+            if (!hasOwnProp(this, '_monthsRegex')) {
+                computeMonthsParse.call(this);
+            }
+            if (isStrict) {
+                return this._monthsStrictRegex;
+            } else {
+                return this._monthsRegex;
+            }
+        } else {
+            if (!hasOwnProp(this, '_monthsRegex')) {
+                this._monthsRegex = defaultMonthsRegex;
+            }
+            return this._monthsStrictRegex && isStrict ?
+                this._monthsStrictRegex : this._monthsRegex;
+        }
+    }
+
+    function computeMonthsParse () {
+        function cmpLenRev(a, b) {
+            return b.length - a.length;
+        }
+
+        var shortPieces = [], longPieces = [], mixedPieces = [],
+            i, mom;
+        for (i = 0; i < 12; i++) {
+            // make the regex if we don't have it already
+            mom = create_utc__createUTC([2000, i]);
+            shortPieces.push(this.monthsShort(mom, ''));
+            longPieces.push(this.months(mom, ''));
+            mixedPieces.push(this.months(mom, ''));
+            mixedPieces.push(this.monthsShort(mom, ''));
+        }
+        // Sorting makes sure if one month (or abbr) is a prefix of another it
+        // will match the longer piece.
+        shortPieces.sort(cmpLenRev);
+        longPieces.sort(cmpLenRev);
+        mixedPieces.sort(cmpLenRev);
+        for (i = 0; i < 12; i++) {
+            shortPieces[i] = regexEscape(shortPieces[i]);
+            longPieces[i] = regexEscape(longPieces[i]);
+        }
+        for (i = 0; i < 24; i++) {
+            mixedPieces[i] = regexEscape(mixedPieces[i]);
+        }
+
+        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
+        this._monthsShortRegex = this._monthsRegex;
+        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
+        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
+    }
+
+    // FORMATTING
+
+    addFormatToken('Y', 0, 0, function () {
+        var y = this.year();
+        return y <= 9999 ? '' + y : '+' + y;
+    });
+
+    addFormatToken(0, ['YY', 2], 0, function () {
+        return this.year() % 100;
+    });
+
+    addFormatToken(0, ['YYYY',   4],       0, 'year');
+    addFormatToken(0, ['YYYYY',  5],       0, 'year');
+    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
+
+    // ALIASES
+
+    addUnitAlias('year', 'y');
+
+    // PRIORITIES
+
+    addUnitPriority('year', 1);
+
+    // PARSING
+
+    addRegexToken('Y',      matchSigned);
+    addRegexToken('YY',     match1to2, match2);
+    addRegexToken('YYYY',   match1to4, match4);
+    addRegexToken('YYYYY',  match1to6, match6);
+    addRegexToken('YYYYYY', match1to6, match6);
+
+    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
+    addParseToken('YYYY', function (input, array) {
+        array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
+    });
+    addParseToken('YY', function (input, array) {
+        array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
+    });
+    addParseToken('Y', function (input, array) {
+        array[YEAR] = parseInt(input, 10);
+    });
+
+    // HELPERS
+
+    function daysInYear(year) {
+        return isLeapYear(year) ? 366 : 365;
+    }
+
+    function isLeapYear(year) {
+        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
+    }
+
+    // HOOKS
+
+    utils_hooks__hooks.parseTwoDigitYear = function (input) {
+        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
+    };
+
+    // MOMENTS
+
+    var getSetYear = makeGetSet('FullYear', true);
+
+    function getIsLeapYear () {
+        return isLeapYear(this.year());
+    }
+
+    function createDate (y, m, d, h, M, s, ms) {
+        //can't just apply() to create a date:
+        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
+        var date = new Date(y, m, d, h, M, s, ms);
+
+        //the date constructor remaps years 0-99 to 1900-1999
+        if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
+            date.setFullYear(y);
+        }
+        return date;
+    }
+
+    function createUTCDate (y) {
+        var date = new Date(Date.UTC.apply(null, arguments));
+
+        //the Date.UTC function remaps years 0-99 to 1900-1999
+        if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
+            date.setUTCFullYear(y);
+        }
+        return date;
+    }
+
+    // start-of-first-week - start-of-year
+    function firstWeekOffset(year, dow, doy) {
+        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
+            fwd = 7 + dow - doy,
+            // first-week day local weekday -- which local weekday is fwd
+            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
+
+        return -fwdlw + fwd - 1;
+    }
+
+    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
+    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
+        var localWeekday = (7 + weekday - dow) % 7,
+            weekOffset = firstWeekOffset(year, dow, doy),
+            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
+            resYear, resDayOfYear;
+
+        if (dayOfYear <= 0) {
+            resYear = year - 1;
+            resDayOfYear = daysInYear(resYear) + dayOfYear;
+        } else if (dayOfYear > daysInYear(year)) {
+            resYear = year + 1;
+            resDayOfYear = dayOfYear - daysInYear(year);
+        } else {
+            resYear = year;
+            resDayOfYear = dayOfYear;
+        }
+
+        return {
+            year: resYear,
+            dayOfYear: resDayOfYear
+        };
+    }
+
+    function weekOfYear(mom, dow, doy) {
+        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
+            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
+            resWeek, resYear;
+
+        if (week < 1) {
+            resYear = mom.year() - 1;
+            resWeek = week + weeksInYear(resYear, dow, doy);
+        } else if (week > weeksInYear(mom.year(), dow, doy)) {
+            resWeek = week - weeksInYear(mom.year(), dow, doy);
+            resYear = mom.year() + 1;
+        } else {
+            resYear = mom.year();
+            resWeek = week;
+        }
+
+        return {
+            week: resWeek,
+            year: resYear
+        };
+    }
+
+    function weeksInYear(year, dow, doy) {
+        var weekOffset = firstWeekOffset(year, dow, doy),
+            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
+        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
+    }
+
+    // FORMATTING
+
+    addFormatToken('w', ['ww', 2], 'wo', 'week');
+    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
+
+    // ALIASES
+
+    addUnitAlias('week', 'w');
+    addUnitAlias('isoWeek', 'W');
+
+    // PRIORITIES
+
+    addUnitPriority('week', 5);
+    addUnitPriority('isoWeek', 5);
+
+    // PARSING
+
+    addRegexToken('w',  match1to2);
+    addRegexToken('ww', match1to2, match2);
+    addRegexToken('W',  match1to2);
+    addRegexToken('WW', match1to2, match2);
+
+    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
+        week[token.substr(0, 1)] = toInt(input);
+    });
+
+    // HELPERS
+
+    // LOCALES
+
+    function localeWeek (mom) {
+        return weekOfYear(mom, this._week.dow, this._week.doy).week;
+    }
+
+    var defaultLocaleWeek = {
+        dow : 0, // Sunday is the first day of the week.
+        doy : 6  // The week that contains Jan 1st is the first week of the year.
+    };
+
+    function localeFirstDayOfWeek () {
+        return this._week.dow;
+    }
+
+    function localeFirstDayOfYear () {
+        return this._week.doy;
+    }
+
+    // MOMENTS
+
+    function getSetWeek (input) {
+        var week = this.localeData().week(this);
+        return input == null ? week : this.add((input - week) * 7, 'd');
+    }
+
+    function getSetISOWeek (input) {
+        var week = weekOfYear(this, 1, 4).week;
+        return input == null ? week : this.add((input - week) * 7, 'd');
+    }
+
+    // FORMATTING
+
+    addFormatToken('d', 0, 'do', 'day');
+
+    addFormatToken('dd', 0, 0, function (format) {
+        return this.localeData().weekdaysMin(this, format);
+    });
+
+    addFormatToken('ddd', 0, 0, function (format) {
+        return this.localeData().weekdaysShort(this, format);
+    });
+
+    addFormatToken('dddd', 0, 0, function (format) {
+        return this.localeData().weekdays(this, format);
+    });
+
+    addFormatToken('e', 0, 0, 'weekday');
+    addFormatToken('E', 0, 0, 'isoWeekday');
+
+    // ALIASES
+
+    addUnitAlias('day', 'd');
+    addUnitAlias('weekday', 'e');
+    addUnitAlias('isoWeekday', 'E');
+
+    // PRIORITY
+    addUnitPriority('day', 11);
+    addUnitPriority('weekday', 11);
+    addUnitPriority('isoWeekday', 11);
+
+    // PARSING
+
+    addRegexToken('d',    match1to2);
+    addRegexToken('e',    match1to2);
+    addRegexToken('E',    match1to2);
+    addRegexToken('dd',   function (isStrict, locale) {
+        return locale.weekdaysMinRegex(isStrict);
+    });
+    addRegexToken('ddd',   function (isStrict, locale) {
+        return locale.weekdaysShortRegex(isStrict);
+    });
+    addRegexToken('dddd',   function (isStrict, locale) {
+        return locale.weekdaysRegex(isStrict);
+    });
+
+    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
+        var weekday = config._locale.weekdaysParse(input, token, config._strict);
+        // if we didn't get a weekday name, mark the date as invalid
+        if (weekday != null) {
+            week.d = weekday;
+        } else {
+            getParsingFlags(config).invalidWeekday = input;
+        }
+    });
+
+    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
+        week[token] = toInt(input);
+    });
+
+    // HELPERS
+
+    function parseWeekday(input, locale) {
+        if (typeof input !== 'string') {
+            return input;
+        }
+
+        if (!isNaN(input)) {
+            return parseInt(input, 10);
+        }
+
+        input = locale.weekdaysParse(input);
+        if (typeof input === 'number') {
+            return input;
+        }
+
+        return null;
+    }
+
+    function parseIsoWeekday(input, locale) {
+        if (typeof input === 'string') {
+            return locale.weekdaysParse(input) % 7 || 7;
+        }
+        return isNaN(input) ? null : input;
+    }
+
+    // LOCALES
+
+    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
+    function localeWeekdays (m, format) {
+        if (!m) {
+            return this._weekdays;
+        }
+        return isArray(this._weekdays) ? this._weekdays[m.day()] :
+            this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
+    }
+
+    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
+    function localeWeekdaysShort (m) {
+        return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
+    }
+
+    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
+    function localeWeekdaysMin (m) {
+        return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
+    }
+
+    function day_of_week__handleStrictParse(weekdayName, format, strict) {
+        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
+        if (!this._weekdaysParse) {
+            this._weekdaysParse = [];
+            this._shortWeekdaysParse = [];
+            this._minWeekdaysParse = [];
+
+            for (i = 0; i < 7; ++i) {
+                mom = create_utc__createUTC([2000, 1]).day(i);
+                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
+                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
+                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
+            }
+        }
+
+        if (strict) {
+            if (format === 'dddd') {
+                ii = indexOf.call(this._weekdaysParse, llc);
+                return ii !== -1 ? ii : null;
+            } else if (format === 'ddd') {
+                ii = indexOf.call(this._shortWeekdaysParse, llc);
+                return ii !== -1 ? ii : null;
+            } else {
+                ii = indexOf.call(this._minWeekdaysParse, llc);
+                return ii !== -1 ? ii : null;
+            }
+        } else {
+            if (format === 'dddd') {
+                ii = indexOf.call(this._weekdaysParse, llc);
+                if (ii !== -1) {
+                    return ii;
+                }
+                ii = indexOf.call(this._shortWeekdaysParse, llc);
+                if (ii !== -1) {
+                    return ii;
+                }
+                ii = indexOf.call(this._minWeekdaysParse, llc);
+                return ii !== -1 ? ii : null;
+            } else if (format === 'ddd') {
+                ii = indexOf.call(this._shortWeekdaysParse, llc);
+                if (ii !== -1) {
+                    return ii;
+                }
+                ii = indexOf.call(this._weekdaysParse, llc);
+                if (ii !== -1) {
+                    return ii;
+                }
+                ii = indexOf.call(this._minWeekdaysParse, llc);
+                return ii !== -1 ? ii : null;
+            } else {
+                ii = indexOf.call(this._minWeekdaysParse, llc);
+                if (ii !== -1) {
+                    return ii;
+                }
+                ii = indexOf.call(this._weekdaysParse, llc);
+                if (ii !== -1) {
+                    return ii;
+                }
+                ii = indexOf.call(this._shortWeekdaysParse, llc);
+                return ii !== -1 ? ii : null;
+            }
+        }
+    }
+
+    function localeWeekdaysParse (weekdayName, format, strict) {
+        var i, mom, regex;
+
+        if (this._weekdaysParseExact) {
+            return day_of_week__handleStrictParse.call(this, weekdayName, format, strict);
+        }
+
+        if (!this._weekdaysParse) {
+            this._weekdaysParse = [];
+            this._minWeekdaysParse = [];
+            this._shortWeekdaysParse = [];
+            this._fullWeekdaysParse = [];
+        }
+
+        for (i = 0; i < 7; i++) {
+            // make the regex if we don't have it already
+
+            mom = create_utc__createUTC([2000, 1]).day(i);
+            if (strict && !this._fullWeekdaysParse[i]) {
+                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
+                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
+                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
+            }
+            if (!this._weekdaysParse[i]) {
+                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
+                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
+            }
+            // test the regex
+            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
+                return i;
+            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
+                return i;
+            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
+                return i;
+            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
+                return i;
+            }
+        }
+    }
+
+    // MOMENTS
+
+    function getSetDayOfWeek (input) {
+        if (!this.isValid()) {
+            return input != null ? this : NaN;
+        }
+        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
+        if (input != null) {
+            input = parseWeekday(input, this.localeData());
+            return this.add(input - day, 'd');
+        } else {
+            return day;
+        }
+    }
+
+    function getSetLocaleDayOfWeek (input) {
+        if (!this.isValid()) {
+            return input != null ? this : NaN;
+        }
+        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
+        return input == null ? weekday : this.add(input - weekday, 'd');
+    }
+
+    function getSetISODayOfWeek (input) {
+        if (!this.isValid()) {
+            return input != null ? this : NaN;
+        }
+
+        // behaves the same as moment#day except
+        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
+        // as a setter, sunday should belong to the previous week.
+
+        if (input != null) {
+            var weekday = parseIsoWeekday(input, this.localeData());
+            return this.day(this.day() % 7 ? weekday : weekday - 7);
+        } else {
+            return this.day() || 7;
+        }
+    }
+
+    var defaultWeekdaysRegex = matchWord;
+    function weekdaysRegex (isStrict) {
+        if (this._weekdaysParseExact) {
+            if (!hasOwnProp(this, '_weekdaysRegex')) {
+                computeWeekdaysParse.call(this);
+            }
+            if (isStrict) {
+                return this._weekdaysStrictRegex;
+            } else {
+                return this._weekdaysRegex;
+            }
+        } else {
+            if (!hasOwnProp(this, '_weekdaysRegex')) {
+                this._weekdaysRegex = defaultWeekdaysRegex;
+            }
+            return this._weekdaysStrictRegex && isStrict ?
+                this._weekdaysStrictRegex : this._weekdaysRegex;
+        }
+    }
+
+    var defaultWeekdaysShortRegex = matchWord;
+    function weekdaysShortRegex (isStrict) {
+        if (this._weekdaysParseExact) {
+            if (!hasOwnProp(this, '_weekdaysRegex')) {
+                computeWeekdaysParse.call(this);
+            }
+            if (isStrict) {
+                return this._weekdaysShortStrictRegex;
+            } else {
+                return this._weekdaysShortRegex;
+            }
+        } else {
+            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
+                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
+            }
+            return this._weekdaysShortStrictRegex && isStrict ?
+                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
+        }
+    }
+
+    var defaultWeekdaysMinRegex = matchWord;
+    function weekdaysMinRegex (isStrict) {
+        if (this._weekdaysParseExact) {
+            if (!hasOwnProp(this, '_weekdaysRegex')) {
+                computeWeekdaysParse.call(this);
+            }
+            if (isStrict) {
+                return this._weekdaysMinStrictRegex;
+            } else {
+                return this._weekdaysMinRegex;
+            }
+        } else {
+            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
+                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
+            }
+            return this._weekdaysMinStrictRegex && isStrict ?
+                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
+        }
+    }
+
+
+    function computeWeekdaysParse () {
+        function cmpLenRev(a, b) {
+            return b.length - a.length;
+        }
+
+        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
+            i, mom, minp, shortp, longp;
+        for (i = 0; i < 7; i++) {
+            // make the regex if we don't have it already
+            mom = create_utc__createUTC([2000, 1]).day(i);
+            minp = this.weekdaysMin(mom, '');
+            shortp = this.weekdaysShort(mom, '');
+            longp = this.weekdays(mom, '');
+            minPieces.push(minp);
+            shortPieces.push(shortp);
+            longPieces.push(longp);
+            mixedPieces.push(minp);
+            mixedPieces.push(shortp);
+            mixedPieces.push(longp);
+        }
+        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
+        // will match the longer piece.
+        minPieces.sort(cmpLenRev);
+        shortPieces.sort(cmpLenRev);
+        longPieces.sort(cmpLenRev);
+        mixedPieces.sort(cmpLenRev);
+        for (i = 0; i < 7; i++) {
+            shortPieces[i] = regexEscape(shortPieces[i]);
+            longPieces[i] = regexEscape(longPieces[i]);
+            mixedPieces[i] = regexEscape(mixedPieces[i]);
+        }
+
+        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
+        this._weekdaysShortRegex = this._weekdaysRegex;
+        this._weekdaysMinRegex = this._weekdaysRegex;
+
+        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
+        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
+        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
+    }
+
+    // FORMATTING
+
+    function hFormat() {
+        return this.hours() % 12 || 12;
+    }
+
+    function kFormat() {
+        return this.hours() || 24;
+    }
+
+    addFormatToken('H', ['HH', 2], 0, 'hour');
+    addFormatToken('h', ['hh', 2], 0, hFormat);
+    addFormatToken('k', ['kk', 2], 0, kFormat);
+
+    addFormatToken('hmm', 0, 0, function () {
+        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
+    });
+
+    addFormatToken('hmmss', 0, 0, function () {
+        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
+            zeroFill(this.seconds(), 2);
+    });
+
+    addFormatToken('Hmm', 0, 0, function () {
+        return '' + this.hours() + zeroFill(this.minutes(), 2);
+    });
+
+    addFormatToken('Hmmss', 0, 0, function () {
+        return '' + this.hours() + zeroFill(this.minutes(), 2) +
+            zeroFill(this.seconds(), 2);
+    });
+
+    function meridiem (token, lowercase) {
+        addFormatToken(token, 0, 0, function () {
+            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
+        });
+    }
+
+    meridiem('a', true);
+    meridiem('A', false);
+
+    // ALIASES
+
+    addUnitAlias('hour', 'h');
+
+    // PRIORITY
+    addUnitPriority('hour', 13);
+
+    // PARSING
+
+    function matchMeridiem (isStrict, locale) {
+        return locale._meridiemParse;
+    }
+
+    addRegexToken('a',  matchMeridiem);
+    addRegexToken('A',  matchMeridiem);
+    addRegexToken('H',  match1to2);
+    addRegexToken('h',  match1to2);
+    addRegexToken('HH', match1to2, match2);
+    addRegexToken('hh', match1to2, match2);
+
+    addRegexToken('hmm', match3to4);
+    addRegexToken('hmmss', match5to6);
+    addRegexToken('Hmm', match3to4);
+    addRegexToken('Hmmss', match5to6);
+
+    addParseToken(['H', 'HH'], HOUR);
+    addParseToken(['a', 'A'], function (input, array, config) {
+        config._isPm = config._locale.isPM(input);
+        config._meridiem = input;
+    });
+    addParseToken(['h', 'hh'], function (input, array, config) {
+        array[HOUR] = toInt(input);
+        getParsingFlags(config).bigHour = true;
+    });
+    addParseToken('hmm', function (input, array, config) {
+        var pos = input.length - 2;
+        array[HOUR] = toInt(input.substr(0, pos));
+        array[MINUTE] = toInt(input.substr(pos));
+        getParsingFlags(config).bigHour = true;
+    });
+    addParseToken('hmmss', function (input, array, config) {
+        var pos1 = input.length - 4;
+        var pos2 = input.length - 2;
+        array[HOUR] = toInt(input.substr(0, pos1));
+        array[MINUTE] = toInt(input.substr(pos1, 2));
+        array[SECOND] = toInt(input.substr(pos2));
+        getParsingFlags(config).bigHour = true;
+    });
+    addParseToken('Hmm', function (input, array, config) {
+        var pos = input.length - 2;
+        array[HOUR] = toInt(input.substr(0, pos));
+        array[MINUTE] = toInt(input.substr(pos));
+    });
+    addParseToken('Hmmss', function (input, array, config) {
+        var pos1 = input.length - 4;
+        var pos2 = input.length - 2;
+        array[HOUR] = toInt(input.substr(0, pos1));
+        array[MINUTE] = toInt(input.substr(pos1, 2));
+        array[SECOND] = toInt(input.substr(pos2));
+    });
+
+    // LOCALES
+
+    function localeIsPM (input) {
+        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
+        // Using charAt should be more compatible.
+        return ((input + '').toLowerCase().charAt(0) === 'p');
+    }
+
+    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
+    function localeMeridiem (hours, minutes, isLower) {
+        if (hours > 11) {
+            return isLower ? 'pm' : 'PM';
+        } else {
+            return isLower ? 'am' : 'AM';
+        }
+    }
+
+
+    // MOMENTS
+
+    // Setting the hour should keep the time, because the user explicitly
+    // specified which hour he wants. So trying to maintain the same hour (in
+    // a new timezone) makes sense. Adding/subtracting hours does not follow
+    // this rule.
+    var getSetHour = makeGetSet('Hours', true);
+
+    var baseConfig = {
+        calendar: defaultCalendar,
+        longDateFormat: defaultLongDateFormat,
+        invalidDate: defaultInvalidDate,
+        ordinal: defaultOrdinal,
+        ordinalParse: defaultOrdinalParse,
+        relativeTime: defaultRelativeTime,
+
+        months: defaultLocaleMonths,
+        monthsShort: defaultLocaleMonthsShort,
+
+        week: defaultLocaleWeek,
+
+        weekdays: defaultLocaleWeekdays,
+        weekdaysMin: defaultLocaleWeekdaysMin,
+        weekdaysShort: defaultLocaleWeekdaysShort,
+
+        meridiemParse: defaultLocaleMeridiemParse
+    };
+
+    // internal storage for locale config files
+    var locales = {};
+    var globalLocale;
+
+    function normalizeLocale(key) {
+        return key ? key.toLowerCase().replace('_', '-') : key;
+    }
+
+    // pick the locale from the array
+    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
+    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
+    function chooseLocale(names) {
+        var i = 0, j, next, locale, split;
+
+        while (i < names.length) {
+            split = normalizeLocale(names[i]).split('-');
+            j = split.length;
+            next = normalizeLocale(names[i + 1]);
+            next = next ? next.split('-') : null;
+            while (j > 0) {
+                locale = loadLocale(split.slice(0, j).join('-'));
+                if (locale) {
+                    return locale;
+                }
+                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
+                    //the next array item is better than a shallower substring of this one
+                    break;
+                }
+                j--;
+            }
+            i++;
+        }
+        return null;
+    }
+
+    function loadLocale(name) {
+        var oldLocale = null;
+        // TODO: Find a better way to register and load all the locales in Node
+        if (!locales[name] && (typeof module !== 'undefined') &&
+                module && module.exports) {
+            try {
+                oldLocale = globalLocale._abbr;
+                require('./locale/' + name);
+                // because defineLocale currently also sets the global locale, we
+                // want to undo that for lazy loaded locales
+                locale_locales__getSetGlobalLocale(oldLocale);
+            } catch (e) { }
+        }
+        return locales[name];
+    }
+
+    // This function will load locale and then set the global locale.  If
+    // no arguments are passed in, it will simply return the current global
+    // locale key.
+    function locale_locales__getSetGlobalLocale (key, values) {
+        var data;
+        if (key) {
+            if (isUndefined(values)) {
+                data = locale_locales__getLocale(key);
+            }
+            else {
+                data = defineLocale(key, values);
+            }
+
+            if (data) {
+                // moment.duration._locale = moment._locale = data;
+                globalLocale = data;
+            }
+        }
+
+        return globalLocale._abbr;
+    }
+
+    function defineLocale (name, config) {
+        if (config !== null) {
+            var parentConfig = baseConfig;
+            config.abbr = name;
+            if (locales[name] != null) {
+                deprecateSimple('defineLocaleOverride',
+                        'use moment.updateLocale(localeName, config) to change ' +
+                        'an existing locale. moment.defineLocale(localeName, ' +
+                        'config) should only be used for creating a new locale ' +
+                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
+                parentConfig = locales[name]._config;
+            } else if (config.parentLocale != null) {
+                if (locales[config.parentLocale] != null) {
+                    parentConfig = locales[config.parentLocale]._config;
+                } else {
+                    // treat as if there is no base config
+                    deprecateSimple('parentLocaleUndefined',
+                            'specified parentLocale is not defined yet. See http://momentjs.com/guides/#/warnings/parent-locale/');
+                }
+            }
+            locales[name] = new Locale(mergeConfigs(parentConfig, config));
+
+            // backwards compat for now: also set the locale
+            locale_locales__getSetGlobalLocale(name);
+
+            return locales[name];
+        } else {
+            // useful for testing
+            delete locales[name];
+            return null;
+        }
+    }
+
+    function updateLocale(name, config) {
+        if (config != null) {
+            var locale, parentConfig = baseConfig;
+            // MERGE
+            if (locales[name] != null) {
+                parentConfig = locales[name]._config;
+            }
+            config = mergeConfigs(parentConfig, config);
+            locale = new Locale(config);
+            locale.parentLocale = locales[name];
+            locales[name] = locale;
+
+            // backwards compat for now: also set the locale
+            locale_locales__getSetGlobalLocale(name);
+        } else {
+            // pass null for config to unupdate, useful for tests
+            if (locales[name] != null) {
+                if (locales[name].parentLocale != null) {
+                    locales[name] = locales[name].parentLocale;
+                } else if (locales[name] != null) {
+                    delete locales[name];
+                }
+            }
+        }
+        return locales[name];
+    }
+
+    // returns locale data
+    function locale_locales__getLocale (key) {
+        var locale;
+
+        if (key && key._locale && key._locale._abbr) {
+            key = key._locale._abbr;
+        }
+
+        if (!key) {
+            return globalLocale;
+        }
+
+        if (!isArray(key)) {
+            //short-circuit everything else
+            locale = loadLocale(key);
+            if (locale) {
+                return locale;
+            }
+            key = [key];
+        }
+
+        return chooseLocale(key);
+    }
+
+    function locale_locales__listLocales() {
+        return keys(locales);
+    }
+
+    function checkOverflow (m) {
+        var overflow;
+        var a = m._a;
+
+        if (a && getParsingFlags(m).overflow === -2) {
+            overflow =
+                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
+                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
+                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
+                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
+                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
+                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
+                -1;
+
+            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
+                overflow = DATE;
+            }
+            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
+                overflow = WEEK;
+            }
+            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
+                overflow = WEEKDAY;
+            }
+
+            getParsingFlags(m).overflow = overflow;
+        }
+
+        return m;
+    }
+
+    // iso 8601 regex
+    // 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)
+    var 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)?)?/;
+    var 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)?)?/;
+
+    var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
+
+    var isoDates = [
+        ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
+        ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
+        ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
+        ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
+        ['YYYY-DDD', /\d{4}-\d{3}/],
+        ['YYYY-MM', /\d{4}-\d\d/, false],
+        ['YYYYYYMMDD', /[+-]\d{10}/],
+        ['YYYYMMDD', /\d{8}/],
+        // YYYYMM is NOT allowed by the standard
+        ['GGGG[W]WWE', /\d{4}W\d{3}/],
+        ['GGGG[W]WW', /\d{4}W\d{2}/, false],
+        ['YYYYDDD', /\d{7}/]
+    ];
+
+    // iso time formats and regexes
+    var isoTimes = [
+        ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
+        ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
+        ['HH:mm:ss', /\d\d:\d\d:\d\d/],
+        ['HH:mm', /\d\d:\d\d/],
+        ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
+        ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
+        ['HHmmss', /\d\d\d\d\d\d/],
+        ['HHmm', /\d\d\d\d/],
+        ['HH', /\d\d/]
+    ];
+
+    var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
+
+    // date from iso format
+    function configFromISO(config) {
+        var i, l,
+            string = config._i,
+            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
+            allowTime, dateFormat, timeFormat, tzFormat;
+
+        if (match) {
+            getParsingFlags(config).iso = true;
+
+            for (i = 0, l = isoDates.length; i < l; i++) {
+                if (isoDates[i][1].exec(match[1])) {
+                    dateFormat = isoDates[i][0];
+                    allowTime = isoDates[i][2] !== false;
+                    break;
+                }
+            }
+            if (dateFormat == null) {
+                config._isValid = false;
+                return;
+            }
+            if (match[3]) {
+                for (i = 0, l = isoTimes.length; i < l; i++) {
+                    if (isoTimes[i][1].exec(match[3])) {
+                        // match[2] should be 'T' or space
+                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
+                        break;
+                    }
+                }
+                if (timeFormat == null) {
+                    config._isValid = false;
+                    return;
+                }
+            }
+            if (!allowTime && timeFormat != null) {
+                config._isValid = false;
+                return;
+            }
+            if (match[4]) {
+                if (tzRegex.exec(match[4])) {
+                    tzFormat = 'Z';
+                } else {
+                    config._isValid = false;
+                    return;
+                }
+            }
+            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
+            configFromStringAndFormat(config);
+        } else {
+            config._isValid = false;
+        }
+    }
+
+    // date from iso format or fallback
+    function configFromString(config) {
+        var matched = aspNetJsonRegex.exec(config._i);
+
+        if (matched !== null) {
+            config._d = new Date(+matched[1]);
+            return;
+        }
+
+        configFromISO(config);
+        if (config._isValid === false) {
+            delete config._isValid;
+            utils_hooks__hooks.createFromInputFallback(config);
+        }
+    }
+
+    utils_hooks__hooks.createFromInputFallback = deprecate(
+        'value provided is not in a recognized ISO format. moment construction falls back to js Date(), ' +
+        'which is not reliable across all browsers and versions. Non ISO date formats are ' +
+        'discouraged and will be removed in an upcoming major release. Please refer to ' +
+        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
+        function (config) {
+            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
+        }
+    );
+
+    // Pick the first defined of two or three arguments.
+    function defaults(a, b, c) {
+        if (a != null) {
+            return a;
+        }
+        if (b != null) {
+            return b;
+        }
+        return c;
+    }
+
+    function currentDateArray(config) {
+        // hooks is actually the exported moment object
+        var nowValue = new Date(utils_hooks__hooks.now());
+        if (config._useUTC) {
+            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
+        }
+        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
+    }
+
+    // convert an array to a date.
+    // the array should mirror the parameters below
+    // note: all values past the year are optional and will default to the lowest possible value.
+    // [year, month, day , hour, minute, second, millisecond]
+    function configFromArray (config) {
+        var i, date, input = [], currentDate, yearToUse;
+
+        if (config._d) {
+            return;
+        }
+
+        currentDate = currentDateArray(config);
+
+        //compute day of the year from weeks and weekdays
+        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
+            dayOfYearFromWeekInfo(config);
+        }
+
+        //if the day of the year is set, figure out what it is
+        if (config._dayOfYear) {
+            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
+
+            if (config._dayOfYear > daysInYear(yearToUse)) {
+                getParsingFlags(config)._overflowDayOfYear = true;
+            }
+
+            date = createUTCDate(yearToUse, 0, config._dayOfYear);
+            config._a[MONTH] = date.getUTCMonth();
+            config._a[DATE] = date.getUTCDate();
+        }
+
+        // Default to current date.
+        // * if no year, month, day of month are given, default to today
+        // * if day of month is given, default month and year
+        // * if month is given, default only year
+        // * if year is given, don't default anything
+        for (i = 0; i < 3 && config._a[i] == null; ++i) {
+            config._a[i] = input[i] = currentDate[i];
+        }
+
+        // Zero out whatever was not defaulted, including time
+        for (; i < 7; i++) {
+            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
+        }
+
+        // Check for 24:00:00.000
+        if (config._a[HOUR] === 24 &&
+                config._a[MINUTE] === 0 &&
+                config._a[SECOND] === 0 &&
+                config._a[MILLISECOND] === 0) {
+            config._nextDay = true;
+            config._a[HOUR] = 0;
+        }
+
+        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
+        // Apply timezone offset from input. The actual utcOffset can be changed
+        // with parseZone.
+        if (config._tzm != null) {
+            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
+        }
+
+        if (config._nextDay) {
+            config._a[HOUR] = 24;
+        }
+    }
+
+    function dayOfYearFromWeekInfo(config) {
+        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
+
+        w = config._w;
+        if (w.GG != null || w.W != null || w.E != null) {
+            dow = 1;
+            doy = 4;
+
+            // TODO: We need to take the current isoWeekYear, but that depends on
+            // how we interpret now (local, utc, fixed offset). So create
+            // a now version of current config (take local/utc/offset flags, and
+            // create now).
+            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);
+            week = defaults(w.W, 1);
+            weekday = defaults(w.E, 1);
+            if (weekday < 1 || weekday > 7) {
+                weekdayOverflow = true;
+            }
+        } else {
+            dow = config._locale._week.dow;
+            doy = config._locale._week.doy;
+
+            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);
+            week = defaults(w.w, 1);
+
+            if (w.d != null) {
+                // weekday -- low day numbers are considered next week
+                weekday = w.d;
+                if (weekday < 0 || weekday > 6) {
+                    weekdayOverflow = true;
+                }
+            } else if (w.e != null) {
+                // local weekday -- counting starts from begining of week
+                weekday = w.e + dow;
+                if (w.e < 0 || w.e > 6) {
+                    weekdayOverflow = true;
+                }
+            } else {
+                // default to begining of week
+                weekday = dow;
+            }
+        }
+        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
+            getParsingFlags(config)._overflowWeeks = true;
+        } else if (weekdayOverflow != null) {
+            getParsingFlags(config)._overflowWeekday = true;
+        } else {
+            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
+            config._a[YEAR] = temp.year;
+            config._dayOfYear = temp.dayOfYear;
+        }
+    }
+
+    // constant that refers to the ISO standard
+    utils_hooks__hooks.ISO_8601 = function () {};
+
+    // date from string and format string
+    function configFromStringAndFormat(config) {
+        // TODO: Move this to another part of the creation flow to prevent circular deps
+        if (config._f === utils_hooks__hooks.ISO_8601) {
+            configFromISO(config);
+            return;
+        }
+
+        config._a = [];
+        getParsingFlags(config).empty = true;
+
+        // This array is used to make a Date, either with `new Date` or `Date.UTC`
+        var string = '' + config._i,
+            i, parsedInput, tokens, token, skipped,
+            stringLength = string.length,
+            totalParsedInputLength = 0;
+
+        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
+
+        for (i = 0; i < tokens.length; i++) {
+            token = tokens[i];
+            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
+            // console.log('token', token, 'parsedInput', parsedInput,
+            //         'regex', getParseRegexForToken(token, config));
+            if (parsedInput) {
+                skipped = string.substr(0, string.indexOf(parsedInput));
+                if (skipped.length > 0) {
+                    getParsingFlags(config).unusedInput.push(skipped);
+                }
+                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
+                totalParsedInputLength += parsedInput.length;
+            }
+            // don't parse if it's not a known token
+            if (formatTokenFunctions[token]) {
+                if (parsedInput) {
+                    getParsingFlags(config).empty = false;
+                }
+                else {
+                    getParsingFlags(config).unusedTokens.push(token);
+                }
+                addTimeToArrayFromToken(token, parsedInput, config);
+            }
+            else if (config._strict && !parsedInput) {
+                getParsingFlags(config).unusedTokens.push(token);
+            }
+        }
+
+        // add remaining unparsed input length to the string
+        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
+        if (string.length > 0) {
+            getParsingFlags(config).unusedInput.push(string);
+        }
+
+        // clear _12h flag if hour is <= 12
+        if (config._a[HOUR] <= 12 &&
+            getParsingFlags(config).bigHour === true &&
+            config._a[HOUR] > 0) {
+            getParsingFlags(config).bigHour = undefined;
+        }
+
+        getParsingFlags(config).parsedDateParts = config._a.slice(0);
+        getParsingFlags(config).meridiem = config._meridiem;
+        // handle meridiem
+        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
+
+        configFromArray(config);
+        checkOverflow(config);
+    }
+
+
+    function meridiemFixWrap (locale, hour, meridiem) {
+        var isPm;
+
+        if (meridiem == null) {
+            // nothing to do
+            return hour;
+        }
+        if (locale.meridiemHour != null) {
+            return locale.meridiemHour(hour, meridiem);
+        } else if (locale.isPM != null) {
+            // Fallback
+            isPm = locale.isPM(meridiem);
+            if (isPm && hour < 12) {
+                hour += 12;
+            }
+            if (!isPm && hour === 12) {
+                hour = 0;
+            }
+            return hour;
+        } else {
+            // this is not supposed to happen
+            return hour;
+        }
+    }
+
+    // date from string and array of format strings
+    function configFromStringAndArray(config) {
+        var tempConfig,
+            bestMoment,
+
+            scoreToBeat,
+            i,
+            currentScore;
+
+        if (config._f.length === 0) {
+            getParsingFlags(config).invalidFormat = true;
+            config._d = new Date(NaN);
+            return;
+        }
+
+        for (i = 0; i < config._f.length; i++) {
+            currentScore = 0;
+            tempConfig = copyConfig({}, config);
+            if (config._useUTC != null) {
+                tempConfig._useUTC = config._useUTC;
+            }
+            tempConfig._f = config._f[i];
+            configFromStringAndFormat(tempConfig);
+
+            if (!valid__isValid(tempConfig)) {
+                continue;
+            }
+
+            // if there is any input that was not parsed add a penalty for that format
+            currentScore += getParsingFlags(tempConfig).charsLeftOver;
+
+            //or tokens
+            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
+
+            getParsingFlags(tempConfig).score = currentScore;
+
+            if (scoreToBeat == null || currentScore < scoreToBeat) {
+                scoreToBeat = currentScore;
+                bestMoment = tempConfig;
+            }
+        }
+
+        extend(config, bestMoment || tempConfig);
+    }
+
+    function configFromObject(config) {
+        if (config._d) {
+            return;
+        }
+
+        var i = normalizeObjectUnits(config._i);
+        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
+            return obj && parseInt(obj, 10);
+        });
+
+        configFromArray(config);
+    }
+
+    function createFromConfig (config) {
+        var res = new Moment(checkOverflow(prepareConfig(config)));
+        if (res._nextDay) {
+            // Adding is smart enough around DST
+            res.add(1, 'd');
+            res._nextDay = undefined;
+        }
+
+        return res;
+    }
+
+    function prepareConfig (config) {
+        var input = config._i,
+            format = config._f;
+
+        config._locale = config._locale || locale_locales__getLocale(config._l);
+
+        if (input === null || (format === undefined && input === '')) {
+            return valid__createInvalid({nullInput: true});
+        }
+
+        if (typeof input === 'string') {
+            config._i = input = config._locale.preparse(input);
+        }
+
+        if (isMoment(input)) {
+            return new Moment(checkOverflow(input));
+        } else if (isArray(format)) {
+            configFromStringAndArray(config);
+        } else if (isDate(input)) {
+            config._d = input;
+        } else if (format) {
+            configFromStringAndFormat(config);
+        }  else {
+            configFromInput(config);
+        }
+
+        if (!valid__isValid(config)) {
+            config._d = null;
+        }
+
+        return config;
+    }
+
+    function configFromInput(config) {
+        var input = config._i;
+        if (input === undefined) {
+            config._d = new Date(utils_hooks__hooks.now());
+        } else if (isDate(input)) {
+            config._d = new Date(input.valueOf());
+        } else if (typeof input === 'string') {
+            configFromString(config);
+        } else if (isArray(input)) {
+            config._a = map(input.slice(0), function (obj) {
+                return parseInt(obj, 10);
+            });
+            configFromArray(config);
+        } else if (typeof(input) === 'object') {
+            configFromObject(config);
+        } else if (typeof(input) === 'number') {
+            // from milliseconds
+            config._d = new Date(input);
+        } else {
+            utils_hooks__hooks.createFromInputFallback(config);
+        }
+    }
+
+    function createLocalOrUTC (input, format, locale, strict, isUTC) {
+        var c = {};
+
+        if (typeof(locale) === 'boolean') {
+            strict = locale;
+            locale = undefined;
+        }
+
+        if ((isObject(input) && isObjectEmpty(input)) ||
+                (isArray(input) && input.length === 0)) {
+            input = undefined;
+        }
+        // object construction must be done this way.
+        // https://github.com/moment/moment/issues/1423
+        c._isAMomentObject = true;
+        c._useUTC = c._isUTC = isUTC;
+        c._l = locale;
+        c._i = input;
+        c._f = format;
+        c._strict = strict;
+
+        return createFromConfig(c);
+    }
+
+    function local__createLocal (input, format, locale, strict) {
+        return createLocalOrUTC(input, format, locale, strict, false);
+    }
+
+    var prototypeMin = deprecate(
+        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
+        function () {
+            var other = local__createLocal.apply(null, arguments);
+            if (this.isValid() && other.isValid()) {
+                return other < this ? this : other;
+            } else {
+                return valid__createInvalid();
+            }
+        }
+    );
+
+    var prototypeMax = deprecate(
+        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
+        function () {
+            var other = local__createLocal.apply(null, arguments);
+            if (this.isValid() && other.isValid()) {
+                return other > this ? this : other;
+            } else {
+                return valid__createInvalid();
+            }
+        }
+    );
+
+    // Pick a moment m from moments so that m[fn](other) is true for all
+    // other. This relies on the function fn to be transitive.
+    //
+    // moments should either be an array of moment objects or an array, whose
+    // first element is an array of moment objects.
+    function pickBy(fn, moments) {
+        var res, i;
+        if (moments.length === 1 && isArray(moments[0])) {
+            moments = moments[0];
+        }
+        if (!moments.length) {
+            return local__createLocal();
+        }
+        res = moments[0];
+        for (i = 1; i < moments.length; ++i) {
+            if (!moments[i].isValid() || moments[i][fn](res)) {
+                res = moments[i];
+            }
+        }
+        return res;
+    }
+
+    // TODO: Use [].sort instead?
+    function min () {
+        var args = [].slice.call(arguments, 0);
+
+        return pickBy('isBefore', args);
+    }
+
+    function max () {
+        var args = [].slice.call(arguments, 0);
+
+        return pickBy('isAfter', args);
+    }
+
+    var now = function () {
+        return Date.now ? Date.now() : +(new Date());
+    };
+
+    function Duration (duration) {
+        var normalizedInput = normalizeObjectUnits(duration),
+            years = normalizedInput.year || 0,
+            quarters = normalizedInput.quarter || 0,
+            months = normalizedInput.month || 0,
+            weeks = normalizedInput.week || 0,
+            days = normalizedInput.day || 0,
+            hours = normalizedInput.hour || 0,
+            minutes = normalizedInput.minute || 0,
+            seconds = normalizedInput.second || 0,
+            milliseconds = normalizedInput.millisecond || 0;
+
+        // representation for dateAddRemove
+        this._milliseconds = +milliseconds +
+            seconds * 1e3 + // 1000
+            minutes * 6e4 + // 1000 * 60
+            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
+        // Because of dateAddRemove treats 24 hours as different from a
+        // day when working around DST, we need to store them separately
+        this._days = +days +
+            weeks * 7;
+        // It is impossible translate months into days without knowing
+        // which months you are are talking about, so we have to store
+        // it separately.
+        this._months = +months +
+            quarters * 3 +
+            years * 12;
+
+        this._data = {};
+
+        this._locale = locale_locales__getLocale();
+
+        this._bubble();
+    }
+
+    function isDuration (obj) {
+        return obj instanceof Duration;
+    }
+
+    function absRound (number) {
+        if (number < 0) {
+            return Math.round(-1 * number) * -1;
+        } else {
+            return Math.round(number);
+        }
+    }
+
+    // FORMATTING
+
+    function offset (token, separator) {
+        addFormatToken(token, 0, 0, function () {
+            var offset = this.utcOffset();
+            var sign = '+';
+            if (offset < 0) {
+                offset = -offset;
+                sign = '-';
+            }
+            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
+        });
+    }
+
+    offset('Z', ':');
+    offset('ZZ', '');
+
+    // PARSING
+
+    addRegexToken('Z',  matchShortOffset);
+    addRegexToken('ZZ', matchShortOffset);
+    addParseToken(['Z', 'ZZ'], function (input, array, config) {
+        config._useUTC = true;
+        config._tzm = offsetFromString(matchShortOffset, input);
+    });
+
+    // HELPERS
+
+    // timezone chunker
+    // '+10:00' > ['10',  '00']
+    // '-1530'  > ['-15', '30']
+    var chunkOffset = /([\+\-]|\d\d)/gi;
+
+    function offsetFromString(matcher, string) {
+        var matches = ((string || '').match(matcher) || []);
+        var chunk   = matches[matches.length - 1] || [];
+        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
+        var minutes = +(parts[1] * 60) + toInt(parts[2]);
+
+        return parts[0] === '+' ? minutes : -minutes;
+    }
+
+    // Return a moment from input, that is local/utc/zone equivalent to model.
+    function cloneWithOffset(input, model) {
+        var res, diff;
+        if (model._isUTC) {
+            res = model.clone();
+            diff = (isMoment(input) || isDate(input) ? input.valueOf() : local__createLocal(input).valueOf()) - res.valueOf();
+            // Use low-level api, because this fn is low-level api.
+            res._d.setTime(res._d.valueOf() + diff);
+            utils_hooks__hooks.updateOffset(res, false);
+            return res;
+        } else {
+            return local__createLocal(input).local();
+        }
+    }
+
+    function getDateOffset (m) {
+        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
+        // https://github.com/moment/moment/pull/1871
+        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
+    }
+
+    // HOOKS
+
+    // This function will be called whenever a moment is mutated.
+    // It is intended to keep the offset in sync with the timezone.
+    utils_hooks__hooks.updateOffset = function () {};
+
+    // MOMENTS
+
+    // keepLocalTime = true means only change the timezone, without
+    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
+    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
+    // +0200, so we adjust the time as needed, to be valid.
+    //
+    // Keeping the time actually adds/subtracts (one hour)
+    // from the actual represented time. That is why we call updateOffset
+    // a second time. In case it wants us to change the offset again
+    // _changeInProgress == true case, then we have to adjust, because
+    // there is no such time in the given timezone.
+    function getSetOffset (input, keepLocalTime) {
+        var offset = this._offset || 0,
+            localAdjust;
+        if (!this.isValid()) {
+            return input != null ? this : NaN;
+        }
+        if (input != null) {
+            if (typeof input === 'string') {
+                input = offsetFromString(matchShortOffset, input);
+            } else if (Math.abs(input) < 16) {
+                input = input * 60;
+            }
+            if (!this._isUTC && keepLocalTime) {
+                localAdjust = getDateOffset(this);
+            }
+            this._offset = input;
+            this._isUTC = true;
+            if (localAdjust != null) {
+                this.add(localAdjust, 'm');
+            }
+            if (offset !== input) {
+                if (!keepLocalTime || this._changeInProgress) {
+                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);
+                } else if (!this._changeInProgress) {
+                    this._changeInProgress = true;
+                    utils_hooks__hooks.updateOffset(this, true);
+                    this._changeInProgress = null;
+                }
+            }
+            return this;
+        } else {
+            return this._isUTC ? offset : getDateOffset(this);
+        }
+    }
+
+    function getSetZone (input, keepLocalTime) {
+        if (input != null) {
+            if (typeof input !== 'string') {
+                input = -input;
+            }
+
+            this.utcOffset(input, keepLocalTime);
+
+            return this;
+        } else {
+            return -this.utcOffset();
+        }
+    }
+
+    function setOffsetToUTC (keepLocalTime) {
+        return this.utcOffset(0, keepLocalTime);
+    }
+
+    function setOffsetToLocal (keepLocalTime) {
+        if (this._isUTC) {
+            this.utcOffset(0, keepLocalTime);
+            this._isUTC = false;
+
+            if (keepLocalTime) {
+                this.subtract(getDateOffset(this), 'm');
+            }
+        }
+        return this;
+    }
+
+    function setOffsetToParsedOffset () {
+        if (this._tzm) {
+            this.utcOffset(this._tzm);
+        } else if (typeof this._i === 'string') {
+            var tZone = offsetFromString(matchOffset, this._i);
+
+            if (tZone === 0) {
+                this.utcOffset(0, true);
+            } else {
+                this.utcOffset(offsetFromString(matchOffset, this._i));
+            }
+        }
+        return this;
+    }
+
+    function hasAlignedHourOffset (input) {
+        if (!this.isValid()) {
+            return false;
+        }
+        input = input ? local__createLocal(input).utcOffset() : 0;
+
+        return (this.utcOffset() - input) % 60 === 0;
+    }
+
+    function isDaylightSavingTime () {
+        return (
+            this.utcOffset() > this.clone().month(0).utcOffset() ||
+            this.utcOffset() > this.clone().month(5).utcOffset()
+        );
+    }
+
+    function isDaylightSavingTimeShifted () {
+        if (!isUndefined(this._isDSTShifted)) {
+            return this._isDSTShifted;
+        }
+
+        var c = {};
+
+        copyConfig(c, this);
+        c = prepareConfig(c);
+
+        if (c._a) {
+            var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);
+            this._isDSTShifted = this.isValid() &&
+                compareArrays(c._a, other.toArray()) > 0;
+        } else {
+            this._isDSTShifted = false;
+        }
+
+        return this._isDSTShifted;
+    }
+
+    function isLocal () {
+        return this.isValid() ? !this._isUTC : false;
+    }
+
+    function isUtcOffset () {
+        return this.isValid() ? this._isUTC : false;
+    }
+
+    function isUtc () {
+        return this.isValid() ? this._isUTC && this._offset === 0 : false;
+    }
+
+    // ASP.NET json date format regex
+    var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
+
+    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
+    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
+    // and further modified to allow for strings containing both week and day
+    var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;
+
+    function create__createDuration (input, key) {
+        var duration = input,
+            // matching against regexp is expensive, do it on demand
+            match = null,
+            sign,
+            ret,
+            diffRes;
+
+        if (isDuration(input)) {
+            duration = {
+                ms : input._milliseconds,
+                d  : input._days,
+                M  : input._months
+            };
+        } else if (typeof input === 'number') {
+            duration = {};
+            if (key) {
+                duration[key] = input;
+            } else {
+                duration.milliseconds = input;
+            }
+        } else if (!!(match = aspNetRegex.exec(input))) {
+            sign = (match[1] === '-') ? -1 : 1;
+            duration = {
+                y  : 0,
+                d  : toInt(match[DATE])                         * sign,
+                h  : toInt(match[HOUR])                         * sign,
+                m  : toInt(match[MINUTE])                       * sign,
+                s  : toInt(match[SECOND])                       * sign,
+                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
+            };
+        } else if (!!(match = isoRegex.exec(input))) {
+            sign = (match[1] === '-') ? -1 : 1;
+            duration = {
+                y : parseIso(match[2], sign),
+                M : parseIso(match[3], sign),
+                w : parseIso(match[4], sign),
+                d : parseIso(match[5], sign),
+                h : parseIso(match[6], sign),
+                m : parseIso(match[7], sign),
+                s : parseIso(match[8], sign)
+            };
+        } else if (duration == null) {// checks for null or undefined
+            duration = {};
+        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
+            diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));
+
+            duration = {};
+            duration.ms = diffRes.milliseconds;
+            duration.M = diffRes.months;
+        }
+
+        ret = new Duration(duration);
+
+        if (isDuration(input) && hasOwnProp(input, '_locale')) {
+            ret._locale = input._locale;
+        }
+
+        return ret;
+    }
+
+    create__createDuration.fn = Duration.prototype;
+
+    function parseIso (inp, sign) {
+        // We'd normally use ~~inp for this, but unfortunately it also
+        // converts floats to ints.
+        // inp may be undefined, so careful calling replace on it.
+        var res = inp && parseFloat(inp.replace(',', '.'));
+        // apply sign while we're at it
+        return (isNaN(res) ? 0 : res) * sign;
+    }
+
+    function positiveMomentsDifference(base, other) {
+        var res = {milliseconds: 0, months: 0};
+
+        res.months = other.month() - base.month() +
+            (other.year() - base.year()) * 12;
+        if (base.clone().add(res.months, 'M').isAfter(other)) {
+            --res.months;
+        }
+
+        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
+
+        return res;
+    }
+
+    function momentsDifference(base, other) {
+        var res;
+        if (!(base.isValid() && other.isValid())) {
+            return {milliseconds: 0, months: 0};
+        }
+
+        other = cloneWithOffset(other, base);
+        if (base.isBefore(other)) {
+            res = positiveMomentsDifference(base, other);
+        } else {
+            res = positiveMomentsDifference(other, base);
+            res.milliseconds = -res.milliseconds;
+            res.months = -res.months;
+        }
+
+        return res;
+    }
+
+    // TODO: remove 'name' arg after deprecation is removed
+    function createAdder(direction, name) {
+        return function (val, period) {
+            var dur, tmp;
+            //invert the arguments, but complain about it
+            if (period !== null && !isNaN(+period)) {
+                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
+                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
+                tmp = val; val = period; period = tmp;
+            }
+
+            val = typeof val === 'string' ? +val : val;
+            dur = create__createDuration(val, period);
+            add_subtract__addSubtract(this, dur, direction);
+            return this;
+        };
+    }
+
+    function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {
+        var milliseconds = duration._milliseconds,
+            days = absRound(duration._days),
+            months = absRound(duration._months);
+
+        if (!mom.isValid()) {
+            // No op
+            return;
+        }
+
+        updateOffset = updateOffset == null ? true : updateOffset;
+
+        if (milliseconds) {
+            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
+        }
+        if (days) {
+            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
+        }
+        if (months) {
+            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);
+        }
+        if (updateOffset) {
+            utils_hooks__hooks.updateOffset(mom, days || months);
+        }
+    }
+
+    var add_subtract__add      = createAdder(1, 'add');
+    var add_subtract__subtract = createAdder(-1, 'subtract');
+
+    function getCalendarFormat(myMoment, now) {
+        var diff = myMoment.diff(now, 'days', true);
+        return diff < -6 ? 'sameElse' :
+                diff < -1 ? 'lastWeek' :
+                diff < 0 ? 'lastDay' :
+                diff < 1 ? 'sameDay' :
+                diff < 2 ? 'nextDay' :
+                diff < 7 ? 'nextWeek' : 'sameElse';
+    }
+
+    function moment_calendar__calendar (time, formats) {
+        // We want to compare the start of today, vs this.
+        // Getting start-of-today depends on whether we're local/utc/offset or not.
+        var now = time || local__createLocal(),
+            sod = cloneWithOffset(now, this).startOf('day'),
+            format = utils_hooks__hooks.calendarFormat(this, sod) || 'sameElse';
+
+        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
+
+        return this.format(output || this.localeData().calendar(format, this, local__createLocal(now)));
+    }
+
+    function clone () {
+        return new Moment(this);
+    }
+
+    function isAfter (input, units) {
+        var localInput = isMoment(input) ? input : local__createLocal(input);
+        if (!(this.isValid() && localInput.isValid())) {
+            return false;
+        }
+        units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
+        if (units === 'millisecond') {
+            return this.valueOf() > localInput.valueOf();
+        } else {
+            return localInput.valueOf() < this.clone().startOf(units).valueOf();
+        }
+    }
+
+    function isBefore (input, units) {
+        var localInput = isMoment(input) ? input : local__createLocal(input);
+        if (!(this.isValid() && localInput.isValid())) {
+            return false;
+        }
+        units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
+        if (units === 'millisecond') {
+            return this.valueOf() < localInput.valueOf();
+        } else {
+            return this.clone().endOf(units).valueOf() < localInput.valueOf();
+        }
+    }
+
+    function isBetween (from, to, units, inclusivity) {
+        inclusivity = inclusivity || '()';
+        return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
+            (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
+    }
+
+    function isSame (input, units) {
+        var localInput = isMoment(input) ? input : local__createLocal(input),
+            inputMs;
+        if (!(this.isValid() && localInput.isValid())) {
+            return false;
+        }
+        units = normalizeUnits(units || 'millisecond');
+        if (units === 'millisecond') {
+            return this.valueOf() === localInput.valueOf();
+        } else {
+            inputMs = localInput.valueOf();
+            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
+        }
+    }
+
+    function isSameOrAfter (input, units) {
+        return this.isSame(input, units) || this.isAfter(input,units);
+    }
+
+    function isSameOrBefore (input, units) {
+        return this.isSame(input, units) || this.isBefore(input,units);
+    }
+
+    function diff (input, units, asFloat) {
+        var that,
+            zoneDelta,
+            delta, output;
+
+        if (!this.isValid()) {
+            return NaN;
+        }
+
+        that = cloneWithOffset(input, this);
+
+        if (!that.isValid()) {
+            return NaN;
+        }
+
+        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
+
+        units = normalizeUnits(units);
+
+        if (units === 'year' || units === 'month' || units === 'quarter') {
+            output = monthDiff(this, that);
+            if (units === 'quarter') {
+                output = output / 3;
+            } else if (units === 'year') {
+                output = output / 12;
+            }
+        } else {
+            delta = this - that;
+            output = units === 'second' ? delta / 1e3 : // 1000
+                units === 'minute' ? delta / 6e4 : // 1000 * 60
+                units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
+                units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
+                units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
+                delta;
+        }
+        return asFloat ? output : absFloor(output);
+    }
+
+    function monthDiff (a, b) {
+        // difference in months
+        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
+            // b is in (anchor - 1 month, anchor + 1 month)
+            anchor = a.clone().add(wholeMonthDiff, 'months'),
+            anchor2, adjust;
+
+        if (b - anchor < 0) {
+            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
+            // linear across the month
+            adjust = (b - anchor) / (anchor - anchor2);
+        } else {
+            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
+            // linear across the month
+            adjust = (b - anchor) / (anchor2 - anchor);
+        }
+
+        //check for negative zero, return zero if negative zero
+        return -(wholeMonthDiff + adjust) || 0;
+    }
+
+    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
+    utils_hooks__hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
+
+    function toString () {
+        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
+    }
+
+    function moment_format__toISOString () {
+        var m = this.clone().utc();
+        if (0 < m.year() && m.year() <= 9999) {
+            if (isFunction(Date.prototype.toISOString)) {
+                // native implementation is ~50x faster, use it when we can
+                return this.toDate().toISOString();
+            } else {
+                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
+            }
+        } else {
+            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
+        }
+    }
+
+    function format (inputString) {
+        if (!inputString) {
+            inputString = this.isUtc() ? utils_hooks__hooks.defaultFormatUtc : utils_hooks__hooks.defaultFormat;
+        }
+        var output = formatMoment(this, inputString);
+        return this.localeData().postformat(output);
+    }
+
+    function from (time, withoutSuffix) {
+        if (this.isValid() &&
+                ((isMoment(time) && time.isValid()) ||
+                 local__createLocal(time).isValid())) {
+            return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
+        } else {
+            return this.localeData().invalidDate();
+        }
+    }
+
+    function fromNow (withoutSuffix) {
+        return this.from(local__createLocal(), withoutSuffix);
+    }
+
+    function to (time, withoutSuffix) {
+        if (this.isValid() &&
+                ((isMoment(time) && time.isValid()) ||
+                 local__createLocal(time).isValid())) {
+            return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
+        } else {
+            return this.localeData().invalidDate();
+        }
+    }
+
+    function toNow (withoutSuffix) {
+        return this.to(local__createLocal(), withoutSuffix);
+    }
+
+    // If passed a locale key, it will set the locale for this
+    // instance.  Otherwise, it will return the locale configuration
+    // variables for this instance.
+    function locale (key) {
+        var newLocaleData;
+
+        if (key === undefined) {
+            return this._locale._abbr;
+        } else {
+            newLocaleData = locale_locales__getLocale(key);
+            if (newLocaleData != null) {
+                this._locale = newLocaleData;
+            }
+            return this;
+        }
+    }
+
+    var lang = deprecate(
+        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
+        function (key) {
+            if (key === undefined) {
+                return this.localeData();
+            } else {
+                return this.locale(key);
+            }
+        }
+    );
+
+    function localeData () {
+        return this._locale;
+    }
+
+    function startOf (units) {
+        units = normalizeUnits(units);
+        // the following switch intentionally omits break keywords
+        // to utilize falling through the cases.
+        switch (units) {
+            case 'year':
+                this.month(0);
+                /* falls through */
+            case 'quarter':
+            case 'month':
+                this.date(1);
+                /* falls through */
+            case 'week':
+            case 'isoWeek':
+            case 'day':
+            case 'date':
+                this.hours(0);
+                /* falls through */
+            case 'hour':
+                this.minutes(0);
+                /* falls through */
+            case 'minute':
+                this.seconds(0);
+                /* falls through */
+            case 'second':
+                this.milliseconds(0);
+        }
+
+        // weeks are a special case
+        if (units === 'week') {
+            this.weekday(0);
+        }
+        if (units === 'isoWeek') {
+            this.isoWeekday(1);
+        }
+
+        // quarters are also special
+        if (units === 'quarter') {
+            this.month(Math.floor(this.month() / 3) * 3);
+        }
+
+        return this;
+    }
+
+    function endOf (units) {
+        units = normalizeUnits(units);
+        if (units === undefined || units === 'millisecond') {
+            return this;
+        }
+
+        // 'date' is an alias for 'day', so it should be considered as such.
+        if (units === 'date') {
+            units = 'day';
+        }
+
+        return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
+    }
+
+    function to_type__valueOf () {
+        return this._d.valueOf() - ((this._offset || 0) * 60000);
+    }
+
+    function unix () {
+        return Math.floor(this.valueOf() / 1000);
+    }
+
+    function toDate () {
+        return new Date(this.valueOf());
+    }
+
+    function toArray () {
+        var m = this;
+        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
+    }
+
+    function toObject () {
+        var m = this;
+        return {
+            years: m.year(),
+            months: m.month(),
+            date: m.date(),
+            hours: m.hours(),
+            minutes: m.minutes(),
+            seconds: m.seconds(),
+            milliseconds: m.milliseconds()
+        };
+    }
+
+    function toJSON () {
+        // new Date(NaN).toJSON() === null
+        return this.isValid() ? this.toISOString() : null;
+    }
+
+    function moment_valid__isValid () {
+        return valid__isValid(this);
+    }
+
+    function parsingFlags () {
+        return extend({}, getParsingFlags(this));
+    }
+
+    function invalidAt () {
+        return getParsingFlags(this).overflow;
+    }
+
+    function creationData() {
+        return {
+            input: this._i,
+            format: this._f,
+            locale: this._locale,
+            isUTC: this._isUTC,
+            strict: this._strict
+        };
+    }
+
+    // FORMATTING
+
+    addFormatToken(0, ['gg', 2], 0, function () {
+        return this.weekYear() % 100;
+    });
+
+    addFormatToken(0, ['GG', 2], 0, function () {
+        return this.isoWeekYear() % 100;
+    });
+
+    function addWeekYearFormatToken (token, getter) {
+        addFormatToken(0, [token, token.length], 0, getter);
+    }
+
+    addWeekYearFormatToken('gggg',     'weekYear');
+    addWeekYearFormatToken('ggggg',    'weekYear');
+    addWeekYearFormatToken('GGGG',  'isoWeekYear');
+    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
+
+    // ALIASES
+
+    addUnitAlias('weekYear', 'gg');
+    addUnitAlias('isoWeekYear', 'GG');
+
+    // PRIORITY
+
+    addUnitPriority('weekYear', 1);
+    addUnitPriority('isoWeekYear', 1);
+
+
+    // PARSING
+
+    addRegexToken('G',      matchSigned);
+    addRegexToken('g',      matchSigned);
+    addRegexToken('GG',     match1to2, match2);
+    addRegexToken('gg',     match1to2, match2);
+    addRegexToken('GGGG',   match1to4, match4);
+    addRegexToken('gggg',   match1to4, match4);
+    addRegexToken('GGGGG',  match1to6, match6);
+    addRegexToken('ggggg',  match1to6, match6);
+
+    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
+        week[token.substr(0, 2)] = toInt(input);
+    });
+
+    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
+        week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
+    });
+
+    // MOMENTS
+
+    function getSetWeekYear (input) {
+        return getSetWeekYearHelper.call(this,
+                input,
+                this.week(),
+                this.weekday(),
+                this.localeData()._week.dow,
+                this.localeData()._week.doy);
+    }
+
+    function getSetISOWeekYear (input) {
+        return getSetWeekYearHelper.call(this,
+                input, this.isoWeek(), this.isoWeekday(), 1, 4);
+    }
+
+    function getISOWeeksInYear () {
+        return weeksInYear(this.year(), 1, 4);
+    }
+
+    function getWeeksInYear () {
+        var weekInfo = this.localeData()._week;
+        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
+    }
+
+    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
+        var weeksTarget;
+        if (input == null) {
+            return weekOfYear(this, dow, doy).year;
+        } else {
+            weeksTarget = weeksInYear(input, dow, doy);
+            if (week > weeksTarget) {
+                week = weeksTarget;
+            }
+            return setWeekAll.call(this, input, week, weekday, dow, doy);
+        }
+    }
+
+    function setWeekAll(weekYear, week, weekday, dow, doy) {
+        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
+            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
+
+        this.year(date.getUTCFullYear());
+        this.month(date.getUTCMonth());
+        this.date(date.getUTCDate());
+        return this;
+    }
+
+    // FORMATTING
+
+    addFormatToken('Q', 0, 'Qo', 'quarter');
+
+    // ALIASES
+
+    addUnitAlias('quarter', 'Q');
+
+    // PRIORITY
+
+    addUnitPriority('quarter', 7);
+
+    // PARSING
+
+    addRegexToken('Q', match1);
+    addParseToken('Q', function (input, array) {
+        array[MONTH] = (toInt(input) - 1) * 3;
+    });
+
+    // MOMENTS
+
+    function getSetQuarter (input) {
+        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
+    }
+
+    // FORMATTING
+
+    addFormatToken('D', ['DD', 2], 'Do', 'date');
+
+    // ALIASES
+
+    addUnitAlias('date', 'D');
+
+    // PRIOROITY
+    addUnitPriority('date', 9);
+
+    // PARSING
+
+    addRegexToken('D',  match1to2);
+    addRegexToken('DD', match1to2, match2);
+    addRegexToken('Do', function (isStrict, locale) {
+        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;
+    });
+
+    addParseToken(['D', 'DD'], DATE);
+    addParseToken('Do', function (input, array) {
+        array[DATE] = toInt(input.match(match1to2)[0], 10);
+    });
+
+    // MOMENTS
+
+    var getSetDayOfMonth = makeGetSet('Date', true);
+
+    // FORMATTING
+
+    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
+
+    // ALIASES
+
+    addUnitAlias('dayOfYear', 'DDD');
+
+    // PRIORITY
+    addUnitPriority('dayOfYear', 4);
+
+    // PARSING
+
+    addRegexToken('DDD',  match1to3);
+    addRegexToken('DDDD', match3);
+    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
+        config._dayOfYear = toInt(input);
+    });
+
+    // HELPERS
+
+    // MOMENTS
+
+    function getSetDayOfYear (input) {
+        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
+        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
+    }
+
+    // FORMATTING
+
+    addFormatToken('m', ['mm', 2], 0, 'minute');
+
+    // ALIASES
+
+    addUnitAlias('minute', 'm');
+
+    // PRIORITY
+
+    addUnitPriority('minute', 14);
+
+    // PARSING
+
+    addRegexToken('m',  match1to2);
+    addRegexToken('mm', match1to2, match2);
+    addParseToken(['m', 'mm'], MINUTE);
+
+    // MOMENTS
+
+    var getSetMinute = makeGetSet('Minutes', false);
+
+    // FORMATTING
+
+    addFormatToken('s', ['ss', 2], 0, 'second');
+
+    // ALIASES
+
+    addUnitAlias('second', 's');
+
+    // PRIORITY
+
+    addUnitPriority('second', 15);
+
+    // PARSING
+
+    addRegexToken('s',  match1to2);
+    addRegexToken('ss', match1to2, match2);
+    addParseToken(['s', 'ss'], SECOND);
+
+    // MOMENTS
+
+    var getSetSecond = makeGetSet('Seconds', false);
+
+    // FORMATTING
+
+    addFormatToken('S', 0, 0, function () {
+        return ~~(this.millisecond() / 100);
+    });
+
+    addFormatToken(0, ['SS', 2], 0, function () {
+        return ~~(this.millisecond() / 10);
+    });
+
+    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
+    addFormatToken(0, ['SSSS', 4], 0, function () {
+        return this.millisecond() * 10;
+    });
+    addFormatToken(0, ['SSSSS', 5], 0, function () {
+        return this.millisecond() * 100;
+    });
+    addFormatToken(0, ['SSSSSS', 6], 0, function () {
+        return this.millisecond() * 1000;
+    });
+    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
+        return this.millisecond() * 10000;
+    });
+    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
+        return this.millisecond() * 100000;
+    });
+    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
+        return this.millisecond() * 1000000;
+    });
+
+
+    // ALIASES
+
+    addUnitAlias('millisecond', 'ms');
+
+    // PRIORITY
+
+    addUnitPriority('millisecond', 16);
+
+    // PARSING
+
+    addRegexToken('S',    match1to3, match1);
+    addRegexToken('SS',   match1to3, match2);
+    addRegexToken('SSS',  match1to3, match3);
+
+    var token;
+    for (token = 'SSSS'; token.length <= 9; token += 'S') {
+        addRegexToken(token, matchUnsigned);
+    }
+
+    function parseMs(input, array) {
+        array[MILLISECOND] = toInt(('0.' + input) * 1000);
+    }
+
+    for (token = 'S'; token.length <= 9; token += 'S') {
+        addParseToken(token, parseMs);
+    }
+    // MOMENTS
+
+    var getSetMillisecond = makeGetSet('Milliseconds', false);
+
+    // FORMATTING
+
+    addFormatToken('z',  0, 0, 'zoneAbbr');
+    addFormatToken('zz', 0, 0, 'zoneName');
+
+    // MOMENTS
+
+    function getZoneAbbr () {
+        return this._isUTC ? 'UTC' : '';
+    }
+
+    function getZoneName () {
+        return this._isUTC ? 'Coordinated Universal Time' : '';
+    }
+
+    var momentPrototype__proto = Moment.prototype;
+
+    momentPrototype__proto.add               = add_subtract__add;
+    momentPrototype__proto.calendar          = moment_calendar__calendar;
+    momentPrototype__proto.clone             = clone;
+    momentPrototype__proto.diff              = diff;
+    momentPrototype__proto.endOf             = endOf;
+    momentPrototype__proto.format            = format;
+    momentPrototype__proto.from              = from;
+    momentPrototype__proto.fromNow           = fromNow;
+    momentPrototype__proto.to                = to;
+    momentPrototype__proto.toNow             = toNow;
+    momentPrototype__proto.get               = stringGet;
+    momentPrototype__proto.invalidAt         = invalidAt;
+    momentPrototype__proto.isAfter           = isAfter;
+    momentPrototype__proto.isBefore          = isBefore;
+    momentPrototype__proto.isBetween         = isBetween;
+    momentPrototype__proto.isSame            = isSame;
+    momentPrototype__proto.isSameOrAfter     = isSameOrAfter;
+    momentPrototype__proto.isSameOrBefore    = isSameOrBefore;
+    momentPrototype__proto.isValid           = moment_valid__isValid;
+    momentPrototype__proto.lang              = lang;
+    momentPrototype__proto.locale            = locale;
+    momentPrototype__proto.localeData        = localeData;
+    momentPrototype__proto.max               = prototypeMax;
+    momentPrototype__proto.min               = prototypeMin;
+    momentPrototype__proto.parsingFlags      = parsingFlags;
+    momentPrototype__proto.set               = stringSet;
+    momentPrototype__proto.startOf           = startOf;
+    momentPrototype__proto.subtract          = add_subtract__subtract;
+    momentPrototype__proto.toArray           = toArray;
+    momentPrototype__proto.toObject          = toObject;
+    momentPrototype__proto.toDate            = toDate;
+    momentPrototype__proto.toISOString       = moment_format__toISOString;
+    momentPrototype__proto.toJSON            = toJSON;
+    momentPrototype__proto.toString          = toString;
+    momentPrototype__proto.unix              = unix;
+    momentPrototype__proto.valueOf           = to_type__valueOf;
+    momentPrototype__proto.creationData      = creationData;
+
+    // Year
+    momentPrototype__proto.year       = getSetYear;
+    momentPrototype__proto.isLeapYear = getIsLeapYear;
+
+    // Week Year
+    momentPrototype__proto.weekYear    = getSetWeekYear;
+    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;
+
+    // Quarter
+    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;
+
+    // Month
+    momentPrototype__proto.month       = getSetMonth;
+    momentPrototype__proto.daysInMonth = getDaysInMonth;
+
+    // Week
+    momentPrototype__proto.week           = momentPrototype__proto.weeks        = getSetWeek;
+    momentPrototype__proto.isoWeek        = momentPrototype__proto.isoWeeks     = getSetISOWeek;
+    momentPrototype__proto.weeksInYear    = getWeeksInYear;
+    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;
+
+    // Day
+    momentPrototype__proto.date       = getSetDayOfMonth;
+    momentPrototype__proto.day        = momentPrototype__proto.days             = getSetDayOfWeek;
+    momentPrototype__proto.weekday    = getSetLocaleDayOfWeek;
+    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;
+    momentPrototype__proto.dayOfYear  = getSetDayOfYear;
+
+    // Hour
+    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;
+
+    // Minute
+    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;
+
+    // Second
+    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;
+
+    // Millisecond
+    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;
+
+    // Offset
+    momentPrototype__proto.utcOffset            = getSetOffset;
+    momentPrototype__proto.utc                  = setOffsetToUTC;
+    momentPrototype__proto.local                = setOffsetToLocal;
+    momentPrototype__proto.parseZone            = setOffsetToParsedOffset;
+    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;
+    momentPrototype__proto.isDST                = isDaylightSavingTime;
+    momentPrototype__proto.isLocal              = isLocal;
+    momentPrototype__proto.isUtcOffset          = isUtcOffset;
+    momentPrototype__proto.isUtc                = isUtc;
+    momentPrototype__proto.isUTC                = isUtc;
+
+    // Timezone
+    momentPrototype__proto.zoneAbbr = getZoneAbbr;
+    momentPrototype__proto.zoneName = getZoneName;
+
+    // Deprecations
+    momentPrototype__proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
+    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
+    momentPrototype__proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
+    momentPrototype__proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
+    momentPrototype__proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
+
+    var momentPrototype = momentPrototype__proto;
+
+    function moment__createUnix (input) {
+        return local__createLocal(input * 1000);
+    }
+
+    function moment__createInZone () {
+        return local__createLocal.apply(null, arguments).parseZone();
+    }
+
+    function preParsePostFormat (string) {
+        return string;
+    }
+
+    var prototype__proto = Locale.prototype;
+
+    prototype__proto.calendar        = locale_calendar__calendar;
+    prototype__proto.longDateFormat  = longDateFormat;
+    prototype__proto.invalidDate     = invalidDate;
+    prototype__proto.ordinal         = ordinal;
+    prototype__proto.preparse        = preParsePostFormat;
+    prototype__proto.postformat      = preParsePostFormat;
+    prototype__proto.relativeTime    = relative__relativeTime;
+    prototype__proto.pastFuture      = pastFuture;
+    prototype__proto.set             = locale_set__set;
+
+    // Month
+    prototype__proto.months            =        localeMonths;
+    prototype__proto.monthsShort       =        localeMonthsShort;
+    prototype__proto.monthsParse       =        localeMonthsParse;
+    prototype__proto.monthsRegex       = monthsRegex;
+    prototype__proto.monthsShortRegex  = monthsShortRegex;
+
+    // Week
+    prototype__proto.week = localeWeek;
+    prototype__proto.firstDayOfYear = localeFirstDayOfYear;
+    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;
+
+    // Day of Week
+    prototype__proto.weekdays       =        localeWeekdays;
+    prototype__proto.weekdaysMin    =        localeWeekdaysMin;
+    prototype__proto.weekdaysShort  =        localeWeekdaysShort;
+    prototype__proto.weekdaysParse  =        localeWeekdaysParse;
+
+    prototype__proto.weekdaysRegex       =        weekdaysRegex;
+    prototype__proto.weekdaysShortRegex  =        weekdaysShortRegex;
+    prototype__proto.weekdaysMinRegex    =        weekdaysMinRegex;
+
+    // Hours
+    prototype__proto.isPM = localeIsPM;
+    prototype__proto.meridiem = localeMeridiem;
+
+    function lists__get (format, index, field, setter) {
+        var locale = locale_locales__getLocale();
+        var utc = create_utc__createUTC().set(setter, index);
+        return locale[field](utc, format);
+    }
+
+    function listMonthsImpl (format, index, field) {
+        if (typeof format === 'number') {
+            index = format;
+            format = undefined;
+        }
+
+        format = format || '';
+
+        if (index != null) {
+            return lists__get(format, index, field, 'month');
+        }
+
+        var i;
+        var out = [];
+        for (i = 0; i < 12; i++) {
+            out[i] = lists__get(format, i, field, 'month');
+        }
+        return out;
+    }
+
+    // ()
+    // (5)
+    // (fmt, 5)
+    // (fmt)
+    // (true)
+    // (true, 5)
+    // (true, fmt, 5)
+    // (true, fmt)
+    function listWeekdaysImpl (localeSorted, format, index, field) {
+        if (typeof localeSorted === 'boolean') {
+            if (typeof format === 'number') {
+                index = format;
+                format = undefined;
+            }
+
+            format = format || '';
+        } else {
+            format = localeSorted;
+            index = format;
+            localeSorted = false;
+
+            if (typeof format === 'number') {
+                index = format;
+                format = undefined;
+            }
+
+            format = format || '';
+        }
+
+        var locale = locale_locales__getLocale(),
+            shift = localeSorted ? locale._week.dow : 0;
+
+        if (index != null) {
+            return lists__get(format, (index + shift) % 7, field, 'day');
+        }
+
+        var i;
+        var out = [];
+        for (i = 0; i < 7; i++) {
+            out[i] = lists__get(format, (i + shift) % 7, field, 'day');
+        }
+        return out;
+    }
+
+    function lists__listMonths (format, index) {
+        return listMonthsImpl(format, index, 'months');
+    }
+
+    function lists__listMonthsShort (format, index) {
+        return listMonthsImpl(format, index, 'monthsShort');
+    }
+
+    function lists__listWeekdays (localeSorted, format, index) {
+        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
+    }
+
+    function lists__listWeekdaysShort (localeSorted, format, index) {
+        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
+    }
+
+    function lists__listWeekdaysMin (localeSorted, format, index) {
+        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
+    }
+
+    locale_locales__getSetGlobalLocale('en', {
+        ordinalParse: /\d{1,2}(th|st|nd|rd)/,
+        ordinal : function (number) {
+            var b = number % 10,
+                output = (toInt(number % 100 / 10) === 1) ? 'th' :
+                (b === 1) ? 'st' :
+                (b === 2) ? 'nd' :
+                (b === 3) ? 'rd' : 'th';
+            return number + output;
+        }
+    });
+
+    // Side effect imports
+    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);
+    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);
+
+    var mathAbs = Math.abs;
+
+    function duration_abs__abs () {
+        var data           = this._data;
+
+        this._milliseconds = mathAbs(this._milliseconds);
+        this._days         = mathAbs(this._days);
+        this._months       = mathAbs(this._months);
+
+        data.milliseconds  = mathAbs(data.milliseconds);
+        data.seconds       = mathAbs(data.seconds);
+        data.minutes       = mathAbs(data.minutes);
+        data.hours         = mathAbs(data.hours);
+        data.months        = mathAbs(data.months);
+        data.years         = mathAbs(data.years);
+
+        return this;
+    }
+
+    function duration_add_subtract__addSubtract (duration, input, value, direction) {
+        var other = create__createDuration(input, value);
+
+        duration._milliseconds += direction * other._milliseconds;
+        duration._days         += direction * other._days;
+        duration._months       += direction * other._months;
+
+        return duration._bubble();
+    }
+
+    // supports only 2.0-style add(1, 's') or add(duration)
+    function duration_add_subtract__add (input, value) {
+        return duration_add_subtract__addSubtract(this, input, value, 1);
+    }
+
+    // supports only 2.0-style subtract(1, 's') or subtract(duration)
+    function duration_add_subtract__subtract (input, value) {
+        return duration_add_subtract__addSubtract(this, input, value, -1);
+    }
+
+    function absCeil (number) {
+        if (number < 0) {
+            return Math.floor(number);
+        } else {
+            return Math.ceil(number);
+        }
+    }
+
+    function bubble () {
+        var milliseconds = this._milliseconds;
+        var days         = this._days;
+        var months       = this._months;
+        var data         = this._data;
+        var seconds, minutes, hours, years, monthsFromDays;
+
+        // if we have a mix of positive and negative values, bubble down first
+        // check: https://github.com/moment/moment/issues/2166
+        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
+                (milliseconds <= 0 && days <= 0 && months <= 0))) {
+            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
+            days = 0;
+            months = 0;
+        }
+
+        // The following code bubbles up values, see the tests for
+        // examples of what that means.
+        data.milliseconds = milliseconds % 1000;
+
+        seconds           = absFloor(milliseconds / 1000);
+        data.seconds      = seconds % 60;
+
+        minutes           = absFloor(seconds / 60);
+        data.minutes      = minutes % 60;
+
+        hours             = absFloor(minutes / 60);
+        data.hours        = hours % 24;
+
+        days += absFloor(hours / 24);
+
+        // convert days to months
+        monthsFromDays = absFloor(daysToMonths(days));
+        months += monthsFromDays;
+        days -= absCeil(monthsToDays(monthsFromDays));
+
+        // 12 months -> 1 year
+        years = absFloor(months / 12);
+        months %= 12;
+
+        data.days   = days;
+        data.months = months;
+        data.years  = years;
+
+        return this;
+    }
+
+    function daysToMonths (days) {
+        // 400 years have 146097 days (taking into account leap year rules)
+        // 400 years have 12 months === 4800
+        return days * 4800 / 146097;
+    }
+
+    function monthsToDays (months) {
+        // the reverse of daysToMonths
+        return months * 146097 / 4800;
+    }
+
+    function as (units) {
+        var days;
+        var months;
+        var milliseconds = this._milliseconds;
+
+        units = normalizeUnits(units);
+
+        if (units === 'month' || units === 'year') {
+            days   = this._days   + milliseconds / 864e5;
+            months = this._months + daysToMonths(days);
+            return units === 'month' ? months : months / 12;
+        } else {
+            // handle milliseconds separately because of floating point math errors (issue #1867)
+            days = this._days + Math.round(monthsToDays(this._months));
+            switch (units) {
+                case 'week'   : return days / 7     + milliseconds / 6048e5;
+                case 'day'    : return days         + milliseconds / 864e5;
+                case 'hour'   : return days * 24    + milliseconds / 36e5;
+                case 'minute' : return days * 1440  + milliseconds / 6e4;
+                case 'second' : return days * 86400 + milliseconds / 1000;
+                // Math.floor prevents floating point math errors here
+                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
+                default: throw new Error('Unknown unit ' + units);
+            }
+        }
+    }
+
+    // TODO: Use this.as('ms')?
+    function duration_as__valueOf () {
+        return (
+            this._milliseconds +
+            this._days * 864e5 +
+            (this._months % 12) * 2592e6 +
+            toInt(this._months / 12) * 31536e6
+        );
+    }
+
+    function makeAs (alias) {
+        return function () {
+            return this.as(alias);
+        };
+    }
+
+    var asMilliseconds = makeAs('ms');
+    var asSeconds      = makeAs('s');
+    var asMinutes      = makeAs('m');
+    var asHours        = makeAs('h');
+    var asDays         = makeAs('d');
+    var asWeeks        = makeAs('w');
+    var asMonths       = makeAs('M');
+    var asYears        = makeAs('y');
+
+    function duration_get__get (units) {
+        units = normalizeUnits(units);
+        return this[units + 's']();
+    }
+
+    function makeGetter(name) {
+        return function () {
+            return this._data[name];
+        };
+    }
+
+    var milliseconds = makeGetter('milliseconds');
+    var seconds      = makeGetter('seconds');
+    var minutes      = makeGetter('minutes');
+    var hours        = makeGetter('hours');
+    var days         = makeGetter('days');
+    var months       = makeGetter('months');
+    var years        = makeGetter('years');
+
+    function weeks () {
+        return absFloor(this.days() / 7);
+    }
+
+    var round = Math.round;
+    var thresholds = {
+        s: 45,  // seconds to minute
+        m: 45,  // minutes to hour
+        h: 22,  // hours to day
+        d: 26,  // days to month
+        M: 11   // months to year
+    };
+
+    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
+    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
+        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
+    }
+
+    function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {
+        var duration = create__createDuration(posNegDuration).abs();
+        var seconds  = round(duration.as('s'));
+        var minutes  = round(duration.as('m'));
+        var hours    = round(duration.as('h'));
+        var days     = round(duration.as('d'));
+        var months   = round(duration.as('M'));
+        var years    = round(duration.as('y'));
+
+        var a = seconds < thresholds.s && ['s', seconds]  ||
+                minutes <= 1           && ['m']           ||
+                minutes < thresholds.m && ['mm', minutes] ||
+                hours   <= 1           && ['h']           ||
+                hours   < thresholds.h && ['hh', hours]   ||
+                days    <= 1           && ['d']           ||
+                days    < thresholds.d && ['dd', days]    ||
+                months  <= 1           && ['M']           ||
+                months  < thresholds.M && ['MM', months]  ||
+                years   <= 1           && ['y']           || ['yy', years];
+
+        a[2] = withoutSuffix;
+        a[3] = +posNegDuration > 0;
+        a[4] = locale;
+        return substituteTimeAgo.apply(null, a);
+    }
+
+    // This function allows you to set the rounding function for relative time strings
+    function duration_humanize__getSetRelativeTimeRounding (roundingFunction) {
+        if (roundingFunction === undefined) {
+            return round;
+        }
+        if (typeof(roundingFunction) === 'function') {
+            round = roundingFunction;
+            return true;
+        }
+        return false;
+    }
+
+    // This function allows you to set a threshold for relative time strings
+    function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {
+        if (thresholds[threshold] === undefined) {
+            return false;
+        }
+        if (limit === undefined) {
+            return thresholds[threshold];
+        }
+        thresholds[threshold] = limit;
+        return true;
+    }
+
+    function humanize (withSuffix) {
+        var locale = this.localeData();
+        var output = duration_humanize__relativeTime(this, !withSuffix, locale);
+
+        if (withSuffix) {
+            output = locale.pastFuture(+this, output);
+        }
+
+        return locale.postformat(output);
+    }
+
+    var iso_string__abs = Math.abs;
+
+    function iso_string__toISOString() {
+        // for ISO strings we do not use the normal bubbling rules:
+        //  * milliseconds bubble up until they become hours
+        //  * days do not bubble at all
+        //  * months bubble up until they become years
+        // This is because there is no context-free conversion between hours and days
+        // (think of clock changes)
+        // and also not between days and months (28-31 days per month)
+        var seconds = iso_string__abs(this._milliseconds) / 1000;
+        var days         = iso_string__abs(this._days);
+        var months       = iso_string__abs(this._months);
+        var minutes, hours, years;
+
+        // 3600 seconds -> 60 minutes -> 1 hour
+        minutes           = absFloor(seconds / 60);
+        hours             = absFloor(minutes / 60);
+        seconds %= 60;
+        minutes %= 60;
+
+        // 12 months -> 1 year
+        years  = absFloor(months / 12);
+        months %= 12;
+
+
+        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
+        var Y = years;
+        var M = months;
+        var D = days;
+        var h = hours;
+        var m = minutes;
+        var s = seconds;
+        var total = this.asSeconds();
+
+        if (!total) {
+            // this is the same as C#'s (Noda) and python (isodate)...
+            // but not other JS (goog.date)
+            return 'P0D';
+        }
+
+        return (total < 0 ? '-' : '') +
+            'P' +
+            (Y ? Y + 'Y' : '') +
+            (M ? M + 'M' : '') +
+            (D ? D + 'D' : '') +
+            ((h || m || s) ? 'T' : '') +
+            (h ? h + 'H' : '') +
+            (m ? m + 'M' : '') +
+            (s ? s + 'S' : '');
+    }
+
+    var duration_prototype__proto = Duration.prototype;
+
+    duration_prototype__proto.abs            = duration_abs__abs;
+    duration_prototype__proto.add            = duration_add_subtract__add;
+    duration_prototype__proto.subtract       = duration_add_subtract__subtract;
+    duration_prototype__proto.as             = as;
+    duration_prototype__proto.asMilliseconds = asMilliseconds;
+    duration_prototype__proto.asSeconds      = asSeconds;
+    duration_prototype__proto.asMinutes      = asMinutes;
+    duration_prototype__proto.asHours        = asHours;
+    duration_prototype__proto.asDays         = asDays;
+    duration_prototype__proto.asWeeks        = asWeeks;
+    duration_prototype__proto.asMonths       = asMonths;
+    duration_prototype__proto.asYears        = asYears;
+    duration_prototype__proto.valueOf        = duration_as__valueOf;
+    duration_prototype__proto._bubble        = bubble;
+    duration_prototype__proto.get            = duration_get__get;
+    duration_prototype__proto.milliseconds   = milliseconds;
+    duration_prototype__proto.seconds        = seconds;
+    duration_prototype__proto.minutes        = minutes;
+    duration_prototype__proto.hours          = hours;
+    duration_prototype__proto.days           = days;
+    duration_prototype__proto.weeks          = weeks;
+    duration_prototype__proto.months         = months;
+    duration_prototype__proto.years          = years;
+    duration_prototype__proto.humanize       = humanize;
+    duration_prototype__proto.toISOString    = iso_string__toISOString;
+    duration_prototype__proto.toString       = iso_string__toISOString;
+    duration_prototype__proto.toJSON         = iso_string__toISOString;
+    duration_prototype__proto.locale         = locale;
+    duration_prototype__proto.localeData     = localeData;
+
+    // Deprecations
+    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);
+    duration_prototype__proto.lang = lang;
+
+    // Side effect imports
+
+    // FORMATTING
+
+    addFormatToken('X', 0, 0, 'unix');
+    addFormatToken('x', 0, 0, 'valueOf');
+
+    // PARSING
+
+    addRegexToken('x', matchSigned);
+    addRegexToken('X', matchTimestamp);
+    addParseToken('X', function (input, array, config) {
+        config._d = new Date(parseFloat(input, 10) * 1000);
+    });
+    addParseToken('x', function (input, array, config) {
+        config._d = new Date(toInt(input));
+    });
+
+    // Side effect imports
+
+
+    utils_hooks__hooks.version = '2.15.1';
+
+    setHookCallback(local__createLocal);
+
+    utils_hooks__hooks.fn                    = momentPrototype;
+    utils_hooks__hooks.min                   = min;
+    utils_hooks__hooks.max                   = max;
+    utils_hooks__hooks.now                   = now;
+    utils_hooks__hooks.utc                   = create_utc__createUTC;
+    utils_hooks__hooks.unix                  = moment__createUnix;
+    utils_hooks__hooks.months                = lists__listMonths;
+    utils_hooks__hooks.isDate                = isDate;
+    utils_hooks__hooks.locale                = locale_locales__getSetGlobalLocale;
+    utils_hooks__hooks.invalid               = valid__createInvalid;
+    utils_hooks__hooks.duration              = create__createDuration;
+    utils_hooks__hooks.isMoment              = isMoment;
+    utils_hooks__hooks.weekdays              = lists__listWeekdays;
+    utils_hooks__hooks.parseZone             = moment__createInZone;
+    utils_hooks__hooks.localeData            = locale_locales__getLocale;
+    utils_hooks__hooks.isDuration            = isDuration;
+    utils_hooks__hooks.monthsShort           = lists__listMonthsShort;
+    utils_hooks__hooks.weekdaysMin           = lists__listWeekdaysMin;
+    utils_hooks__hooks.defineLocale          = defineLocale;
+    utils_hooks__hooks.updateLocale          = updateLocale;
+    utils_hooks__hooks.locales               = locale_locales__listLocales;
+    utils_hooks__hooks.weekdaysShort         = lists__listWeekdaysShort;
+    utils_hooks__hooks.normalizeUnits        = normalizeUnits;
+    utils_hooks__hooks.relativeTimeRounding = duration_humanize__getSetRelativeTimeRounding;
+    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;
+    utils_hooks__hooks.calendarFormat        = getCalendarFormat;
+    utils_hooks__hooks.prototype             = momentPrototype;
+
+    var _moment = utils_hooks__hooks;
+
+    return _moment;
+
+}));

+ 28 - 0
Day61-65/code/project_of_tornado/assets/js/theme.js

@@ -0,0 +1,28 @@
+var saveSelectColor = {
+    'Name': 'SelcetColor',
+    'Color': 'theme-black'
+}
+
+
+
+// 判断用户是否已有自己选择的模板风格
+if (storageLoad('SelcetColor')) {
+    $('body').attr('class', storageLoad('SelcetColor').Color)
+} else {
+    storageSave(saveSelectColor);
+    $('body').attr('class', 'theme-black')
+}
+
+
+// 本地缓存
+function storageSave(objectData) {
+    localStorage.setItem(objectData.Name, JSON.stringify(objectData));
+}
+
+function storageLoad(objectName) {
+    if (localStorage.getItem(objectName)) {
+        return JSON.parse(localStorage.getItem(objectName))
+    } else {
+        return false
+    }
+}

+ 54 - 0
Day61-65/code/project_of_tornado/backend_server.py

@@ -0,0 +1,54 @@
+"""
+backend_server.py - 后台服务器
+"""
+import asyncio
+import os
+import threading
+
+import aiomysql
+import tornado.web
+
+from tornado.ioloop import IOLoop
+from tornado.platform.asyncio import AnyThreadEventLoopPolicy
+
+from service.handlers.handlers_for_charts import send_data
+from service.handlers.handlers_for_nav import IndexHandler
+from service.handlers.handlers_for_tables import EmpHandler
+from service.handlers.handlers_for_charts import ChartHandler
+
+
+async def connect_mysql():
+    return await aiomysql.connect(
+        host='120.77.222.217',
+        port=3306,
+        db='hrs',
+        charset='utf8',
+        use_unicode=True,
+        user='root',
+        password='123456',
+    )
+
+
+def main():
+    # Tornado 5开始使用线程必须指定事件循环的策略否则无法启动线程
+    asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())
+    # 启动通过WebSocket长连接发送数据的线程
+    threading.Thread(target=send_data, daemon=True, args=(5, )).start()
+    app = tornado.web.Application(
+        handlers=[
+            (r'/', IndexHandler),
+            (r'/api/emps', EmpHandler),
+            (r'/ws/charts', ChartHandler),
+        ],
+        template_path=os.path.join(os.path.dirname(__file__), 'templates'),
+        static_path=os.path.join(os.path.dirname(__file__), 'assets'),
+        cookie_secret='MWM2MzEyOWFlOWRiOWM2MGMzZThhYTk0ZDNlMDA0OTU=',
+        mysql=IOLoop.current().run_sync(connect_mysql),
+        debug=True
+    )
+    app.listen(8888)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()

+ 8 - 0
Day61-65/code/project_of_tornado/requirements.txt

@@ -0,0 +1,8 @@
+aiomysql==0.0.20
+asn1crypto==0.24.0
+cffi==1.12.2
+cryptography==2.6.1
+pycparser==2.19
+PyMySQL==0.9.2
+six==1.12.0
+tornado==5.1.1

+ 0 - 0
Day61-65/code/project_of_tornado/service/__init__.py


+ 0 - 0
Day61-65/code/project_of_tornado/service/handlers/__init__.py


+ 34 - 0
Day61-65/code/project_of_tornado/service/handlers/handlers_for_charts.py

@@ -0,0 +1,34 @@
+import json
+import random
+import time
+
+import tornado.websocket
+
+clients_set = set()
+
+
+class ChartHandler(tornado.websocket.WebSocketHandler):
+
+    def open(self):
+        clients_set.add(self)
+
+    def on_close(self):
+        clients_set.remove(self)
+
+
+def gen_mock_data(num_of_series, num_of_sample):
+    data = []
+    for _ in range(num_of_series):
+        series = []
+        for _ in range(num_of_sample):
+            series.append(random.randint(50, 500))
+        data.append(series)
+    return data
+
+
+def send_data(delay):
+    while True:
+        for ws_client in clients_set:
+            data = gen_mock_data(3, 7)
+            ws_client.write_message(json.dumps(data).encode())
+        time.sleep(delay)

+ 7 - 0
Day61-65/code/project_of_tornado/service/handlers/handlers_for_nav.py

@@ -0,0 +1,7 @@
+import tornado
+
+
+class IndexHandler(tornado.web.RequestHandler):
+
+    async def get(self, *args, **kwargs):
+        return await self.render('index.html')

+ 13 - 0
Day61-65/code/project_of_tornado/service/handlers/handlers_for_tables.py

@@ -0,0 +1,13 @@
+import json
+
+import aiomysql
+import tornado
+
+
+class EmpHandler(tornado.web.RequestHandler):
+
+    async def get(self, *args, **kwargs):
+        async with self.settings['mysql'].cursor(aiomysql.DictCursor) as cursor:
+            await cursor.execute("select eno as no, ename as name, job, sal, intro from tb_emp")
+            emps = list(await cursor.fetchall())
+            self.finish(json.dumps(emps))

+ 511 - 0
Day61-65/code/project_of_tornado/templates/index.html

@@ -0,0 +1,511 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>后台数据监控项目</title>
+    <meta name="description" content="这是一个 index 页面">
+    <meta name="keywords" content="index">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="Cache-Control" content="no-siteapp" />
+    <link rel="icon" type="image/png" href="{{ static_url('i/favicon.png') }}">
+    <link rel="apple-touch-icon-precomposed" href="{{ static_url('i/app-icon72x72@2x.png') }}">
+    <meta name="apple-mobile-web-app-title" content="Amaze UI" />
+    <script src="{{ static_url('js/echarts.min.js') }}"></script>
+    <link rel="stylesheet" href="{{ static_url('css/amazeui.min.css') }}" />
+    <link rel="stylesheet" href="{{ static_url('css/amazeui.datatables.min.css') }}" />
+    <link rel="stylesheet" href="{{ static_url('css/app.css') }}">
+    <script src="{{ static_url('js/jquery.min.js') }}"></script>
+</head>
+<body data-type="index">
+    <script src="{{ static_url('js/theme.js') }}"></script>
+    <div class="am-g tpl-g">
+        <!-- 头部 -->
+        <header>
+            <!-- logo -->
+            <div class="am-fl tpl-header-logo">
+                <a href="javascript:;"><img src="{{ static_url('img/logo.png') }}" alt=""></a>
+            </div>
+            <!-- 右侧内容 -->
+            <div class="tpl-header-fluid">
+                <!-- 侧边切换 -->
+                <div class="am-fl tpl-header-switch-button am-icon-list">
+                    <span>
+
+                </span>
+                </div>
+                <!-- 搜索 -->
+                <div class="am-fl tpl-header-search">
+                    <form class="tpl-header-search-form" action="javascript:;">
+                        <button class="tpl-header-search-btn am-icon-search"></button>
+                        <input class="tpl-header-search-box" type="text" placeholder="搜索内容...">
+                    </form>
+                </div>
+                <!-- 其它功能-->
+                <div class="am-fr tpl-header-navbar">
+                    <ul>
+                        <!-- 欢迎语 -->
+                        <li class="am-text-sm tpl-header-navbar-welcome">
+                            <a href="javascript:;">欢迎你, <span>Amaze UI</span> </a>
+                        </li>
+
+                        <!-- 新邮件 -->
+                        <li class="am-dropdown tpl-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle tpl-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-envelope"></i>
+                                <span class="am-badge am-badge-success am-round item-feed-badge">4</span>
+                            </a>
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="{{ static_url('img/user04.png') }}" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            3小时前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-success"></i>
+                                                <span>夕风色</span>
+                                            </div>
+                                            <div class="am-text-truncate"> Amaze UI 的诞生,依托于 GitHub 及其他技术社区上一些优秀的资源;Amaze UI 的成长,则离不开用户的支持。 </div>
+                                            <div class="menu-messages-content-time">2016-09-21 下午 16:40</div>
+                                        </div>
+                                    </a>
+                                </li>
+
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <div class="menu-messages-ico">
+                                            <img src="{{ static_url('img/user02.png') }}" alt="">
+                                        </div>
+                                        <div class="menu-messages-time">
+                                            5天前
+                                        </div>
+                                        <div class="menu-messages-content">
+                                            <div class="menu-messages-content-title">
+                                                <i class="am-icon-circle-o am-text-warning"></i>
+                                                <span>禁言小张</span>
+                                            </div>
+                                            <div class="am-text-truncate"> 为了能最准确的传达所描述的问题, 建议你在反馈时附上演示,方便我们理解。 </div>
+                                            <div class="menu-messages-content-time">2016-09-16 上午 09:23</div>
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-messages">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-messages-item am-cf">
+                                        <i class="am-icon-circle-o"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+
+                        <!-- 新提示 -->
+                        <li class="am-dropdown" data-am-dropdown>
+                            <a href="javascript:;" class="am-dropdown-toggle" data-am-dropdown-toggle>
+                                <i class="am-icon-bell"></i>
+                                <span class="am-badge am-badge-warning am-round item-feed-badge">5</span>
+                            </a>
+
+                            <!-- 弹出列表 -->
+                            <ul class="am-dropdown-content tpl-dropdown-content">
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-line-chart"></i>
+                                            <span> 有6笔新的销售订单</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            12分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-star"></i>
+                                            <span> 有3个来自人事部的消息</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            30分钟前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <div class="tpl-dropdown-menu-notifications-title">
+                                            <i class="am-icon-folder-o"></i>
+                                            <span> 上午开会记录存档</span>
+                                        </div>
+                                        <div class="tpl-dropdown-menu-notifications-time">
+                                            1天前
+                                        </div>
+                                    </a>
+                                </li>
+                                <li class="tpl-dropdown-menu-notifications">
+                                    <a href="javascript:;" class="tpl-dropdown-menu-notifications-item am-cf">
+                                        <i class="am-icon-bell"></i> 进入列表…
+                                    </a>
+                                </li>
+                            </ul>
+                        </li>
+                        <!-- 退出 -->
+                        <li class="am-text-sm">
+                            <a href="javascript:;">
+                                <span class="am-icon-sign-out"></span> 退出
+                            </a>
+                        </li>
+                    </ul>
+                </div>
+            </div>
+
+        </header>
+        <!-- 风格切换 -->
+        <div class="tpl-skiner">
+            <div class="tpl-skiner-toggle am-icon-cog">
+            </div>
+            <div class="tpl-skiner-content">
+                <div class="tpl-skiner-content-title">
+                    选择主题
+                </div>
+                <div class="tpl-skiner-content-bar">
+                    <span class="skiner-color skiner-white" data-color="theme-white"></span>
+                    <span class="skiner-color skiner-black" data-color="theme-black"></span>
+                </div>
+            </div>
+        </div>
+        <!-- 侧边导航栏 -->
+        <div class="left-sidebar">
+            <!-- 用户信息 -->
+            <div class="tpl-sidebar-user-panel">
+                <div class="tpl-user-panel-slide-toggleable">
+                    <div class="tpl-user-panel-profile-picture">
+                        <img src="{{ static_url('img/user04.png') }}" alt="">
+                    </div>
+                    <span class="user-panel-logged-in-text">
+                      <i class="am-icon-circle-o am-text-success tpl-user-panel-status-icon"></i>
+                      禁言小张
+                  </span>
+                    <a href="javascript:;" class="tpl-user-panel-action-link"> <span class="am-icon-pencil"></span> 账号设置</a>
+                </div>
+            </div>
+            <!-- 菜单 -->
+            <ul class="sidebar-nav">
+                <li class="sidebar-nav-heading">Components <span class="sidebar-nav-heading-info"> 附加组件</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="/" class="active">
+                        <i class="am-icon-home sidebar-nav-link-logo"></i> 首页
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="{{ static_url('html/tables.html') }}">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 表格
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="{{ static_url('html/calendar.html') }}">
+                        <i class="am-icon-calendar sidebar-nav-link-logo"></i> 日历
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="{{ static_url('html/form.html') }}">
+                        <i class="am-icon-wpforms sidebar-nav-link-logo"></i> 表单
+
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="{{ static_url('html/chart.html') }}">
+                        <i class="am-icon-bar-chart sidebar-nav-link-logo"></i> 图表
+
+                    </a>
+                </li>
+
+                <li class="sidebar-nav-heading">Page<span class="sidebar-nav-heading-info"> 常用页面</span></li>
+                <li class="sidebar-nav-link">
+                    <a href="javascript:;" class="sidebar-nav-sub-title">
+                        <i class="am-icon-table sidebar-nav-link-logo"></i> 数据列表
+                        <span class="am-icon-chevron-down am-fr am-margin-right-sm sidebar-nav-sub-ico"></span>
+                    </a>
+                    <ul class="sidebar-nav sidebar-nav-sub">
+                        <li class="sidebar-nav-link">
+                            <a href="{{ static_url('html/table-list.html') }}">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 文字列表
+                            </a>
+                        </li>
+
+                        <li class="sidebar-nav-link">
+                            <a href="{{ static_url('html/table-list-img.html') }}">
+                                <span class="am-icon-angle-right sidebar-nav-link-logo"></span> 图文列表
+                            </a>
+                        </li>
+                    </ul>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="{{ static_url('html/sign-up.html') }}">
+                        <i class="am-icon-clone sidebar-nav-link-logo"></i> 注册
+                        <span class="am-badge am-badge-secondary sidebar-nav-link-logo-ico am-round am-fr am-margin-right-sm">6</span>
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="{{ static_url('html/login.html') }}">
+                        <i class="am-icon-key sidebar-nav-link-logo"></i> 登录
+                    </a>
+                </li>
+                <li class="sidebar-nav-link">
+                    <a href="{{ static_url('html/404.html') }}">
+                        <i class="am-icon-tv sidebar-nav-link-logo"></i> 404错误
+                    </a>
+                </li>
+
+            </ul>
+        </div>
+
+        <!-- 内容区域 -->
+        <div class="tpl-content-wrapper">
+            <div class="container-fluid am-cf">
+                <div class="row">
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-9">
+                        <div class="page-header-heading"><span class="am-icon-home page-header-heading-icon"></span> 部件首页 <small>Amaze UI</small></div>
+                        <p class="page-header-description">Amaze UI 含近 20 个 CSS 组件、20 余 JS 组件,更有多个包含不同主题的 Web 组件。</p>
+                    </div>
+                    <div class="am-u-lg-3 tpl-index-settings-button">
+                        <button type="button" class="page-header-button"><span class="am-icon-paint-brush"></span> 设置</button>
+                    </div>
+                </div>
+            </div>
+
+            <div class="row-content am-cf">
+                <div class="row  am-cf">
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-4">
+                        <div class="widget am-cf">
+                            <div class="widget-head am-cf">
+                                <div class="widget-title am-fl">月度财务收支计划</div>
+                                <div class="widget-function am-fr">
+                                    <a href="javascript:;" class="am-icon-cog"></a>
+                                </div>
+                            </div>
+                            <div class="widget-body am-fr">
+                                <div class="am-fl">
+                                    <div class="widget-fluctuation-period-text">
+                                        ¥61746.45
+                                        <button class="widget-fluctuation-tpl-btn">
+                        <i class="am-icon-calendar"></i>
+                        更多月份
+                      </button>
+                                    </div>
+                                </div>
+                                <div class="am-fr am-cf">
+                                    <div class="widget-fluctuation-description-amount text-success" am-cf>
+                                        +¥30420.56
+
+                                    </div>
+                                    <div class="widget-fluctuation-description-text am-text-right">
+                                        8月份收入
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+
+                    </div>
+                    <div class="am-u-sm-12 am-u-md-6 am-u-lg-4">
+                        <div class="widget widget-primary am-cf">
+                            <div class="widget-statistic-header">
+                                本季度利润
+                            </div>
+                            <div class="widget-statistic-body">
+                                <div class="widget-statistic-value">
+                                    ¥27,294
+                                </div>
+                                <div class="widget-statistic-description">
+                                    本季度比去年多收入 <strong>2593元</strong> 人民币
+                                </div>
+                                <span class="widget-statistic-icon am-icon-credit-card-alt"></span>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="am-u-sm-12 am-u-md-6 am-u-lg-4">
+                        <div class="widget widget-purple am-cf">
+                            <div class="widget-statistic-header">
+                                本季度利润
+                            </div>
+                            <div class="widget-statistic-body">
+                                <div class="widget-statistic-value">
+                                    ¥27,294
+                                </div>
+                                <div class="widget-statistic-description">
+                                    本季度比去年多收入 <strong>2593元</strong> 人民币
+                                </div>
+                                <span class="widget-statistic-icon am-icon-support"></span>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="row am-cf">
+                    <div class="am-u-sm-12 am-u-md-8">
+                        <div class="widget am-cf">
+                            <div class="widget-head am-cf">
+                                <div class="widget-title am-fl">月度财务收支计划</div>
+                                <div class="widget-function am-fr">
+                                    <a href="javascript:;" class="am-icon-cog"></a>
+                                </div>
+                            </div>
+                            <div class="widget-body-md widget-body tpl-amendment-echarts am-fr" id="tpl-echarts">
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="am-u-sm-12 am-u-md-4">
+                        <div class="widget am-cf">
+                            <div class="widget-head am-cf">
+                                <div class="widget-title am-fl">专用服务器负载</div>
+                                <div class="widget-function am-fr">
+                                    <a href="javascript:;" class="am-icon-cog"></a>
+                                </div>
+                            </div>
+                            <div class="widget-body widget-body-md am-fr">
+                                <div class="am-progress-title">CPU Load <span class="am-fr am-progress-title-more">28% / 100%</span></div>
+                                <div class="am-progress">
+                                    <div class="am-progress-bar" style="width: 15%"></div>
+                                </div>
+                                <div class="am-progress-title">CPU Load <span class="am-fr am-progress-title-more">28% / 100%</span></div>
+                                <div class="am-progress">
+                                    <div class="am-progress-bar  am-progress-bar-warning" style="width: 75%"></div>
+                                </div>
+                                <div class="am-progress-title">CPU Load <span class="am-fr am-progress-title-more">28% / 100%</span></div>
+                                <div class="am-progress">
+                                    <div class="am-progress-bar am-progress-bar-danger" style="width: 35%"></div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+
+
+                <div class="row am-cf">
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-4 widget-margin-bottom-lg ">
+                        <div class="tpl-user-card am-text-center widget-body-lg">
+                            <div class="tpl-user-card-title">
+                                禁言小张
+                            </div>
+                            <div class="achievement-subheading">
+                                月度最佳员工
+                            </div>
+                            <img class="achievement-image" src="{{ static_url('img/user07.png') }}" alt="">
+                            <div class="achievement-description">
+                                禁言小张在
+                                <strong>30天内</strong> 禁言了
+                                <strong>200多</strong>人。
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="am-u-sm-12 am-u-md-12 am-u-lg-8 widget-margin-bottom-lg">
+                        <div class="widget am-cf widget-body-lg">
+                            <div class="widget-body  am-fr">
+                                <div class="am-scrollable-horizontal ">
+                                    <table width="100%" class="am-table am-table-compact am-text-nowrap tpl-table-black " id="example-r">
+                                        <thead>
+                                            <tr>
+                                                <th>文章标题</th>
+                                                <th>作者</th>
+                                                <th>时间</th>
+                                                <th>操作</th>
+                                            </tr>
+                                        </thead>
+                                        <tbody>
+                                            <tr class="gradeX">
+                                                <td>新加坡大数据初创公司 Latize 获 150 万美元风险融资</td>
+                                                <td>张鹏飞</td>
+                                                <td>2016-09-26</td>
+                                                <td>
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            <tr class="even gradeC">
+                                                <td>自拍的“政治角色”:观众背对希拉里自拍合影表示“支持”</td>
+                                                <td>天纵之人</td>
+                                                <td>2016-09-26</td>
+                                                <td>
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            <tr class="gradeX">
+                                                <td>关于创新管理,我想和你当面聊聊。</td>
+                                                <td>王宽师</td>
+                                                <td>2016-09-26</td>
+                                                <td>
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            <tr class="even gradeC">
+                                                <td>究竟是趋势带动投资,还是投资引领趋势?</td>
+                                                <td>着迷</td>
+                                                <td>2016-09-26</td>
+                                                <td>
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                            <tr class="even gradeC">
+                                                <td>Docker领域再添一员,网易云发布“蜂巢”,加入云计算之争</td>
+                                                <td>醉里挑灯看键</td>
+                                                <td>2016-09-26</td>
+                                                <td>
+                                                    <div class="tpl-table-black-operation">
+                                                        <a href="javascript:;">
+                                                            <i class="am-icon-pencil"></i> 编辑
+                                                        </a>
+                                                        <a href="javascript:;" class="tpl-table-black-operation-del">
+                                                            <i class="am-icon-trash"></i> 删除
+                                                        </a>
+                                                    </div>
+                                                </td>
+                                            </tr>
+                                        </tbody>
+                                    </table>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    </div>
+    <script src="{{ static_url('js/amazeui.min.js') }}"></script>
+    <script src="{{ static_url('js/amazeui.datatables.min.js') }}"></script>
+    <script src="{{ static_url('js/dataTables.responsive.min.js') }}"></script>
+    <script src="{{ static_url('js/app.js') }}"></script>
+</body>
+</html>

BIN
Day61-65/res/run-hello-world-app.png


BIN
Day61-65/res/websocket.png


BIN
Day61-65/res/ws_wss.png


Деякі файли не було показано, через те що забагато файлів було змінено