diff --git a/2019/12/30/hello-world/index.html b/2019/12/30/hello-world/index.html new file mode 100644 index 0000000..1a1765a --- /dev/null +++ b/2019/12/30/hello-world/index.html @@ -0,0 +1,16 @@ +Hello World | 随言碎语

随言碎语

咕叽咕叽

Hello World

欢迎来到我的博客,这是我的第一篇博客,由hexo+next构建。

0%
\ No newline at end of file diff --git a/2020/01/03/VMware安装centos7/index.html b/2020/01/03/VMware安装centos7/index.html new file mode 100644 index 0000000..4e19a5d --- /dev/null +++ b/2020/01/03/VMware安装centos7/index.html @@ -0,0 +1,16 @@ +VMware安装centos7 | 随言碎语

随言碎语

咕叽咕叽

VMware安装centos7

在VMware Workstation上安装centos。

1. 准备:

  • VMware Workstation

  • 镜像文件:CentOS-7-x86_64-bin-DVD1.iso

2. 新建虚拟机

  1. 新建虚拟机,选择自定义

  2. 硬盘兼容性–默认

image-20230422105921574

  1. 稍后安装操作系统(需要在虚拟机安装完成之后,删除不需要的硬件,所以稍后安装操作系统)

  2. 择客户端操作系统:客户机操作系统–Linux版本centos 64位

  3. 处理器配置(CPU)和内存,按需要配置

  4. 网络类型–桥接网络(可以使虚拟机与主机使用同一网络)

  • 注:若是NAT和仅主机模式,需要注意网卡的地址,创建的虚拟机和所使用的网卡在同一个网段。
  1. 选择I/O控制器类型、磁盘类型和创建新的虚拟磁盘(一般默认就行)

  2. 指定磁盘容量(不低于20G)

  3. 指定磁盘文件(.vmdk)文件

  4. 完成后,删除不必要的设备

    image-20230422111309578

  5. 选中CD/DVD,使用ISO镜像文件-选择镜像文件

    image-20230422111531776

12.确定后,打开这个虚拟机的电源

image-20230422114456361

3. 进入centos7安装页面

  1. 选择install centos7

image-20230422111901398

  1. 设置语言–使用中文-简体中文–点击继续

image-20230422114739708

  • 注:如果这里选择了中文简体,那么键盘布局一定要选择英文
  1. 进一步设置要安装的信息

    image-20230422115039348

    软件选择:这里我们选择最小化安装,即只有最基础的系统,没有桌面

    image-20230422115156841

  2. 系统安装位置,点进去进行自定义分区(如果没有特别的要求,默认分区也行)

    image-20230422115350829
    4.1 若需要自主分区,点击我要配置分区
    image-20230422115507917
    4.2 选择标准分组,点击**+**
    image-20230422115613958
    4.3 依次添加新挂载点:/boot;swap;/;
    image-20230422115944392
    注:

    • /boot 分区:是引导分区;作用:系统启动,在boot分区存放着grub,内核文件等,一般200M就够了。
    • swap交换分区:内存扩展分区;一般也就2G 。
    • / 根目录:10G左右,数据一般也不会直接放在根目录下。

    4.4 点击完成,接受更改即可。

    image-20230422120644423

  3. 关掉KDUMP

    image-20230422120802249

  4. 配置网络和主机名

    image-20230422120925893

    网络要根据自己的环境和需求去配置,配置后点击保存即可。

  5. 安全策略保持默认的即可,直接点击开始安装

    image-20230422121138262

  6. 设置用户名和密码(主要是设置root密码,创建用户可以不做)

    image-20230422121219185

    点击root密码,输入密码点击完成。

    image-20230422121357933

  7. 点击重启,等待系统安装完成即可使用了

    image-20230422121530317

0%
\ No newline at end of file diff --git a/2023/03/23/esxi+openwrt+dsm+homeassistant-软路由all-in-one/index.html b/2023/03/23/esxi+openwrt+dsm+homeassistant-软路由all-in-one/index.html new file mode 100644 index 0000000..593587c --- /dev/null +++ b/2023/03/23/esxi+openwrt+dsm+homeassistant-软路由all-in-one/index.html @@ -0,0 +1,16 @@ +esxi+openwrt+dsm+homeassistant 软路由 all in one | 随言碎语

随言碎语

咕叽咕叽

esxi+openwrt+dsm+homeassistant 软路由 all in one

软路由 all in one,在J425小主机上安装esxi+openwrt+dsm+homeassistant,集软路由、网盘、智能家居控制于一体。

硬件介绍

软件安装

  1. esxi8.0安装
  2. esxi+openwrt作为旁路由
  3. esxi安装群晖dsm7.1
  4. esxi安装homeassistant
0%
\ No newline at end of file diff --git a/2023/03/23/esxi8.0安装/index.html b/2023/03/23/esxi8.0安装/index.html new file mode 100644 index 0000000..a33991b --- /dev/null +++ b/2023/03/23/esxi8.0安装/index.html @@ -0,0 +1,16 @@ +esxi8.0安装 | 随言碎语

随言碎语

咕叽咕叽

esxi8.0安装

esxi 8.0的安装。

准备工具

硬件:

  • 8G以上U盘一个
  • 待安装的主机一套

软件:

  • rufus-3.15p.exe 用来刻录镜像

  • VMware-VMvisor-Installer-8.0.0-21203435.x86_64-Dell_Customized-A03.iso

    注:这里使用的是DELL定制版本,其他版本可从官网下载。操作步骤都是一样的

刻录镜像到启动U盘

  1. 打开rufus-3.15p.exe
    image-20230422123404610
  2. 依次选择U盘,选择镜像文件,点击开始。
  3. 写入完成后拔下U盘。

安装ESXI8.0

  1. 将写好的U盘插到机器上,开机进入bios页面,选择从U盘启动。

  2. 在加载页面按 SHIFT+O (5秒倒计时结束前按)

    image-20230422124229021

  3. 输入autoParititionOSDataSize=8192设置缓存大小

    image-20230422130103695

    • 注:如果不设置的话,默认是划分120G
  4. 等待页面加载

    image-20230422130452177

  5. 按回车确定,然后F11接受协议。

    image-20230422130636232

  6. 选择安装的硬盘,建议安装到SSD盘

    image-20230422131134063

  7. 如果之前安装过,会让选择安装方式。如果之前的不想要的,就直接选择第三个覆盖安装。(按空格选中,回车确定)

    image-20230422131415703

  8. 键盘选择US Default

    image-20230422131519284

  9. 设置root密码,并确认安装

    image-20230422131707324

  10. 安装完成后,会提示拔出U盘并重启

    image-20230422131850437

  11. 重启后显示下图的页面即表示成功了

    image-20230422131945389

给ESXi 设置为静态 IP

  1. 按 F2 进入,提示需要输入账户密码,用户名为 root,密码为刚刚安装时设置的密码,然后回车。

    image-20230422132154911

  2. 选择**configure management network **

    image-20230422132512778

  3. 然后选择 IPV4 configuration 回车

    image-20230422132558114

  4. 接着移动光标到第三项,随后按空格键确定选择

  5. 接着填入你需要设置的 ESXi 静态 IP 地址。

    image-20230422132853991

第一行填入 esxi 的静态 IP,第二行填入子网掩码 255.255.255.0,第三行填写路由器的网关地址,设置好后回车即可。

  1. 打开浏览器,输入管理地址即可访问esxi系统

    image-20230422133642869

设置管理网口(多网卡)

如果有多张网卡,可以指定哪个网口可以访问esxi的管理页面,没有指定的将无法访问。

  1. F2进入后,依次选择**configure management network **->**Network Adapters **

    image-20230422133918448

  2. 选择网卡,这里可以选择多个,如果只选择了某一个,以后就只有插在这个网口上的机器能访问管理页面。

    image-20230422134113958

0%
\ No newline at end of file diff --git a/2023/03/24/esxi安装homeassistant/index.html b/2023/03/24/esxi安装homeassistant/index.html new file mode 100644 index 0000000..59120d0 --- /dev/null +++ b/2023/03/24/esxi安装homeassistant/index.html @@ -0,0 +1,16 @@ +esxi安装homeassistant | 随言碎语

随言碎语

咕叽咕叽

esxi安装homeassistant

在esxi上安装homeassistant

准备

0%
\ No newline at end of file diff --git a/2023/03/24/esxi安装openwrt/index.html b/2023/03/24/esxi安装openwrt/index.html new file mode 100644 index 0000000..8c47cfb --- /dev/null +++ b/2023/03/24/esxi安装openwrt/index.html @@ -0,0 +1,16 @@ +esxi+openwrt作为旁路由 | 随言碎语

随言碎语

咕叽咕叽

esxi+openwrt作为旁路由

在esxi上安装openwrt,并作为旁路由来使用。

准备

  • starwindconverter.exe 用来将img转换为VMDK
  • openwrt-x86-64-generic-squashfs-combined-efi.img.gz openwrt固件包

1. 构建/获取openWRT

这里推荐使用supes.top 自己选择需要的固件,然后进行构建。5分钟左右就能获取到自定义的固件。

  1. 访问supes.top 官网

image-20230422145319548

  1. 自己根据需求去构建,或者是直接下载构建好的通用包

    image-20230422145651697

  • 注:目前免费的用户,一天之内只能构建一次,有需求的可充值解锁。

2. 转换固件为vmdk格式

  1. 解压openwrt-x86-64-generic-squashfs-combined-efi.img.gz

  2. 解压后的文件是openwrt-x86-64-generic-squashfs-combined-efi.img,这个格式是无法在esxi中直接使用的,因此需要转一下

  3. 安装starwindconverter.exe ,没啥可交代的,一路next即可。

  4. 打开安装好的starwindconverter软件,选择local file->next

    image-20230422150336027

  5. 选择解压后的openwrt-x86-64-generic-squashfs-combined-efi.img

    image-20230422150500119

  6. 还是选择local file

image-20230422150951371

  1. 选择VMDK

    image-20230422151034204

  2. 选择ESXI Server image

    image-20230422151136889

9.选择** ESXI pre-allocates image**

image-20230422151215810

10.选择输出的路径和名称,点击conver

image-20230422151331578

11.转换完成后,会出来两个大小不一样的文件

image-20230422151557911

3. 创建虚拟机

  1. 进入esxi的管理页面,依次点击虚拟机->创建虚拟机

    image-20230422151821830

  2. 选择名称和客户机操作系统

    image-20230422152710801

客户机操作系统系列: 选择Linux,客户机操作系统版本:其他Linux(64位)

  1. 选择存储,如果由多块硬盘,可选择安装的位置

    image-20230422152842237

  2. 内存设置为1G,删除掉硬盘以及其他不需要的设备

    image-20230422153126229

  3. 添加硬盘->现有硬盘

    image-20230422153403639

  4. 将转换后的两个vmdk文件全部都上传上去(只会显示1个),然后选择上传的文件

    image-20230422153716292

    • 注:如果需要网卡直通,可点击添加其他设备->PCI设备。

    • 如果由多个网卡,但是这里无法点击,说明这个设别没有进行直通。如何直通可参考之前的文章 esxi常规配置

      image-20230422154249143

  5. 点击下一步,确认一下配置,无误后点击完成即可。

  6. 选中虚拟机,点击打开电源,等待开机

    image-20230422154411639

  7. 点击进入操作台,可看到openwrt已经正常启动,在浏览器中输入IP地址即可访问openwrt的管理页面。

    image-20230422154700759

4. 配置opwrt作为旁路由

由于是作为旁路由来使用的,所有wan口是不需要的,只需要LAN即可。

  1. 进入openwrt的管理页面,依次点击网络->接口,将wan和wan6全部删除掉。

image-20230422161227530

注:删除后,不要点击 保存并应用!!! 不要点击 保存并应用!!! 不要点击 保存并应用!!!

  1. 点击设备,选择br-lan,点击配置…

image-20230422161705488

  1. 网桥端口中,将所有的网卡都勾选上

    image-20230422161814059

  2. 回到接口页面,编辑lan

    image-20230422161955936

  3. 确认里面的设备是br-lan

    image-20230422162141208

  4. 保存后,点击最外层的保存并应用

    image-20230422162251244

  5. 网络连接正常后,配置自己需要的服务,然后需要这些服务的设备,将openwrt作为网关就可以了。

5. 问题

  1. 为什么不作为主路由使用,而是选择旁路由?

    1
    2
    3
    1。主要还是看各自的需要来决定的,各有利弊。
    2.对我来说,只是想用一下它的插件功能,例如广告拦截,proxy等。
    3.即便是软路由整体挂了,也不会影响家里的其他设别的正常使用。
  2. 如何修改openwrt的地址?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    1.修改lan口的ip地址

    [root@OpenWrt:03:52 PM ~] # cat /etc/config/network

    ....

    config interface 'lan'
    option device 'br-lan'
    option proto 'static'
    option netmask '255.255.255.0'
    option ip6assign '60'
    option ipaddr '10.1.100.254'
    option gateway '10.1.100.1'
    option dns '223.5.5.5'
    option delegate '0'

    ....

    2. 改完后保存退出,并reboot重启
  3. 网卡直通后,无法访问openwrt的管理页面?

1
2
多张网卡直通后,可能会造成网卡识别混乱。
如果当前无法访问,把网线拔了,可换个网口再试试,肯定会有一个是能够访问的。
0%
\ No newline at end of file diff --git a/2023/03/24/esxi安装群晖dsm7.1/index.html b/2023/03/24/esxi安装群晖dsm7.1/index.html new file mode 100644 index 0000000..115c7e8 --- /dev/null +++ b/2023/03/24/esxi安装群晖dsm7.1/index.html @@ -0,0 +1,16 @@ +esxi安装群晖dsm7.1 | 随言碎语

随言碎语

咕叽咕叽

esxi安装群晖dsm7.1

在esxi上安装DSM

准备

0%
\ No newline at end of file diff --git a/2023/03/26/esxi常规配置/index.html b/2023/03/26/esxi常规配置/index.html new file mode 100644 index 0000000..2f59801 --- /dev/null +++ b/2023/03/26/esxi常规配置/index.html @@ -0,0 +1,16 @@ +esxi常规配置 | 随言碎语

随言碎语

咕叽咕叽

esxi常规配置

esxi修改网卡顺序、网卡直通、修改安全策略、开机自动启动虚拟机。

修改网卡顺序

系统中网卡的显示顺序可能和实际的对应不上,可以修改相关的配置文件,让其能和实际的端口对上。

先确定当前的顺序,以及希望修改后的顺序:

实际网口名称ESXi中默认网口名称希望的网口名称
eth0vmnic1vmnic0
eth1vmnic2vmnic1
eth2vmnic0vmnic2
eth3vmnic3vmnic3
  1. 开启维护模式,和ssh连接。

  2. 查看系统中当前pci和逻辑pci对应的网卡名称

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias list
    Bus type Bus address Alias
    ------------------------------------
    pci m00008501 vmnic0
    pci m00008901 vmhba0
    pci p0000:04:00.0 vmnic3
    pci s00000003.00 vmnic1
    pci p0000:02:00.0 vmnic2
    logical pci#s00000003.00#0 vmnic1
    logical pci#m00008501#0 vmnic0
    logical pci#m00008901#0 vmhba0
    logical pci#p0000:02:00.0#0 vmnic2
    logical pci#p0000:04:00.0#0 vmnic3

  3. 修改网卡名称,这里pci和逻辑pci对应的名称要同时修改,并且要一致。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic0 --bus-address s00000003.00
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic0 --bus-address "pci#s00000003.00#0"

    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic1 --bus-address p0000:02:00.0
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic1 --bus-address "pci#p0000:02:00.0#0"

    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic2 --bus-address m00008501
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic2 --bus-address "pci#m00008501#0"

  4. 重启机器

网卡直通

安装软路由时,需要将网卡直通,从而发挥网卡的最大性能。

  1. 进入esxi的管理页面

    image-20230422142105492

注:至少要保留一个网口,用来作为esxi的管理网口,否则将无法登录esxi

  1. 选择需要直通的网口,进行切换即可

修改安全策略

可能会出现虚拟机和esxi之间相互ping不通的情况,这是由于esxi的安全策略导致的

  1. 依次点击网络->虚拟交换机->编辑vSwith0

    image-20230422143110862

  2. 将安全选项中,混杂模式和伪传输改为接受

开机自动启动虚拟机

设置开启后自动启动虚拟机,以及启动顺序

1.依次点击主机->管理->系统->自动启动->编辑设置,将总开关打开

image-20230422143559690

2.选择虚拟机,设置是否开机自启、调整启动的顺序和延迟启动时间。

  • 注:这里最好错开启动,不要同时启动,由依赖的虚拟机先启动。
0%
\ No newline at end of file diff --git a/about/index.html b/about/index.html new file mode 100644 index 0000000..feb4ec5 --- /dev/null +++ b/about/index.html @@ -0,0 +1,16 @@ +about | 随言碎语

随言碎语

咕叽咕叽

about

0%
\ No newline at end of file diff --git a/archives/2019/12/index.html b/archives/2019/12/index.html new file mode 100644 index 0000000..d5070ad --- /dev/null +++ b/archives/2019/12/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2019
0%
\ No newline at end of file diff --git a/archives/2019/index.html b/archives/2019/index.html new file mode 100644 index 0000000..cc708e9 --- /dev/null +++ b/archives/2019/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2019
0%
\ No newline at end of file diff --git a/archives/2020/01/index.html b/archives/2020/01/index.html new file mode 100644 index 0000000..011a700 --- /dev/null +++ b/archives/2020/01/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2020
0%
\ No newline at end of file diff --git a/archives/2020/index.html b/archives/2020/index.html new file mode 100644 index 0000000..2342b0b --- /dev/null +++ b/archives/2020/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2020
0%
\ No newline at end of file diff --git a/archives/2023/03/index.html b/archives/2023/03/index.html new file mode 100644 index 0000000..f555724 --- /dev/null +++ b/archives/2023/03/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2023
0%
\ No newline at end of file diff --git a/archives/2023/index.html b/archives/2023/index.html new file mode 100644 index 0000000..b0305ed --- /dev/null +++ b/archives/2023/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2023
0%
\ No newline at end of file diff --git a/archives/index.html b/archives/index.html new file mode 100644 index 0000000..5eca31e --- /dev/null +++ b/archives/index.html @@ -0,0 +1,16 @@ +归档 | 随言碎语

随言碎语

咕叽咕叽

嗯..! 目前共计 8 篇日志。 继续努力。
2023
2020
2019
0%
\ No newline at end of file diff --git a/atom.xml b/atom.xml new file mode 100644 index 0000000..b8f3526 --- /dev/null +++ b/atom.xml @@ -0,0 +1,188 @@ + + + 随言碎语 + + 咕叽咕叽 + + + + 2023-04-22T06:40:08.722Z + http://kiki.kim/ + + + 小梦同学的blog + + + + Hexo + + + esxi常规配置 + + http://kiki.kim/2023/03/26/esxi%E5%B8%B8%E8%A7%84%E9%85%8D%E7%BD%AE/ + 2023-03-26T03:45:22.000Z + 2023-04-22T06:40:08.722Z + + + <p>esxi修改网卡顺序、网卡直通、修改安全策略、开机自动启动虚拟机。</p> + + + + + + + + + + + + esxi安装homeassistant + + http://kiki.kim/2023/03/24/esxi%E5%AE%89%E8%A3%85homeassistant/ + 2023-03-24T12:15:04.000Z + 2023-04-22T08:51:44.267Z + + + <p>在esxi上安装homeassistant</p> + + + + + + + + + + + + esxi+openwrt作为旁路由 + + http://kiki.kim/2023/03/24/esxi%E5%AE%89%E8%A3%85openwrt/ + 2023-03-24T12:15:04.000Z + 2023-04-22T08:39:45.162Z + + + <p>在esxi上安装openwrt,并作为旁路由来使用。</p> + + + + + + + + + + + + + + + + esxi安装群晖dsm7.1 + + http://kiki.kim/2023/03/24/esxi%E5%AE%89%E8%A3%85%E7%BE%A4%E6%99%96dsm7.1/ + 2023-03-24T12:15:04.000Z + 2023-04-22T08:51:15.950Z + + + <p>在esxi上安装DSM</p> + + + + + + + + + + + + + + esxi+openwrt+dsm+homeassistant 软路由 all in one + + http://kiki.kim/2023/03/23/esxi+openwrt+dsm+homeassistant-%E8%BD%AF%E8%B7%AF%E7%94%B1all-in-one/ + 2023-03-23T13:25:34.000Z + 2023-04-24T04:53:03.818Z + + + <p>软路由 all in one,在J425小主机上安装esxi+openwrt+dsm+homeassistant,集软路由、网盘、智能家居控制于一体。</p> + + + + + + + + + + + + + + + + + + + + esxi8.0安装 + + http://kiki.kim/2023/03/23/esxi8.0%E5%AE%89%E8%A3%85/ + 2023-03-23T13:25:34.000Z + 2023-04-24T01:37:17.777Z + + + <p>esxi 8.0的安装。</p> + + + + + + + + + + + + VMware安装centos7 + + http://kiki.kim/2020/01/03/VMware%E5%AE%89%E8%A3%85centos7/ + 2020-01-03T13:25:34.000Z + 2023-04-22T06:02:29.866Z + + + <p>在VMware Workstation上安装centos。</p> + + + + + + + + + + + + Hello World + + http://kiki.kim/2019/12/30/hello-world/ + 2019-12-30T15:25:34.000Z + 2023-04-22T05:46:03.233Z + + + + + + + <p>欢迎来到我的博客,这是我的第一篇博客,由hexo+next构建。</p> + + + + + + + + + + diff --git a/css/hbe.style.css b/css/hbe.style.css new file mode 100644 index 0000000..2935f20 --- /dev/null +++ b/css/hbe.style.css @@ -0,0 +1,749 @@ +.hbe, +.hbe:after, +.hbe:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.hbe-container{ + margin: 0 auto; + overflow: hidden; +} +.hbe-content { + text-align: center; + font-size: 150%; + padding: 1em 0; +} + +.hbe-input { + position: relative; + z-index: 1; + display: inline-block; + margin: 1em; + width: 80%; + min-width: 400px; + vertical-align: top; +} + +.hbe-input-field { + line-height: normal; + font-size: 100%; + margin: 0; + position: relative; + display: block; + float: right; + padding: 0.8em; + width: 60%; + border: none; + border-radius: 0; + background: #f0f0f0; + color: #aaa; + font-weight: 400; + font-family: "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif; + -webkit-appearance: none; /* for box shadows to show on iOS */ +} + +.hbe-input-field:focus { + outline: none; +} + +.hbe-input-label { + display: inline-block; + float: right; + padding: 0 1em; + width: 40%; + color: #696969; + font-weight: bold; + font-size: 70.25%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.hbe-input-label-content { + position: relative; + display: block; + padding: 1.6em 0; + width: 100%; +} + +.hbe-graphic { + position: absolute; + top: 0; + left: 0; + fill: none; +} + +/* hbe button in post page */ +.hbe-button { + width: 130px; + height: 40px; + background: linear-gradient(to bottom, #4eb5e5 0%,#389ed5 100%); /* W3C */ + border: none; + border-radius: 5px; + position: relative; + border-bottom: 4px solid #2b8bc6; + color: #fbfbfb; + font-weight: 600; + font-family: 'Open Sans', sans-serif; + text-shadow: 1px 1px 1px rgba(0,0,0,.4); + font-size: 15px; + text-align: left; + text-indent: 5px; + box-shadow: 0px 3px 0px 0px rgba(0,0,0,.2); + cursor: pointer; + + display: block; + margin: 0 auto; + margin-bottom: 20px; +} + +.hbe-button:active { + box-shadow: 0px 2px 0px 0px rgba(0,0,0,.2); + top: 1px; +} + +.hbe-button:after { + content: ""; + width: 0; + height: 0; + display: block; + border-top: 20px solid #187dbc; + border-bottom: 20px solid #187dbc; + border-left: 16px solid transparent; + border-right: 20px solid #187dbc; + position: absolute; + opacity: 0.6; + right: 0; + top: 0; + border-radius: 0 5px 5px 0; +} +/* hbe button in post page */ + +/* default theme {{{ */ +.hbe-input-default { + overflow: hidden; +} + +.hbe-input-field-default { + width: 100%; + background: transparent; + padding: 0.5em; + margin-bottom: 2em; + color: #f9f7f6; + z-index: 100; + opacity: 0; +} + +.hbe-input-label-default { + width: 100%; + position: absolute; + text-align: left; + padding: 0.5em 0; + pointer-events: none; + font-size: 1em; +} + +.hbe-input-label-default::before, +.hbe-input-label-default::after { + content: ''; + position: absolute; + width: 100%; + left: 0; +} + +.hbe-input-label-default::before { + height: 100%; + background: #666666; + top: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + -webkit-transition: -webkit-transform 0.2s; + transition: transform 0.2s; +} + +.hbe-input-label-default::after { + height: 2px; + background: #666666; + top: 100%; + -webkit-transition: opacity 0.2s; + transition: opacity 0.2s; +} + +.hbe-input-label-content-default { + padding: 0; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transition: -webkit-transform 0.2s, color 0.2s; + transition: transform 0.2s, color 0.2s; +} + +.hbe-input-field-default:focus, +.hbe-input--filled .hbe-input-field-default { + opacity: 1; + -webkit-transition: opacity 0s 0.2s; + transition: opacity 0s 0.2s; +} + +.hbe-input-label-default::before, +.hbe-input-label-default::after, +.hbe-input-label-content-default, +.hbe-input-field-default:focus, +.hbe-input--filled .hbe-input-field-default { + -webkit-transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); + transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); +} + +.hbe-input-field-default:focus + .hbe-input-label-default::before, +.hbe-input--filled .hbe-input-label-default::before { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.hbe-input-field-default:focus + .hbe-input-label-default::after, +.hbe-input--filled .hbe-input-label-default::after { + opacity: 0; +} + +.hbe-input-field-default:focus + .hbe-input-label-default .hbe-input-label-content-default, +.hbe-input--filled .hbe-input-label-default .hbe-input-label-content-default { + color: #555555; + -webkit-transform: translate3d(0, 2.1em, 0) scale3d(0.65, 0.65, 1); + transform: translate3d(0, 2.1em, 0) scale3d(0.65, 0.65, 1); +} +/* default theme }}} */ + +/* up theme {{{ */ +.hbe-input-up { + overflow: hidden; + padding-top: 2em; +} + +.hbe-input-field-up { + width: 100%; + background: transparent; + opacity: 0; + padding: 0.35em; + z-index: 100; + color: #837482; +} + +.hbe-input-label-up { + width: 100%; + bottom: 0; + position: absolute; + pointer-events: none; + text-align: left; + color: #8E9191; + padding: 0 0.5em; +} + +.hbe-input-label-up::before { + content: ''; + position: absolute; + width: 100%; + height: 4em; + top: 100%; + left: 0; + background: #fff; + border-top: 4px solid #9B9F9F; + -webkit-transform: translate3d(0, -3px, 0); + transform: translate3d(0, -3px, 0); + -webkit-transition: -webkit-transform 0.4s; + transition: transform 0.4s; + -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); + transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); +} + +.hbe-input-label-content-up { + padding: 0.5em 0; + -webkit-transform-origin: 0% 100%; + transform-origin: 0% 100%; + -webkit-transition: -webkit-transform 0.4s, color 0.4s; + transition: transform 0.4s, color 0.4s; + -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); + transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); +} + +.hbe-input-field-up:focus, +.input--filled .hbe-input-field-up { + cursor: text; + opacity: 1; + -webkit-transition: opacity 0s 0.4s; + transition: opacity 0s 0.4s; +} + +.hbe-input-field-up:focus + .hbe-input-label-up::before, +.input--filled .hbe-input-label-up::before { + -webkit-transition-delay: 0.05s; + transition-delay: 0.05s; + -webkit-transform: translate3d(0, -3.3em, 0); + transform: translate3d(0, -3.3em, 0); +} + +.hbe-input-field-up:focus + .hbe-input-label-up .hbe-input-label-content-up, +.input--filled .hbe-input-label-content-up { + color: #6B6E6E; + -webkit-transform: translate3d(0, -3.3em, 0) scale3d(0.81, 0.81, 1); + transform: translate3d(0, -3.3em, 0) scale3d(0.81, 0.81, 1); +} +/* up theme }}} */ + +/* wave theme {{{ */ +.hbe-input-wave { + overflow: hidden; + padding-top: 1em; +} + +.hbe-input-field-wave { + padding: 0.5em 0em 0.25em; + width: 100%; + background: transparent; + color: #9da8b2; + font-size: 1.25em; +} + +.hbe-input-label-wave { + position: absolute; + top: 0.95em; + font-size: 0.85em; + left: 0; + display: block; + width: 100%; + text-align: left; + padding: 0em; + pointer-events: none; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transition: -webkit-transform 0.2s 0.15s, color 1s; + transition: transform 0.2s 0.15s, color 1s; + -webkit-transition-timing-function: ease-out; + transition-timing-function: ease-out; +} + +.hbe-graphic-wave { + stroke: #92989e; + pointer-events: none; + -webkit-transition: -webkit-transform 0.7s, stroke 0.7s; + transition: transform 0.7s, stroke 0.7s; + -webkit-transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); + transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); +} + +.hbe-input-field-wave:focus + .hbe-input-label-wave, +.input--filled .hbe-input-label-wave { + color: #333; + -webkit-transform: translate3d(0, -1.25em, 0) scale3d(0.75, 0.75, 1); + transform: translate3d(0, -1.25em, 0) scale3d(0.75, 0.75, 1); +} + +.hbe-input-field-wave:focus ~ .hbe-graphic-wave, +.input--filled .graphic-wave { + stroke: #333; + -webkit-transform: translate3d(-66.6%, 0, 0); + transform: translate3d(-66.6%, 0, 0); +} +/* wave theme }}} */ + +/* flip theme {{{ */ +.hbe-input-field-flip { + width: 100%; + background-color: #d0d1d0; + border: 2px solid transparent; + -webkit-transition: background-color 0.25s, border-color 0.25s; + transition: background-color 0.25s, border-color 0.25s; +} + +.hbe-input-label-flip { + width: 100%; + text-align: left; + position: absolute; + bottom: 100%; + pointer-events: none; + overflow: hidden; + padding: 0 1.25em; + -webkit-transform: translate3d(0, 3em, 0); + transform: translate3d(0, 3em, 0); + -webkit-transition: -webkit-transform 0.25s; + transition: transform 0.25s ; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; +} + +.hbe-input-label-content-flip { + color: #8B8C8B; + padding: 0.25em 0; + -webkit-transition: -webkit-transform 0.25s; + transition: transform 0.25s; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; +} + +.hbe-input-label-content-flip::after { + content: attr(data-content); + position: absolute; + font-weight: 800; + bottom: 100%; + left: 0; + height: 100%; + width: 100%; + color: #666666; + padding: 0.25em 0; + letter-spacing: 1px; + font-size: 1em; +} + +.hbe-input-field-flip:focus + .hbe-input-label-flip, +.input--filled .hbe-input-label-flip { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.hbe-input-field-flip:focus + .hbe-input-label-flip .hbe-input-label-content-flip, +.input--filled .hbe-input-label-content-flip { + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); +} + +.hbe-input-field-flip:focus + .hbe-input-field-flip, +.input--filled .hbe-input-field-flip { + background-color: transparent; + border-color: #666666; +} +/* flip theme }}} */ + +/* xray theme {{{ */ +.hbe-input-xray { + overflow: hidden; + padding-bottom: 2.5em; +} + +.hbe-input-field-xray { + padding: 0; + margin-top: 1.2em; + width: 100%; + background: transparent; + color: #84AF9B ; + font-size: 1.55em; +} + +.hbe-input-label-xray { + position: absolute; + top: 2em; + left: 0; + display: block; + width: 100%; + text-align: left; + padding: 0em; + letter-spacing: 1px; + color: #84AF9B ; + pointer-events: none; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transition: -webkit-transform 0.2s 0.1s, color 0.3s; + transition: transform 0.2s 0.1s, color 0.3s; + -webkit-transition-timing-function: ease-out; + transition-timing-function: ease-out; +} + +.hbe-graphic-xray { + stroke: #84AF9B ; + pointer-events: none; + stroke-width: 2px; + top: 1.25em; + bottom: 0px; + height: 3.275em; + -webkit-transition: -webkit-transform 0.7s, stroke 0.7s; + transition: transform 0.7s, stroke 0.7s; + -webkit-transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); + transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); +} + +.hbe-input-field-xray:focus + .hbe-input-label-xray, +.input--filled .hbe-input-label-xray { + color: #84AF9B ; + -webkit-transform: translate3d(0, 3.5em, 0) scale3d(0.85, 0.85, 1); + transform: translate3d(0, 3.5em, 0) scale3d(0.85, 0.85, 1); +} + +.hbe-input-field-xray:focus ~ .hbe-graphic-xray, +.input--filled .graphic-xray { + stroke: #84AF9B ; + -webkit-transform: translate3d(-66.6%, 0, 0); + transform: translate3d(-66.6%, 0, 0); +} +/* xray theme }}} */ + +/* blink theme {{{ */ +.hbe-input-blink { + padding-top: 1em; +} + +.hbe-input-field-blink { + width: 100%; + padding: 0.8em 0.5em; + background: transparent; + border: 2px solid; + color: #8781bd; + -webkit-transition: border-color 0.25s; + transition: border-color 0.25s; +} + +.hbe-input-label-blink { + width: 100%; + position: absolute; + top: 0; + text-align: left; + overflow: hidden; + padding: 0; + pointer-events: none; + -webkit-transform: translate3d(0, 3em, 0); + transform: translate3d(0, 3em, 0); +} + +.hbe-input-label-content-blink { + padding: 0 1em; + font-weight: 400; + color: #b5b5b5; +} + +.hbe-input-label-content-blink::after { + content: attr(data-content); + position: absolute; + top: -200%; + left: 0; + color: #8781bd ; + font-weight: 800; +} + +.hbe-input-field-blink:focus, +.input--filled .hbe-input-field-blink { + border-color: #8781bd ; +} + +.hbe-input-field-blink:focus + .hbe-input-label-blink, +.input--filled .hbe-input-label-blink { + -webkit-animation: anim-blink-1 0.25s forwards; + animation: anim-blink-1 0.25s forwards; +} + +.hbe-input-field-blink:focus + .hbe-input-label-blink .hbe-input-label-content-blink, +.input--filled .hbe-input-label-content-blink { + -webkit-animation: anim-blink-2 0.25s forwards ease-in; + animation: anim-blink-2 0.25s forwards ease-in; +} + +@-webkit-keyframes anim-blink-1 { + 0%, 70% { + -webkit-transform: translate3d(0, 3em, 0); + transform: translate3d(0, 3em, 0); + } + 71%, 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@-webkit-keyframes anim-blink-2 { + 0% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 70%, 71% { + -webkit-transform: translate3d(0, 125%, 0); + transform: translate3d(0, 125%, 0); + opacity: 0; + -webkit-animation-timing-function: ease-out; + } + 100% { + color: transparent; + -webkit-transform: translate3d(0, 200%, 0); + transform: translate3d(0, 200%, 0); + } +} + +@keyframes anim-blink-1 { + 0%, 70% { + -webkit-transform: translate3d(0, 3em, 0); + transform: translate3d(0, 3em, 0); + } + 71%, 100% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes anim-blink-2 { + 0% { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + 70%, 71% { + -webkit-transform: translate3d(0, 125%, 0); + transform: translate3d(0, 125%, 0); + opacity: 0; + -webkit-animation-timing-function: ease-out; + } + 100% { + color: transparent; + -webkit-transform: translate3d(0, 200%, 0); + transform: translate3d(0, 200%, 0); + } +} +/* blink theme }}} */ + +/* surge theme {{{ */ +.hbe-input-surge { + overflow: hidden; + padding-bottom: 1em; +} + +.hbe-input-field-surge { + padding: 0.25em 0.5em; + margin-top: 1.25em; + width: 100%; + background: transparent; + color: #D0D0D0; + font-size: 1.55em; + opacity: 0; +} + +.hbe-input-label-surge { + width: 100%; + text-align: left; + position: absolute; + top: 1em; + pointer-events: none; + overflow: hidden; + padding: 0 0.25em; + -webkit-transform: translate3d(1em, 2.75em, 0); + transform: translate3d(1em, 2.75em, 0); + -webkit-transition: -webkit-transform 0.3s; + transition: transform 0.3s; +} + +.hbe-input-label-content-surge { + color: #A4A5A6; + padding: 0.4em 0 0.25em; + -webkit-transition: -webkit-transform 0.3s; + transition: transform 0.3s; +} + +.hbe-input-label-content-surge::after { + content: attr(data-content); + position: absolute; + font-weight: 800; + top: 100%; + left: 0; + height: 100%; + width: 100%; + color: #2C3E50; + padding: 0.25em 0; + letter-spacing: 1px; + font-size: 0.85em; +} + +.hbe-graphic-surge { + fill: #2C3E50; + pointer-events: none; + top: 1em; + bottom: 0px; + height: 4.5em; + z-index: -1; + -webkit-transition: -webkit-transform 0.7s, fill 0.7s; + transition: transform 0.7s, fill 0.7s; + -webkit-transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); + transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); +} + +.hbe-input-field-surge:focus, +.input--filled .hbe-input-field-surge { + -webkit-transition: opacity 0s 0.35s; + transition: opacity 0s 0.35s; + opacity: 1; +} + +.hbe-input-field-surge:focus + .hbe-input-label-surge, +.input--filled .hbe-input-label-surge { + -webkit-transition-delay: 0.15s; + transition-delay: 0.15s; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.hbe-input-field-surge:focus + .hbe-input-label-surge .hbe-input-label-content-surge, +.input--filled .hbe-input-label-content-surge { + -webkit-transition-delay: 0.15s; + transition-delay: 0.15s; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); +} + +.hbe-input-field-surge:focus ~ .hbe-graphic-surge, +.input--filled .graphic-surge { + fill: #2C3E50; + -webkit-transform: translate3d(-66.6%, 0, 0); + transform: translate3d(-66.6%, 0, 0); +} +/* surge theme }}} */ + +/* shrink theme {{{ */ +.hbe-input-field-shrink { + width: 100%; + background: transparent; + padding: 0.5em 0; + margin-bottom: 2em; + color: #2C3E50; +} + +.hbe-input-label-shrink { + width: 100%; + position: absolute; + text-align: left; + font-size: 1em; + padding: 10px 0 5px; + pointer-events: none; +} + +.hbe-input-label-shrink::after { + content: ''; + position: absolute; + width: 100%; + height: 7px; + background: #B7C3AC; + left: 0; + top: 100%; + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; + -webkit-transition: -webkit-transform 0.3s, background-color 0.3s; + transition: transform 0.3s, background-color 0.3s; +} + +.hbe-input-label-content-shrink { + padding: 0; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transition: -webkit-transform 0.3s, color 0.3s; + transition: transform 0.3s, color 0.3s; +} + +.hbe-input-field-shrink:focus + .hbe-input-label-shrink::after, +.input--filled .hbe-input-label-shrink::after { + background: #84AF9B; + -webkit-transform: scale3d(1, 0.25, 1); + transform: scale3d(1, 0.25, 1); +} + +.hbe-input-field-shrink:focus + .hbe-input-label-shrink .hbe-input-label-content-shrink, +.input--filled .hbe-input-label-shrink .hbe-input-label-content-shrink { + color: #84AF9B; + -webkit-transform: translate3d(0, 2em, 0) scale3d(0.655, 0.655, 1); + transform: translate3d(0, 2em, 0) scale3d(0.655, 0.655, 1); +} +/* shrink theme }}} */ diff --git a/css/link.css b/css/link.css new file mode 100644 index 0000000..7a8708d --- /dev/null +++ b/css/link.css @@ -0,0 +1,3 @@ +/* build time:Tue Apr 25 2023 15:41:31 GMT+0800 (GMT+08:00)*/ +.links-content{margin-top:1rem}.link-navigation::after{content:" ";display:block;clear:both}.card{width:130px;font-size:1rem;padding:0;border-radius:4px;transition-duration:.15s;margin-bottom:1rem;display:block;float:left;box-shadow:0 2px 6px 0 rgba(0,0,0,.12);background:#f5f5f5}.card{margin-left:16px}@media(max-width:567px){.card{margin-left:16px;width:calc((100% - 16px)/ 2)}.card:nth-child(2n+1){margin-left:0}.card:not(:nth-child(2n+1)){margin-left:16px}}@media(min-width:567px){.card{margin-left:16px;width:calc((100% - 32px)/ 3)}.card:nth-child(3n+1){margin-left:0}.card:not(:nth-child(3n+1)){margin-left:16px}}@media(min-width:768px){.card{margin-left:16px;width:calc((100% - 48px)/ 4)}.card:nth-child(4n+1){margin-left:0}.card:not(:nth-child(4n+1)){margin-left:16px}}@media(min-width:1200px){.card{margin-left:16px;width:calc((100% - 64px)/ 5)}.card:nth-child(5n+1){margin-left:0}.card:not(:nth-child(5n+1)){margin-left:16px}}.card:hover{transform:scale(1.1);box-shadow:0 2px 6px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04)}.card .thumb{width:100%;height:0;padding-bottom:100%;background-size:100% 100%!important}.posts-expand .post-body img{margin:0;padding:0;border:0}.card .card-header{display:block;text-align:center;padding:1rem .25rem;font-weight:500;color:#333;white-space:normal}.card .card-header a{font-style:normal;color:#2bbc8a;font-weight:700;text-decoration:none;border:0}.card .card-header a:hover{color:#d480aa;text-decoration:none;border:0} +/* rebuild by neat */ \ No newline at end of file diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000..54fb0fe --- /dev/null +++ b/css/main.css @@ -0,0 +1,9 @@ +/* build time:Tue Apr 25 2023 15:41:35 GMT+0800 (GMT+08:00)*/ +:root{--body-bg-color:#eee;--content-bg-color:#fff;--card-bg-color:#f5f5f5;--text-color:#555;--blockquote-color:#666;--link-color:#555;--link-hover-color:#222;--brand-color:#fff;--brand-hover-color:#fff;--table-row-odd-bg-color:#f9f9f9;--table-row-hover-bg-color:#f5f5f5;--menu-item-bg-color:#f5f5f5;--theme-color:#222;--btn-default-bg:#fff;--btn-default-color:#555;--btn-default-border-color:#555;--btn-default-hover-bg:#222;--btn-default-hover-color:#fff;--btn-default-hover-border-color:#222;--highlight-background:#fefbec;--highlight-foreground:#6e6b5e;--highlight-gutter-background:#efecdd;--highlight-gutter-foreground:#7c796c;color-scheme:light}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background:0 0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}::selection{background:#262a30;color:#eee}body,html{height:100%}body{background:var(--body-bg-color);box-sizing:border-box;color:var(--text-color);font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;font-size:1em;line-height:2;min-height:100%;position:relative;transition:padding .2s ease-in-out}h1,h2,h3,h4,h5,h6{font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;font-weight:700;line-height:1.5;margin:30px 0 15px}h1{font-size:1.5em}h2{font-size:1.375em}h3{font-size:1.25em}h4{font-size:1.125em}h5{font-size:1em}h6{font-size:.875em}p{margin:0 0 20px}a{border-bottom:1px solid #999;color:var(--link-color);cursor:pointer;outline:0;text-decoration:none;overflow-wrap:break-word}a:hover{border-bottom-color:var(--link-hover-color);color:var(--link-hover-color)}embed,iframe,img,video{display:block;margin-left:auto;margin-right:auto;max-width:100%}hr{background-image:repeating-linear-gradient(-45deg,#ddd,#ddd 4px,transparent 4px,transparent 8px);border:0;height:3px;margin:40px 0}blockquote{border-left:4px solid #ddd;color:var(--blockquote-color);margin:0;padding:0 15px}blockquote cite::before{content:'-';padding:0 5px}dt{font-weight:700}dd{margin:0;padding:0}.table-container{overflow:auto}table{border-collapse:collapse;border-spacing:0;font-size:.875em;margin:0 0 20px;width:100%}tbody tr:nth-of-type(odd){background:var(--table-row-odd-bg-color)}tbody tr:hover{background:var(--table-row-hover-bg-color)}caption,td,th{padding:8px}td,th{border:1px solid #ddd;border-bottom:3px solid #ddd}th{font-weight:700;padding-bottom:10px}td{border-bottom-width:1px}.btn{background:var(--btn-default-bg);border:2px solid var(--btn-default-border-color);border-radius:2px;color:var(--btn-default-color);display:inline-block;font-size:.875em;line-height:2;padding:0 20px;transition:background-color .2s ease-in-out}.btn:hover{background:var(--btn-default-hover-bg);border-color:var(--btn-default-hover-border-color);color:var(--btn-default-hover-color)}.btn+.btn{margin:0 0 8px 8px}.btn .fa-fw{text-align:left;width:1.285714285714286em}.toggle{line-height:0}.toggle .toggle-line{background:#fff;display:block;height:2px;left:0;position:relative;top:0;transition:all .4s;width:100%}.toggle .toggle-line:first-child{margin-top:1px}.toggle .toggle-line:not(:first-child){margin-top:4px}.toggle.toggle-arrow :first-child{left:50%;top:2px;transform:rotate(45deg);width:50%}.toggle.toggle-arrow :last-child{left:50%;top:-2px;transform:rotate(-45deg);width:50%}.toggle.toggle-close :nth-child(2){opacity:0}.toggle.toggle-close :first-child{top:6px;transform:rotate(45deg)}.toggle.toggle-close :last-child{top:-6px;transform:rotate(-45deg)}/*! + Theme: Atelier Dune Light + Author: Bram de Haan (http://atelierbramdehaan.nl) + License: ~ MIT (or more permissive) [via base16-schemes-source] + Maintainer: @highlightjs/core-team + Version: 2021.09.0 +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#6e6b5e;background:#fefbec}.hljs ::selection,.hljs::selection{background-color:#a6a28c;color:#6e6b5e}.hljs-comment{color:#999580}.hljs-tag{color:#7d7a68}.hljs-operator,.hljs-punctuation,.hljs-subst{color:#6e6b5e}.hljs-operator{opacity:.7}.hljs-bullet,.hljs-deletion,.hljs-name,.hljs-selector-tag,.hljs-template-variable,.hljs-variable{color:#d73737}.hljs-attr,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol,.hljs-variable.constant_{color:#b65611}.hljs-class .hljs-title,.hljs-title,.hljs-title.class_{color:#ae9513}.hljs-strong{font-weight:700;color:#ae9513}.hljs-addition,.hljs-code,.hljs-string,.hljs-title.class_.inherited__{color:#60ac39}.hljs-built_in,.hljs-doctag,.hljs-keyword.hljs-atrule,.hljs-quote,.hljs-regexp{color:#1fad83}.hljs-attribute,.hljs-function .hljs-title,.hljs-section,.hljs-title.function_,.ruby .hljs-property{color:#6684e1}.diff .hljs-meta,.hljs-keyword,.hljs-template-tag,.hljs-type{color:#b854d4}.hljs-emphasis{color:#b854d4;font-style:italic}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#d43552}.hljs-meta .hljs-keyword,.hljs-meta-keyword{font-weight:700}.highlight:hover .copy-btn,pre:hover .copy-btn{opacity:1}figure.highlight .table-container{position:relative}.copy-btn{color:#333;cursor:pointer;line-height:1.6;opacity:0;padding:2px 6px;position:absolute;transition:opacity .2s ease-in-out;background:#fff;border:0;font-size:.8125em;right:0;top:0}code,figure.highlight,kbd,pre{background:var(--highlight-background);color:var(--highlight-foreground)}figure.highlight,pre{line-height:1.6;margin:0 auto 20px}figure.highlight figcaption,pre .caption,pre figcaption{background:var(--highlight-gutter-background);color:var(--highlight-foreground);display:flow-root;font-size:.875em;line-height:1.2;padding:.5em}figure.highlight figcaption a,pre .caption a,pre figcaption a{color:var(--highlight-foreground);float:right}figure.highlight figcaption a:hover,pre .caption a:hover,pre figcaption a:hover{border-bottom-color:var(--highlight-foreground)}code,pre{font-family:consolas,Menlo,monospace,'PingFang SC','Microsoft YaHei'}code{border-radius:3px;font-size:.875em;padding:2px 4px;overflow-wrap:break-word}kbd{border:2px solid #ccc;border-radius:.2em;box-shadow:.1em .1em .2em rgba(0,0,0,.1);font-family:inherit;padding:.1em .3em;white-space:nowrap}figure.highlight{overflow:auto;position:relative}figure.highlight pre{border:0;margin:0;padding:10px 0}figure.highlight table{border:0;margin:0;width:auto}figure.highlight td{border:0;padding:0}figure.highlight .gutter{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}figure.highlight .gutter pre{background:var(--highlight-gutter-background);color:var(--highlight-gutter-foreground);padding-left:10px;padding-right:10px;text-align:right}figure.highlight .code pre{padding-left:10px;width:100%}figure.highlight .marked{background:rgba(0,0,0,.3)}pre .caption,pre figcaption{margin-bottom:10px}.gist table{width:auto}.gist table td{border:0}pre{overflow:auto;padding:10px;position:relative}pre code{background:0 0;padding:0;text-shadow:none}.blockquote-center{border-left:0;margin:40px 0;padding:0;position:relative;text-align:center}.blockquote-center::after,.blockquote-center::before{left:0;line-height:1;opacity:.6;position:absolute;width:100%}.blockquote-center::before{border-top:1px solid #ccc;text-align:left;top:-20px;content:'\f10d';font-family:'Font Awesome 6 Free';font-weight:900}.blockquote-center::after{border-bottom:1px solid #ccc;bottom:-20px;text-align:right;content:'\f10e';font-family:'Font Awesome 6 Free';font-weight:900}.blockquote-center div,.blockquote-center p{text-align:center}.group-picture{margin-bottom:20px}.group-picture .group-picture-row{display:flex;gap:3px;margin-bottom:3px}.group-picture .group-picture-column{flex:1}.group-picture .group-picture-column img{height:100%;margin:0;object-fit:cover;width:100%}.post-body .label{color:#555;padding:0 2px}.post-body .label.default{background:#f0f0f0}.post-body .label.primary{background:#efe6f7}.post-body .label.info{background:#e5f2f8}.post-body .label.success{background:#e7f4e9}.post-body .label.warning{background:#fcf6e1}.post-body .label.danger{background:#fae8eb}.post-body .link-grid{display:grid;grid-gap:1.5rem;gap:1.5rem;grid-template-columns:1fr 1fr;margin-bottom:20px;padding:1rem}@media (max-width:767px){.post-body .link-grid{grid-template-columns:1fr}}.post-body .link-grid .link-grid-container{border:solid #ddd;box-shadow:1rem 1rem .5rem rgba(0,0,0,.5);min-height:5rem;min-width:0;padding:.5rem;position:relative;transition:background .3s}.post-body .link-grid .link-grid-container:hover{animation:next-shake .5s;background:var(--card-bg-color)}.post-body .link-grid .link-grid-container:active{box-shadow:.5rem .5rem .25rem rgba(0,0,0,.5);transform:translate(.2rem,.2rem)}.post-body .link-grid .link-grid-container .link-grid-image{border:1px solid #ddd;border-radius:50%;box-sizing:border-box;height:5rem;padding:3px;position:absolute;width:5rem}.post-body .link-grid .link-grid-container p{margin:0 1rem 0 6rem}.post-body .link-grid .link-grid-container p:first-of-type{font-size:1.2em}.post-body .link-grid .link-grid-container p:last-of-type{font-size:.8em;line-height:1.3rem;opacity:.7}.post-body .link-grid .link-grid-container a{border:0;height:100%;left:0;position:absolute;top:0;width:100%}@keyframes next-shake{0%{transform:translate(1pt,1pt) rotate(0)}10%{transform:translate(-1pt,-2pt) rotate(-1deg)}20%{transform:translate(-3pt,0) rotate(1deg)}30%{transform:translate(3pt,2pt) rotate(0)}40%{transform:translate(1pt,-1pt) rotate(1deg)}50%{transform:translate(-1pt,2pt) rotate(-1deg)}60%{transform:translate(-3pt,1pt) rotate(0)}70%{transform:translate(3pt,1pt) rotate(-1deg)}80%{transform:translate(-1pt,-1pt) rotate(1deg)}90%{transform:translate(1pt,2pt) rotate(0)}100%{transform:translate(1pt,-2pt) rotate(-1deg)}}.post-body .note{border-radius:3px;margin-bottom:20px;padding:1em;position:relative;background:#f9f9f9;border:initial;border-left:3px solid #eee}.post-body .note summary{cursor:pointer;outline:0}.post-body .note summary p{display:inline}.post-body .note h2,.post-body .note h3,.post-body .note h4,.post-body .note h5,.post-body .note h6{border-bottom:initial;margin:0;padding-top:0}.post-body .note :first-child{margin-top:0}.post-body .note :last-child{margin-bottom:0}.post-body .note:not(.no-icon){padding-left:2.5em}.post-body .note:not(.no-icon)::before{font-size:1.5em;left:.3em;position:absolute;top:calc(50% - 1em)}.post-body .note.default{background:#f7f7f7;border-left-color:#777}.post-body .note.default h2,.post-body .note.default h3,.post-body .note.default h4,.post-body .note.default h5,.post-body .note.default h6{color:#777}.post-body .note.default:not(.no-icon)::before{content:'\f0a9';font-family:'Font Awesome 6 Free';font-weight:900;color:#777}.post-body .note.primary{background:#f5f0fa;border-left-color:#6f42c1}.post-body .note.primary h2,.post-body .note.primary h3,.post-body .note.primary h4,.post-body .note.primary h5,.post-body .note.primary h6{color:#6f42c1}.post-body .note.primary:not(.no-icon)::before{content:'\f055';font-family:'Font Awesome 6 Free';font-weight:900;color:#6f42c1}.post-body .note.info{background:#eef7fa;border-left-color:#428bca}.post-body .note.info h2,.post-body .note.info h3,.post-body .note.info h4,.post-body .note.info h5,.post-body .note.info h6{color:#428bca}.post-body .note.info:not(.no-icon)::before{content:'\f05a';font-family:'Font Awesome 6 Free';font-weight:900;color:#428bca}.post-body .note.success{background:#eff8f0;border-left-color:#5cb85c}.post-body .note.success h2,.post-body .note.success h3,.post-body .note.success h4,.post-body .note.success h5,.post-body .note.success h6{color:#5cb85c}.post-body .note.success:not(.no-icon)::before{content:'\f058';font-family:'Font Awesome 6 Free';font-weight:900;color:#5cb85c}.post-body .note.warning{background:#fdf8ea;border-left-color:#f0ad4e}.post-body .note.warning h2,.post-body .note.warning h3,.post-body .note.warning h4,.post-body .note.warning h5,.post-body .note.warning h6{color:#f0ad4e}.post-body .note.warning:not(.no-icon)::before{content:'\f06a';font-family:'Font Awesome 6 Free';font-weight:900;color:#f0ad4e}.post-body .note.danger{background:#fcf1f2;border-left-color:#d9534f}.post-body .note.danger h2,.post-body .note.danger h3,.post-body .note.danger h4,.post-body .note.danger h5,.post-body .note.danger h6{color:#d9534f}.post-body .note.danger:not(.no-icon)::before{content:'\f056';font-family:'Font Awesome 6 Free';font-weight:900;color:#d9534f}.post-body .tabs{margin-bottom:20px}.post-body .tabs,.tabs-comment{padding-top:10px}.post-body .tabs ul.nav-tabs,.tabs-comment ul.nav-tabs{background:var(--content-bg-color);display:flex;display:flex;flex-wrap:wrap;justify-content:center;margin:0;padding:0;position:-webkit-sticky;position:sticky;top:0;z-index:5}@media (max-width:413px){.post-body .tabs ul.nav-tabs,.tabs-comment ul.nav-tabs{display:block;margin-bottom:5px}}.post-body .tabs ul.nav-tabs li.tab,.tabs-comment ul.nav-tabs li.tab{border-bottom:1px solid #ddd;border-left:1px solid transparent;border-right:1px solid transparent;border-radius:0;border-top:3px solid transparent;flex-grow:1;list-style-type:none}@media (max-width:413px){.post-body .tabs ul.nav-tabs li.tab,.tabs-comment ul.nav-tabs li.tab{border-bottom:1px solid transparent;border-left:3px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent}}@media (max-width:413px){.post-body .tabs ul.nav-tabs li.tab,.tabs-comment ul.nav-tabs li.tab{border-radius:0}}.post-body .tabs ul.nav-tabs li.tab a,.tabs-comment ul.nav-tabs li.tab a{border-bottom:initial;display:block;line-height:1.8;padding:.25em .75em;text-align:center;transition:all .2s ease-out}.post-body .tabs ul.nav-tabs li.tab a i,.tabs-comment ul.nav-tabs li.tab a i{width:1.285714285714286em}.post-body .tabs ul.nav-tabs li.tab.active,.tabs-comment ul.nav-tabs li.tab.active{border-bottom-color:transparent;border-left-color:#ddd;border-right-color:#ddd;border-top-color:#fc6423}@media (max-width:413px){.post-body .tabs ul.nav-tabs li.tab.active,.tabs-comment ul.nav-tabs li.tab.active{border-bottom-color:#ddd;border-left-color:#fc6423;border-right-color:#ddd;border-top-color:#ddd}}.post-body .tabs ul.nav-tabs li.tab.active a,.tabs-comment ul.nav-tabs li.tab.active a{cursor:default}.post-body .tabs .tab-content,.tabs-comment .tab-content{border:1px solid #ddd;border-radius:0;border-top-color:transparent}@media (max-width:413px){.post-body .tabs .tab-content,.tabs-comment .tab-content{border-radius:0;border-top-color:#ddd}}.post-body .tabs .tab-content .tab-pane,.tabs-comment .tab-content .tab-pane{padding:20px 20px 0}.post-body .tabs .tab-content .tab-pane:not(.active),.tabs-comment .tab-content .tab-pane:not(.active){display:none}.pagination .next,.pagination .page-number,.pagination .prev,.pagination .space{display:inline-block;margin:-1px 10px 0;padding:0 10px}@media (max-width:767px){.pagination .next,.pagination .page-number,.pagination .prev,.pagination .space{margin:0 5px}}.pagination .page-number.current{background:#ccc;border-color:#ccc;color:var(--content-bg-color)}.pagination{border-top:1px solid #eee;margin:120px 0 0;text-align:center}.pagination .next,.pagination .page-number,.pagination .prev{border-bottom:0;border-top:1px solid #eee;transition:border-color .2s ease-in-out}.pagination .next:hover,.pagination .page-number:hover,.pagination .prev:hover{border-top-color:var(--link-hover-color)}@media (max-width:767px){.pagination{border-top:0}.pagination .next,.pagination .page-number,.pagination .prev{border-bottom:1px solid #eee;border-top:0}.pagination .next:hover,.pagination .page-number:hover,.pagination .prev:hover{border-bottom-color:var(--link-hover-color)}}.pagination .space{margin:0;padding:0}.comments{margin-top:60px;overflow:hidden}.comment-button-group{display:flex;display:flex;flex-wrap:wrap;justify-content:center;justify-content:center;margin:1em 0}.comment-button-group .comment-button{margin:.1em .2em}.comment-button-group .comment-button.active{background:var(--btn-default-hover-bg);border-color:var(--btn-default-hover-border-color);color:var(--btn-default-hover-color)}.comment-position{display:none}.comment-position.active{display:block}.tabs-comment{margin-top:4em;padding-top:0}.tabs-comment .comments{margin-top:0;padding-top:0}.headband{background:var(--theme-color);height:3px}@media (max-width:991px){.headband{display:none}}.site-brand-container{display:flex;flex-shrink:0;padding:0 10px}.use-motion .column,.use-motion .site-brand-container .toggle{opacity:0}.site-meta{flex-grow:1;text-align:center}@media (max-width:767px){.site-meta{text-align:center}}.custom-logo-image{margin-top:20px}@media (max-width:991px){.custom-logo-image{display:none}}.brand{border-bottom:0;color:var(--brand-color);display:inline-block;padding:0}.brand:hover{color:var(--brand-hover-color)}.site-title{font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;font-size:1.375em;font-weight:400;line-height:1.5;margin:0}.site-subtitle{color:#ddd;font-size:.8125em;margin:10px 10px 0}.use-motion .custom-logo-image,.use-motion .site-subtitle,.use-motion .site-title{opacity:0;position:relative;top:-10px}.site-nav-right,.site-nav-toggle{display:none}@media (max-width:767px){.site-nav-right,.site-nav-toggle{display:flex;flex-direction:column;justify-content:center}}.site-nav-right .toggle,.site-nav-toggle .toggle{color:var(--text-color);padding:10px;width:22px}.site-nav-right .toggle .toggle-line,.site-nav-toggle .toggle .toggle-line{background:var(--text-color);border-radius:1px}@media (max-width:767px){.site-nav{--scroll-height:0;height:0;overflow:hidden;transition:.2s ease-in-out;transition-property:height,visibility;visibility:hidden}body:not(.site-nav-on) .site-nav .animated{animation:none}body.site-nav-on .site-nav{height:var(--scroll-height);visibility:unset}}.menu{margin:0;padding:1em 0;text-align:center}.menu-item{display:inline-block;list-style:none;margin:0 10px}@media (max-width:767px){.menu-item{display:block;margin-top:10px}.menu-item.menu-item-search{display:none}}.menu-item a{border-bottom:0;display:block;font-size:.8125em;transition:border-color .2s ease-in-out}.menu-item a.menu-item-active,.menu-item a:hover{background:var(--menu-item-bg-color)}.menu-item .fa,.menu-item .fab,.menu-item .far,.menu-item .fas{margin-right:8px}.menu-item .badge{display:inline-block;font-weight:700;line-height:1;margin-left:.35em;margin-top:.35em;text-align:center;white-space:nowrap}@media (max-width:767px){.menu-item .badge{float:right;margin-left:0}}.use-motion .menu-item{visibility:hidden}.github-corner :hover .octo-arm{animation:octocat-wave 560ms ease-in-out}.github-corner svg{color:#fff;fill:var(--theme-color);position:absolute;right:0;top:0;z-index:5}@media (max-width:991px){.github-corner{display:none}.github-corner svg{color:var(--theme-color);fill:#fff}.github-corner .github-corner:hover .octo-arm{animation:none}.github-corner .github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}.sidebar-inner{color:#999;padding:18px 10px;text-align:center;display:flex;flex-direction:column;justify-content:center}.cc-license .cc-opacity{border-bottom:0;opacity:.7}.cc-license .cc-opacity:hover{opacity:.9}.cc-license img{display:inline-block}.site-author-image{border:1px solid #eee;max-width:120px;padding:2px;border-radius:50%;transition:transform 1s ease-out}.site-author-image:hover{transform:rotateZ(360deg)}.site-author-name{color:var(--text-color);font-weight:600;margin:0}.site-description{color:#999;font-size:.8125em;margin-top:0}.links-of-author a{font-size:.8125em}.sidebar .sidebar-button:not(:first-child){margin-top:15px}.sidebar .sidebar-button button{background:0 0;color:#fc6423;cursor:pointer;line-height:2;padding:0 15px;border:1px solid #fc6423;border-radius:4px}.sidebar .sidebar-button button:hover{background:#fc6423;color:#fff}.sidebar .sidebar-button button .fa,.sidebar .sidebar-button button .fab,.sidebar .sidebar-button button .far,.sidebar .sidebar-button button .fas{margin-right:5px}.links-of-blogroll{font-size:.8125em}.links-of-blogroll-title{font-size:.875em;font-weight:600}.links-of-blogroll-list{list-style:none;margin:0;padding:0}.sidebar-nav{font-size:.875em;height:0;margin:0;overflow:hidden;padding-left:0;pointer-events:none;transition:.2s ease-in-out;transition-property:height,visibility;visibility:hidden}.sidebar-nav-active .sidebar-nav{height:calc(2em + 1px);pointer-events:unset;visibility:unset}.sidebar-nav li{border-bottom:1px solid transparent;color:var(--text-color);cursor:pointer;display:inline-block;transition:.2s ease-in-out;transition-property:border-bottom-color,color}.sidebar-nav li.sidebar-nav-overview{margin-left:10px}.sidebar-nav li:hover{color:#fc6423}.sidebar-overview-active .sidebar-nav-overview,.sidebar-toc-active .sidebar-nav-toc{border-bottom-color:#fc6423;color:#fc6423;transition-delay:.2s}.sidebar-overview-active .sidebar-nav-overview:hover,.sidebar-toc-active .sidebar-nav-toc:hover{color:#fc6423}.sidebar-panel-container{align-items:start;display:grid;flex:1;overflow-x:hidden;overflow-y:auto;padding-top:0;transition:padding-top .2s ease-in-out}.sidebar-nav-active .sidebar-panel-container{padding-top:20px}.sidebar-panel{animation:deactivate-sidebar-panel .2s ease-in-out;grid-area:1/1;height:0;opacity:0;overflow:hidden;pointer-events:none;transform:translateY(0);transition:.2s ease-in-out;transition-delay:0s;transition-property:opacity,transform,visibility;visibility:hidden}.sidebar-nav-active .sidebar-panel,.sidebar-overview-active .sidebar-panel.post-toc-wrap{transform:translateY(-20px)}.sidebar-overview-active:not(.sidebar-nav-active) .sidebar-panel.post-toc-wrap{transition-delay:0s,.2s,0s}.sidebar-overview-active .sidebar-panel.site-overview-wrap,.sidebar-toc-active .sidebar-panel.post-toc-wrap{animation-name:activate-sidebar-panel;height:auto;opacity:1;pointer-events:unset;transform:translateY(0);transition-delay:.2s,.2s,0s;visibility:unset}.sidebar-panel.site-overview-wrap{display:flex;flex-direction:column;justify-content:center;gap:10px;justify-content:flex-start}@keyframes deactivate-sidebar-panel{from{height:var(--inactive-panel-height,0)}to{height:var(--active-panel-height,0)}}@keyframes activate-sidebar-panel{from{height:var(--inactive-panel-height,auto)}to{height:var(--active-panel-height,auto)}}.sidebar-toggle{bottom:61px;height:16px;padding:5px;width:16px;background:#222;cursor:pointer;opacity:.6;position:fixed;z-index:30;right:30px}@media (max-width:991px){.sidebar-toggle{right:20px}}.sidebar-toggle:hover{opacity:.8}@media (max-width:991px){.sidebar-toggle{opacity:.8}}.sidebar-toggle:hover .toggle-line{background:#fc6423}@media (any-hover:hover){body:not(.sidebar-active) .sidebar-toggle:hover :first-child{left:50%;top:2px;transform:rotate(45deg);width:50%}body:not(.sidebar-active) .sidebar-toggle:hover :last-child{left:50%;top:-2px;transform:rotate(-45deg);width:50%}}.sidebar-active .sidebar-toggle :nth-child(2){opacity:0}.sidebar-active .sidebar-toggle :first-child{top:6px;transform:rotate(45deg)}.sidebar-active .sidebar-toggle :last-child{top:-6px;transform:rotate(-45deg)}.post-toc{font-size:.875em}.post-toc ol{list-style:none;margin:0;padding:0 2px 0 10px;text-align:left}.post-toc ol>:last-child{margin-bottom:5px}.post-toc ol>ol{padding-left:0}.post-toc ol a{transition:all .2s ease-in-out}.post-toc .nav-item{line-height:1.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.post-toc .nav .nav-child{--height:0;height:0;opacity:0;overflow:hidden;transition-property:height,opacity,visibility;transition:.2s ease-in-out;visibility:hidden}.post-toc .nav .active>.nav-child{height:var(--height,auto);opacity:1;visibility:unset}.post-toc .nav .active>a{border-bottom-color:#fc6423;color:#fc6423}.post-toc .nav .active-current>a{color:#fc6423}.post-toc .nav .active-current>a:hover{color:#fc6423}.site-state{display:flex;flex-wrap:wrap;justify-content:center;line-height:1.4}.site-state-item{padding:0 15px}.site-state-item a{border-bottom:0;display:block}.site-state-item-count{display:block;font-size:1em;font-weight:600}.site-state-item-name{color:#999;font-size:.8125em}.footer{color:#999;font-size:.875em;padding:20px 0;transition:.2s ease-in-out;transition-property:left,right}.footer.footer-fixed{bottom:0;left:0;position:absolute;right:0}.footer-inner{box-sizing:border-box;text-align:center;display:flex;flex-direction:column;justify-content:center;margin:0 auto;width:calc(100% - 20px)}@media (max-width:767px){.footer-inner{width:auto}}@media (min-width:1200px){.footer-inner{width:1160px}}@media (min-width:1600px){.footer-inner{width:73%}}.use-motion .footer{opacity:0}.languages{display:inline-block;font-size:1.125em;position:relative}.languages .lang-select-label span{margin:0 .5em}.languages .lang-select{height:100%;left:0;opacity:0;position:absolute;top:0;width:100%}.with-love{color:red;display:inline-block;margin:0 5px}.busuanzi-count #busuanzi_container_site_uv{display:none}.busuanzi-count #busuanzi_container_site_pv{display:none}@keyframes icon-animate{0%,100%{transform:scale(1)}10%,30%{transform:scale(.9)}20%,40%,60%,80%{transform:scale(1.1)}50%,70%{transform:scale(1.1)}}.back-to-top{font-size:12px;align-items:center;bottom:-100px;color:#fff;display:flex;height:26px;transition:bottom .2s ease-in-out;background:#222;cursor:pointer;opacity:.6;position:fixed;z-index:30;right:30px}.back-to-top span{margin-right:8px}.back-to-top .fa{text-align:center;width:26px}@media (max-width:991px){.back-to-top{right:20px}}.back-to-top:hover{opacity:.8}@media (max-width:991px){.back-to-top{opacity:.8}}.back-to-top:hover{color:#fc6423}.back-to-top.back-to-top-on{bottom:30px}.reading-progress-bar{--progress:0;background:#37c6c0;height:3px;position:fixed;z-index:50;width:var(--progress);left:0;bottom:0}.rtl.post-body a,.rtl.post-body h1,.rtl.post-body h2,.rtl.post-body h3,.rtl.post-body h4,.rtl.post-body h5,.rtl.post-body h6,.rtl.post-body li,.rtl.post-body ol,.rtl.post-body p,.rtl.post-body ul{direction:rtl;font-family:UKIJ Ekran}.rtl.post-title{font-family:UKIJ Ekran}.post-button{margin-top:40px;text-align:center}.use-motion .comments,.use-motion .pagination,.use-motion .post-block{visibility:hidden}.use-motion .post-header{visibility:hidden}.use-motion .post-body{visibility:hidden}.use-motion .collection-header{visibility:hidden}.posts-collapse .post-content{margin-bottom:35px;margin-left:35px;position:relative}@media (max-width:767px){.posts-collapse .post-content{margin-left:0;margin-right:0}}.posts-collapse .post-content .collection-title{font-size:1.125em;position:relative}.posts-collapse .post-content .collection-title::before{background:#999;border:1px solid #fff;margin-left:-6px;margin-top:-4px;position:absolute;top:50%;border-radius:50%;content:' ';height:10px;width:10px}.posts-collapse .post-content .collection-year{font-size:1.5em;font-weight:700;margin:60px 0;position:relative}.posts-collapse .post-content .collection-year::before{background:#bbb;margin-left:-4px;margin-top:-4px;position:absolute;top:50%;border-radius:50%;content:' ';height:8px;width:8px}.posts-collapse .post-content .collection-header{display:block;margin-left:20px}.posts-collapse .post-content .collection-header small{color:#bbb;margin-left:5px}.posts-collapse .post-content .post-header{border-bottom:1px dashed #ccc;margin:30px 2px 0;padding-left:15px;position:relative;transition:border .2s ease-in-out}.posts-collapse .post-content .post-header::before{background:#bbb;border:1px solid #fff;left:-6px;position:absolute;top:.75em;transition:background .2s ease-in-out;border-radius:50%;content:' ';height:6px;width:6px}.posts-collapse .post-content .post-header:hover{border-bottom-color:#666}.posts-collapse .post-content .post-header:hover::before{background:#222}.posts-collapse .post-content .post-meta-container{display:inline;font-size:.75em;margin-right:10px}.posts-collapse .post-content .post-title{display:inline}.posts-collapse .post-content .post-title a{border-bottom:0;color:var(--link-color)}.posts-collapse .post-content .post-title .fa-external-link-alt{font-size:.875em;margin-left:5px}.posts-collapse .post-content::before{background:#f5f5f5;content:' ';height:100%;margin-left:-2px;position:absolute;top:1.25em;width:4px}.post-body{font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;overflow-wrap:break-word}@media (min-width:1200px){.post-body{font-size:1.125em}}@media (min-width:992px){.post-body{text-align:justify}}@media (max-width:991px){.post-body{text-align:justify}}.post-body h1 .header-anchor,.post-body h1 .headerlink,.post-body h2 .header-anchor,.post-body h2 .headerlink,.post-body h3 .header-anchor,.post-body h3 .headerlink,.post-body h4 .header-anchor,.post-body h4 .headerlink,.post-body h5 .header-anchor,.post-body h5 .headerlink,.post-body h6 .header-anchor,.post-body h6 .headerlink{border-bottom-style:none;color:inherit;float:right;font-size:.875em;margin-left:10px;opacity:0}.post-body h1 .header-anchor::before,.post-body h1 .headerlink::before,.post-body h2 .header-anchor::before,.post-body h2 .headerlink::before,.post-body h3 .header-anchor::before,.post-body h3 .headerlink::before,.post-body h4 .header-anchor::before,.post-body h4 .headerlink::before,.post-body h5 .header-anchor::before,.post-body h5 .headerlink::before,.post-body h6 .header-anchor::before,.post-body h6 .headerlink::before{content:'\f0c1';font-family:'Font Awesome 6 Free';font-weight:900}.post-body h1:hover .header-anchor,.post-body h1:hover .headerlink,.post-body h2:hover .header-anchor,.post-body h2:hover .headerlink,.post-body h3:hover .header-anchor,.post-body h3:hover .headerlink,.post-body h4:hover .header-anchor,.post-body h4:hover .headerlink,.post-body h5:hover .header-anchor,.post-body h5:hover .headerlink,.post-body h6:hover .header-anchor,.post-body h6:hover .headerlink{opacity:.5}.post-body h1:hover .header-anchor:hover,.post-body h1:hover .headerlink:hover,.post-body h2:hover .header-anchor:hover,.post-body h2:hover .headerlink:hover,.post-body h3:hover .header-anchor:hover,.post-body h3:hover .headerlink:hover,.post-body h4:hover .header-anchor:hover,.post-body h4:hover .headerlink:hover,.post-body h5:hover .header-anchor:hover,.post-body h5:hover .headerlink:hover,.post-body h6:hover .header-anchor:hover,.post-body h6:hover .headerlink:hover{opacity:1}.post-body .exturl .fa{font-size:.875em;margin-left:4px}.post-body .fancybox+figcaption,.post-body .image-caption,.post-body img+figcaption{color:#999;font-size:.875em;font-weight:700;line-height:1;margin:-15px auto 15px;text-align:center}.post-body embed,.post-body iframe,.post-body img,.post-body video{margin-bottom:20px}.post-body .video-container{height:0;margin-bottom:20px;overflow:hidden;padding-top:75%;position:relative;width:100%}.post-body .video-container embed,.post-body .video-container iframe,.post-body .video-container object{height:100%;left:0;margin:0;position:absolute;top:0;width:100%}.post-gallery{display:flex;min-height:200px}.post-gallery .post-gallery-image{flex:1}.post-gallery .post-gallery-image:not(:first-child){clip-path:polygon(40px 0,100% 0,100% 100%,0 100%);margin-left:-20px}.post-gallery .post-gallery-image:not(:last-child){margin-right:-20px}.post-gallery .post-gallery-image img{height:100%;object-fit:cover;opacity:1;width:100%}.posts-expand .post-gallery{margin-bottom:60px}.posts-collapse .post-gallery{margin:15px 0}.posts-expand .post-header{font-size:1.125em;margin-bottom:60px;text-align:center}.posts-expand .post-title{font-size:1.5em;font-weight:400;margin:initial;overflow-wrap:break-word}.posts-expand .post-title-link{border-bottom:0;color:var(--link-color);display:inline-block;position:relative}.posts-expand .post-title-link::before{background:var(--link-color);bottom:0;content:'';height:2px;left:0;position:absolute;transform:scaleX(0);transition:transform .2s ease-in-out;width:100%}.posts-expand .post-title-link:hover::before{transform:scaleX(1)}.posts-expand .post-title-link .fa-external-link-alt{font-size:.875em;margin-left:5px}.post-sticky-flag{display:inline-block;margin-right:8px;transform:rotate(30deg)}.posts-expand .post-meta-container{color:#999;font-family:Lato,'PingFang SC','Microsoft YaHei',sans-serif;font-size:.75em;margin-top:3px}.posts-expand .post-meta-container .post-description{font-size:.875em;margin-top:2px}.posts-expand .post-meta-container time{border-bottom:1px dashed #999}.post-meta{display:flex;flex-wrap:wrap;justify-content:center}:not(.post-meta-break)+.post-meta-item::before{content:'|';margin:0 .5em}.post-meta-item-icon{margin-right:3px}@media (max-width:991px){.post-meta-item-text{display:none}}.post-meta-break{flex-basis:100%;height:0}#busuanzi_container_page_pv{display:none}.post-nav{border-top:1px solid #eee;display:flex;gap:30px;justify-content:space-between;margin-top:1em;padding:10px 5px 0}.post-nav-item{flex:1}.post-nav-item a{border-bottom:0;display:block;font-size:.875em;line-height:1.6}.post-nav-item a:active{top:2px}.post-nav-item .fa{font-size:.75em}.post-nav-item:first-child .fa{margin-right:5px}.post-nav-item:last-child{text-align:right}.post-nav-item:last-child .fa{margin-left:5px}.post-footer{display:flex;flex-direction:column;justify-content:center}.post-eof{background:#ccc;height:1px;margin:80px auto 60px;width:8%}.post-block:last-of-type .post-eof{display:none}.post-copyright ul{list-style:none;overflow:hidden;padding:.5em 1em;position:relative;background:var(--card-bg-color);border-left:3px solid #ff2a2a;margin:1em 0 0}.post-copyright ul::after{content:'\f25e';font-family:'Font Awesome 6 Brands';font-size:200px;opacity:.1;position:absolute;right:-50px;top:-150px}.post-tags{margin-top:40px;text-align:center}.post-tags a{display:inline-block;font-size:.8125em}.post-tags a:not(:last-child){margin-right:10px}.social-like{border-top:1px solid #eee;font-size:.875em;margin-top:1em;padding-top:1em;text-align:center}.reward-container{margin:1em 0 0;padding:1em 0;text-align:center}.reward-container button{background:0 0;color:#fc6423;cursor:pointer;line-height:2;padding:0 15px;border:2px solid #fc6423;border-radius:2px;outline:0;transition:all .2s ease-in-out;vertical-align:text-top}.reward-container button:hover{background:#fc6423;color:#fff}.post-reward{display:none;padding-top:20px}.post-reward.active{display:block}.post-reward div{display:inline-block}.post-reward div span{display:block}.post-reward img{display:inline-block;margin:.8em 2em 0;max-width:100%;width:180px}@keyframes next-roll{from{transform:rotateZ(30deg)}to{transform:rotateZ(-30deg)}}.category-all-page .category-all-title{text-align:center}.category-all-page .category-all{margin-top:20px}.category-all-page .category-list{list-style:none;margin:0;padding:0}.category-all-page .category-list-item{margin:5px 10px}.category-all-page .category-list-count{color:#bbb}.category-all-page .category-list-count::before{content:' ('}.category-all-page .category-list-count::after{content:') '}.category-all-page .category-list-child{padding-left:10px}.event-list hr{background:#222;margin:20px 0 45px}.event-list hr::after{background:#222;color:#fff;content:'NOW';display:inline-block;font-weight:700;padding:0 5px}.event-list .event{--event-background:#222;--event-foreground:#bbb;--event-title:#fff;background:var(--event-background);padding:15px}.event-list .event .event-summary{border-bottom:0;color:var(--event-title);margin:0;padding:0 0 0 35px;position:relative}.event-list .event .event-summary::before{animation:dot-flash 1s alternate infinite ease-in-out;background:var(--event-title);left:0;margin-top:-6px;position:absolute;top:50%;border-radius:50%;content:' ';height:12px;width:12px}.event-list .event:nth-of-type(odd) .event-summary::before{animation-delay:.5s}.event-list .event:not(:last-child){margin-bottom:20px}.event-list .event .event-relative-time{color:var(--event-foreground);display:inline-block;font-size:12px;font-weight:400;padding-left:12px}.event-list .event .event-details{color:var(--event-foreground);display:block;line-height:18px;padding:6px 0 6px 35px}.event-list .event .event-details::before{color:var(--event-foreground);display:inline-block;margin-right:9px;width:14px;font-family:'Font Awesome 6 Free';font-weight:900}.event-list .event .event-details.event-location::before{content:'\f041'}.event-list .event .event-details.event-duration::before{content:'\f017'}.event-list .event .event-details.event-description::before{content:'\f024'}.event-list .event-past{--event-background:#f5f5f5;--event-foreground:#999;--event-title:#222}@keyframes dot-flash{from{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.8)}}ul.breadcrumb{font-size:.75em;list-style:none;margin:1em 0;padding:0 2em;text-align:center}ul.breadcrumb li{display:inline}ul.breadcrumb li:not(:first-child)::before{content:'/\00a0';font-weight:400;padding:.5em}ul.breadcrumb li:last-child{font-weight:700}.tag-cloud{text-align:center}.tag-cloud a{display:inline-block;margin:10px}.tag-cloud-0{border-bottom-color:#aaa;color:#aaa}.tag-cloud-1{border-bottom-color:#9a9a9a;color:#9a9a9a}.tag-cloud-2{border-bottom-color:#8b8b8b;color:#8b8b8b}.tag-cloud-3{border-bottom-color:#7c7c7c;color:#7c7c7c}.tag-cloud-4{border-bottom-color:#6c6c6c;color:#6c6c6c}.tag-cloud-5{border-bottom-color:#5d5d5d;color:#5d5d5d}.tag-cloud-6{border-bottom-color:#4e4e4e;color:#4e4e4e}.tag-cloud-7{border-bottom-color:#3e3e3e;color:#3e3e3e}.tag-cloud-8{border-bottom-color:#2f2f2f;color:#2f2f2f}.tag-cloud-9{border-bottom-color:#202020;color:#202020}.tag-cloud-10{border-bottom-color:#111;color:#111}.search-active{overflow:hidden}.search-pop-overlay{background:rgba(0,0,0,0);display:flex;height:100%;left:0;position:fixed;top:0;transition:visibility .4s,background .4s;visibility:hidden;width:100%;z-index:40}.search-active .search-pop-overlay{background:rgba(0,0,0,.3);visibility:visible}.search-popup{background:var(--card-bg-color);border-radius:5px;height:80%;margin:auto;transform:scale(0);transition:transform .4s;width:700px}.search-active .search-popup{transform:scale(1)}@media (max-width:767px){.search-popup{border-radius:0;height:100%;width:100%}}.search-popup .popup-btn-close,.search-popup .search-icon{color:#999;font-size:18px;padding:0 10px}.search-popup .popup-btn-close{cursor:pointer}.search-popup .popup-btn-close:hover .fa{color:#222}.search-popup .search-header{background:#eee;border-top-left-radius:5px;border-top-right-radius:5px;display:flex;padding:5px}.search-popup input.search-input{background:0 0;border:0;outline:0;width:100%}.search-popup input.search-input::-webkit-search-cancel-button{display:none}.search-popup .search-result-container{height:calc(100% - 55px);overflow:auto;padding:5px 25px}.search-popup .search-result-container hr{margin:5px 0 10px}.search-popup .search-result-container hr:first-child{display:none}.search-popup .search-result-list{margin:0 5px;padding:0}.search-popup a.search-result-title{font-weight:700}.search-popup p.search-result{border-bottom:1px dashed #ccc;padding:5px 0}.search-popup .search-input-container{flex-grow:1;padding:2px}.search-popup .no-result{display:flex}.search-popup .search-result-list{width:100%}.search-popup .search-result-icon{color:#ccc;margin:auto}mark.search-keyword{background:0 0;border-bottom:1px dashed #ff2a2a;color:#ff2a2a;font-weight:700}.use-motion .animated{animation-fill-mode:none;visibility:inherit}.use-motion .sidebar .animated{animation-fill-mode:both}.header{background:var(--content-bg-color);border-radius:20px 20px 20px 20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12)}@media (max-width:991px){.header{border-radius:initial}}.main{align-items:stretch;display:flex;justify-content:space-between;margin:0 auto;width:calc(100% - 20px)}@media (max-width:767px){.main{width:auto}}@media (min-width:1200px){.main{width:1160px}}@media (min-width:1600px){.main{width:73%}}@media (max-width:991px){.main{display:block;width:auto}}.main-inner{border-radius:20px 20px 20px 20px;box-sizing:border-box;width:calc(100% - 252px)}@media (max-width:991px){.main-inner{border-radius:initial;width:100%}}.footer-inner{padding-left:252px}@media (max-width:991px){.footer-inner{padding-left:0;padding-right:0;width:auto}}.column{width:240px}@media (max-width:991px){.column{width:auto}}.site-brand-container{background:var(--theme-color)}@media (max-width:991px){.site-nav-on .site-brand-container{box-shadow:0 0 16px rgba(0,0,0,.5)}}.site-meta{padding:20px 0}@media (min-width:768px) and (max-width:991px){.site-nav-right,.site-nav-toggle{display:flex;flex-direction:column;justify-content:center}}.site-nav-right .toggle,.site-nav-toggle .toggle{color:#fff}.site-nav-right .toggle .toggle-line,.site-nav-toggle .toggle .toggle-line{background:#fff}@media (min-width:768px) and (max-width:991px){.site-nav{--scroll-height:0;height:0;overflow:hidden;transition:.2s ease-in-out;transition-property:height,visibility;visibility:hidden}body:not(.site-nav-on) .site-nav .animated{animation:none}body.site-nav-on .site-nav{height:var(--scroll-height);visibility:unset}}.menu .menu-item{display:block;margin:0}.menu .menu-item a{padding:5px 20px;position:relative;text-align:left;transition-property:background-color}@media (max-width:991px){.menu .menu-item.menu-item-search{display:none}}.menu .menu-item .badge{background:#ccc;border-radius:10px;color:var(--content-bg-color);float:right;padding:2px 5px;text-shadow:1px 1px 0 rgba(0,0,0,.1)}.sub-menu{margin:0;padding:6px 0}.sub-menu .menu-item{display:inline-block}.sub-menu .menu-item a{background:0 0;margin:5px 10px;padding:initial}.sub-menu .menu-item a:hover{background:0 0;color:#fc6423}.sub-menu .menu-item-active{border-bottom-color:#fc6423;color:#fc6423}.sub-menu .menu-item-active:hover{border-bottom-color:#fc6423}.sidebar{position:-webkit-sticky;position:sticky;top:12px}@media (max-width:991px){.sidebar{display:none}}.sidebar-inner{background:var(--content-bg-color);border-radius:20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12),0 -1px .5px 0 rgba(0,0,0,.09);box-sizing:border-box;color:var(--text-color);margin-top:12px;max-height:calc(100vh - 24px);visibility:hidden}.site-state-item{padding:0 10px}.sidebar .sidebar-button{border-bottom:1px dotted #ccc;border-top:1px dotted #ccc}.sidebar .sidebar-button button{border:0;color:#fc6423;display:block;width:100%}.sidebar .sidebar-button button:hover{background:0 0;border:0;color:#e34603}.links-of-author{display:flex;flex-wrap:wrap;justify-content:center}.links-of-author-item{margin:5px 0 0}.links-of-author-item a{box-sizing:border-box;display:inline-block;max-width:100%;overflow:hidden;padding:0 5px;text-overflow:ellipsis;white-space:nowrap}.links-of-author-item a{border-bottom:0;border-radius:4px;display:block}.links-of-author-item a:hover{background:var(--body-bg-color)}.main-inner .comment-position .comments,.main-inner .pagination,.main-inner .post-block,.main-inner .sub-menu,.main-inner .tabs-comment,.main-inner>.comments{background:var(--content-bg-color);border-radius:20px 20px 20px 20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12)}.main-inner .post-block:not(:first-child):not(:first-child){border-radius:20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12),0 -1px .5px 0 rgba(0,0,0,.09);margin-top:12px}@media (min-width:768px) and (max-width:991px){.main-inner .post-block:not(:first-child):not(:first-child){margin-top:10px}}@media (max-width:767px){.main-inner .post-block:not(:first-child):not(:first-child){margin-top:8px}}.main-inner .comment-position .comments,.main-inner .pagination,.main-inner .tabs-comment,.main-inner>.comments{border-radius:20px;box-shadow:0 2px 2px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.06),0 1px 5px 0 rgba(0,0,0,.12),0 -1px .5px 0 rgba(0,0,0,.09);margin-top:12px}@media (min-width:768px) and (max-width:991px){.main-inner .comment-position .comments,.main-inner .pagination,.main-inner .tabs-comment,.main-inner>.comments{margin-top:10px}}@media (max-width:767px){.main-inner .comment-position .comments,.main-inner .pagination,.main-inner .tabs-comment,.main-inner>.comments{margin-top:8px}}.comments,.post-block{padding:40px}.post-eof{display:none}.pagination{border-top:initial;padding:10px 0}.post-body h1,.post-body h2{border-bottom:1px solid #eee}.post-body h3{border-bottom:1px dotted #eee}@media (min-width:768px) and (max-width:991px){.main-inner{padding:10px}.posts-expand .post-button{margin-top:20px}.post-block{padding:20px}.comments{padding:10px 20px}}@media (max-width:767px){.main-inner{padding:8px}.posts-expand .post-button{margin:12px 0}.post-block{padding:12px}.comments{padding:10px 12px}} +/* rebuild by neat */ \ No newline at end of file diff --git a/css/noscript.css b/css/noscript.css new file mode 100644 index 0000000..2b54dc1 --- /dev/null +++ b/css/noscript.css @@ -0,0 +1,3 @@ +/* build time:Tue Apr 25 2023 15:41:35 GMT+0800 (GMT+08:00)*/ +body{margin-top:2rem}.use-motion .collection-header,.use-motion .comments,.use-motion .menu-item,.use-motion .pagination,.use-motion .post-block,.use-motion .post-body,.use-motion .post-header,.use-motion .sidebar,.use-motion .sidebar-inner{visibility:visible}.use-motion .column,.use-motion .footer,.use-motion .site-brand-container .toggle{opacity:initial}.use-motion .custom-logo-image,.use-motion .site-subtitle,.use-motion .site-title{opacity:initial;top:initial}.use-motion .logo-line{transform:scaleX(1)}.search-pop-overlay,.sidebar-nav{display:none}.sidebar-panel{display:block}.noscript-warning{background-color:#f55;color:#fff;font-family:sans-serif;font-size:1rem;font-weight:700;left:0;position:fixed;text-align:center;top:0;width:100%;z-index:50} +/* rebuild by neat */ \ No newline at end of file diff --git a/guestbook/index.html b/guestbook/index.html new file mode 100644 index 0000000..2c4273f --- /dev/null +++ b/guestbook/index.html @@ -0,0 +1,16 @@ +留言板 | 随言碎语

随言碎语

咕叽咕叽

留言板

欢迎来到我的博客!

欢迎在这里留言!任何问题都可以在这里留言,博主会及时回复的,添加email可以收到回复提示

0%
\ No newline at end of file diff --git a/images/apple-touch-icon-next.png b/images/apple-touch-icon-next.png new file mode 100644 index 0000000..86a0d1d Binary files /dev/null and b/images/apple-touch-icon-next.png differ diff --git a/images/avatar.gif b/images/avatar.gif new file mode 100644 index 0000000..3b5d744 Binary files /dev/null and b/images/avatar.gif differ diff --git a/images/favicon-16x16-next.png b/images/favicon-16x16-next.png new file mode 100644 index 0000000..de8c5d3 Binary files /dev/null and b/images/favicon-16x16-next.png differ diff --git a/images/favicon-32x32-next.png b/images/favicon-32x32-next.png new file mode 100644 index 0000000..e02f5f4 Binary files /dev/null and b/images/favicon-32x32-next.png differ diff --git a/images/logo-algolia-nebula-blue-full.svg b/images/logo-algolia-nebula-blue-full.svg new file mode 100644 index 0000000..886c422 --- /dev/null +++ b/images/logo-algolia-nebula-blue-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/logo.svg b/images/logo.svg new file mode 100644 index 0000000..992c1a5 --- /dev/null +++ b/images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/nh.jpg b/images/nh.jpg new file mode 100644 index 0000000..4dd8a36 Binary files /dev/null and b/images/nh.jpg differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..1f3931a --- /dev/null +++ b/index.html @@ -0,0 +1,16 @@ +随言碎语

随言碎语

咕叽咕叽

esxi修改网卡顺序、网卡直通、修改安全策略、开机自动启动虚拟机。

阅读全文 »

欢迎来到我的博客,这是我的第一篇博客,由hexo+next构建。

0%
\ No newline at end of file diff --git a/js/bookmark.js b/js/bookmark.js new file mode 100644 index 0000000..8e3ae6a --- /dev/null +++ b/js/bookmark.js @@ -0,0 +1,56 @@ +/* global CONFIG */ + +document.addEventListener('DOMContentLoaded', () => { + 'use strict'; + + const doSaveScroll = () => { + localStorage.setItem('bookmark' + location.pathname, window.scrollY); + }; + + const scrollToMark = () => { + let top = localStorage.getItem('bookmark' + location.pathname); + top = parseInt(top, 10); + // If the page opens with a specific hash, just jump out + if (!isNaN(top) && location.hash === '') { + // Auto scroll to the position + window.anime({ + targets : document.scrollingElement, + duration : 200, + easing : 'linear', + scrollTop: top + }); + } + }; + // Register everything + const init = function(trigger) { + // Create a link element + const link = document.querySelector('.book-mark-link'); + // Scroll event + window.addEventListener('scroll', () => link.classList.toggle('book-mark-link-fixed', window.scrollY === 0), { passive: true }); + // Register beforeunload event when the trigger is auto + if (trigger === 'auto') { + // Register beforeunload event + window.addEventListener('beforeunload', doSaveScroll); + document.addEventListener('pjax:send', doSaveScroll); + } + // Save the position by clicking the icon + link.addEventListener('click', () => { + doSaveScroll(); + window.anime({ + targets : link, + duration: 200, + easing : 'linear', + top : -30, + complete: () => { + setTimeout(() => { + link.style.top = ''; + }, 400); + } + }); + }); + scrollToMark(); + document.addEventListener('pjax:success', scrollToMark); + }; + + init(CONFIG.bookmark.save); +}); diff --git a/js/comments-buttons.js b/js/comments-buttons.js new file mode 100644 index 0000000..505c21b --- /dev/null +++ b/js/comments-buttons.js @@ -0,0 +1,25 @@ +/* global CONFIG */ + +(function() { + const commentButton = document.querySelectorAll('.comment-button'); + commentButton.forEach(element => { + const commentClass = element.classList[2]; + element.addEventListener('click', () => { + commentButton.forEach(active => active.classList.toggle('active', active === element)); + document.querySelectorAll('.comment-position').forEach(active => active.classList.toggle('active', active.classList.contains(commentClass))); + if (CONFIG.comments.storage) { + localStorage.setItem('comments_active', commentClass); + } + }); + }); + let { activeClass } = CONFIG.comments; + if (CONFIG.comments.storage) { + activeClass = localStorage.getItem('comments_active') || activeClass; + } + if (activeClass) { + const activeButton = document.querySelector(`.comment-button.${activeClass}`); + if (activeButton) { + activeButton.click(); + } + } +})(); diff --git a/js/comments.js b/js/comments.js new file mode 100644 index 0000000..4045e8c --- /dev/null +++ b/js/comments.js @@ -0,0 +1,21 @@ +/* global CONFIG */ + +window.addEventListener('tabs:register', () => { + let { activeClass } = CONFIG.comments; + if (CONFIG.comments.storage) { + activeClass = localStorage.getItem('comments_active') || activeClass; + } + if (activeClass) { + const activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`); + if (activeTab) { + activeTab.click(); + } + } +}); +if (CONFIG.comments.storage) { + window.addEventListener('tabs:click', event => { + if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return; + const commentClass = event.target.classList[1]; + localStorage.setItem('comments_active', commentClass); + }); +} diff --git a/js/config.js b/js/config.js new file mode 100644 index 0000000..caa0075 --- /dev/null +++ b/js/config.js @@ -0,0 +1,66 @@ +if (!window.NexT) window.NexT = {}; + +(function() { + const className = 'next-config'; + + const staticConfig = {}; + let variableConfig = {}; + + const parse = text => JSON.parse(text || '{}'); + + const update = name => { + const targetEle = document.querySelector(`.${className}[data-name="${name}"]`); + if (!targetEle) return; + const parsedConfig = parse(targetEle.text); + if (name === 'main') { + Object.assign(staticConfig, parsedConfig); + } else { + variableConfig[name] = parsedConfig; + } + }; + + update('main'); + + window.CONFIG = new Proxy({}, { + get(overrideConfig, name) { + let existing; + if (name in staticConfig) { + existing = staticConfig[name]; + } else { + if (!(name in variableConfig)) update(name); + existing = variableConfig[name]; + } + + // For unset override and mixable existing + if (!(name in overrideConfig) && typeof existing === 'object') { + // Get ready to mix. + overrideConfig[name] = {}; + } + + if (name in overrideConfig) { + const override = overrideConfig[name]; + + // When mixable + if (typeof override === 'object' && typeof existing === 'object') { + // Mix, proxy changes to the override. + return new Proxy({ ...existing, ...override }, { + set(target, prop, value) { + target[prop] = value; + override[prop] = value; + return true; + } + }); + } + + return override; + } + + // Only when not mixable and override hasn't been set. + return existing; + } + }); + + document.addEventListener('pjax:success', () => { + variableConfig = {}; + }); +})(); diff --git a/js/cursor/explosion.min.js b/js/cursor/explosion.min.js new file mode 100644 index 0000000..cb967a5 --- /dev/null +++ b/js/cursor/explosion.min.js @@ -0,0 +1 @@ +"use strict";function updateCoords(e){pointerX=(e.clientX||e.touches[0].clientX)-canvasEl.getBoundingClientRect().left,pointerY=e.clientY||e.touches[0].clientY-canvasEl.getBoundingClientRect().top}function setParticuleDirection(e){var t=anime.random(0,360)*Math.PI/180,a=anime.random(50,180),n=[-1,1][anime.random(0,1)]*a;return{x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)}}function createParticule(e,t){var a={};return a.x=e,a.y=t,a.color=colors[anime.random(0,colors.length-1)],a.radius=anime.random(16,32),a.endPos=setParticuleDirection(a),a.draw=function(){ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.fillStyle=a.color,ctx.fill()},a}function createCircle(e,t){var a={};return a.x=e,a.y=t,a.color="#F00",a.radius=.1,a.alpha=.5,a.lineWidth=6,a.draw=function(){ctx.globalAlpha=a.alpha,ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.lineWidth=a.lineWidth,ctx.strokeStyle=a.color,ctx.stroke(),ctx.globalAlpha=1},a}function renderParticule(e){for(var t=0;t { + if (circle.position.x > this.area.width || circle.position.y > this.area.height) { + return this.circles.splice(index, 1) + } + circle.move() + }) + if (this.circles.length == 0) { + this.stop = true + } + } + + draw() { + this.circles.forEach(circle => circle.draw()) + } +} + +class CursorSpecialEffects { + constructor() { + this.computerCanvas = document.createElement('canvas') + this.renderCanvas = document.createElement('canvas') + + this.computerContext = this.computerCanvas.getContext('2d') + this.renderContext = this.renderCanvas.getContext('2d') + + this.globalWidth = window.innerWidth + this.globalHeight = window.innerHeight + + this.booms = [] + this.running = false + } + + handleMouseDown(e) { + const boom = new Boom({ + origin: { x: e.clientX, y: e.clientY }, + context: this.computerContext, + area: { + width: this.globalWidth, + height: this.globalHeight + } + }) + boom.init() + this.booms.push(boom) + this.running || this.run() + } + + handlePageHide() { + this.booms = [] + this.running = false + } + + init() { + const style = this.renderCanvas.style + style.position = 'fixed' + style.top = style.left = 0 + style.zIndex = '999999999999999999999999999999999999999999' + style.pointerEvents = 'none' + + style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth + style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight + + document.body.append(this.renderCanvas) + + window.addEventListener('mousedown', this.handleMouseDown.bind(this)) + window.addEventListener('pagehide', this.handlePageHide.bind(this)) + } + + run() { + this.running = true + if (this.booms.length == 0) { + return this.running = false + } + + requestAnimationFrame(this.run.bind(this)) + + this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight) + this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight) + + this.booms.forEach((boom, index) => { + if (boom.stop) { + return this.booms.splice(index, 1) + } + boom.move() + boom.draw() + }) + this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight) + } +} + +const cursorSpecialEffects = new CursorSpecialEffects() +cursorSpecialEffects.init() diff --git a/js/cursor/love.min.js b/js/cursor/love.min.js new file mode 100644 index 0000000..cdf22df --- /dev/null +++ b/js/cursor/love.min.js @@ -0,0 +1 @@ +!function(e,t,a){function n(){c(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o(),r()}function r(){for(var e=0;e").text(a[a_idx]); + var x = e.pageX, + y = e.pageY; + $i.css({ + "z-index": 99999, + "top": y - 28, + "left": x - a[a_idx].length * 8, + "position": "absolute", + "color": "#ff7a45" + }); + $("body").append($i); + $i.animate({ + "top": y - 180, + "opacity": 0 + }, 1500, function() { + $i.remove(); + }); + a_idx = (a_idx + 1) % a.length; + }); +}); diff --git a/js/link.js b/js/link.js new file mode 100644 index 0000000..4641df0 --- /dev/null +++ b/js/link.js @@ -0,0 +1,26 @@ +// 随机排列 +function shuffle(arr) { + let i = arr.length; + while (i) { + let j = Math.floor(Math.random() * i--); + [arr[j], arr[i]] = [arr[i], arr[j]]; + } +} + +// 渲染数据 +function renderlink(data) { + var name, avatar, site, li = ""; + shuffle(data); + for (var i = 0; i < data.length; i++) { + name = data[i].name; + avatar = data[i].avatar; + site = data[i].site; + li += '
' + '' + '
' + '
' + '
' + '
' + '
' + name + '
' + '
' + '
'; + } + document.querySelector(".link-navigation").innerHTML = li; +} + +// 获取 json 文件 +fetch('/links/linklist.json') + .then(response => response.json()) + .then(res => renderlink(res)); diff --git a/js/motion.js b/js/motion.js new file mode 100644 index 0000000..aad22db --- /dev/null +++ b/js/motion.js @@ -0,0 +1,140 @@ +/* global NexT, CONFIG */ + +NexT.motion = {}; + +NexT.motion.integrator = { + queue: [], + init : function() { + this.queue = []; + return this; + }, + add: function(fn) { + const sequence = fn(); + if (CONFIG.motion.async) this.queue.push(sequence); + else this.queue = this.queue.concat(sequence); + return this; + }, + bootstrap: function() { + if (!CONFIG.motion.async) this.queue = [this.queue]; + this.queue.forEach(sequence => { + const timeline = window.anime.timeline({ + duration: 200, + easing : 'linear' + }); + sequence.forEach(item => { + if (item.deltaT) timeline.add(item, item.deltaT); + else timeline.add(item); + }); + }); + } +}; + +NexT.motion.middleWares = { + header: function() { + const sequence = []; + + function getMistLineSettings(targets) { + sequence.push({ + targets, + scaleX : [0, 1], + duration: 500, + deltaT : '-=200' + }); + } + + function pushToSequence(targets, sequenceQueue = false) { + sequence.push({ + targets, + opacity: 1, + top : 0, + deltaT : sequenceQueue ? '-=200' : '-=0' + }); + } + + pushToSequence('.column'); + CONFIG.scheme === 'Mist' && getMistLineSettings('.logo-line'); + CONFIG.scheme === 'Muse' && pushToSequence('.custom-logo-image'); + pushToSequence('.site-title'); + pushToSequence('.site-brand-container .toggle', true); + pushToSequence('.site-subtitle'); + (CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini') && pushToSequence('.custom-logo-image'); + + const menuItemTransition = CONFIG.motion.transition.menu_item; + if (menuItemTransition) { + document.querySelectorAll('.menu-item').forEach(targets => { + sequence.push({ + targets, + complete: () => targets.classList.add('animated', menuItemTransition), + deltaT : '-=200' + }); + }); + } + + return sequence; + }, + + subMenu: function() { + const subMenuItem = document.querySelectorAll('.sub-menu .menu-item'); + if (subMenuItem.length > 0) { + subMenuItem.forEach(element => { + element.classList.add('animated'); + }); + } + return []; + }, + + postList: function() { + const sequence = []; + const { post_block, post_header, post_body, coll_header } = CONFIG.motion.transition; + + function animate(animation, elements) { + if (!animation) return; + elements.forEach(targets => { + sequence.push({ + targets, + complete: () => targets.classList.add('animated', animation), + deltaT : '-=100' + }); + }); + } + + document.querySelectorAll('.post-block').forEach(targets => { + sequence.push({ + targets, + complete: () => targets.classList.add('animated', post_block), + deltaT : '-=100' + }); + animate(coll_header, targets.querySelectorAll('.collection-header')); + animate(post_header, targets.querySelectorAll('.post-header')); + animate(post_body, targets.querySelectorAll('.post-body')); + }); + + animate(post_block, document.querySelectorAll('.pagination, .comments')); + + return sequence; + }, + + sidebar: function() { + const sequence = []; + const sidebar = document.querySelectorAll('.sidebar-inner'); + const sidebarTransition = CONFIG.motion.transition.sidebar; + // Only for Pisces | Gemini. + if (sidebarTransition && (CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini')) { + sidebar.forEach(targets => { + sequence.push({ + targets, + complete: () => targets.classList.add('animated', sidebarTransition), + deltaT : '-=100' + }); + }); + } + return sequence; + }, + + footer: function() { + return [{ + targets: document.querySelector('.footer'), + opacity: 1 + }]; + } +}; diff --git a/js/next-boot.js b/js/next-boot.js new file mode 100644 index 0000000..1225fd2 --- /dev/null +++ b/js/next-boot.js @@ -0,0 +1,75 @@ +/* global NexT, CONFIG */ + +NexT.boot = {}; + +NexT.boot.registerEvents = function() { + + NexT.utils.registerScrollPercent(); + NexT.utils.registerCanIUseTag(); + + // Mobile top menu bar. + document.querySelector('.site-nav-toggle .toggle').addEventListener('click', event => { + event.currentTarget.classList.toggle('toggle-close'); + const siteNav = document.querySelector('.site-nav'); + if (!siteNav) return; + siteNav.style.setProperty('--scroll-height', siteNav.scrollHeight + 'px'); + document.body.classList.toggle('site-nav-on'); + }); + + document.querySelectorAll('.sidebar-nav li').forEach((element, index) => { + element.addEventListener('click', () => { + NexT.utils.activateSidebarPanel(index); + }); + }); + + window.addEventListener('hashchange', () => { + const tHash = location.hash; + if (tHash !== '' && !tHash.match(/%\S{2}/)) { + const target = document.querySelector(`.tabs ul.nav-tabs li a[href="${tHash}"]`); + target && target.click(); + } + }); +}; + +NexT.boot.refresh = function() { + + /** + * Register JS handlers by condition option. + * Need to add config option in Front-End at 'scripts/helpers/next-config.js' file. + */ + CONFIG.prism && window.Prism.highlightAll(); + CONFIG.mediumzoom && window.mediumZoom('.post-body :not(a) > img, .post-body > img', { + background: 'var(--content-bg-color)' + }); + CONFIG.lazyload && window.lozad('.post-body img').observe(); + CONFIG.pangu && window.pangu.spacingPage(); + + CONFIG.exturl && NexT.utils.registerExtURL(); + NexT.utils.wrapTableWithBox(); + NexT.utils.registerCopyCode(); + NexT.utils.registerTabsTag(); + NexT.utils.registerActiveMenuItem(); + NexT.utils.registerLangSelect(); + NexT.utils.registerSidebarTOC(); + NexT.utils.registerPostReward(); + NexT.utils.registerVideoIframe(); +}; + +NexT.boot.motion = function() { + // Define Motion Sequence & Bootstrap Motion. + if (CONFIG.motion.enable) { + NexT.motion.integrator + .add(NexT.motion.middleWares.header) + .add(NexT.motion.middleWares.postList) + .add(NexT.motion.middleWares.sidebar) + .add(NexT.motion.middleWares.footer) + .bootstrap(); + } + NexT.utils.updateSidebarPosition(); +}; + +document.addEventListener('DOMContentLoaded', () => { + NexT.boot.registerEvents(); + NexT.boot.refresh(); + NexT.boot.motion(); +}); diff --git a/js/pjax.js b/js/pjax.js new file mode 100644 index 0000000..f81a6a0 --- /dev/null +++ b/js/pjax.js @@ -0,0 +1,50 @@ +/* global NexT, CONFIG, Pjax */ + +const pjax = new Pjax({ + selectors: [ + 'head title', + 'script[type="application/json"]', + // Precede .main-inner to prevent placeholder TOC changes asap + '.post-toc-wrap', + '.main-inner', + '.languages', + '.pjax' + ], + switches: { + '.post-toc-wrap': function(oldWrap, newWrap) { + if (newWrap.querySelector('.post-toc')) { + Pjax.switches.outerHTML.call(this, oldWrap, newWrap); + } else { + const curTOC = oldWrap.querySelector('.post-toc'); + if (curTOC) { + curTOC.classList.add('placeholder-toc'); + } + this.onSwitch(); + } + } + }, + analytics: false, + cacheBust: false, + scrollTo : !CONFIG.bookmark.enable +}); + +document.addEventListener('pjax:success', () => { + pjax.executeScripts(document.querySelectorAll('script[data-pjax]')); + NexT.boot.refresh(); + // Define Motion Sequence & Bootstrap Motion. + if (CONFIG.motion.enable) { + NexT.motion.integrator + .init() + .add(NexT.motion.middleWares.subMenu) + .add(NexT.motion.middleWares.postList) + // Add sidebar-post-related transition. + .add(NexT.motion.middleWares.sidebar) + .bootstrap(); + } + if (CONFIG.sidebar.display !== 'remove') { + const hasTOC = document.querySelector('.post-toc:not(.placeholder-toc)'); + document.querySelector('.sidebar-inner').classList.toggle('sidebar-nav-active', hasTOC); + NexT.utils.activateSidebarPanel(hasTOC ? 0 : 1); + NexT.utils.updateSidebarPosition(); + } +}); diff --git a/js/schedule.js b/js/schedule.js new file mode 100644 index 0000000..8f0c26c --- /dev/null +++ b/js/schedule.js @@ -0,0 +1,138 @@ +/* global CONFIG */ + +// https://developers.google.com/calendar/api/v3/reference/events/list +(function() { + // Initialization + const calendar = { + orderBy : 'startTime', + showLocation: false, + offsetMax : 72, + offsetMin : 4, + showDeleted : false, + singleEvents: true, + maxResults : 250 + }; + + // Read config form theme config file + Object.assign(calendar, CONFIG.calendar); + + const now = new Date(); + const timeMax = new Date(); + const timeMin = new Date(); + + timeMax.setHours(now.getHours() + calendar.offsetMax); + timeMin.setHours(now.getHours() - calendar.offsetMin); + + // Build URL + const params = { + key : calendar.api_key, + orderBy : calendar.orderBy, + timeMax : timeMax.toISOString(), + timeMin : timeMin.toISOString(), + showDeleted : calendar.showDeleted, + singleEvents: calendar.singleEvents, + maxResults : calendar.maxResults + }; + + const request_url = new URL(`https://www.googleapis.com/calendar/v3/calendars/${calendar.calendar_id}/events`); + Object.entries(params).forEach(param => request_url.searchParams.append(...param)); + + function getRelativeTime(current, previous) { + const msPerMinute = 60 * 1000; + const msPerHour = msPerMinute * 60; + const msPerDay = msPerHour * 24; + const msPerMonth = msPerDay * 30; + const msPerYear = msPerDay * 365; + + let elapsed = current - previous; + const tense = elapsed > 0 ? ' ago' : ' later'; + + elapsed = Math.abs(elapsed); + + if (elapsed < msPerHour) { + return Math.round(elapsed / msPerMinute) + ' minutes' + tense; + } else if (elapsed < msPerDay) { + return Math.round(elapsed / msPerHour) + ' hours' + tense; + } else if (elapsed < msPerMonth) { + return 'about ' + Math.round(elapsed / msPerDay) + ' days' + tense; + } else if (elapsed < msPerYear) { + return 'about ' + Math.round(elapsed / msPerMonth) + ' months' + tense; + } + + return 'about ' + Math.round(elapsed / msPerYear) + ' years' + tense; + } + + function buildEventDOM(tense, event, start, end) { + const durationFormat = { + weekday: 'short', + hour : '2-digit', + minute : '2-digit' + }; + const relativeTime = tense === 'now' ? 'NOW' : getRelativeTime(now, start); + const duration = start.toLocaleTimeString([], durationFormat) + ' - ' + end.toLocaleTimeString([], durationFormat); + + let location = ''; + if (calendar.showLocation && event.location) { + location = `${event.location}`; + } + let description = ''; + if (event.description) { + description = `${event.description}`; + } + + const eventContent = `
+

+ ${event.summary} + ${relativeTime} +

+ ${location} + ${duration} + ${description} +
`; + return eventContent; + } + + function fetchData() { + const eventList = document.querySelector('.event-list'); + if (!eventList) return; + + fetch(request_url.href).then(response => { + return response.json(); + }).then(data => { + if (data.items.length === 0) { + eventList.innerHTML = '
'; + return; + } + // Clean the event list + eventList.innerHTML = ''; + let prevEnd = 0; // used to decide where to insert an
+ const utc = new Date().getTimezoneOffset() * 60000; + + data.items.forEach(event => { + // Parse data + const start = new Date(event.start.dateTime || (new Date(event.start.date).getTime() + utc)); + const end = new Date(event.end.dateTime || (new Date(event.end.date).getTime() + utc)); + + let tense = 'now'; + if (end < now) { + tense = 'past'; + } else if (start > now) { + tense = 'future'; + } + + if (tense === 'future' && prevEnd < now) { + eventList.insertAdjacentHTML('beforeend', '
'); + } + + eventList.insertAdjacentHTML('beforeend', buildEventDOM(tense, event, start, end)); + prevEnd = end; + }); + }); + } + + fetchData(); + const fetchDataTimer = setInterval(fetchData, 60000); + document.addEventListener('pjax:send', () => { + clearInterval(fetchDataTimer); + }); +})(); diff --git a/js/schemes/muse.js b/js/schemes/muse.js new file mode 100644 index 0000000..ba60b51 --- /dev/null +++ b/js/schemes/muse.js @@ -0,0 +1,60 @@ +/* global CONFIG */ + +document.addEventListener('DOMContentLoaded', () => { + + const isRight = CONFIG.sidebar.position === 'right'; + + const sidebarToggleMotion = { + mouse: {}, + init : function() { + window.addEventListener('mousedown', this.mousedownHandler.bind(this)); + window.addEventListener('mouseup', this.mouseupHandler.bind(this)); + document.querySelector('.sidebar-dimmer').addEventListener('click', this.clickHandler.bind(this)); + document.querySelector('.sidebar-toggle').addEventListener('click', this.clickHandler.bind(this)); + window.addEventListener('sidebar:show', this.showSidebar); + window.addEventListener('sidebar:hide', this.hideSidebar); + }, + mousedownHandler: function(event) { + this.mouse.X = event.pageX; + this.mouse.Y = event.pageY; + }, + mouseupHandler: function(event) { + const deltaX = event.pageX - this.mouse.X; + const deltaY = event.pageY - this.mouse.Y; + const clickingBlankPart = Math.hypot(deltaX, deltaY) < 20 && event.target.matches('.main'); + // Fancybox has z-index property, but medium-zoom does not, so the sidebar will overlay the zoomed image. + if (clickingBlankPart || event.target.matches('img.medium-zoom-image')) { + this.hideSidebar(); + } + }, + clickHandler: function() { + document.body.classList.contains('sidebar-active') ? this.hideSidebar() : this.showSidebar(); + }, + showSidebar: function() { + document.body.classList.add('sidebar-active'); + const animateAction = isRight ? 'fadeInRight' : 'fadeInLeft'; + document.querySelectorAll('.sidebar .animated').forEach((element, index) => { + element.style.animationDelay = (100 * index) + 'ms'; + element.classList.remove(animateAction); + setTimeout(() => { + // Trigger a DOM reflow + element.classList.add(animateAction); + }); + }); + }, + hideSidebar: function() { + document.body.classList.remove('sidebar-active'); + } + }; + if (CONFIG.sidebar.display !== 'remove') sidebarToggleMotion.init(); + + function updateFooterPosition() { + const footer = document.querySelector('.footer'); + const containerHeight = document.querySelector('.main').offsetHeight + footer.offsetHeight; + footer.classList.toggle('footer-fixed', containerHeight <= window.innerHeight); + } + + updateFooterPosition(); + window.addEventListener('resize', updateFooterPosition); + window.addEventListener('scroll', updateFooterPosition, { passive: true }); +}); diff --git a/js/tagcanvas.js b/js/tagcanvas.js new file mode 100644 index 0000000..80866a2 --- /dev/null +++ b/js/tagcanvas.js @@ -0,0 +1,2243 @@ +/** + * Copyright (C) 2010-2015 Graham Breach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +/** + * TagCanvas 2.9 + * For more information, please contact + */ +(function(){ +"use strict"; +var i, j, abs = Math.abs, sin = Math.sin, cos = Math.cos, max = Math.max, + min = Math.min, ceil = Math.ceil, sqrt = Math.sqrt, pow = Math.pow, + hexlookup3 = {}, hexlookup2 = {}, hexlookup1 = { + 0:"0,", 1:"17,", 2:"34,", 3:"51,", 4:"68,", 5:"85,", + 6:"102,", 7:"119,", 8:"136,", 9:"153,", a:"170,", A:"170,", + b:"187,", B:"187,", c:"204,", C:"204,", d:"221,", D:"221,", + e:"238,", E:"238,", f:"255,", F:"255," + }, Oproto, Tproto, TCproto, Mproto, Vproto, TSproto, TCVproto, + doc = document, ocanvas, handlers = {}; +for(i = 0; i < 256; ++i) { + j = i.toString(16); + if(i < 16) + j = '0' + j; + hexlookup2[j] = hexlookup2[j.toUpperCase()] = i.toString() + ','; +} +function Defined(d) { + return typeof d != 'undefined'; +} +function IsObject(o) { + return typeof o == 'object' && o != null; +} +function Clamp(v, mn, mx) { + return isNaN(v) ? mx : min(mx, max(mn, v)); +} +function Nop() { + return false; +} +function TimeNow() { + return new Date().valueOf(); +} +function SortList(l, f) { + var nl = [], tl = l.length, i; + for(i = 0; i < tl; ++i) + nl.push(l[i]); + nl.sort(f); + return nl; +} +function Shuffle(a) { + var i = a.length-1, t, p; + while(i) { + p = ~~(Math.random()*i); + t = a[i]; + a[i] = a[p]; + a[p] = t; + --i; + } +} +function Vector(x, y, z) { + this.x = x; + this.y = y; + this.z = z; +} +Vproto = Vector.prototype; +Vproto.length = function() { + return sqrt(this.x * this.x + this.y * this.y + this.z * this.z); +}; +Vproto.dot = function(v) { + return this.x * v.x + this.y * v.y + this.z * v.z; +}; +Vproto.cross = function(v) { + var x = this.y * v.z - this.z * v.y, + y = this.z * v.x - this.x * v.z, + z = this.x * v.y - this.y * v.x; + return new Vector(x, y, z); +}; +Vproto.angle = function(v) { + var dot = this.dot(v), ac; + if(dot == 0) + return Math.PI / 2.0; + ac = dot / (this.length() * v.length()); + if(ac >= 1) + return 0; + if(ac <= -1) + return Math.PI; + return Math.acos(ac); +}; +Vproto.unit = function() { + var l = this.length(); + return new Vector(this.x / l, this.y / l, this.z / l); +}; +function MakeVector(lg, lt) { + lt = lt * Math.PI / 180; + lg = lg * Math.PI / 180; + var x = sin(lg) * cos(lt), y = -sin(lt), z = -cos(lg) * cos(lt); + return new Vector(x, y, z); +} +function Matrix(a) { + this[1] = {1: a[0], 2: a[1], 3: a[2]}; + this[2] = {1: a[3], 2: a[4], 3: a[5]}; + this[3] = {1: a[6], 2: a[7], 3: a[8]}; +} +Mproto = Matrix.prototype; +Matrix.Identity = function() { + return new Matrix([1,0,0, 0,1,0, 0,0,1]); +}; +Matrix.Rotation = function(angle, u) { + var sina = sin(angle), cosa = cos(angle), mcos = 1 - cosa; + return new Matrix([ + cosa + pow(u.x, 2) * mcos, u.x * u.y * mcos - u.z * sina, u.x * u.z * mcos + u.y * sina, + u.y * u.x * mcos + u.z * sina, cosa + pow(u.y, 2) * mcos, u.y * u.z * mcos - u.x * sina, + u.z * u.x * mcos - u.y * sina, u.z * u.y * mcos + u.x * sina, cosa + pow(u.z, 2) * mcos + ]); +} +Mproto.mul = function(m) { + var a = [], i, j, mmatrix = (m.xform ? 1 : 0); + for(i = 1; i <= 3; ++i) + for(j = 1; j <= 3; ++j) { + if(mmatrix) + a.push(this[i][1] * m[1][j] + + this[i][2] * m[2][j] + + this[i][3] * m[3][j]); + else + a.push(this[i][j] * m); + } + return new Matrix(a); +}; +Mproto.xform = function(p) { + var a = {}, x = p.x, y = p.y, z = p.z; + a.x = x * this[1][1] + y * this[2][1] + z * this[3][1]; + a.y = x * this[1][2] + y * this[2][2] + z * this[3][2]; + a.z = x * this[1][3] + y * this[2][3] + z * this[3][3]; + return a; +}; +function PointsOnSphere(n,xr,yr,zr,magic) { + var i, y, r, phi, pts = [], off = 2/n, inc; + inc = Math.PI * (3 - sqrt(5) + (parseFloat(magic) ? parseFloat(magic) : 0)); + for(i = 0; i < n; ++i) { + y = i * off - 1 + (off / 2); + r = sqrt(1 - y*y); + phi = i * inc; + pts.push([cos(phi) * r * xr, y * yr, sin(phi) * r * zr]); + } + return pts; +} +function Cylinder(n,o,xr,yr,zr,magic) { + var phi, pts = [], off = 2/n, inc, i, j, k, l; + inc = Math.PI * (3 - sqrt(5) + (parseFloat(magic) ? parseFloat(magic) : 0)); + for(i = 0; i < n; ++i) { + j = i * off - 1 + (off / 2); + phi = i * inc; + k = cos(phi); + l = sin(phi); + pts.push(o ? [j * xr, k * yr, l * zr] : [k * xr, j * yr, l * zr]); + } + return pts; +} +function Ring(o, n, xr, yr, zr, j) { + var phi, pts = [], inc = Math.PI * 2 / n, i, k, l; + for(i = 0; i < n; ++i) { + phi = i * inc; + k = cos(phi); + l = sin(phi); + pts.push(o ? [j * xr, k * yr, l * zr] : [k * xr, j * yr, l * zr]); + } + return pts; +} +function PointsOnCylinderV(n,xr,yr,zr,m) { return Cylinder(n, 0, xr, yr, zr, m) } +function PointsOnCylinderH(n,xr,yr,zr,m) { return Cylinder(n, 1, xr, yr, zr, m) } +function PointsOnRingV(n, xr, yr, zr, offset) { + offset = isNaN(offset) ? 0 : offset * 1; + return Ring(0, n, xr, yr, zr, offset); +} +function PointsOnRingH(n, xr, yr, zr, offset) { + offset = isNaN(offset) ? 0 : offset * 1; + return Ring(1, n, xr, yr, zr, offset); +} +function CentreImage(t) { + var i = new Image; + i.onload = function() { + var dx = i.width / 2, dy = i.height / 2; + t.centreFunc = function(c, w, h, cx, cy) { + c.setTransform(1, 0, 0, 1, 0, 0); + c.globalAlpha = 1; + c.drawImage(i, cx - dx, cy - dy); + }; + }; + i.src = t.centreImage; +} +function SetAlpha(c,a) { + var d = c, p1, p2, ae = (a*1).toPrecision(3) + ')'; + if(c[0] === '#') { + if(!hexlookup3[c]) + if(c.length === 4) + hexlookup3[c] = 'rgba(' + hexlookup1[c[1]] + hexlookup1[c[2]] + hexlookup1[c[3]]; + else + hexlookup3[c] = 'rgba(' + hexlookup2[c.substr(1,2)] + hexlookup2[c.substr(3,2)] + hexlookup2[c.substr(5,2)]; + d = hexlookup3[c] + ae; + } else if(c.substr(0,4) === 'rgb(' || c.substr(0,4) === 'hsl(') { + d = (c.replace('(','a(').replace(')', ',' + ae)); + } else if(c.substr(0,5) === 'rgba(' || c.substr(0,5) === 'hsla(') { + p1 = c.lastIndexOf(',') + 1, p2 = c.indexOf(')'); + a *= parseFloat(c.substring(p1,p2)); + d = c.substr(0,p1) + a.toPrecision(3) + ')'; + } + return d; +} +function NewCanvas(w,h) { + // if using excanvas, give up now + if(window.G_vmlCanvasManager) + return null; + var c = doc.createElement('canvas'); + c.width = w; + c.height = h; + return c; +} +// I think all browsers pass this test now... +function ShadowAlphaBroken() { + var cv = NewCanvas(3,3), c, i; + if(!cv) + return false; + c = cv.getContext('2d'); + c.strokeStyle = '#000'; + c.shadowColor = '#fff'; + c.shadowBlur = 3; + c.globalAlpha = 0; + c.strokeRect(2,2,2,2); + c.globalAlpha = 1; + i = c.getImageData(2,2,1,1); + cv = null; + return (i.data[0] > 0); +} +function SetGradient(c, l, o, g) { + var gd = c.createLinearGradient(0, 0, l, 0), i; + for(i in g) + gd.addColorStop(1 - i, g[i]); + c.fillStyle = gd; + c.fillRect(0, o, l, 1); +} +function FindGradientColour(tc, p, r) { + var l = 1024, h = 1, gl = tc.weightGradient, cv, c, i, d; + if(tc.gCanvas) { + c = tc.gCanvas.getContext('2d'); + h = tc.gCanvas.height; + } else { + if(IsObject(gl[0])) + h = gl.length; + else + gl = [gl]; + tc.gCanvas = cv = NewCanvas(l, h); + if(!cv) + return null; + c = cv.getContext('2d'); + for(i = 0; i < h; ++i) + SetGradient(c, l, i, gl[i]); + } + r = max(min(r || 0, h - 1), 0); + d = c.getImageData(~~((l - 1) * p), r, 1, 1).data; + return 'rgba(' + d[0] + ',' + d[1] + ',' + d[2] + ',' + (d[3]/255) + ')'; +} +function TextSet(ctxt, font, colour, strings, padx, pady, shadowColour, + shadowBlur, shadowOffsets, maxWidth, widths, align) { + var xo = padx + (shadowBlur || 0) + + (shadowOffsets.length && shadowOffsets[0] < 0 ? abs(shadowOffsets[0]) : 0), + yo = pady + (shadowBlur || 0) + + (shadowOffsets.length && shadowOffsets[1] < 0 ? abs(shadowOffsets[1]) : 0), i, xc; + ctxt.font = font; + ctxt.textBaseline = 'top'; + ctxt.fillStyle = colour; + shadowColour && (ctxt.shadowColor = shadowColour); + shadowBlur && (ctxt.shadowBlur = shadowBlur); + shadowOffsets.length && (ctxt.shadowOffsetX = shadowOffsets[0], + ctxt.shadowOffsetY = shadowOffsets[1]); + for(i = 0; i < strings.length; ++i) { + xc = 0; + if(widths) { + if('right' == align) { + xc = maxWidth - widths[i]; + } else if('centre' == align) { + xc = (maxWidth - widths[i]) / 2; + } + } + ctxt.fillText(strings[i], xo + xc, yo); + yo += parseInt(font); + } +} +function RRect(c, x, y, w, h, r, s) { + if(r) { + c.beginPath(); + c.moveTo(x, y + h - r); + c.arcTo(x, y, x + r, y, r); + c.arcTo(x + w, y, x + w, y + r, r); + c.arcTo(x + w, y + h, x + w - r, y + h, r); + c.arcTo(x, y + h, x, y + h - r, r); + c.closePath(); + c[s ? 'stroke' : 'fill'](); + } else { + c[s ? 'strokeRect' : 'fillRect'](x, y, w, h); + } +} +function TextCanvas(strings, font, w, h, maxWidth, stringWidths, align, valign, + scale) { + this.strings = strings; + this.font = font; + this.width = w; + this.height = h; + this.maxWidth = maxWidth; + this.stringWidths = stringWidths; + this.align = align; + this.valign = valign; + this.scale = scale; +} +TCVproto = TextCanvas.prototype; +TCVproto.SetImage = function(image, w, h, position, padding, align, valign, + scale) { + this.image = image; + this.iwidth = w * this.scale; + this.iheight = h * this.scale; + this.ipos = position; + this.ipad = padding * this.scale; + this.iscale = scale; + this.ialign = align; + this.ivalign = valign; +}; +TCVproto.Align = function(size, space, a) { + var pos = 0; + if(a == 'right' || a == 'bottom') + pos = space - size; + else if(a != 'left' && a != 'top') + pos = (space - size) / 2; + return pos; +}; +TCVproto.Create = function(colour, bgColour, bgOutline, bgOutlineThickness, + shadowColour, shadowBlur, shadowOffsets, padding, radius) { + var cv, cw, ch, c, x1, x2, y1, y2, offx, offy, ix, iy, iw, ih, rr, + sox = abs(shadowOffsets[0]), soy = abs(shadowOffsets[1]), shadowcv, shadowc; + padding = max(padding, sox + shadowBlur, soy + shadowBlur); + x1 = 2 * (padding + bgOutlineThickness); + y1 = 2 * (padding + bgOutlineThickness); + cw = this.width + x1; + ch = this.height + y1; + offx = offy = padding + bgOutlineThickness; + + if(this.image) { + ix = iy = padding + bgOutlineThickness; + iw = this.iwidth; + ih = this.iheight; + if(this.ipos == 'top' || this.ipos == 'bottom') { + if(iw < this.width) + ix += this.Align(iw, this.width, this.ialign); + else + offx += this.Align(this.width, iw, this.align); + if(this.ipos == 'top') + offy += ih + this.ipad; + else + iy += this.height + this.ipad; + cw = max(cw, iw + x1); + ch += ih + this.ipad; + } else { + if(ih < this.height) + iy += this.Align(ih, this.height, this.ivalign); + else + offy += this.Align(this.height, ih, this.valign); + if(this.ipos == 'right') + ix += this.width + this.ipad; + else + offx += iw + this.ipad; + cw += iw + this.ipad; + ch = max(ch, ih + y1); + } + } + + cv = NewCanvas(cw, ch); + if(!cv) + return null; + x1 = y1 = bgOutlineThickness / 2; + x2 = cw - bgOutlineThickness; + y2 = ch - bgOutlineThickness; + rr = min(radius, x2 / 2, y2 / 2); + c = cv.getContext('2d'); + if(bgColour) { + c.fillStyle = bgColour; + RRect(c, x1, y1, x2, y2, rr); + } + if(bgOutlineThickness) { + c.strokeStyle = bgOutline; + c.lineWidth = bgOutlineThickness; + RRect(c, x1, y1, x2, y2, rr, true); + } + if(shadowBlur || sox || soy) { + // use a transparent canvas to draw on + shadowcv = NewCanvas(cw, ch); + if(shadowcv) { + shadowc = c; + c = shadowcv.getContext('2d'); + } + } + + // don't use TextSet shadow support because it adds space for shadow + TextSet(c, this.font, colour, this.strings, offx, offy, 0, 0, [], + this.maxWidth, this.stringWidths, this.align); + + if(this.image) + c.drawImage(this.image, ix, iy, iw, ih); + + if(shadowc) { + // draw the text and image with the added shadow + c = shadowc; + shadowColour && (c.shadowColor = shadowColour); + shadowBlur && (c.shadowBlur = shadowBlur); + c.shadowOffsetX = shadowOffsets[0]; + c.shadowOffsetY = shadowOffsets[1]; + c.drawImage(shadowcv, 0, 0); + } + return cv; +}; +function ExpandImage(i, w, h) { + var cv = NewCanvas(w, h), c; + if(!cv) + return null; + c = cv.getContext('2d'); + c.drawImage(i, (w - i.width) / 2, (h - i.height) / 2); + return cv; +} +function ScaleImage(i, w, h) { + var cv = NewCanvas(w, h), c; + if(!cv) + return null; + c = cv.getContext('2d'); + c.drawImage(i, 0, 0, w, h); + return cv; +} +function AddBackgroundToImage(i, w, h, scale, colour, othickness, ocolour, + padding, radius, ofill) { + var cw = w + ((2 * padding) + othickness) * scale, + ch = h + ((2 * padding) + othickness) * scale, + cv = NewCanvas(cw, ch), c, x1, y1, x2, y2, ocanvas, cc, rr; + if(!cv) + return null; + othickness *= scale; + radius *= scale; + x1 = y1 = othickness / 2; + x2 = cw - othickness; + y2 = ch - othickness; + padding = (padding * scale) + x1; // add space for outline + c = cv.getContext('2d'); + rr = min(radius, x2 / 2, y2 / 2); + if(colour) { + c.fillStyle = colour; + RRect(c, x1, y1, x2, y2, rr); + } + if(othickness) { + c.strokeStyle = ocolour; + c.lineWidth = othickness; + RRect(c, x1, y1, x2, y2, rr, true); + } + + if(ofill) { + // use compositing to colour in the image and border + ocanvas = NewCanvas(cw, ch); + cc = ocanvas.getContext('2d'); + cc.drawImage(i, padding, padding, w, h); + cc.globalCompositeOperation = 'source-in'; + cc.fillStyle = ocolour; + cc.fillRect(0, 0, cw, ch); + cc.globalCompositeOperation = 'destination-over'; + cc.drawImage(cv, 0, 0); + cc.globalCompositeOperation = 'source-over'; + c.drawImage(ocanvas, 0, 0); + } else { + c.drawImage(i, padding, padding, i.width, i.height); + } + return {image: cv, width: cw / scale, height: ch / scale}; +} +/** + * Rounds off the corners of an image + */ +function RoundImage(i, r, iw, ih, s) { + var cv, c, r1 = parseFloat(r), l = max(iw, ih); + cv = NewCanvas(iw, ih); + if(!cv) + return null; + if(r.indexOf('%') > 0) + r1 = l * r1 / 100; + else + r1 = r1 * s; + c = cv.getContext('2d'); + c.globalCompositeOperation = 'source-over'; + c.fillStyle = '#fff'; + if(r1 >= l/2) { + r1 = min(iw,ih) / 2; + c.beginPath(); + c.moveTo(iw/2,ih/2); + c.arc(iw/2,ih/2,r1,0,2*Math.PI,false); + c.fill(); + c.closePath(); + } else { + r1 = min(iw/2,ih/2,r1); + RRect(c, 0, 0, iw, ih, r1, true); + c.fill(); + } + c.globalCompositeOperation = 'source-in'; + c.drawImage(i, 0, 0, iw, ih); + return cv; +} +/** + * Creates a new canvas containing the image and its shadow + * Returns an object containing the image and its dimensions at z=0 + */ +function AddShadowToImage(i, w, h, scale, sc, sb, so) { + var sw = abs(so[0]), sh = abs(so[1]), + cw = w + (sw > sb ? sw + sb : sb * 2) * scale, + ch = h + (sh > sb ? sh + sb : sb * 2) * scale, + xo = scale * ((sb || 0) + (so[0] < 0 ? sw : 0)), + yo = scale * ((sb || 0) + (so[1] < 0 ? sh : 0)), cv, c; + cv = NewCanvas(cw, ch); + if(!cv) + return null; + c = cv.getContext('2d'); + sc && (c.shadowColor = sc); + sb && (c.shadowBlur = sb * scale); + so && (c.shadowOffsetX = so[0] * scale, c.shadowOffsetY = so[1] * scale); + c.drawImage(i, xo, yo, w, h); + return {image: cv, width: cw / scale, height: ch / scale}; +} +function FindTextBoundingBox(s,f,ht) { + var w = parseInt(s.toString().length * ht), h = parseInt(ht * 2 * s.length), + cv = NewCanvas(w,h), c, idata, w1, h1, x, y, i, ex; + if(!cv) + return null; + c = cv.getContext('2d'); + c.fillStyle = '#000'; + c.fillRect(0,0,w,h); + TextSet(c,ht + 'px ' + f,'#fff',s,0,0,0,0,[],'centre') + + idata = c.getImageData(0,0,w,h); + w1 = idata.width; h1 = idata.height; + ex = { + min: { x: w1, y: h1 }, + max: { x: -1, y: -1 } + }; + for(y = 0; y < h1; ++y) { + for(x = 0; x < w1; ++x) { + i = (y * w1 + x) * 4; + if(idata.data[i+1] > 0) { + if(x < ex.min.x) ex.min.x = x; + if(x > ex.max.x) ex.max.x = x; + if(y < ex.min.y) ex.min.y = y; + if(y > ex.max.y) ex.max.y = y; + } + } + } + // device pixels might not be css pixels + if(w1 != w) { + ex.min.x *= (w / w1); + ex.max.x *= (w / w1); + } + if(h1 != h) { + ex.min.y *= (w / h1); + ex.max.y *= (w / h1); + } + + cv = null; + return ex; +} +function FixFont(f) { + return "'" + f.replace(/(\'|\")/g,'').replace(/\s*,\s*/g, "', '") + "'"; +} +function AddHandler(h,f,e) { + e = e || doc; + if(e.addEventListener) + e.addEventListener(h,f,false); + else + e.attachEvent('on' + h, f); +} +function RemoveHandler(h,f,e) { + e = e || doc; + if(e.removeEventListener) + e.removeEventListener(h, f); + else + e.detachEvent('on' + h, f); +} +function AddImage(i, o, t, tc) { + var s = tc.imageScale, mscale, ic, bc, oc, iw, ih; + // image not loaded, wait for image onload + if(!o.complete) + return AddHandler('load',function() { AddImage(i,o,t,tc); }, o); + if(!i.complete) + return AddHandler('load',function() { AddImage(i,o,t,tc); }, i); + + // Yes, this does look like nonsense, but it makes sure that both the + // width and height are actually set and not just calculated. This is + // required to keep proportional sizes when the images are hidden, so + // the images can be used again for another cloud. + o.width = o.width; + o.height = o.height; + + if(s) { + i.width = o.width * s; + i.height = o.height * s; + } + // the standard width of the image, with imageScale applied + t.iw = i.width; + t.ih = i.height; + if(tc.txtOpt) { + ic = i; + mscale = tc.zoomMax * tc.txtScale; + iw = t.iw * mscale; + ih = t.ih * mscale; + if(iw < o.naturalWidth || ih < o.naturalHeight) { + ic = ScaleImage(i, iw, ih); + if(ic) + t.fimage = ic; + } else { + iw = t.iw; + ih = t.ih; + mscale = 1; + } + if(parseFloat(tc.imageRadius)) + t.image = t.fimage = i = RoundImage(t.image, tc.imageRadius, iw, ih, mscale); + if(!t.HasText()) { + if(tc.shadow) { + ic = AddShadowToImage(t.image, iw, ih, mscale, tc.shadow, tc.shadowBlur, + tc.shadowOffset); + if(ic) { + t.fimage = ic.image; + t.w = ic.width; + t.h = ic.height; + } + } + if(tc.bgColour || tc.bgOutlineThickness) { + bc = tc.bgColour == 'tag' ? GetProperty(t.a, 'background-color') : + tc.bgColour; + oc = tc.bgOutline == 'tag' ? GetProperty(t.a, 'color') : + (tc.bgOutline || tc.textColour); + iw = t.fimage.width; + ih = t.fimage.height; + if(tc.outlineMethod == 'colour') { + // create the outline version first, using the current image state + ic = AddBackgroundToImage(t.fimage, iw, ih, mscale, bc, + tc.bgOutlineThickness, t.outline.colour, tc.padding, tc.bgRadius, 1); + if(ic) + t.oimage = ic.image; + } + ic = AddBackgroundToImage(t.fimage, iw, ih, mscale, bc, + tc.bgOutlineThickness, oc, tc.padding, tc.bgRadius); + if(ic) { + t.fimage = ic.image; + t.w = ic.width; + t.h = ic.height; + } + } + if(tc.outlineMethod == 'size') { + if(tc.outlineIncrease > 0) { + t.iw += 2 * tc.outlineIncrease; + t.ih += 2 * tc.outlineIncrease; + iw = mscale * t.iw; + ih = mscale * t.ih; + ic = ScaleImage(t.fimage, iw, ih); + t.oimage = ic; + t.fimage = ExpandImage(t.fimage, t.oimage.width, t.oimage.height); + } else { + iw = mscale * (t.iw + (2 * tc.outlineIncrease)); + ih = mscale * (t.ih + (2 * tc.outlineIncrease)); + ic = ScaleImage(t.fimage, iw, ih); + t.oimage = ExpandImage(ic, t.fimage.width, t.fimage.height); + } + } + } + } + t.Init(); +} +function GetProperty(e,p) { + var dv = doc.defaultView, pc = p.replace(/\-([a-z])/g,function(a){return a.charAt(1).toUpperCase()}); + return (dv && dv.getComputedStyle && dv.getComputedStyle(e,null).getPropertyValue(p)) || + (e.currentStyle && e.currentStyle[pc]); +} +function FindWeight(a, wFrom, tHeight) { + var w = 1, p; + if(wFrom) { + w = 1 * (a.getAttribute(wFrom) || tHeight); + } else if(p = GetProperty(a,'font-size')) { + w = (p.indexOf('px') > -1 && p.replace('px','') * 1) || + (p.indexOf('pt') > -1 && p.replace('pt','') * 1.25) || + p * 3.3; + } + return w; +} +function EventToCanvasId(e) { + return e.target && Defined(e.target.id) ? e.target.id : + e.srcElement.parentNode.id; +} +function EventXY(e, c) { + var xy, p, xmul = parseInt(GetProperty(c, 'width')) / c.width, + ymul = parseInt(GetProperty(c, 'height')) / c.height; + if(Defined(e.offsetX)) { + xy = {x: e.offsetX, y: e.offsetY}; + } else { + p = AbsPos(c.id); + if(Defined(e.changedTouches)) + e = e.changedTouches[0]; + if(e.pageX) + xy = {x: e.pageX - p.x, y: e.pageY - p.y}; + } + if(xy && xmul && ymul) { + xy.x /= xmul; + xy.y /= ymul; + } + return xy; +} +function MouseOut(e) { + var cv = e.target || e.fromElement.parentNode, tc = TagCanvas.tc[cv.id]; + if(tc) { + tc.mx = tc.my = -1; + tc.UnFreeze(); + tc.EndDrag(); + } +} +function MouseMove(e) { + var i, t = TagCanvas, tc, p, tg = EventToCanvasId(e); + for(i in t.tc) { + tc = t.tc[i]; + if(tc.tttimer) { + clearTimeout(tc.tttimer); + tc.tttimer = null; + } + } + if(tg && t.tc[tg]) { + tc = t.tc[tg]; + if(p = EventXY(e, tc.canvas)) { + tc.mx = p.x; + tc.my = p.y; + tc.Drag(e, p); + } + tc.drawn = 0; + } +} +function MouseDown(e) { + var t = TagCanvas, cb = doc.addEventListener ? 0 : 1, + tg = EventToCanvasId(e); + if(tg && e.button == cb && t.tc[tg]) { + t.tc[tg].BeginDrag(e); + } +} +function MouseUp(e) { + var t = TagCanvas, cb = doc.addEventListener ? 0 : 1, + tg = EventToCanvasId(e), tc; + if(tg && e.button == cb && t.tc[tg]) { + tc = t.tc[tg]; + MouseMove(e); + if(!tc.EndDrag() && !tc.touchState) + tc.Clicked(e); + } +} +function TouchDown(e) { + var tg = EventToCanvasId(e), tc = (tg && TagCanvas.tc[tg]), p; + if(tc && e.changedTouches) { + if(e.touches.length == 1 && tc.touchState == 0) { + tc.touchState = 1; + tc.BeginDrag(e); + if(p = EventXY(e, tc.canvas)) { + tc.mx = p.x; + tc.my = p.y; + tc.drawn = 0; + } + } else if(e.targetTouches.length == 2 && tc.pinchZoom) { + tc.touchState = 3; + tc.EndDrag(); + tc.BeginPinch(e); + } else { + tc.EndDrag(); + tc.EndPinch(); + tc.touchState = 0; + } + } +} +function TouchUp(e) { + var tg = EventToCanvasId(e), tc = (tg && TagCanvas.tc[tg]); + if(tc && e.changedTouches) { + switch(tc.touchState) { + case 1: + tc.Draw(); + tc.Clicked(); + break; + case 2: + tc.EndDrag(); + break; + case 3: + tc.EndPinch(); + } + tc.touchState = 0; + } +} +function TouchMove(e) { + var i, t = TagCanvas, tc, p, tg = EventToCanvasId(e); + for(i in t.tc) { + tc = t.tc[i]; + if(tc.tttimer) { + clearTimeout(tc.tttimer); + tc.tttimer = null; + } + } + tc = (tg && t.tc[tg]); + if(tc && e.changedTouches && tc.touchState) { + switch(tc.touchState) { + case 1: + case 2: + if(p = EventXY(e, tc.canvas)) { + tc.mx = p.x; + tc.my = p.y; + if(tc.Drag(e, p)) + tc.touchState = 2; + } + break; + case 3: + tc.Pinch(e); + } + tc.drawn = 0; + } +} +function MouseWheel(e) { + var t = TagCanvas, tg = EventToCanvasId(e); + if(tg && t.tc[tg]) { + e.cancelBubble = true; + e.returnValue = false; + e.preventDefault && e.preventDefault(); + t.tc[tg].Wheel((e.wheelDelta || e.detail) > 0); + } +} +function Scroll(e) { + var i, t = TagCanvas; + clearTimeout(t.scrollTimer); + for(i in t.tc) { + t.tc[i].Pause(); + } + t.scrollTimer = setTimeout(function() { + var i, t = TagCanvas; + for(i in t.tc) { + t.tc[i].Resume(); + } + }, t.scrollPause); +} +function DrawCanvas() { + DrawCanvasRAF(TimeNow()); +} +function DrawCanvasRAF(t) { + var tc = TagCanvas.tc, i; + TagCanvas.NextFrame(TagCanvas.interval); + t = t || TimeNow(); + for(i in tc) + tc[i].Draw(t); +} +function AbsPos(id) { + var e = doc.getElementById(id), r = e.getBoundingClientRect(), + dd = doc.documentElement, b = doc.body, w = window, + xs = w.pageXOffset || dd.scrollLeft, + ys = w.pageYOffset || dd.scrollTop, + xo = dd.clientLeft || b.clientLeft, + yo = dd.clientTop || b.clientTop; + return { x: r.left + xs - xo, y: r.top + ys - yo }; +} +function Project(tc,p1,sx,sy) { + var m = tc.radius * tc.z1 / (tc.z1 + tc.z2 + p1.z); + return { + x: p1.x * m * sx, + y: p1.y * m * sy, + z: p1.z, + w: (tc.z1 - p1.z) / tc.z2 + }; +} +/** + * @constructor + * for recursively splitting tag contents on
tags + */ +function TextSplitter(e) { + this.e = e; + this.br = 0; + this.line = []; + this.text = []; + this.original = e.innerText || e.textContent; +} +TSproto = TextSplitter.prototype; +TSproto.Empty = function() { + for(var i = 0; i < this.text.length; ++i) + if(this.text[i].length) + return false; + return true; +}; +TSproto.Lines = function(e) { + var r = e ? 1 : 0, cn, cl, i; + e = e || this.e; + cn = e.childNodes; + cl = cn.length; + + for(i = 0; i < cl; ++i) { + if(cn[i].nodeName == 'BR') { + this.text.push(this.line.join(' ')); + this.br = 1; + } else if(cn[i].nodeType == 3) { + if(this.br) { + this.line = [cn[i].nodeValue]; + this.br = 0; + } else { + this.line.push(cn[i].nodeValue); + } + } else { + this.Lines(cn[i]); + } + } + r || this.br || this.text.push(this.line.join(' ')); + return this.text; +}; +TSproto.SplitWidth = function(w, c, f, h) { + var i, j, words, text = []; + c.font = h + 'px ' + f; + for(i = 0; i < this.text.length; ++i) { + words = this.text[i].split(/\s+/); + this.line = [words[0]]; + for(j = 1; j < words.length; ++j) { + if(c.measureText(this.line.join(' ') + ' ' + words[j]).width > w) { + text.push(this.line.join(' ')); + this.line = [words[j]]; + } else { + this.line.push(words[j]); + } + } + text.push(this.line.join(' ')); + } + return this.text = text; +}; +/** + * @constructor + */ +function Outline(tc,t) { + this.ts = null; + this.tc = tc; + this.tag = t; + this.x = this.y = this.w = this.h = this.sc = 1; + this.z = 0; + this.pulse = 1; + this.pulsate = tc.pulsateTo < 1; + this.colour = tc.outlineColour; + this.adash = ~~tc.outlineDash; + this.agap = ~~tc.outlineDashSpace || this.adash; + this.aspeed = tc.outlineDashSpeed * 1; + if(this.colour == 'tag') + this.colour = GetProperty(t.a, 'color'); + else if(this.colour == 'tagbg') + this.colour = GetProperty(t.a, 'background-color'); + this.Draw = this.pulsate ? this.DrawPulsate : this.DrawSimple; + this.radius = tc.outlineRadius | 0; + this.SetMethod(tc.outlineMethod); +} +Oproto = Outline.prototype; +Oproto.SetMethod = function(om) { + var methods = { + block: ['PreDraw','DrawBlock'], + colour: ['PreDraw','DrawColour'], + outline: ['PostDraw','DrawOutline'], + classic: ['LastDraw','DrawOutline'], + size: ['PreDraw','DrawSize'], + none: ['LastDraw'] + }, funcs = methods[om] || methods.outline; + if(om == 'none') { + this.Draw = function() { return 1; } + } else { + this.drawFunc = this[funcs[1]]; + } + this[funcs[0]] = this.Draw; +}; +Oproto.Update = function(x,y,w,h,sc,z,xo,yo) { + var o = this.tc.outlineOffset, o2 = 2 * o; + this.x = sc * x + xo - o; + this.y = sc * y + yo - o; + this.w = sc * w + o2; + this.h = sc * h + o2; + this.sc = sc; // used to determine frontmost + this.z = z; +}; +Oproto.Ants = function(c) { + if(!this.adash) + return; + var l = this.adash, g = this.agap, s = this.aspeed, length = l + g, + l1 = 0, l2 = l, g1 = g, g2 = 0, seq = 0, ants; + if(s) { + seq = abs(s) * (TimeNow() - this.ts) / 50; + if(s < 0) + seq = 8.64e6 - seq; + s = ~~seq % length; + } + if(s) { + if(l >= s) { + l1 = l - s; + l2 = s; + } else { + g1 = length - s; + g2 = g - g1; + } + ants = [l1, g1, l2, g2]; + } else { + ants = [l,g]; + } + c.setLineDash(ants); +} +Oproto.DrawOutline = function(c,x,y,w,h,colour) { + var r = min(this.radius, h/2, w/2); + c.strokeStyle = colour; + this.Ants(c); + RRect(c, x, y, w, h, r, true); +}; +Oproto.DrawSize = function(c,x,y,w,h,colour,tag,x1,y1) { + var tw = tag.w, th = tag.h, m, i, sc; + if(this.pulsate) { + if(tag.image) + sc = (tag.image.height + this.tc.outlineIncrease) / tag.image.height; + else + sc = tag.oscale; + i = tag.fimage || tag.image; + m = 1 + ((sc - 1) * (1-this.pulse)); + tag.h *= m; + tag.w *= m; + } else { + i = tag.oimage; + } + tag.alpha = 1; + tag.Draw(c, x1, y1, i); + tag.h = th; + tag.w = tw; + return 1; +}; +Oproto.DrawColour = function(c,x,y,w,h,colour,tag,x1,y1) { + if(tag.oimage) { + if(this.pulse < 1) { + tag.alpha = 1 - pow(this.pulse, 2); + tag.Draw(c, x1, y1, tag.fimage); + tag.alpha = this.pulse; + } else { + tag.alpha = 1; + } + tag.Draw(c, x1, y1, tag.oimage); + return 1; + } + return this[tag.image ? 'DrawColourImage' : 'DrawColourText'](c,x,y,w,h,colour,tag,x1,y1); +}; +Oproto.DrawColourText = function(c,x,y,w,h,colour,tag,x1,y1) { + var normal = tag.colour; + tag.colour = colour; + tag.alpha = 1; + tag.Draw(c,x1,y1); + tag.colour = normal; + return 1; +}; +Oproto.DrawColourImage = function(c,x,y,w,h,colour,tag,x1,y1) { + var ccanvas = c.canvas, fx = ~~max(x,0), fy = ~~max(y,0), + fw = min(ccanvas.width - fx, w) + .5|0, fh = min(ccanvas.height - fy,h) + .5|0, cc; + if(ocanvas) + ocanvas.width = fw, ocanvas.height = fh; + else + ocanvas = NewCanvas(fw, fh); + if(!ocanvas) + return this.SetMethod('outline'); // if using IE and images, give up! + cc = ocanvas.getContext('2d'); + + cc.drawImage(ccanvas,fx,fy,fw,fh,0,0,fw,fh); + c.clearRect(fx,fy,fw,fh); + if(this.pulsate) { + tag.alpha = 1 - pow(this.pulse, 2); + } else { + tag.alpha = 1; + } + tag.Draw(c,x1,y1); + c.setTransform(1,0,0,1,0,0); + c.save(); + c.beginPath(); + c.rect(fx,fy,fw,fh); + c.clip(); + c.globalCompositeOperation = 'source-in'; + c.fillStyle = colour; + c.fillRect(fx,fy,fw,fh); + c.restore(); + c.globalAlpha = 1; + c.globalCompositeOperation = 'destination-over'; + c.drawImage(ocanvas,0,0,fw,fh,fx,fy,fw,fh); + c.globalCompositeOperation = 'source-over'; + return 1; +}; +Oproto.DrawBlock = function(c,x,y,w,h,colour) { + var r = min(this.radius, h/2, w/2); + c.fillStyle = colour; + RRect(c, x, y, w, h, r); +}; +Oproto.DrawSimple = function(c, tag, x1, y1, ga, useGa) { + var t = this.tc; + c.setTransform(1,0,0,1,0,0); + c.strokeStyle = this.colour; + c.lineWidth = t.outlineThickness; + c.shadowBlur = c.shadowOffsetX = c.shadowOffsetY = 0; + c.globalAlpha = useGa ? ga : 1; + return this.drawFunc(c,this.x,this.y,this.w,this.h,this.colour,tag,x1,y1); +}; +Oproto.DrawPulsate = function(c, tag, x1, y1) { + var diff = TimeNow() - this.ts, t = this.tc, + ga = t.pulsateTo + ((1 - t.pulsateTo) * + (0.5 + (cos(2 * Math.PI * diff / (1000 * t.pulsateTime)) / 2))); + this.pulse = ga = TagCanvas.Smooth(1,ga); + return this.DrawSimple(c, tag, x1, y1, ga, 1); +}; +Oproto.Active = function(c,x,y) { + var a = (x >= this.x && y >= this.y && + x <= this.x + this.w && y <= this.y + this.h); + if(a) { + this.ts = this.ts || TimeNow(); + } else { + this.ts = null; + } + return a; +}; +Oproto.PreDraw = Oproto.PostDraw = Oproto.LastDraw = Nop; +/** + * @constructor + */ +function Tag(tc, text, a, v, w, h, col, bcol, bradius, boutline, bothickness, + font, padding, original) { + this.tc = tc; + this.image = null; + this.text = text; + this.text_original = original; + this.line_widths = []; + this.title = a.title || null; + this.a = a; + this.position = new Vector(v[0], v[1], v[2]); + this.x = this.y = this.z = 0; + this.w = w; + this.h = h; + this.colour = col || tc.textColour; + this.bgColour = bcol || tc.bgColour; + this.bgRadius = bradius | 0; + this.bgOutline = boutline || this.colour; + this.bgOutlineThickness = bothickness | 0; + this.textFont = font || tc.textFont; + this.padding = padding | 0; + this.sc = this.alpha = 1; + this.weighted = !tc.weight; + this.outline = new Outline(tc,this); +} +Tproto = Tag.prototype; +Tproto.Init = function(e) { + var tc = this.tc; + this.textHeight = tc.textHeight; + if(this.HasText()) { + this.Measure(tc.ctxt,tc); + } else { + this.w = this.iw; + this.h = this.ih; + } + + this.SetShadowColour = tc.shadowAlpha ? this.SetShadowColourAlpha : this.SetShadowColourFixed; + this.SetDraw(tc); +}; +Tproto.Draw = Nop; +Tproto.HasText = function() { + return this.text && this.text[0].length > 0; +}; +Tproto.EqualTo = function(e) { + var i = e.getElementsByTagName('img'); + if(this.a.href != e.href) + return 0; + if(i.length) + return this.image.src == i[0].src; + return (e.innerText || e.textContent) == this.text_original; +}; +Tproto.SetImage = function(i) { + this.image = this.fimage = i; +}; +Tproto.SetDraw = function(t) { + this.Draw = this.fimage ? (t.ie > 7 ? this.DrawImageIE : this.DrawImage) : this.DrawText; + t.noSelect && (this.CheckActive = Nop); +}; +Tproto.MeasureText = function(c) { + var i, l = this.text.length, w = 0, wl; + for(i = 0; i < l; ++i) { + this.line_widths[i] = wl = c.measureText(this.text[i]).width; + w = max(w, wl); + } + return w; +}; +Tproto.Measure = function(c,t) { + var extents = FindTextBoundingBox(this.text, this.textFont, this.textHeight), + s, th, f, soff, cw, twidth, theight, img, tcv; + // add the gap at the top to the height to make equal gap at bottom + theight = extents ? extents.max.y + extents.min.y : this.textHeight; + c.font = this.font = this.textHeight + 'px ' + this.textFont; + twidth = this.MeasureText(c); + if(t.txtOpt) { + s = t.txtScale; + th = s * this.textHeight; + f = th + 'px ' + this.textFont; + soff = [s * t.shadowOffset[0], s * t.shadowOffset[1]]; + c.font = f; + cw = this.MeasureText(c); + tcv = new TextCanvas(this.text, f, cw + s, (s * theight) + s, cw, + this.line_widths, t.textAlign, t.textVAlign, s); + + if(this.image) + tcv.SetImage(this.image, this.iw, this.ih, t.imagePosition, t.imagePadding, + t.imageAlign, t.imageVAlign, t.imageScale); + + img = tcv.Create(this.colour, this.bgColour, this.bgOutline, + s * this.bgOutlineThickness, t.shadow, s * t.shadowBlur, soff, + s * this.padding, s * this.bgRadius); + + // add outline image using highlight colour + if(t.outlineMethod == 'colour') { + this.oimage = tcv.Create(this.outline.colour, this.bgColour, this.outline.colour, + s * this.bgOutlineThickness, t.shadow, s * t.shadowBlur, soff, + s * this.padding, s * this.bgRadius); + + } else if(t.outlineMethod == 'size') { + extents = FindTextBoundingBox(this.text, this.textFont, + this.textHeight + t.outlineIncrease); + th = extents.max.y + extents.min.y; + f = (s * (this.textHeight + t.outlineIncrease)) + 'px ' + this.textFont; + c.font = f; + cw = this.MeasureText(c); + + tcv = new TextCanvas(this.text, f, cw + s, (s * th) + s, cw, + this.line_widths, t.textAlign, t.textVAlign, s); + if(this.image) + tcv.SetImage(this.image, this.iw + t.outlineIncrease, + this.ih + t.outlineIncrease, t.imagePosition, t.imagePadding, + t.imageAlign, t.imageVAlign, t.imageScale); + + this.oimage = tcv.Create(this.colour, this.bgColour, this.bgOutline, + s * this.bgOutlineThickness, t.shadow, s * t.shadowBlur, soff, + s * this.padding, s * this.bgRadius); + + this.oscale = this.oimage.width / img.width; + if(t.outlineIncrease > 0) + img = ExpandImage(img, this.oimage.width, this.oimage.height); + else + this.oimage = ExpandImage(this.oimage, img.width, img.height); + } + if(img) { + this.fimage = img; + twidth = this.fimage.width / s; + theight = this.fimage.height / s; + } + this.SetDraw(t); + t.txtOpt = !!this.fimage; + } + this.h = theight; + this.w = twidth; +}; +Tproto.SetFont = function(f, c, bc, boc) { + this.textFont = f; + this.colour = c; + this.bgColour = bc; + this.bgOutline = boc; + this.Measure(this.tc.ctxt, this.tc); +}; +Tproto.SetWeight = function(w) { + var tc = this.tc, modes = tc.weightMode.split(/[, ]/), m, s, wl = w.length; + if(!this.HasText()) + return; + this.weighted = true; + for(s = 0; s < wl; ++s) { + m = modes[s] || 'size'; + if('both' == m) { + this.Weight(w[s], tc.ctxt, tc, 'size', tc.min_weight[s], + tc.max_weight[s], s); + this.Weight(w[s], tc.ctxt, tc, 'colour', tc.min_weight[s], + tc.max_weight[s], s); + } else { + this.Weight(w[s], tc.ctxt, tc, m, tc.min_weight[s], tc.max_weight[s], s); + } + } + this.Measure(tc.ctxt, tc); +}; +Tproto.Weight = function(w, c, t, m, wmin, wmax, wnum) { + w = isNaN(w) ? 1 : w; + var nweight = (w - wmin) / (wmax - wmin); + if('colour' == m) + this.colour = FindGradientColour(t, nweight, wnum); + else if('bgcolour' == m) + this.bgColour = FindGradientColour(t, nweight, wnum); + else if('bgoutline' == m) + this.bgOutline = FindGradientColour(t, nweight, wnum); + else if('outline' == m) + this.outline.colour = FindGradientColour(t, nweight, wnum); + else if('size' == m) { + if(t.weightSizeMin > 0 && t.weightSizeMax > t.weightSizeMin) { + this.textHeight = t.weightSize * + (t.weightSizeMin + (t.weightSizeMax - t.weightSizeMin) * nweight); + } else { + // min textHeight of 1 + this.textHeight = max(1, w * t.weightSize); + } + } +}; +Tproto.SetShadowColourFixed = function(c,s,a) { + c.shadowColor = s; +}; +Tproto.SetShadowColourAlpha = function(c,s,a) { + c.shadowColor = SetAlpha(s, a); +}; +Tproto.DrawText = function(c,xoff,yoff) { + var t = this.tc, x = this.x, y = this.y, s = this.sc, i, xl; + c.globalAlpha = this.alpha; + c.fillStyle = this.colour; + t.shadow && this.SetShadowColour(c,t.shadow,this.alpha); + c.font = this.font; + x += xoff / s; + y += (yoff / s) - (this.h / 2); + for(i = 0; i < this.text.length; ++i) { + xl = x; + if('right' == t.textAlign) { + xl += this.w / 2 - this.line_widths[i]; + } else if('centre' == t.textAlign) { + xl -= this.line_widths[i] / 2; + } else { + xl -= this.w / 2; + } + c.setTransform(s, 0, 0, s, s * xl, s * y); + c.fillText(this.text[i], 0, 0); + y += this.textHeight; + } +}; +Tproto.DrawImage = function(c,xoff,yoff,im) { + var x = this.x, y = this.y, s = this.sc, + i = im || this.fimage, w = this.w, h = this.h, a = this.alpha, + shadow = this.shadow; + c.globalAlpha = a; + shadow && this.SetShadowColour(c,shadow,a); + x += (xoff / s) - (w / 2); + y += (yoff / s) - (h / 2); + c.setTransform(s, 0, 0, s, s * x, s * y); + c.drawImage(i, 0, 0, w, h); +}; +Tproto.DrawImageIE = function(c,xoff,yoff) { + var i = this.fimage, s = this.sc, + w = i.width = this.w*s, h = i.height = this.h * s, + x = (this.x*s) + xoff - (w/2), y = (this.y*s) + yoff - (h/2); + c.setTransform(1,0,0,1,0,0); + c.globalAlpha = this.alpha; + c.drawImage(i, x, y); +}; +Tproto.Calc = function(m,a) { + var pp, t = this.tc, mnb = t.minBrightness, + mxb = t.maxBrightness, r = t.max_radius; + pp = m.xform(this.position); + this.xformed = pp; + pp = Project(t, pp, t.stretchX, t.stretchY); + this.x = pp.x; + this.y = pp.y; + this.z = pp.z; + this.sc = pp.w; + this.alpha = a * Clamp(mnb + (mxb - mnb) * (r - this.z) / (2 * r), 0, 1); + return this.xformed; +}; +Tproto.UpdateActive = function(c, xoff, yoff) { + var o = this.outline, w = this.w, h = this.h, + x = this.x - w/2, y = this.y - h/2; + o.Update(x, y, w, h, this.sc, this.z, xoff, yoff); + return o; +}; +Tproto.CheckActive = function(c,xoff,yoff) { + var t = this.tc, o = this.UpdateActive(c, xoff, yoff); + return o.Active(c, t.mx, t.my) ? o : null; +}; +Tproto.Clicked = function(e) { + var a = this.a, t = a.target, h = a.href, evt; + if(t != '' && t != '_self') { + if(self.frames[t]) { + self.frames[t].document.location = h; + } else{ + try { + if(top.frames[t]) { + top.frames[t].document.location = h; + return; + } + } catch(err) { + // different domain/port/protocol? + } + window.open(h, t); + } + return; + } + if(doc.createEvent) { + evt = doc.createEvent('MouseEvents'); + evt.initMouseEvent('click', 1, 1, window, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null); + if(!a.dispatchEvent(evt)) + return; + } else if(a.fireEvent) { + if(!a.fireEvent('onclick')) + return; + } + doc.location = h; +}; +/** + * @constructor + */ +function TagCanvas(cid,lctr,opt) { + var i, p, c = doc.getElementById(cid), cp = ['id','class','innerHTML'], raf; + + if(!c) throw 0; + if(Defined(window.G_vmlCanvasManager)) { + c = window.G_vmlCanvasManager.initElement(c); + this.ie = parseFloat(navigator.appVersion.split('MSIE')[1]); + } + if(c && (!c.getContext || !c.getContext('2d').fillText)) { + p = doc.createElement('DIV'); + for(i = 0; i < cp.length; ++i) + p[cp[i]] = c[cp[i]]; + c.parentNode.insertBefore(p,c); + c.parentNode.removeChild(c); + throw 0; + } + for(i in TagCanvas.options) + this[i] = opt && Defined(opt[i]) ? opt[i] : + (Defined(TagCanvas[i]) ? TagCanvas[i] : TagCanvas.options[i]); + + this.canvas = c; + this.ctxt = c.getContext('2d'); + this.z1 = 250 / max(this.depth, 0.001); + this.z2 = this.z1 / this.zoom; + this.radius = min(c.height, c.width) * 0.0075; // fits radius of 100 in canvas + this.max_radius = 100; + this.max_weight = []; + this.min_weight = []; + this.textFont = this.textFont && FixFont(this.textFont); + this.textHeight *= 1; + this.imageRadius = this.imageRadius.toString(); + this.pulsateTo = Clamp(this.pulsateTo, 0, 1); + this.minBrightness = Clamp(this.minBrightness, 0, 1); + this.maxBrightness = Clamp(this.maxBrightness, this.minBrightness, 1); + this.ctxt.textBaseline = 'top'; + this.lx = (this.lock + '').indexOf('x') + 1; + this.ly = (this.lock + '').indexOf('y') + 1; + this.frozen = this.dx = this.dy = this.fixedAnim = this.touchState = 0; + this.fixedAlpha = 1; + this.source = lctr || cid; + this.repeatTags = min(64, ~~this.repeatTags); + this.minTags = min(200, ~~this.minTags); + if(~~this.scrollPause > 0) + TagCanvas.scrollPause = ~~this.scrollPause; + else + this.scrollPause = 0; + if(this.minTags > 0 && this.repeatTags < 1 && (i = this.GetTags().length)) + this.repeatTags = ceil(this.minTags / i) - 1; + this.transform = Matrix.Identity(); + this.startTime = this.time = TimeNow(); + this.mx = this.my = -1; + this.centreImage && CentreImage(this); + this.Animate = this.dragControl ? this.AnimateDrag : this.AnimatePosition; + this.animTiming = (typeof TagCanvas[this.animTiming] == 'function' ? + TagCanvas[this.animTiming] : TagCanvas.Smooth); + if(this.shadowBlur || this.shadowOffset[0] || this.shadowOffset[1]) { + // let the browser translate "red" into "#ff0000" + this.ctxt.shadowColor = this.shadow; + this.shadow = this.ctxt.shadowColor; + this.shadowAlpha = ShadowAlphaBroken(); + } else { + delete this.shadow; + } + this.Load(); + if(lctr && this.hideTags) { + (function(t) { + if(TagCanvas.loaded) + t.HideTags(); + else + AddHandler('load', function() { t.HideTags(); }, window); + })(this); + } + + this.yaw = this.initial ? this.initial[0] * this.maxSpeed : 0; + this.pitch = this.initial ? this.initial[1] * this.maxSpeed : 0; + if(this.tooltip) { + this.ctitle = c.title; + c.title = ''; + if(this.tooltip == 'native') { + this.Tooltip = this.TooltipNative; + } else { + this.Tooltip = this.TooltipDiv; + if(!this.ttdiv) { + this.ttdiv = doc.createElement('div'); + this.ttdiv.className = this.tooltipClass; + this.ttdiv.style.position = 'absolute'; + this.ttdiv.style.zIndex = c.style.zIndex + 1; + AddHandler('mouseover',function(e){e.target.style.display='none';},this.ttdiv); + doc.body.appendChild(this.ttdiv); + } + } + } else { + this.Tooltip = this.TooltipNone; + } + if(!this.noMouse && !handlers[cid]) { + handlers[cid] = [ + ['mousemove', MouseMove], + ['mouseout', MouseOut], + ['mouseup', MouseUp], + ['touchstart', TouchDown], + ['touchend', TouchUp], + ['touchcancel', TouchUp], + ['touchmove', TouchMove] + ]; + if(this.dragControl) { + handlers[cid].push(['mousedown', MouseDown]); + handlers[cid].push(['selectstart', Nop]); + } + if(this.wheelZoom) { + handlers[cid].push(['mousewheel', MouseWheel]); + handlers[cid].push(['DOMMouseScroll', MouseWheel]); + } + if(this.scrollPause) { + handlers[cid].push(['scroll', Scroll, window]); + } + for(i = 0; i < handlers[cid].length; ++i) { + p = handlers[cid][i]; + AddHandler(p[0], p[1], p[2] ? p[2] : c); + } + } + if(!TagCanvas.started) { + raf = window.requestAnimationFrame = window.requestAnimationFrame || + window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || + window.msRequestAnimationFrame; + TagCanvas.NextFrame = raf ? TagCanvas.NextFrameRAF : + TagCanvas.NextFrameTimeout; + TagCanvas.interval = this.interval; + TagCanvas.NextFrame(this.interval); + TagCanvas.started = 1; + } +} +TCproto = TagCanvas.prototype; +TCproto.SourceElements = function() { + if(doc.querySelectorAll) + return doc.querySelectorAll('#' + this.source); + return [doc.getElementById(this.source)]; +}; +TCproto.HideTags = function() { + var el = this.SourceElements(), i; + for(i = 0; i < el.length; ++i) + el[i].style.display = 'none'; +}; +TCproto.GetTags = function() { + var el = this.SourceElements(), etl, tl = [], i, j, k; + for(k = 0; k <= this.repeatTags; ++k) { + for(i = 0; i < el.length; ++i) { + etl = el[i].getElementsByTagName('a'); + for(j = 0; j < etl.length; ++j) { + tl.push(etl[j]); + } + } + } + return tl; +}; +TCproto.Message = function(text) { + var tl = [], i, p, tc = text.split(''), a, t, x, z; + for(i = 0; i < tc.length; ++i) { + if(tc[i] != ' ') { + p = i - tc.length / 2; + a = doc.createElement('A'); + a.href = '#'; + a.innerText = tc[i]; + x = 100 * sin(p / 9); + z = -100 * cos(p / 9); + t = new Tag(this, tc[i], a, [x,0,z], 2, 18, '#000', '#fff', 0, 0, 0, + 'monospace', 2, tc[i]); + t.Init(); + tl.push(t); + } + } + return tl; +}; +TCproto.CreateTag = function(e) { + var im, i, t, txt, ts, font, bc, boc, p = [0, 0, 0]; + if('text' != this.imageMode) { + im = e.getElementsByTagName('img'); + if(im.length) { + i = new Image; + i.src = im[0].src; + + if(!this.imageMode) { + t = new Tag(this, "", e, p, 0, 0); + t.SetImage(i); + //t.Init(); + AddImage(i, im[0], t, this); + return t; + } + } + } + if('image' != this.imageMode) { + ts = new TextSplitter(e); + txt = ts.Lines(); + if(!ts.Empty()) { + font = this.textFont || FixFont(GetProperty(e,'font-family')); + if(this.splitWidth) + txt = ts.SplitWidth(this.splitWidth, this.ctxt, font, this.textHeight); + + bc = this.bgColour == 'tag' ? GetProperty(e, 'background-color') : + this.bgColour; + boc = this.bgOutline == 'tag' ? GetProperty(e, 'color') : this.bgOutline; + } else { + ts = null; + } + } + if(ts || i) { + t = new Tag(this, txt, e, p, 2, this.textHeight + 2, + this.textColour || GetProperty(e,'color'), bc, this.bgRadius, + boc, this.bgOutlineThickness, font, this.padding, ts && ts.original); + if(i) { + t.SetImage(i); + AddImage(i, im[0], t, this); + } else { + t.Init(); + } + return t; + } +}; +TCproto.UpdateTag = function(t, a) { + var colour = this.textColour || GetProperty(a, 'color'), + font = this.textFont || FixFont(GetProperty(a, 'font-family')), + bc = this.bgColour == 'tag' ? GetProperty(a, 'background-color') : + this.bgColour, boc = this.bgOutline == 'tag' ? GetProperty(a, 'color') : + this.bgOutline; + t.a = a; + t.title = a.title; + if(t.colour != colour || t.textFont != font || t.bgColour != bc || + t.bgOutline != boc) + t.SetFont(font, colour, bc, boc); +}; +TCproto.Weight = function(tl) { + var ll = tl.length, w, i, s, weights = [], valid, + wfrom = this.weightFrom ? this.weightFrom.split(/[, ]/) : [null], + wl = wfrom.length; + for(i = 0; i < ll; ++i) { + weights[i] = []; + for(s = 0; s < wl; ++s) { + w = FindWeight(tl[i].a, wfrom[s], this.textHeight); + if(!this.max_weight[s] || w > this.max_weight[s]) + this.max_weight[s] = w; + if(!this.min_weight[s] || w < this.min_weight[s]) + this.min_weight[s] = w; + weights[i][s] = w; + } + } + for(s = 0; s < wl; ++s) { + if(this.max_weight[s] > this.min_weight[s]) + valid = 1; + } + if(valid) { + for(i = 0; i < ll; ++i) { + tl[i].SetWeight(weights[i]); + } + } +}; +TCproto.Load = function() { + var tl = this.GetTags(), taglist = [], shape, t, + shapeArgs, rx, ry, rz, vl, i, tagmap = [], pfuncs = { + sphere: PointsOnSphere, + vcylinder: PointsOnCylinderV, + hcylinder: PointsOnCylinderH, + vring: PointsOnRingV, + hring: PointsOnRingH + }; + + if(tl.length) { + tagmap.length = tl.length; + for(i = 0; i < tl.length; ++i) + tagmap[i] = i; + this.shuffleTags && Shuffle(tagmap); + rx = 100 * this.radiusX; + ry = 100 * this.radiusY; + rz = 100 * this.radiusZ; + this.max_radius = max(rx, max(ry, rz)); + + for(i = 0; i < tl.length; ++i) { + t = this.CreateTag(tl[tagmap[i]]); + if(t) + taglist.push(t); + } + this.weight && this.Weight(taglist, true); + + if(this.shapeArgs) { + this.shapeArgs[0] = taglist.length; + } else { + shapeArgs = this.shape.toString().split(/[(),]/); + shape = shapeArgs.shift(); + if(typeof window[shape] === 'function') + this.shape = window[shape]; + else + this.shape = pfuncs[shape] || pfuncs.sphere; + this.shapeArgs = [taglist.length, rx, ry, rz].concat(shapeArgs); + } + vl = this.shape.apply(this, this.shapeArgs); + this.listLength = taglist.length; + for(i = 0; i < taglist.length; ++i) + taglist[i].position = new Vector(vl[i][0], vl[i][1], vl[i][2]); + } + if(this.noTagsMessage && !taglist.length) { + i = (this.imageMode && this.imageMode != 'both' ? this.imageMode + ' ': ''); + taglist = this.Message('No ' + i + 'tags'); + } + this.taglist = taglist; +}; +TCproto.Update = function() { + var tl = this.GetTags(), newlist = [], + taglist = this.taglist, found, + added = [], removed = [], vl, ol, nl, i, j; + + if(!this.shapeArgs) + return this.Load(); + + if(tl.length) { + nl = this.listLength = tl.length; + ol = taglist.length; + + // copy existing list, populate "removed" + for(i = 0; i < ol; ++i) { + newlist.push(taglist[i]); + removed.push(i); + } + + // find added and removed tags + for(i = 0; i < nl; ++i) { + for(j = 0, found = 0; j < ol; ++j) { + if(taglist[j].EqualTo(tl[i])) { + this.UpdateTag(newlist[j], tl[i]); + found = removed[j] = -1; + } + } + if(!found) + added.push(i); + } + + // clean out found tags from removed list + for(i = 0, j = 0; i < ol; ++i) { + if(removed[j] == -1) + removed.splice(j,1); + else + ++j; + } + + // insert new tags in gaps where old tags removed + if(removed.length) { + Shuffle(removed); + while(removed.length && added.length) { + i = removed.shift(); + j = added.shift(); + newlist[i] = this.CreateTag(tl[j]); + } + + // remove any more (in reverse order) + removed.sort(function(a,b) {return a-b}); + while(removed.length) { + newlist.splice(removed.pop(), 1); + } + } + + // add any extra tags + j = newlist.length / (added.length + 1); + i = 0; + while(added.length) { + newlist.splice(ceil(++i * j), 0, this.CreateTag(tl[added.shift()])); + } + + // assign correct positions to tags + this.shapeArgs[0] = nl = newlist.length; + vl = this.shape.apply(this, this.shapeArgs); + for(i = 0; i < nl; ++i) + newlist[i].position = new Vector(vl[i][0], vl[i][1], vl[i][2]); + + // reweight tags + this.weight && this.Weight(newlist); + } + this.taglist = newlist; +}; +TCproto.SetShadow = function(c) { + c.shadowBlur = this.shadowBlur; + c.shadowOffsetX = this.shadowOffset[0]; + c.shadowOffsetY = this.shadowOffset[1]; +}; +TCproto.Draw = function(t) { + if(this.paused) + return; + var cv = this.canvas, cw = cv.width, ch = cv.height, max_sc = 0, + tdelta = (t - this.time) * TagCanvas.interval / 1000, + x = cw / 2 + this.offsetX, y = ch / 2 + this.offsetY, c = this.ctxt, + active, a, i, aindex = -1, tl = this.taglist, l = tl.length, + frontsel = this.frontSelect, centreDrawn = (this.centreFunc == Nop), fixed; + this.time = t; + if(this.frozen && this.drawn) + return this.Animate(cw,ch,tdelta); + fixed = this.AnimateFixed(); + c.setTransform(1,0,0,1,0,0); + for(i = 0; i < l; ++i) + tl[i].Calc(this.transform, this.fixedAlpha); + tl = SortList(tl, function(a,b) {return b.z-a.z}); + + if(fixed && this.fixedAnim.active) { + active = this.fixedAnim.tag.UpdateActive(c, x, y); + } else { + this.active = null; + for(i = 0; i < l; ++i) { + a = this.mx >= 0 && this.my >= 0 && this.taglist[i].CheckActive(c, x, y); + if(a && a.sc > max_sc && (!frontsel || a.z <= 0)) { + active = a; + aindex = i; + active.tag = this.taglist[i]; + max_sc = a.sc; + } + } + this.active = active; + } + + this.txtOpt || (this.shadow && this.SetShadow(c)); + c.clearRect(0,0,cw,ch); + for(i = 0; i < l; ++i) { + if(!centreDrawn && tl[i].z <= 0) { + // run the centreFunc if the next tag is at the front + try { this.centreFunc(c, cw, ch, x, y); } + catch(e) { + alert(e); + // don't run it again + this.centreFunc = Nop; + } + centreDrawn = true; + } + + if(!(active && active.tag == tl[i] && active.PreDraw(c, tl[i], x, y))) + tl[i].Draw(c, x, y); + active && active.tag == tl[i] && active.PostDraw(c); + } + if(this.freezeActive && active) { + this.Freeze(); + } else { + this.UnFreeze(); + this.drawn = (l == this.listLength); + } + if(this.fixedCallback) { + this.fixedCallback(this,this.fixedCallbackTag); + this.fixedCallback = null; + } + fixed || this.Animate(cw, ch, tdelta); + active && active.LastDraw(c); + cv.style.cursor = active ? this.activeCursor : ''; + this.Tooltip(active,this.taglist[aindex]); +}; +TCproto.TooltipNone = function() { }; +TCproto.TooltipNative = function(active,tag) { + if(active) + this.canvas.title = tag && tag.title ? tag.title : ''; + else + this.canvas.title = this.ctitle; +}; +TCproto.SetTTDiv = function(title, tag) { + var tc = this, s = tc.ttdiv.style; + if(title != tc.ttdiv.innerHTML) + s.display = 'none'; + tc.ttdiv.innerHTML = title; + tag && (tag.title = tc.ttdiv.innerHTML); + if(s.display == 'none' && ! tc.tttimer) { + tc.tttimer = setTimeout(function() { + var p = AbsPos(tc.canvas.id); + s.display = 'block'; + s.left = p.x + tc.mx + 'px'; + s.top = p.y + tc.my + 24 + 'px'; + tc.tttimer = null; + }, tc.tooltipDelay); + } +}; +TCproto.TooltipDiv = function(active,tag) { + if(active && tag && tag.title) { + this.SetTTDiv(tag.title, tag); + } else if(!active && this.mx != -1 && this.my != -1 && this.ctitle.length) { + this.SetTTDiv(this.ctitle); + } else { + this.ttdiv.style.display = 'none'; + } +}; +TCproto.Transform = function(tc, p, y) { + if(p || y) { + var sp = sin(p), cp = cos(p), sy = sin(y), cy = cos(y), + ym = new Matrix([cy,0,sy, 0,1,0, -sy,0,cy]), + pm = new Matrix([1,0,0, 0,cp,-sp, 0,sp,cp]); + tc.transform = tc.transform.mul(ym.mul(pm)); + } +}; +TCproto.AnimateFixed = function() { + var fa, t1, angle, m, d; + if(this.fadeIn) { + t1 = TimeNow() - this.startTime; + if(t1 >= this.fadeIn) { + this.fadeIn = 0; + this.fixedAlpha = 1; + } else { + this.fixedAlpha = t1 / this.fadeIn; + } + } + if(this.fixedAnim) { + if(!this.fixedAnim.transform) + this.fixedAnim.transform = this.transform; + fa = this.fixedAnim, t1 = TimeNow() - fa.t0, angle = fa.angle, + m, d = this.animTiming(fa.t, t1); + this.transform = fa.transform; + if(t1 >= fa.t) { + this.fixedCallbackTag = fa.tag; + this.fixedCallback = fa.cb; + this.fixedAnim = this.yaw = this.pitch = 0; + } else { + angle *= d; + } + m = Matrix.Rotation(angle, fa.axis); + this.transform = this.transform.mul(m); + return (this.fixedAnim != 0); + } + return false; +}; +TCproto.AnimatePosition = function(w, h, t) { + var tc = this, x = tc.mx, y = tc.my, s, r; + if(!tc.frozen && x >= 0 && y >= 0 && x < w && y < h) { + s = tc.maxSpeed, r = tc.reverse ? -1 : 1; + tc.lx || (tc.yaw = ((x * 2 * s / w) - s) * r * t); + tc.ly || (tc.pitch = ((y * 2 * s / h) - s) * -r * t); + tc.initial = null; + } else if(!tc.initial) { + if(tc.frozen && !tc.freezeDecel) + tc.yaw = tc.pitch = 0; + else + tc.Decel(tc); + } + this.Transform(tc, tc.pitch, tc.yaw); +}; +TCproto.AnimateDrag = function(w, h, t) { + var tc = this, rs = 100 * t * tc.maxSpeed / tc.max_radius / tc.zoom; + if(tc.dx || tc.dy) { + tc.lx || (tc.yaw = tc.dx * rs / tc.stretchX); + tc.ly || (tc.pitch = tc.dy * -rs / tc.stretchY); + tc.dx = tc.dy = 0; + tc.initial = null; + } else if(!tc.initial) { + tc.Decel(tc); + } + this.Transform(tc, tc.pitch, tc.yaw); +}; +TCproto.Freeze = function() { + if(!this.frozen) { + this.preFreeze = [this.yaw, this.pitch]; + this.frozen = 1; + this.drawn = 0; + } +}; +TCproto.UnFreeze = function() { + if(this.frozen) { + this.yaw = this.preFreeze[0]; + this.pitch = this.preFreeze[1]; + this.frozen = 0; + } +}; +TCproto.Decel = function(tc) { + var s = tc.minSpeed, ay = abs(tc.yaw), ap = abs(tc.pitch); + if(!tc.lx && ay > s) + tc.yaw = ay > tc.z0 ? tc.yaw * tc.decel : 0; + if(!tc.ly && ap > s) + tc.pitch = ap > tc.z0 ? tc.pitch * tc.decel : 0; +}; +TCproto.Zoom = function(r) { + this.z2 = this.z1 * (1/r); + this.drawn = 0; +}; +TCproto.Clicked = function(e) { + var a = this.active; + try { + if(a && a.tag) + if(this.clickToFront === false || this.clickToFront === null) + a.tag.Clicked(e); + else + this.TagToFront(a.tag, this.clickToFront, function() { + a.tag.Clicked(e); + }, true); + } catch(ex) { + } +}; +TCproto.Wheel = function(i) { + var z = this.zoom + this.zoomStep * (i ? 1 : -1); + this.zoom = min(this.zoomMax,max(this.zoomMin,z)); + this.Zoom(this.zoom); +}; +TCproto.BeginDrag = function(e) { + this.down = EventXY(e, this.canvas); + e.cancelBubble = true; + e.returnValue = false; + e.preventDefault && e.preventDefault(); +}; +TCproto.Drag = function(e, p) { + if(this.dragControl && this.down) { + var t2 = this.dragThreshold * this.dragThreshold, + dx = p.x - this.down.x, dy = p.y - this.down.y; + if(this.dragging || dx * dx + dy * dy > t2) { + this.dx = dx; + this.dy = dy; + this.dragging = 1; + this.down = p; + } + } + return this.dragging; +}; +TCproto.EndDrag = function() { + var res = this.dragging; + this.dragging = this.down = null; + return res; +}; +function PinchDistance(e) { + var t1 = e.targetTouches[0], t2 = e.targetTouches[1]; + return sqrt(pow(t2.pageX - t1.pageX, 2) + pow(t2.pageY - t1.pageY, 2)); +} +TCproto.BeginPinch = function(e) { + this.pinched = [PinchDistance(e), this.zoom]; + e.preventDefault && e.preventDefault(); +}; +TCproto.Pinch = function(e) { + var z, d, p = this.pinched; + if(!p) + return; + d = PinchDistance(e); + z = p[1] * d / p[0]; + this.zoom = min(this.zoomMax,max(this.zoomMin,z)); + this.Zoom(this.zoom); +}; +TCproto.EndPinch = function(e) { + this.pinched = null; +}; +TCproto.Pause = function() { this.paused = true; }; +TCproto.Resume = function() { this.paused = false; }; +TCproto.SetSpeed = function(i) { + this.initial = i; + this.yaw = i[0] * this.maxSpeed; + this.pitch = i[1] * this.maxSpeed; +}; +TCproto.FindTag = function(t) { + if(!Defined(t)) + return null; + Defined(t.index) && (t = t.index); + if(!IsObject(t)) + return this.taglist[t]; + var srch, tgt, i; + if(Defined(t.id)) + srch = 'id', tgt = t.id; + else if(Defined(t.text)) + srch = 'innerText', tgt = t.text; + + for(i = 0; i < this.taglist.length; ++i) + if(this.taglist[i].a[srch] == tgt) + return this.taglist[i]; +}; +TCproto.RotateTag = function(tag, lt, lg, time, callback, active) { + var t = tag.Calc(this.transform, 1), v1 = new Vector(t.x, t.y, t.z), + v2 = MakeVector(lg, lt), angle = v1.angle(v2), u = v1.cross(v2).unit(); + if(angle == 0) { + this.fixedCallbackTag = tag; + this.fixedCallback = callback; + } else { + this.fixedAnim = { + angle: -angle, + axis: u, + t: time, + t0: TimeNow(), + cb: callback, + tag: tag, + active: active + }; + } +}; +TCproto.TagToFront = function(tag, time, callback, active) { + this.RotateTag(tag, 0, 0, time, callback, active); +}; +TagCanvas.Start = function(id,l,o) { + TagCanvas.Delete(id); + TagCanvas.tc[id] = new TagCanvas(id,l,o); +}; +function tccall(f,id) { + TagCanvas.tc[id] && TagCanvas.tc[id][f](); +} +TagCanvas.Linear = function(t, t0) { return t0 / t; } +TagCanvas.Smooth = function(t, t0) { return 0.5 - cos(t0 * Math.PI / t) / 2; } +TagCanvas.Pause = function(id) { tccall('Pause',id); }; +TagCanvas.Resume = function(id) { tccall('Resume',id); }; +TagCanvas.Reload = function(id) { tccall('Load',id); }; +TagCanvas.Update = function(id) { tccall('Update',id); }; +TagCanvas.SetSpeed = function(id, speed) { + if(IsObject(speed) && TagCanvas.tc[id] && + !isNaN(speed[0]) && !isNaN(speed[1])) { + TagCanvas.tc[id].SetSpeed(speed); + return true; + } + return false; +}; +TagCanvas.TagToFront = function(id, options) { + if(!IsObject(options)) + return false; + options.lat = options.lng = 0; + return TagCanvas.RotateTag(id, options); +}; +TagCanvas.RotateTag = function(id, options) { + if(IsObject(options) && TagCanvas.tc[id]) { + if(isNaN(options.time)) + options.time = 500; + var tt = TagCanvas.tc[id].FindTag(options); + if(tt) { + TagCanvas.tc[id].RotateTag(tt, options.lat, options.lng, + options.time, options.callback, options.active); + return true; + } + } + return false; +}; +TagCanvas.Delete = function(id) { + var i, c; + if(handlers[id]) { + c = doc.getElementById(id); + if(c) { + for(i = 0; i < handlers[id].length; ++i) + RemoveHandler(handlers[id][i][0], handlers[id][i][1], c); + } + } + delete handlers[id]; + delete TagCanvas.tc[id]; +}; +TagCanvas.NextFrameRAF = function() { + requestAnimationFrame(DrawCanvasRAF); +}; +TagCanvas.NextFrameTimeout = function(iv) { + setTimeout(DrawCanvas, iv); +}; +TagCanvas.tc = {}; +TagCanvas.options = { +z1: 20000, +z2: 20000, +z0: 0.0002, +freezeActive: true, +freezeDecel: false, +activeCursor: 'pointer', +pulsateTo: 1, +pulsateTime: 3, +reverse: false, +depth: 0.5, +maxSpeed: 0.05, +minSpeed: 0, +decel: 0.95, +interval: 20, +minBrightness: 0.1, +maxBrightness: 1, +outlineColour: '', +outlineThickness: 2, +outlineOffset: 5, +outlineMethod: 'outline', +outlineRadius: 0, +textColour: ['#222', '#000'], +textHeight: 15, +textFont: 'Helvetica, Arial, sans-serif', +shadow: '#111', +shadowBlur: 1, +shadowOffset: [0.1,0.1], +initial: null, +hideTags: false, +zoom: 0, +weight: false, +weightMode: 'size', +weightFrom: null, +weightSize: 1, +weightSizeMin: null, +weightSizeMax: null, +weightGradient: {0:'#f00', 0.33:'#ff0', 0.66:'#0f0', 1:'#00f'}, +txtOpt: true, +txtScale: 2, +frontSelect: false, +wheelZoom: true, +zoomMin: 0.8, +zoomMax: 0.8, +zoomStep: 0.05, +shape: 'sphere', +lock: null, +tooltip: null, +tooltipDelay: 300, +tooltipClass: 'tctooltip', +radiusX: 1, +radiusY: 1, +radiusZ: 1, +stretchX: 1, +stretchY: 1, +offsetX: 0, +offsetY: 0, +shuffleTags: false, +noSelect: false, +noMouse: false, +imageScale: 1, +paused: false, +dragControl: false, +dragThreshold: 4, +centreFunc: Nop, +splitWidth: 0, +animTiming: 'Smooth', +clickToFront: false, +fadeIn: 0, +padding: 0, +bgColour: null, +bgRadius: 0, +bgOutline: null, +bgOutlineThickness: 0, +outlineIncrease: 4, +textAlign: 'centre', +textVAlign: 'middle', +imageMode: null, +imagePosition: null, +imagePadding: 2, +imageAlign: 'centre', +imageVAlign: 'middle', +noTagsMessage: true, +centreImage: null, +pinchZoom: false, +repeatTags: 0, +minTags: 0, +imageRadius: 0, +scrollPause: false, +outlineDash: 0, +outlineDashSpace: 0, +outlineDashSpeed: 1 +}; +for(i in TagCanvas.options) TagCanvas[i] = TagCanvas.options[i]; +window.TagCanvas = TagCanvas; +// set a flag for when the window has loaded +AddHandler('load',function(){TagCanvas.loaded=1},window); +})(); diff --git a/js/tagcloud.js b/js/tagcloud.js new file mode 100644 index 0000000..a36284d --- /dev/null +++ b/js/tagcloud.js @@ -0,0 +1 @@ +function addLoadEvent(func) {var oldonload = window.onload;if (typeof window.onload != 'function') {window.onload = func;} else {window.onload = function() {oldonload();func();}}}addLoadEvent(function() {console.log('tag cloud plugin rock and roll!'); try { TagCanvas.textFont = 'Trebuchet MS, Helvetica'; TagCanvas.textColour = '#333'; TagCanvas.textHeight = 25; TagCanvas.outlineColour = '#E2E1C1'; TagCanvas.outlineMethod = 'block'; TagCanvas.maxSpeed = 0.03; TagCanvas.minBrightness = 0.2; TagCanvas.depth = 0.92; TagCanvas.pulsateTo = 0.6; TagCanvas.initial = [0.1,-0.1]; TagCanvas.decel = 0.98; TagCanvas.reverse = true; TagCanvas.hideTags = false; TagCanvas.shadow = '#ccf'; TagCanvas.shadowBlur = 3; TagCanvas.weight = false; TagCanvas.imageScale = null; TagCanvas.fadeIn = 1000; TagCanvas.clickToFront = 600; TagCanvas.Start('resCanvas'); TagCanvas.tc['resCanvas'].Wheel(false)} catch(e) { console.log(e); document.getElementById('myCanvasContainer').style.display = 'none'; } }); \ No newline at end of file diff --git a/js/third-party/analytics/baidu-analytics.js b/js/third-party/analytics/baidu-analytics.js new file mode 100644 index 0000000..c10e7d0 --- /dev/null +++ b/js/third-party/analytics/baidu-analytics.js @@ -0,0 +1,7 @@ +/* global _hmt */ + +if (!window._hmt) window._hmt = []; + +document.addEventListener('pjax:success', () => { + _hmt.push(['_trackPageview', location.pathname]); +}); diff --git a/js/third-party/analytics/google-analytics.js b/js/third-party/analytics/google-analytics.js new file mode 100644 index 0000000..2cd128f --- /dev/null +++ b/js/third-party/analytics/google-analytics.js @@ -0,0 +1,35 @@ +/* global CONFIG, dataLayer, gtag */ + +if (!CONFIG.google_analytics.only_pageview) { + if (CONFIG.hostname === location.hostname) { + window.dataLayer = window.dataLayer || []; + window.gtag = function() { + dataLayer.push(arguments); + }; + gtag('js', new Date()); + gtag('config', CONFIG.google_analytics.tracking_id); + + document.addEventListener('pjax:success', () => { + gtag('event', 'page_view', { + page_location: location.href, + page_path : location.pathname, + page_title : document.title + }); + }); + } +} else { + const sendPageView = () => { + if (CONFIG.hostname !== location.hostname) return; + const uid = localStorage.getItem('uid') || (Math.random() + '.' + Math.random()); + localStorage.setItem('uid', uid); + navigator.sendBeacon('https://www.google-analytics.com/collect', new URLSearchParams({ + v : 1, + tid: CONFIG.google_analytics.tracking_id, + cid: uid, + t : 'pageview', + dp : encodeURIComponent(location.pathname) + })); + }; + document.addEventListener('pjax:complete', sendPageView); + sendPageView(); +} diff --git a/js/third-party/analytics/growingio.js b/js/third-party/analytics/growingio.js new file mode 100644 index 0000000..0460833 --- /dev/null +++ b/js/third-party/analytics/growingio.js @@ -0,0 +1,10 @@ +/* global CONFIG, gio */ + +if (!window.gio) { + window.gio = function() { + (window.gio.q = window.gio.q || []).push(arguments); + }; +} + +gio('init', `${CONFIG.growingio_analytics}`, {}); +gio('send'); diff --git a/js/third-party/analytics/matomo.js b/js/third-party/analytics/matomo.js new file mode 100644 index 0000000..290a3e0 --- /dev/null +++ b/js/third-party/analytics/matomo.js @@ -0,0 +1,19 @@ +/* global CONFIG */ + +if (CONFIG.matomo.enable) { + window._paq = window._paq || []; + const _paq = window._paq; + + /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + const u = CONFIG.matomo.server_url; + _paq.push(['setTrackerUrl', u + 'matomo.php']); + _paq.push(['setSiteId', CONFIG.matomo.site_id]); + const d = document; + const g = d.createElement('script'); + const s = d.getElementsByTagName('script')[0]; + g.async = true; + g.src = u + 'matomo.js'; + s.parentNode.insertBefore(g, s); +} diff --git a/js/third-party/chat/chatra.js b/js/third-party/chat/chatra.js new file mode 100644 index 0000000..e495b8e --- /dev/null +++ b/js/third-party/chat/chatra.js @@ -0,0 +1,19 @@ +/* global CONFIG, Chatra */ + +(function() { + if (CONFIG.chatra.embed) { + window.ChatraSetup = { + mode : 'frame', + injectTo: CONFIG.chatra.embed + }; + } + + window.ChatraID = CONFIG.chatra.id; + + const chatButton = document.querySelector('.sidebar-button button'); + if (chatButton) { + chatButton.addEventListener('click', () => { + Chatra('openChat', true); + }); + } +})(); diff --git a/js/third-party/chat/gitter.js b/js/third-party/chat/gitter.js new file mode 100644 index 0000000..2b26d05 --- /dev/null +++ b/js/third-party/chat/gitter.js @@ -0,0 +1,5 @@ +/* global CONFIG */ + +((window.gitter = {}).chat = {}).options = { + room: CONFIG.gitter.room +}; diff --git a/js/third-party/chat/tidio.js b/js/third-party/chat/tidio.js new file mode 100644 index 0000000..bffb918 --- /dev/null +++ b/js/third-party/chat/tidio.js @@ -0,0 +1,10 @@ +/* global tidioChatApi */ + +(function() { + const chatButton = document.querySelector('.sidebar-button button'); + if (chatButton) { + chatButton.addEventListener('click', () => { + tidioChatApi.open(); + }); + } +})(); diff --git a/js/third-party/comments/changyan.js b/js/third-party/comments/changyan.js new file mode 100644 index 0000000..18a1be4 --- /dev/null +++ b/js/third-party/comments/changyan.js @@ -0,0 +1,39 @@ +/* global NexT, CONFIG */ + +document.addEventListener('page:loaded', () => { + const { appid, appkey } = CONFIG.changyan; + const mainJs = 'https://cy-cdn.kuaizhan.com/upload/changyan.js'; + const countJs = `https://cy-cdn.kuaizhan.com/upload/plugins/plugins.list.count.js?clientId=${appid}`; + + // Get the number of comments + setTimeout(() => { + return NexT.utils.getScript(countJs, { + attributes: { + async: true, + id : 'cy_cmt_num' + } + }); + }, 0); + + // When scroll to comment section + if (CONFIG.page.comments && !CONFIG.page.isHome) { + NexT.utils.loadComments('#SOHUCS') + .then(() => { + return NexT.utils.getScript(mainJs, { + attributes: { + async: true + } + }); + }) + .then(() => { + window.changyan.api.config({ + appid, + conf: appkey + }); + }) + .catch(error => { + // eslint-disable-next-line no-console + console.error('Failed to load Changyan', error); + }); + } +}); diff --git a/js/third-party/comments/disqus.js b/js/third-party/comments/disqus.js new file mode 100644 index 0000000..4d1ca9e --- /dev/null +++ b/js/third-party/comments/disqus.js @@ -0,0 +1,41 @@ +/* global NexT, CONFIG, DISQUS */ + +document.addEventListener('page:loaded', () => { + + if (CONFIG.disqus.count) { + if (window.DISQUSWIDGETS) { + window.DISQUSWIDGETS.getCount({ reset: true }); + } else { + // Defer loading until the whole page loading is completed + NexT.utils.getScript(`https://${CONFIG.disqus.shortname}.disqus.com/count.js`, { + attributes: { id: 'dsq-count-scr', defer: true } + }); + } + } + + if (CONFIG.page.comments) { + // `disqus_config` should be a global variable + // See https://help.disqus.com/en/articles/1717084-javascript-configuration-variables + window.disqus_config = function() { + this.page.url = CONFIG.page.permalink; + this.page.identifier = CONFIG.page.path; + this.page.title = CONFIG.page.title; + if (CONFIG.disqus.i18n.disqus !== 'disqus') { + this.language = CONFIG.disqus.i18n.disqus; + } + }; + NexT.utils.loadComments('#disqus_thread').then(() => { + if (window.DISQUS) { + DISQUS.reset({ + reload: true, + config: window.disqus_config + }); + } else { + NexT.utils.getScript(`https://${CONFIG.disqus.shortname}.disqus.com/embed.js`, { + attributes: { dataset: { timestamp: '' + +new Date() } } + }); + } + }); + } + +}); diff --git a/js/third-party/comments/disqusjs.js b/js/third-party/comments/disqusjs.js new file mode 100644 index 0000000..d8401ee --- /dev/null +++ b/js/third-party/comments/disqusjs.js @@ -0,0 +1,23 @@ +/* global NexT, CONFIG, DisqusJS */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('#disqus_thread') + .then(() => NexT.utils.getScript(CONFIG.disqusjs.js, { condition: window.DisqusJS })) + .then(() => { + window.dsqjs = new DisqusJS({ + api : CONFIG.disqusjs.api || 'https://disqus.com/api/', + apikey : CONFIG.disqusjs.apikey, + shortname : CONFIG.disqusjs.shortname, + url : CONFIG.page.permalink, + identifier: CONFIG.page.path, + title : CONFIG.page.title + }); + window.dsqjs.render(document.querySelector('.disqusjs-container')); + }); +}); + +document.addEventListener('pjax:send', () => { + if (window.dsqjs) window.dsqjs.destroy(); +}); diff --git a/js/third-party/comments/gitalk.js b/js/third-party/comments/gitalk.js new file mode 100644 index 0000000..08d07f4 --- /dev/null +++ b/js/third-party/comments/gitalk.js @@ -0,0 +1,24 @@ +/* global NexT, CONFIG, Gitalk */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('.gitalk-container') + .then(() => NexT.utils.getScript(CONFIG.gitalk.js, { + condition: window.Gitalk + })) + .then(() => { + const gitalk = new Gitalk({ + clientID : CONFIG.gitalk.client_id, + clientSecret : CONFIG.gitalk.client_secret, + repo : CONFIG.gitalk.repo, + owner : CONFIG.gitalk.github_id, + admin : [CONFIG.gitalk.admin_user], + id : CONFIG.gitalk.path_md5, + proxy : CONFIG.gitalk.proxy, + language : CONFIG.gitalk.language || window.navigator.language, + distractionFreeMode: CONFIG.gitalk.distraction_free_mode + }); + gitalk.render(document.querySelector('.gitalk-container')); + }); +}); diff --git a/js/third-party/comments/isso.js b/js/third-party/comments/isso.js new file mode 100644 index 0000000..2c70601 --- /dev/null +++ b/js/third-party/comments/isso.js @@ -0,0 +1,15 @@ +/* global NexT, CONFIG */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('#isso-thread') + .then(() => NexT.utils.getScript(`${CONFIG.isso}js/embed.min.js`, { + attributes: { + dataset: { + isso: `${CONFIG.isso}` + } + }, + parentNode: document.querySelector('#isso-thread') + })); +}); diff --git a/js/third-party/comments/livere.js b/js/third-party/comments/livere.js new file mode 100644 index 0000000..c4bcd2e --- /dev/null +++ b/js/third-party/comments/livere.js @@ -0,0 +1,19 @@ +/* global NexT, CONFIG, LivereTower */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('#lv-container').then(() => { + window.livereOptions = { + refer: CONFIG.page.path.replace(/index\.html$/, '') + }; + + if (typeof LivereTower === 'function') return; + + NexT.utils.getScript('https://cdn-city.livere.com/js/embed.dist.js', { + attributes: { + async: true + } + }); + }); +}); diff --git a/js/third-party/comments/utterances.js b/js/third-party/comments/utterances.js new file mode 100644 index 0000000..332ee05 --- /dev/null +++ b/js/third-party/comments/utterances.js @@ -0,0 +1,17 @@ +/* global NexT, CONFIG */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.page.comments) return; + + NexT.utils.loadComments('.utterances-container') + .then(() => NexT.utils.getScript('https://utteranc.es/client.js', { + attributes: { + async : true, + crossOrigin : 'anonymous', + 'repo' : CONFIG.utterances.repo, + 'issue-term': CONFIG.utterances.issue_term, + 'theme' : CONFIG.utterances.theme + }, + parentNode: document.querySelector('.utterances-container') + })); +}); diff --git a/js/third-party/fancybox.js b/js/third-party/fancybox.js new file mode 100644 index 0000000..bb436ab --- /dev/null +++ b/js/third-party/fancybox.js @@ -0,0 +1,38 @@ +document.addEventListener('page:loaded', () => { + + /** + * Wrap images with fancybox. + */ + document.querySelectorAll('.post-body :not(a) > img, .post-body > img').forEach(element => { + const $image = $(element); + const imageLink = $image.attr('data-src') || $image.attr('src'); + const $imageWrapLink = $image.wrap(``).parent('a'); + if ($image.is('.post-gallery img')) { + $imageWrapLink.attr('data-fancybox', 'gallery').attr('rel', 'gallery'); + } else if ($image.is('.group-picture img')) { + $imageWrapLink.attr('data-fancybox', 'group').attr('rel', 'group'); + } else { + $imageWrapLink.attr('data-fancybox', 'default').attr('rel', 'default'); + } + + const imageTitle = $image.attr('title') || $image.attr('alt'); + if (imageTitle) { + // Do not append image-caption if pandoc has already created a figcaption + if (!$imageWrapLink.next('figcaption').length) { + $imageWrapLink.append(`

${imageTitle}

`); + } + // Make sure img title tag will show correctly in fancybox + $imageWrapLink.attr('title', imageTitle).attr('data-caption', imageTitle); + } + }); + + $.fancybox.defaults.hash = false; + $('.fancybox').fancybox({ + loop : true, + helpers: { + overlay: { + locked: false + } + } + }); +}); diff --git a/js/third-party/math/katex.js b/js/third-party/math/katex.js new file mode 100644 index 0000000..ad745b1 --- /dev/null +++ b/js/third-party/math/katex.js @@ -0,0 +1,7 @@ +/* global NexT, CONFIG */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.enableMath) return; + + NexT.utils.getScript(CONFIG.katex.copy_tex_js).catch(() => {}); +}); diff --git a/js/third-party/math/mathjax.js b/js/third-party/math/mathjax.js new file mode 100644 index 0000000..fe4d448 --- /dev/null +++ b/js/third-party/math/mathjax.js @@ -0,0 +1,36 @@ +/* global NexT, CONFIG, MathJax */ + +document.addEventListener('page:loaded', () => { + if (!CONFIG.enableMath) return; + + if (typeof MathJax === 'undefined') { + window.MathJax = { + tex: { + inlineMath: { '[+]': [['$', '$']] }, + tags : CONFIG.mathjax.tags + }, + options: { + renderActions: { + insertedScript: [200, () => { + document.querySelectorAll('mjx-container').forEach(node => { + const target = node.parentNode; + if (target.nodeName.toLowerCase() === 'li') { + target.parentNode.classList.add('has-jax'); + } + }); + }, '', false] + } + } + }; + NexT.utils.getScript(CONFIG.mathjax.js, { + attributes: { + defer: true + } + }); + } else { + MathJax.startup.document.state(0); + MathJax.typesetClear(); + MathJax.texReset(); + MathJax.typesetPromise(); + } +}); diff --git a/js/third-party/pace.js b/js/third-party/pace.js new file mode 100644 index 0000000..c22d59f --- /dev/null +++ b/js/third-party/pace.js @@ -0,0 +1,7 @@ +/* global Pace */ + +Pace.options.restartOnPushState = false; + +document.addEventListener('pjax:send', () => { + Pace.restart(); +}); diff --git a/js/third-party/quicklink.js b/js/third-party/quicklink.js new file mode 100644 index 0000000..2543ad1 --- /dev/null +++ b/js/third-party/quicklink.js @@ -0,0 +1,37 @@ +/* global CONFIG, quicklink */ + +(function() { + if (typeof CONFIG.quicklink.ignores === 'string') { + const ignoresStr = `[${CONFIG.quicklink.ignores}]`; + CONFIG.quicklink.ignores = JSON.parse(ignoresStr); + } + + let resetFn = null; + + const onRefresh = () => { + if (resetFn) resetFn(); + if (!CONFIG.quicklink.enable) return; + + let ignoresArr = CONFIG.quicklink.ignores || []; + if (!Array.isArray(ignoresArr)) { + ignoresArr = [ignoresArr]; + } + + resetFn = quicklink.listen({ + timeout : CONFIG.quicklink.timeout, + priority: CONFIG.quicklink.priority, + ignores : [ + uri => uri.includes('#'), + uri => uri === CONFIG.quicklink.url, + ...ignoresArr + ] + }); + }; + + if (CONFIG.quicklink.delay) { + window.addEventListener('load', onRefresh); + document.addEventListener('pjax:success', onRefresh); + } else { + document.addEventListener('page:loaded', onRefresh); + } +})(); diff --git a/js/third-party/search/algolia-search.js b/js/third-party/search/algolia-search.js new file mode 100644 index 0000000..12a554c --- /dev/null +++ b/js/third-party/search/algolia-search.js @@ -0,0 +1,130 @@ +/* global instantsearch, algoliasearch, CONFIG, pjax */ + +document.addEventListener('DOMContentLoaded', () => { + const { indexName, appID, apiKey, hits } = CONFIG.algolia; + + const search = instantsearch({ + indexName, + searchClient : algoliasearch(appID, apiKey), + searchFunction: helper => { + if (document.querySelector('.search-input').value) { + helper.search(); + } + } + }); + + if (typeof pjax === 'object') { + search.on('render', () => { + pjax.refresh(document.querySelector('.algolia-hits')); + }); + } + + // Registering Widgets + search.addWidgets([ + instantsearch.widgets.configure({ + hitsPerPage: hits.per_page || 10 + }), + + instantsearch.widgets.searchBox({ + container : '.search-input-container', + placeholder : CONFIG.i18n.placeholder, + // Hide default icons of algolia search + showReset : false, + showSubmit : false, + showLoadingIndicator: false, + cssClasses : { + input: 'search-input' + } + }), + + instantsearch.widgets.stats({ + container: '.algolia-stats', + templates: { + text: data => { + const stats = CONFIG.i18n.hits_time + .replace('${hits}', data.nbHits) + .replace('${time}', data.processingTimeMS); + return `${stats} + Algolia`; + } + }, + cssClasses: { + text: 'search-stats' + } + }), + + instantsearch.widgets.hits({ + container : '.algolia-hits', + escapeHTML: false, + templates : { + item: data => { + const { title, excerpt, excerptStrip, contentStripTruncate } = data._highlightResult; + let result = `${title.value}`; + const content = excerpt || excerptStrip || contentStripTruncate; + if (content && content.value) { + const div = document.createElement('div'); + div.innerHTML = content.value; + result += `

${div.textContent.substring(0, 100)}...

`; + } + return result; + }, + empty: data => { + return `
+ ${CONFIG.i18n.empty.replace('${query}', data.query)} +
`; + } + }, + cssClasses: { + list: 'search-result-list' + } + }), + + instantsearch.widgets.pagination({ + container: '.algolia-pagination', + scrollTo : false, + showFirst: false, + showLast : false, + templates: { + first : '', + last : '', + previous: '', + next : '' + }, + cssClasses: { + list : ['pagination', 'algolia-pagination'], + item : 'pagination-item', + link : 'page-number', + selectedItem: 'current', + disabledItem: 'disabled-item' + } + }) + ]); + + search.start(); + + // Handle and trigger popup window + document.querySelectorAll('.popup-trigger').forEach(element => { + element.addEventListener('click', () => { + document.body.classList.add('search-active'); + setTimeout(() => document.querySelector('.search-input').focus(), 500); + }); + }); + + // Monitor main search box + const onPopupClose = () => { + document.body.classList.remove('search-active'); + }; + + document.querySelector('.search-pop-overlay').addEventListener('click', event => { + if (event.target === document.querySelector('.search-pop-overlay')) { + onPopupClose(); + } + }); + document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose); + document.addEventListener('pjax:success', onPopupClose); + window.addEventListener('keyup', event => { + if (event.key === 'Escape') { + onPopupClose(); + } + }); +}); diff --git a/js/third-party/search/local-search.js b/js/third-party/search/local-search.js new file mode 100644 index 0000000..92a264d --- /dev/null +++ b/js/third-party/search/local-search.js @@ -0,0 +1,99 @@ +/* global CONFIG, pjax, LocalSearch */ + +document.addEventListener('DOMContentLoaded', () => { + if (!CONFIG.path) { + // Search DB path + console.warn('`hexo-generator-searchdb` plugin is not installed!'); + return; + } + const localSearch = new LocalSearch({ + path : CONFIG.path, + top_n_per_article: CONFIG.localsearch.top_n_per_article, + unescape : CONFIG.localsearch.unescape + }); + + const input = document.querySelector('.search-input'); + + const inputEventFunction = () => { + if (!localSearch.isfetched) return; + const searchText = input.value.trim().toLowerCase(); + const keywords = searchText.split(/[-\s]+/); + const container = document.querySelector('.search-result-container'); + let resultItems = []; + if (searchText.length > 0) { + // Perform local searching + resultItems = localSearch.getResultItems(keywords); + } + if (keywords.length === 1 && keywords[0] === '') { + container.classList.add('no-result'); + container.innerHTML = '
'; + } else if (resultItems.length === 0) { + container.classList.add('no-result'); + container.innerHTML = '
'; + } else { + resultItems.sort((left, right) => { + if (left.includedCount !== right.includedCount) { + return right.includedCount - left.includedCount; + } else if (left.hitCount !== right.hitCount) { + return right.hitCount - left.hitCount; + } + return right.id - left.id; + }); + const stats = CONFIG.i18n.hits.replace('${hits}', resultItems.length); + + container.classList.remove('no-result'); + container.innerHTML = `
${stats}
+
+
    ${resultItems.map(result => result.item).join('')}
`; + if (typeof pjax === 'object') pjax.refresh(container); + } + }; + + localSearch.highlightSearchWords(document.querySelector('.post-body')); + if (CONFIG.localsearch.preload) { + localSearch.fetchData(); + } + + if (CONFIG.localsearch.trigger === 'auto') { + input.addEventListener('input', inputEventFunction); + } else { + document.querySelector('.search-icon').addEventListener('click', inputEventFunction); + input.addEventListener('keypress', event => { + if (event.key === 'Enter') { + inputEventFunction(); + } + }); + } + window.addEventListener('search:loaded', inputEventFunction); + + // Handle and trigger popup window + document.querySelectorAll('.popup-trigger').forEach(element => { + element.addEventListener('click', () => { + document.body.classList.add('search-active'); + // Wait for search-popup animation to complete + setTimeout(() => input.focus(), 500); + if (!localSearch.isfetched) localSearch.fetchData(); + }); + }); + + // Monitor main search box + const onPopupClose = () => { + document.body.classList.remove('search-active'); + }; + + document.querySelector('.search-pop-overlay').addEventListener('click', event => { + if (event.target === document.querySelector('.search-pop-overlay')) { + onPopupClose(); + } + }); + document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose); + document.addEventListener('pjax:success', () => { + localSearch.highlightSearchWords(document.querySelector('.post-body')); + onPopupClose(); + }); + window.addEventListener('keyup', event => { + if (event.key === 'Escape') { + onPopupClose(); + } + }); +}); diff --git a/js/third-party/statistics/firestore.js b/js/third-party/statistics/firestore.js new file mode 100644 index 0000000..3ea7ba6 --- /dev/null +++ b/js/third-party/statistics/firestore.js @@ -0,0 +1,60 @@ +/* global CONFIG, firebase */ + +firebase.initializeApp({ + apiKey : CONFIG.firestore.apiKey, + projectId: CONFIG.firestore.projectId +}); + +(function() { + const getCount = (doc, increaseCount) => { + // IncreaseCount will be false when not in article page + return doc.get().then(d => { + // Has no data, initialize count + let count = d.exists ? d.data().count : 0; + // If first view this article + if (increaseCount) { + // Increase count + count++; + doc.set({ + count + }); + } + return count; + }); + }; + + const db = firebase.firestore(); + const articles = db.collection(CONFIG.firestore.collection); + + document.addEventListener('page:loaded', () => { + + if (CONFIG.page.isPost) { + // Fix issue #118 + // https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent + const title = document.querySelector('.post-title').textContent.trim(); + const doc = articles.doc(title); + let increaseCount = CONFIG.hostname === location.hostname; + if (localStorage.getItem(title)) { + increaseCount = false; + } else { + // Mark as visited + localStorage.setItem(title, true); + } + getCount(doc, increaseCount).then(count => { + document.querySelector('.firestore-visitors-count').innerText = count; + }); + } else if (CONFIG.page.isHome) { + const promises = [...document.querySelectorAll('.post-title')].map(element => { + const title = element.textContent.trim(); + const doc = articles.doc(title); + return getCount(doc); + }); + Promise.all(promises).then(counts => { + const metas = document.querySelectorAll('.firestore-visitors-count'); + counts.forEach((val, idx) => { + metas[idx].innerText = val; + }); + }); + } + }); +})(); diff --git a/js/third-party/statistics/lean-analytics.js b/js/third-party/statistics/lean-analytics.js new file mode 100644 index 0000000..8397112 --- /dev/null +++ b/js/third-party/statistics/lean-analytics.js @@ -0,0 +1,107 @@ +/* global CONFIG */ +/* eslint-disable no-console */ + +(function() { + const leancloudSelector = url => { + url = encodeURI(url); + return document.getElementById(url).querySelector('.leancloud-visitors-count'); + }; + + const addCount = Counter => { + const visitors = document.querySelector('.leancloud_visitors'); + const url = decodeURI(visitors.id); + const title = visitors.dataset.flagTitle; + + Counter('get', `/classes/Counter?where=${encodeURIComponent(JSON.stringify({ url }))}`) + .then(response => response.json()) + .then(({ results }) => { + if (results.length > 0) { + const counter = results[0]; + leancloudSelector(url).innerText = counter.time + 1; + Counter('put', '/classes/Counter/' + counter.objectId, { + time: { + '__op' : 'Increment', + 'amount': 1 + } + }) + .catch(error => { + console.error('Failed to save visitor count', error); + }); + } else if (CONFIG.leancloud_visitors.security) { + leancloudSelector(url).innerText = 'Counter not initialized! More info at console err msg.'; + console.error('ATTENTION! LeanCloud counter has security bug, see how to solve it here: https://github.com/theme-next/hexo-leancloud-counter-security. \n However, you can still use LeanCloud without security, by setting `security` option to `false`.'); + } else { + Counter('post', '/classes/Counter', { title, url, time: 1 }) + .then(response => response.json()) + .then(() => { + leancloudSelector(url).innerText = 1; + }) + .catch(error => { + console.error('Failed to create', error); + }); + } + }) + .catch(error => { + console.error('LeanCloud Counter Error', error); + }); + }; + + const showTime = Counter => { + const visitors = document.querySelectorAll('.leancloud_visitors'); + const entries = [...visitors].map(element => { + return decodeURI(element.id); + }); + + Counter('get', `/classes/Counter?where=${encodeURIComponent(JSON.stringify({ url: { '$in': entries } }))}`) + .then(response => response.json()) + .then(({ results }) => { + for (const url of entries) { + const target = results.find(item => item.url === url); + leancloudSelector(url).innerText = target ? target.time : 0; + } + }) + .catch(error => { + console.error('LeanCloud Counter Error', error); + }); + }; + + const { app_id, app_key, server_url } = CONFIG.leancloud_visitors; + const fetchData = api_server => { + const Counter = (method, url, data) => { + return fetch(`${api_server}/1.1${url}`, { + method, + headers: { + 'X-LC-Id' : app_id, + 'X-LC-Key' : app_key, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + }); + }; + if (CONFIG.page.isPost) { + if (CONFIG.hostname !== location.hostname) return; + addCount(Counter); + } else if (document.querySelectorAll('.post-title-link').length >= 1) { + showTime(Counter); + } + }; + + let api_server; + if (server_url) { + api_server = server_url; + } else if (app_id.slice(-9) === '-MdYXbMMI') { + api_server = `https://${app_id.slice(0, 8).toLowerCase()}.api.lncldglobal.com`; + } + + document.addEventListener('page:loaded', () => { + if (api_server) { + fetchData(api_server); + } else { + fetch(`https://app-router.leancloud.cn/2/route?appId=${app_id}`) + .then(response => response.json()) + .then(({ api_server }) => { + fetchData(`https://${api_server}`); + }); + } + }); +})(); diff --git a/js/third-party/tags/mermaid.js b/js/third-party/tags/mermaid.js new file mode 100644 index 0000000..9623dc5 --- /dev/null +++ b/js/third-party/tags/mermaid.js @@ -0,0 +1,32 @@ +/* global NexT, CONFIG, mermaid */ + +document.addEventListener('page:loaded', () => { + const mermaidElements = document.querySelectorAll('.mermaid'); + if (mermaidElements.length) { + NexT.utils.getScript(CONFIG.mermaid.js, { + condition: window.mermaid + }).then(() => { + mermaidElements.forEach(element => { + const newElement = document.createElement('div'); + newElement.innerHTML = element.innerHTML; + newElement.className = element.className; + const parent = element.parentNode; + // Fix issue #347 + // Support mermaid inside backtick code block + if (parent.matches('pre')) { + parent.parentNode.replaceChild(newElement, parent); + } else { + parent.replaceChild(newElement, element); + } + }); + mermaid.initialize({ + theme : CONFIG.darkmode && window.matchMedia('(prefers-color-scheme: dark)').matches ? CONFIG.mermaid.theme.dark : CONFIG.mermaid.theme.light, + logLevel : 4, + flowchart: { curve: 'linear' }, + gantt : { axisFormat: '%m/%d/%Y' }, + sequence : { actorMargin: 50 } + }); + mermaid.init(); + }); + } +}); diff --git a/js/third-party/tags/pdf.js b/js/third-party/tags/pdf.js new file mode 100644 index 0000000..7e82891 --- /dev/null +++ b/js/third-party/tags/pdf.js @@ -0,0 +1,23 @@ +/* global NexT, CONFIG, PDFObject */ + +document.addEventListener('page:loaded', () => { + if (document.querySelectorAll('.pdf-container').length) { + NexT.utils.getScript(CONFIG.pdf.object_url, { + condition: window.PDFObject + }).then(() => { + document.querySelectorAll('.pdf-container').forEach(element => { + PDFObject.embed(element.dataset.target, element, { + pdfOpenParams: { + navpanes : 0, + toolbar : 0, + statusbar: 0, + pagemode : 'thumbs', + view : 'FitH' + }, + PDFJS_URL: CONFIG.pdf.url, + height : element.dataset.height + }); + }); + }); + } +}); diff --git a/js/utils.js b/js/utils.js new file mode 100644 index 0000000..ee10f61 --- /dev/null +++ b/js/utils.js @@ -0,0 +1,452 @@ +/* global NexT, CONFIG */ + +HTMLElement.prototype.wrap = function(wrapper) { + this.parentNode.insertBefore(wrapper, this); + this.parentNode.removeChild(this); + wrapper.appendChild(this); +}; + +(function() { + const onPageLoaded = () => document.dispatchEvent( + new Event('page:loaded', { + bubbles: true + }) + ); + + if (document.readyState === 'loading') { + document.addEventListener('readystatechange', onPageLoaded, { once: true }); + } else { + onPageLoaded(); + } + document.addEventListener('pjax:success', onPageLoaded); +})(); + +NexT.utils = { + + registerExtURL: function() { + document.querySelectorAll('span.exturl').forEach(element => { + const link = document.createElement('a'); + // https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings + link.href = decodeURIComponent(atob(element.dataset.url).split('').map(c => { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }).join('')); + link.rel = 'noopener external nofollow noreferrer'; + link.target = '_blank'; + link.className = element.className; + link.title = element.title; + link.innerHTML = element.innerHTML; + element.parentNode.replaceChild(link, element); + }); + }, + + /** + * One-click copy code support. + */ + registerCopyCode: function() { + let figure = document.querySelectorAll('figure.highlight'); + if (figure.length === 0) figure = document.querySelectorAll('pre:not(.mermaid)'); + figure.forEach(element => { + element.querySelectorAll('.code .line span').forEach(span => { + span.classList.forEach(name => { + span.classList.replace(name, `hljs-${name}`); + }); + }); + if (!CONFIG.copycode.enable) return; + let target = element; + if (CONFIG.copycode.style !== 'mac') target = element.querySelector('.table-container') || element; + target.insertAdjacentHTML('beforeend', '
'); + const button = element.querySelector('.copy-btn'); + button.addEventListener('click', () => { + const lines = element.querySelector('.code') || element.querySelector('code'); + const code = lines.innerText; + if (navigator.clipboard) { + // https://caniuse.com/mdn-api_clipboard_writetext + navigator.clipboard.writeText(code).then(() => { + button.querySelector('i').className = 'fa fa-check-circle fa-fw'; + }, () => { + button.querySelector('i').className = 'fa fa-times-circle fa-fw'; + }); + } else { + const ta = document.createElement('textarea'); + ta.style.top = window.scrollY + 'px'; // Prevent page scrolling + ta.style.position = 'absolute'; + ta.style.opacity = '0'; + ta.readOnly = true; + ta.value = code; + document.body.append(ta); + ta.select(); + ta.setSelectionRange(0, code.length); + ta.readOnly = false; + const result = document.execCommand('copy'); + button.querySelector('i').className = result ? 'fa fa-check-circle fa-fw' : 'fa fa-times-circle fa-fw'; + ta.blur(); // For iOS + button.blur(); + document.body.removeChild(ta); + } + }); + element.addEventListener('mouseleave', () => { + setTimeout(() => { + button.querySelector('i').className = 'fa fa-copy fa-fw'; + }, 300); + }); + }); + }, + + wrapTableWithBox: function() { + document.querySelectorAll('table').forEach(element => { + const box = document.createElement('div'); + box.className = 'table-container'; + element.wrap(box); + }); + }, + + registerVideoIframe: function() { + document.querySelectorAll('iframe').forEach(element => { + const supported = [ + 'www.youtube.com', + 'player.vimeo.com', + 'player.youku.com', + 'player.bilibili.com', + 'www.tudou.com' + ].some(host => element.src.includes(host)); + if (supported && !element.parentNode.matches('.video-container')) { + const box = document.createElement('div'); + box.className = 'video-container'; + element.wrap(box); + const width = Number(element.width); + const height = Number(element.height); + if (width && height) { + box.style.paddingTop = (height / width * 100) + '%'; + } + } + }); + }, + + updateActiveNav: function() { + if (!Array.isArray(NexT.utils.sections)) return; + let index = NexT.utils.sections.findIndex(element => { + return element && element.getBoundingClientRect().top > 10; + }); + if (index === -1) { + index = NexT.utils.sections.length - 1; + } else if (index > 0) { + index--; + } + this.activateNavByIndex(index); + }, + + registerScrollPercent: function() { + const backToTop = document.querySelector('.back-to-top'); + const readingProgressBar = document.querySelector('.reading-progress-bar'); + // For init back to top in sidebar if page was scrolled after page refresh. + window.addEventListener('scroll', () => { + if (backToTop || readingProgressBar) { + const contentHeight = document.body.scrollHeight - window.innerHeight; + const scrollPercent = contentHeight > 0 ? Math.min(100 * window.scrollY / contentHeight, 100) : 0; + if (backToTop) { + backToTop.classList.toggle('back-to-top-on', Math.round(scrollPercent) >= 5); + backToTop.querySelector('span').innerText = Math.round(scrollPercent) + '%'; + } + if (readingProgressBar) { + readingProgressBar.style.setProperty('--progress', scrollPercent.toFixed(2) + '%'); + } + } + this.updateActiveNav(); + }, { passive: true }); + + backToTop && backToTop.addEventListener('click', () => { + window.anime({ + targets : document.scrollingElement, + duration : 500, + easing : 'linear', + scrollTop: 0 + }); + }); + }, + + /** + * Tabs tag listener (without twitter bootstrap). + */ + registerTabsTag: function() { + // Binding `nav-tabs` & `tab-content` by real time permalink changing. + document.querySelectorAll('.tabs ul.nav-tabs .tab').forEach(element => { + element.addEventListener('click', event => { + event.preventDefault(); + // Prevent selected tab to select again. + if (element.classList.contains('active')) return; + const nav = element.parentNode; + // Get the height of `tab-pane` which is activated before, and set it as the height of `tab-content` with extra margin / paddings. + const tabContent = nav.nextElementSibling; + tabContent.style.overflow = 'hidden'; + tabContent.style.transition = 'height 1s'; + // Comment system selection tab does not contain .active class. + const activeTab = tabContent.querySelector('.active') || tabContent.firstElementChild; + // Hight might be `auto`. + const prevHeight = parseInt(window.getComputedStyle(activeTab).height.replace('px', ''), 10) || 0; + const paddingTop = parseInt(window.getComputedStyle(activeTab).paddingTop.replace('px', ''), 10); + const marginBottom = parseInt(window.getComputedStyle(activeTab.firstElementChild).marginBottom.replace('px', ''), 10); + tabContent.style.height = prevHeight + paddingTop + marginBottom + 'px'; + // Add & Remove active class on `nav-tabs` & `tab-content`. + [...nav.children].forEach(target => { + target.classList.toggle('active', target === element); + }); + // https://stackoverflow.com/questions/20306204/using-queryselector-with-ids-that-are-numbers + const tActive = document.getElementById(element.querySelector('a').getAttribute('href').replace('#', '')); + [...tActive.parentNode.children].forEach(target => { + target.classList.toggle('active', target === tActive); + }); + // Trigger event + tActive.dispatchEvent(new Event('tabs:click', { + bubbles: true + })); + // Get the height of `tab-pane` which is activated now. + const hasScrollBar = document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight); + const currHeight = parseInt(window.getComputedStyle(tabContent.querySelector('.active')).height.replace('px', ''), 10); + // Reset the height of `tab-content` and see the animation. + tabContent.style.height = currHeight + paddingTop + marginBottom + 'px'; + // Change the height of `tab-content` may cause scrollbar show / disappear, which may result in the change of the `tab-pane`'s height + setTimeout(() => { + if ((document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight)) !== hasScrollBar) { + tabContent.style.transition = 'height 0.3s linear'; + // After the animation, we need reset the height of `tab-content` again. + const currHeightAfterScrollBarChange = parseInt(window.getComputedStyle(tabContent.querySelector('.active')).height.replace('px', ''), 10); + tabContent.style.height = currHeightAfterScrollBarChange + paddingTop + marginBottom + 'px'; + } + // Remove all the inline styles, and let the height be adaptive again. + setTimeout(() => { + tabContent.style.transition = ''; + tabContent.style.height = ''; + }, 250); + }, 1000); + if (!CONFIG.stickytabs) return; + const offset = nav.parentNode.getBoundingClientRect().top + window.scrollY + 10; + window.anime({ + targets : document.scrollingElement, + duration : 500, + easing : 'linear', + scrollTop: offset + }); + }); + }); + + window.dispatchEvent(new Event('tabs:register')); + }, + + registerCanIUseTag: function() { + // Get responsive height passed from iframe. + window.addEventListener('message', ({ data }) => { + if (typeof data === 'string' && data.includes('ciu_embed')) { + const featureID = data.split(':')[1]; + const height = data.split(':')[2]; + document.querySelector(`iframe[data-feature=${featureID}]`).style.height = parseInt(height, 10) + 5 + 'px'; + } + }, false); + }, + + registerActiveMenuItem: function() { + document.querySelectorAll('.menu-item a[href]').forEach(target => { + const isSamePath = target.pathname === location.pathname || target.pathname === location.pathname.replace('index.html', ''); + const isSubPath = !CONFIG.root.startsWith(target.pathname) && location.pathname.startsWith(target.pathname); + target.classList.toggle('menu-item-active', target.hostname === location.hostname && (isSamePath || isSubPath)); + }); + }, + + registerLangSelect: function() { + const selects = document.querySelectorAll('.lang-select'); + selects.forEach(sel => { + sel.value = CONFIG.page.lang; + sel.addEventListener('change', () => { + const target = sel.options[sel.selectedIndex]; + document.querySelectorAll('.lang-select-label span').forEach(span => { + span.innerText = target.text; + }); + // Disable Pjax to force refresh translation of menu item + window.location.href = target.dataset.href; + }); + }); + }, + + registerSidebarTOC: function() { + this.sections = [...document.querySelectorAll('.post-toc:not(.placeholder-toc) li a.nav-link')].map(element => { + const target = document.getElementById(decodeURI(element.getAttribute('href')).replace('#', '')); + // TOC item animation navigate. + element.addEventListener('click', event => { + event.preventDefault(); + const offset = target.getBoundingClientRect().top + window.scrollY; + window.anime({ + targets : document.scrollingElement, + duration : 500, + easing : 'linear', + scrollTop: offset, + complete : () => { + history.pushState(null, document.title, element.href); + } + }); + }); + return target; + }); + this.updateActiveNav(); + }, + + registerPostReward: function() { + const button = document.querySelector('.reward-container button'); + if (!button) return; + button.addEventListener('click', () => { + document.querySelector('.post-reward').classList.toggle('active'); + }); + }, + + activateNavByIndex: function(index) { + const nav = document.querySelector('.post-toc:not(.placeholder-toc) .nav'); + if (!nav) return; + + const navItemList = nav.querySelectorAll('.nav-item'); + const target = navItemList[index]; + if (!target || target.classList.contains('active-current')) return; + + const singleHeight = navItemList[navItemList.length - 1].offsetHeight; + + nav.querySelectorAll('.active').forEach(navItem => { + navItem.classList.remove('active', 'active-current'); + }); + target.classList.add('active', 'active-current'); + + let activateEle = target.querySelector('.nav-child') || target.parentElement; + let navChildHeight = 0; + + while (nav.contains(activateEle)) { + if (activateEle.classList.contains('nav-item')) { + activateEle.classList.add('active'); + } else { // .nav-child or .nav + // scrollHeight isn't reliable for transitioning child items. + // The last nav-item in a list has a margin-bottom of 5px. + navChildHeight += (singleHeight * activateEle.childElementCount) + 5; + activateEle.style.setProperty('--height', `${navChildHeight}px`); + } + activateEle = activateEle.parentElement; + } + + // Scrolling to center active TOC element if TOC content is taller then viewport. + const tocElement = document.querySelector(CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini' ? '.sidebar-panel-container' : '.sidebar'); + if (!document.querySelector('.sidebar-toc-active')) return; + window.anime({ + targets : tocElement, + duration : 200, + easing : 'linear', + scrollTop: tocElement.scrollTop - (tocElement.offsetHeight / 2) + target.getBoundingClientRect().top - tocElement.getBoundingClientRect().top + }); + }, + + updateSidebarPosition: function() { + if (window.innerWidth < 1200 || CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini') return; + // Expand sidebar on post detail page by default, when post has a toc. + const hasTOC = document.querySelector('.post-toc:not(.placeholder-toc)'); + let display = CONFIG.page.sidebar; + if (typeof display !== 'boolean') { + // There's no definition sidebar in the page front-matter. + display = CONFIG.sidebar.display === 'always' || (CONFIG.sidebar.display === 'post' && hasTOC); + } + if (display) { + window.dispatchEvent(new Event('sidebar:show')); + } + }, + + activateSidebarPanel: function(index) { + const sidebar = document.querySelector('.sidebar-inner'); + const activeClassNames = ['sidebar-toc-active', 'sidebar-overview-active']; + if (sidebar.classList.contains(activeClassNames[index])) return; + + const panelContainer = sidebar.querySelector('.sidebar-panel-container'); + const tocPanel = panelContainer.firstElementChild; + const overviewPanel = panelContainer.lastElementChild; + + let postTOCHeight = tocPanel.scrollHeight; + // For TOC activation, try to use the animated TOC height + if (index === 0) { + const nav = tocPanel.querySelector('.nav'); + if (nav) { + postTOCHeight = parseInt(nav.style.getPropertyValue('--height'), 10); + } + } + const panelHeights = [ + postTOCHeight, + overviewPanel.scrollHeight + ]; + panelContainer.style.setProperty('--inactive-panel-height', `${panelHeights[1 - index]}px`); + panelContainer.style.setProperty('--active-panel-height', `${panelHeights[index]}px`); + + sidebar.classList.replace(activeClassNames[1 - index], activeClassNames[index]); + }, + + getScript: function(src, options = {}, legacyCondition) { + if (typeof options === 'function') { + return this.getScript(src, { + condition: legacyCondition + }).then(options); + } + const { + condition = false, + attributes: { + id = '', + async = false, + defer = false, + crossOrigin = '', + dataset = {}, + ...otherAttributes + } = {}, + parentNode = null + } = options; + return new Promise((resolve, reject) => { + if (condition) { + resolve(); + } else { + const script = document.createElement('script'); + + if (id) script.id = id; + if (crossOrigin) script.crossOrigin = crossOrigin; + script.async = async; + script.defer = defer; + Object.assign(script.dataset, dataset); + Object.entries(otherAttributes).forEach(([name, value]) => { + script.setAttribute(name, String(value)); + }); + + script.onload = resolve; + script.onerror = reject; + + if (typeof src === 'object') { + const { url, integrity } = src; + script.src = url; + if (integrity) { + script.integrity = integrity; + script.crossOrigin = 'anonymous'; + } + } else { + script.src = src; + } + (parentNode || document.head).appendChild(script); + } + }); + }, + + loadComments: function(selector, legacyCallback) { + if (legacyCallback) { + return this.loadComments(selector).then(legacyCallback); + } + return new Promise(resolve => { + const element = document.querySelector(selector); + if (!CONFIG.comments.lazyload || !element) { + resolve(); + return; + } + const intersectionObserver = new IntersectionObserver((entries, observer) => { + const entry = entries[0]; + if (!entry.isIntersecting) return; + + resolve(); + observer.disconnect(); + }); + intersectionObserver.observe(element); + }); + } +}; diff --git a/lib/hbe.js b/lib/hbe.js new file mode 100644 index 0000000..bc024dc --- /dev/null +++ b/lib/hbe.js @@ -0,0 +1,293 @@ +(() => { + 'use strict'; + + const cryptoObj = window.crypto || window.msCrypto; + const storage = window.localStorage; + + const storageName = 'hexo-blog-encrypt:#' + window.location.pathname; + const keySalt = textToArray('hexo-blog-encrypt的作者们都是大帅比!'); + const ivSalt = textToArray('hexo-blog-encrypt是地表最强Hexo加密插件!'); + +// As we can't detect the wrong password with AES-CBC, +// so adding an empty div and check it when decrption. +const knownPrefix = ""; + + const mainElement = document.getElementById('hexo-blog-encrypt'); + const wrongPassMessage = mainElement.dataset['wpm']; + const wrongHashMessage = mainElement.dataset['whm']; + const dataElement = mainElement.getElementsByTagName('script')['hbeData']; + const encryptedData = dataElement.innerText; + const HmacDigist = dataElement.dataset['hmacdigest']; + + function hexToArray(s) { + return new Uint8Array(s.match(/[\da-f]{2}/gi).map((h => { + return parseInt(h, 16); + }))); + } + + function textToArray(s) { + var i = s.length; + var n = 0; + var ba = new Array() + + for (var j = 0; j < i;) { + var c = s.codePointAt(j); + if (c < 128) { + ba[n++] = c; + j++; + } else if ((c > 127) && (c < 2048)) { + ba[n++] = (c >> 6) | 192; + ba[n++] = (c & 63) | 128; + j++; + } else if ((c > 2047) && (c < 65536)) { + ba[n++] = (c >> 12) | 224; + ba[n++] = ((c >> 6) & 63) | 128; + ba[n++] = (c & 63) | 128; + j++; + } else { + ba[n++] = (c >> 18) | 240; + ba[n++] = ((c >> 12) & 63) | 128; + ba[n++] = ((c >> 6) & 63) | 128; + ba[n++] = (c & 63) | 128; + j += 2; + } + } + return new Uint8Array(ba); + } + + function arrayBufferToHex(arrayBuffer) { + if (typeof arrayBuffer !== 'object' || arrayBuffer === null || typeof arrayBuffer.byteLength !== 'number') { + throw new TypeError('Expected input to be an ArrayBuffer') + } + + var view = new Uint8Array(arrayBuffer) + var result = '' + var value + + for (var i = 0; i < view.length; i++) { + value = view[i].toString(16) + result += (value.length === 1 ? '0' + value : value) + } + + return result + } + + async function getExecutableScript(oldElem) { + let out = document.createElement('script'); + const attList = ['type', 'text', 'src', 'crossorigin', 'defer', 'referrerpolicy']; + attList.forEach((att) => { + if (oldElem[att]) + out[att] = oldElem[att]; + }) + + return out; + } + + async function convertHTMLToElement(content) { + let out = document.createElement('div'); + out.innerHTML = content; + out.querySelectorAll('script').forEach(async (elem) => { + elem.replaceWith(await getExecutableScript(elem)); + }); + + return out; + } + + function getKeyMaterial(password) { + let encoder = new TextEncoder(); + return cryptoObj.subtle.importKey( + 'raw', + encoder.encode(password), + { + 'name': 'PBKDF2', + }, + false, + [ + 'deriveKey', + 'deriveBits', + ] + ); + } + + function getHmacKey(keyMaterial) { + return cryptoObj.subtle.deriveKey({ + 'name': 'PBKDF2', + 'hash': 'SHA-256', + 'salt': keySalt.buffer, + 'iterations': 1024 + }, keyMaterial, { + 'name': 'HMAC', + 'hash': 'SHA-256', + 'length': 256, + }, true, [ + 'verify', + ]); + } + + function getDecryptKey(keyMaterial) { + return cryptoObj.subtle.deriveKey({ + 'name': 'PBKDF2', + 'hash': 'SHA-256', + 'salt': keySalt.buffer, + 'iterations': 1024, + }, keyMaterial, { + 'name': 'AES-CBC', + 'length': 256, + }, true, [ + 'decrypt', + ]); + } + + function getIv(keyMaterial) { + return cryptoObj.subtle.deriveBits({ + 'name': 'PBKDF2', + 'hash': 'SHA-256', + 'salt': ivSalt.buffer, + 'iterations': 512, + }, keyMaterial, 16 * 8); + } + + async function verifyContent(key, content) { + const encoder = new TextEncoder(); + const encoded = encoder.encode(content); + + let signature = hexToArray(HmacDigist); + + const result = await cryptoObj.subtle.verify({ + 'name': 'HMAC', + 'hash': 'SHA-256', + }, key, signature, encoded); + console.log(`Verification result: ${result}`); + if (!result) { + alert(wrongHashMessage); + console.log(`${wrongHashMessage}, got `, signature, ` but proved wrong.`); + } + return result; + } + + async function decrypt(decryptKey, iv, hmacKey) { + let typedArray = hexToArray(encryptedData); + + const result = await cryptoObj.subtle.decrypt({ + 'name': 'AES-CBC', + 'iv': iv, + }, decryptKey, typedArray.buffer).then(async (result) => { + const decoder = new TextDecoder(); + const decoded = decoder.decode(result); + + // check the prefix, if not then we can sure here is wrong password. + if (!decoded.startsWith(knownPrefix)) { + throw "Decode successfully but not start with KnownPrefix."; + } + + const hideButton = document.createElement('button'); + hideButton.textContent = 'Encrypt again'; + hideButton.type = 'button'; + hideButton.classList.add("hbe-button"); + hideButton.addEventListener('click', () => { + window.localStorage.removeItem(storageName); + window.location.reload(); + }); + + document.getElementById('hexo-blog-encrypt').style.display = 'inline'; + document.getElementById('hexo-blog-encrypt').innerHTML = ''; + document.getElementById('hexo-blog-encrypt').appendChild(await convertHTMLToElement(decoded)); + document.getElementById('hexo-blog-encrypt').appendChild(hideButton); + + // support html5 lazyload functionality. + document.querySelectorAll('img').forEach((elem) => { + if (elem.getAttribute("data-src") && !elem.src) { + elem.src = elem.getAttribute('data-src'); + } + }); + + // support theme-next refresh + window.NexT && NexT.boot && typeof NexT.boot.refresh === 'function' && NexT.boot.refresh(); + + // TOC part + var tocDiv = document.getElementById("toc-div"); + if (tocDiv) { + tocDiv.style.display = 'inline'; + } + + var tocDivs = document.getElementsByClassName('toc-div-class'); + if (tocDivs && tocDivs.length > 0) { + for (var idx = 0; idx < tocDivs.length; idx++) { + tocDivs[idx].style.display = 'inline'; + } + } + + return await verifyContent(hmacKey, decoded); + }).catch((e) => { + alert(wrongPassMessage); + console.log(e); + return false; + }); + + return result; + + } + + function hbeLoader() { + + const oldStorageData = JSON.parse(storage.getItem(storageName)); + + if (oldStorageData) { + console.log(`Password got from localStorage(${storageName}): `, oldStorageData); + + const sIv = hexToArray(oldStorageData.iv).buffer; + const sDk = oldStorageData.dk; + const sHmk = oldStorageData.hmk; + + cryptoObj.subtle.importKey('jwk', sDk, { + 'name': 'AES-CBC', + 'length': 256, + }, true, [ + 'decrypt', + ]).then((dkCK) => { + cryptoObj.subtle.importKey('jwk', sHmk, { + 'name': 'HMAC', + 'hash': 'SHA-256', + 'length': 256, + }, true, [ + 'verify', + ]).then((hmkCK) => { + decrypt(dkCK, sIv, hmkCK).then((result) => { + if (!result) { + storage.removeItem(storageName); + } + }); + }); + }); + } + + mainElement.addEventListener('keydown', async (event) => { + if (event.isComposing || event.keyCode === 13) { + const password = document.getElementById('hbePass').value; + const keyMaterial = await getKeyMaterial(password); + const hmacKey = await getHmacKey(keyMaterial); + const decryptKey = await getDecryptKey(keyMaterial); + const iv = await getIv(keyMaterial); + + decrypt(decryptKey, iv, hmacKey).then((result) => { + console.log(`Decrypt result: ${result}`); + if (result) { + cryptoObj.subtle.exportKey('jwk', decryptKey).then((dk) => { + cryptoObj.subtle.exportKey('jwk', hmacKey).then((hmk) => { + const newStorageData = { + 'dk': dk, + 'iv': arrayBufferToHex(iv), + 'hmk': hmk, + }; + storage.setItem(storageName, JSON.stringify(newStorageData)); + }); + }); + } + }); + } + }); + } + + hbeLoader(); + +})(); diff --git a/lib/pace/LICENSE b/lib/pace/LICENSE new file mode 100644 index 0000000..69a20d6 --- /dev/null +++ b/lib/pace/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 «NexT» + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/lib/pace/README.html b/lib/pace/README.html new file mode 100644 index 0000000..15335de --- /dev/null +++ b/lib/pace/README.html @@ -0,0 +1,39 @@ +

Progress bar for NexT

+ +

Installation

+ +

If you want to use the CDN instead of clone this repo, please jump to the Step 3.

+ +

Step 1 → Go to NexT dir

+ +

Change dir to NexT directory. There must be layout, source, languages and other directories:

+
$ cd themes/next
+$ ls
+_config.yml  crowdin.yml  docs  gulpfile.js  languages  layout  LICENSE.md  package.json  README.md  scripts  source
+
+

Step 2 → Get module

+ +

Install module to source/lib directory:

+
$ git clone https://github.com/theme-next/theme-next-pace source/lib/pace
+
+

Step 3 → Set it up

+ +

Enable module in NexT _config.yml file and select your theme:

+
pace:
+  enable: true
+  # Themes list:
+  # big-counter | bounce | barber-shop | center-atom | center-circle | center-radar | center-simple
+  # corner-indicator | fill-left | flat-top | flash | loading-bar | mac-osx | material | minimal
+  theme: minimal
+
+

And, if you wants to use the CDN, then need to set: (you also need to find your corresponding theme css link in jsdelivr)

+
vendors:
+  ...
+  pace: //cdn.jsdelivr.net/npm/pace-js@1/pace.min.js
+  pace_css: //cdn.jsdelivr.net/npm/pace-js@1/themes/blue/pace-theme-minimal.css
+
+

Update

+ +
$ cd themes/next/source/lib/pace
+$ git pull
+
diff --git a/lib/pace/pace-theme-barber-shop.min.css b/lib/pace/pace-theme-barber-shop.min.css new file mode 100644 index 0000000..971e8a1 --- /dev/null +++ b/lib/pace/pace-theme-barber-shop.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-progress{width:100%;overflow:hidden}.pace,.pace .pace-activity{position:fixed;top:0;left:0}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:2000;height:12px;background:#fff}.pace-inactive{display:none}.pace .pace-progress{background-color:#29d;position:fixed;top:0;bottom:0;right:100%}.pace .pace-activity{right:-32px;bottom:0;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,.2)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,.2)),color-stop(.75,rgba(255,255,255,.2)),color-stop(.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);-webkit-background-size:32px 32px;-moz-background-size:32px 32px;-o-background-size:32px 32px;background-size:32px 32px;-webkit-animation:pace-theme-barber-shop-motion .5s linear infinite;-moz-animation:pace-theme-barber-shop-motion .5s linear infinite;-ms-animation:pace-theme-barber-shop-motion .5s linear infinite;-o-animation:pace-theme-barber-shop-motion .5s linear infinite;animation:pace-theme-barber-shop-motion .5s linear infinite}@-webkit-keyframes pace-theme-barber-shop-motion{0%{-webkit-transform:none;transform:none}100%{-webkit-transform:translate(-32px,0);transform:translate(-32px,0)}}@-moz-keyframes pace-theme-barber-shop-motion{0%{-moz-transform:none;transform:none}100%{-moz-transform:translate(-32px,0);transform:translate(-32px,0)}}@-o-keyframes pace-theme-barber-shop-motion{0%{-o-transform:none;transform:none}100%{-o-transform:translate(-32px,0);transform:translate(-32px,0)}}@-ms-keyframes pace-theme-barber-shop-motion{0%{-ms-transform:none;transform:none}100%{-ms-transform:translate(-32px,0);transform:translate(-32px,0)}}@keyframes pace-theme-barber-shop-motion{0%{transform:none}100%{transform:translate(-32px,0)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-big-counter.min.css b/lib/pace/pace-theme-big-counter.min.css new file mode 100644 index 0000000..f30e0a9 --- /dev/null +++ b/lib/pace/pace-theme-big-counter.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace.pace-inactive .pace-progress{display:none}.pace .pace-progress{position:fixed;z-index:2000;top:0;right:0;height:5rem;width:5rem;-webkit-transform:translate3d(0,0,0)!important;-ms-transform:translate3d(0,0,0)!important;transform:translate3d(0,0,0)!important}.pace .pace-progress:after{display:block;position:absolute;top:0;right:.5rem;content:attr(data-progress-text);font-family:"Helvetica Neue",sans-serif;font-weight:100;font-size:5rem;line-height:1;text-align:right;color:rgba(34,153,221,.19999999999999996)} \ No newline at end of file diff --git a/lib/pace/pace-theme-bounce.min.css b/lib/pace/pace-theme-bounce.min.css new file mode 100644 index 0000000..3edcd35 --- /dev/null +++ b/lib/pace/pace-theme-bounce.min.css @@ -0,0 +1 @@ +.pace{width:140px;height:300px;position:fixed;top:-90px;right:-20px;z-index:2000;-webkit-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);opacity:0;-webkit-transition:all 2s linear 0s;-moz-transition:all 2s linear 0s;transition:all 2s linear 0s}.pace.pace-active{-webkit-transform:scale(.25);-moz-transform:scale(.25);-ms-transform:scale(.25);-o-transform:scale(.25);transform:scale(.25);opacity:1}.pace .pace-activity{width:140px;height:140px;border-radius:70px;background:#29d;position:absolute;top:0;z-index:1911;-webkit-animation:pace-bounce 1s infinite;-moz-animation:pace-bounce 1s infinite;-o-animation:pace-bounce 1s infinite;-ms-animation:pace-bounce 1s infinite;animation:pace-bounce 1s infinite}.pace .pace-progress{position:absolute;display:block;left:50%;bottom:0;z-index:1910;margin-left:-30px;width:60px;height:75px;background:rgba(20,20,20,.1);box-shadow:0 0 20px 35px rgba(20,20,20,.1);border-radius:30px/40px;-webkit-transform:scaleY(.3)!important;-moz-transform:scaleY(.3)!important;-ms-transform:scaleY(.3)!important;-o-transform:scaleY(.3)!important;transform:scaleY(.3)!important;-webkit-animation:pace-compress .5s infinite alternate;-moz-animation:pace-compress .5s infinite alternate;-o-animation:pace-compress .5s infinite alternate;-ms-animation:pace-compress .5s infinite alternate;animation:pace-compress .5s infinite alternate}@-webkit-keyframes pace-bounce{0%,100%,95%{top:0;-webkit-animation-timing-function:ease-in}50%{top:140px;height:140px;-webkit-animation-timing-function:ease-out}55%{top:160px;height:120px;border-radius:70px/60px;-webkit-animation-timing-function:ease-in}65%{top:120px;height:140px;border-radius:70px;-webkit-animation-timing-function:ease-out}}@-moz-keyframes pace-bounce{0%,100%,95%{top:0;-moz-animation-timing-function:ease-in}50%{top:140px;height:140px;-moz-animation-timing-function:ease-out}55%{top:160px;height:120px;border-radius:70px/60px;-moz-animation-timing-function:ease-in}65%{top:120px;height:140px;border-radius:70px;-moz-animation-timing-function:ease-out}}@keyframes pace-bounce{0%,100%,95%{top:0;animation-timing-function:ease-in}50%{top:140px;height:140px;animation-timing-function:ease-out}55%{top:160px;height:120px;border-radius:70px/60px;animation-timing-function:ease-in}65%{top:120px;height:140px;border-radius:70px;animation-timing-function:ease-out}}@-webkit-keyframes pace-compress{0%{bottom:0;margin-left:-30px;width:60px;height:75px;background:rgba(20,20,20,.1);box-shadow:0 0 20px 35px rgba(20,20,20,.1);border-radius:30px/40px;-webkit-animation-timing-function:ease-in}100%{bottom:30px;margin-left:-10px;width:20px;height:5px;background:rgba(20,20,20,.3);box-shadow:0 0 20px 35px rgba(20,20,20,.3);border-radius:20px;-webkit-animation-timing-function:ease-out}}@-moz-keyframes pace-compress{0%{bottom:0;margin-left:-30px;width:60px;height:75px;background:rgba(20,20,20,.1);box-shadow:0 0 20px 35px rgba(20,20,20,.1);border-radius:30px/40px;-moz-animation-timing-function:ease-in}100%{bottom:30px;margin-left:-10px;width:20px;height:5px;background:rgba(20,20,20,.3);box-shadow:0 0 20px 35px rgba(20,20,20,.3);border-radius:20px;-moz-animation-timing-function:ease-out}}@keyframes pace-compress{0%{bottom:0;margin-left:-30px;width:60px;height:75px;background:rgba(20,20,20,.1);box-shadow:0 0 20px 35px rgba(20,20,20,.1);border-radius:30px/40px;animation-timing-function:ease-in}100%{bottom:30px;margin-left:-10px;width:20px;height:5px;background:rgba(20,20,20,.3);box-shadow:0 0 20px 35px rgba(20,20,20,.3);border-radius:20px;animation-timing-function:ease-out}} \ No newline at end of file diff --git a/lib/pace/pace-theme-center-atom.min.css b/lib/pace/pace-theme-center-atom.min.css new file mode 100644 index 0000000..828dcba --- /dev/null +++ b/lib/pace/pace-theme-center-atom.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-progress{z-index:2000;height:60px;width:100px}.pace .pace-activity,.pace .pace-progress:before{border-radius:50%;display:block;position:absolute}.pace.pace-inactive{display:none}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:fixed;margin:auto;top:0;left:0;right:0;bottom:0}.pace .pace-progress{position:absolute;-webkit-transform:translate3d(0,0,0)!important;-ms-transform:translate3d(0,0,0)!important;transform:translate3d(0,0,0)!important}.pace .pace-progress:before{content:attr(data-progress-text);text-align:center;color:#fff;background:#29d;font-family:"Helvetica Neue",sans-serif;font-size:14px;font-weight:100;line-height:1;padding:20% 0 7px;width:50%;height:40%;margin:10px 0 0 30px;z-index:999}.pace .pace-activity{font-size:15px;line-height:1;z-index:2000;-webkit-animation:pace-theme-center-atom-spin 2s linear infinite;-moz-animation:pace-theme-center-atom-spin 2s linear infinite;-o-animation:pace-theme-center-atom-spin 2s linear infinite;animation:pace-theme-center-atom-spin 2s linear infinite;border:5px solid #29d;content:' ';top:0;left:0;height:60px;width:100px}.pace .pace-activity:after,.pace .pace-activity:before{content:' ';display:block;position:absolute;top:-5px;left:-5px;height:60px;width:100px}.pace .pace-activity:after{border-radius:50%;border:5px solid #29d;-webkit-transform:rotate(60deg);-moz-transform:rotate(60deg);-o-transform:rotate(60deg);transform:rotate(60deg)}.pace .pace-activity:before{border-radius:50%;border:5px solid #29d;-webkit-transform:rotate(120deg);-moz-transform:rotate(120deg);-o-transform:rotate(120deg);transform:rotate(120deg)}@-webkit-keyframes pace-theme-center-atom-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(359deg)}}@-moz-keyframes pace-theme-center-atom-spin{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(359deg)}}@-o-keyframes pace-theme-center-atom-spin{0%{-o-transform:rotate(0)}100%{-o-transform:rotate(359deg)}}@keyframes pace-theme-center-atom-spin{0%{transform:rotate(0)}100%{transform:rotate(359deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-center-circle.min.css b/lib/pace/pace-theme-center-circle.min.css new file mode 100644 index 0000000..c005c71 --- /dev/null +++ b/lib/pace/pace-theme-center-circle.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-progress{z-index:2000;left:0;top:0;height:6rem}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-perspective:12rem;-moz-perspective:12rem;-ms-perspective:12rem;-o-perspective:12rem;perspective:12rem;position:fixed;width:6rem;margin:auto;right:0;bottom:0}.pace.pace-inactive .pace-progress{display:none}.pace .pace-progress{display:block;position:absolute;width:6rem!important;line-height:6rem;font-size:2rem;border-radius:50%;background:rgba(34,153,221,.8);color:#fff;font-family:"Helvetica Neue",sans-serif;font-weight:100;text-align:center;-webkit-animation:pace-theme-center-circle-spin linear infinite 2s;-moz-animation:pace-theme-center-circle-spin linear infinite 2s;-ms-animation:pace-theme-center-circle-spin linear infinite 2s;-o-animation:pace-theme-center-circle-spin linear infinite 2s;animation:pace-theme-center-circle-spin linear infinite 2s;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;-o-transform-style:preserve-3d;transform-style:preserve-3d}.pace .pace-progress:after{content:attr(data-progress-text);display:block}@-webkit-keyframes pace-theme-center-circle-spin{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(360deg)}}@-moz-keyframes pace-theme-center-circle-spin{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(360deg)}}@-ms-keyframes pace-theme-center-circle-spin{from{-ms-transform:rotateY(0)}to{-ms-transform:rotateY(360deg)}}@-o-keyframes pace-theme-center-circle-spin{from{-o-transform:rotateY(0)}to{-o-transform:rotateY(360deg)}}@keyframes pace-theme-center-circle-spin{from{transform:rotateY(0)}to{transform:rotateY(360deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-center-radar.min.css b/lib/pace/pace-theme-center-radar.min.css new file mode 100644 index 0000000..8bb4535 --- /dev/null +++ b/lib/pace/pace-theme-center-radar.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-activity{z-index:2000;height:90px;width:90px}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:fixed;margin:auto;top:0;left:0;right:0;bottom:0}.pace.pace-inactive .pace-activity{display:none}.pace .pace-activity,.pace .pace-activity:before{position:absolute;display:block;border-color:#29d transparent transparent;border-radius:50%}.pace .pace-activity{left:-30px;top:-30px;border-width:30px;border-style:double;-webkit-animation:spin 1s linear infinite;-moz-animation:spin 1s linear infinite;-o-animation:spin 1s linear infinite;animation:spin 1s linear infinite}.pace .pace-activity:before{content:' ';top:10px;left:10px;height:50px;width:50px;border-width:10px;border-style:solid}@-webkit-keyframes spin{100%{-webkit-transform:rotate(359deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(359deg)}}@-o-keyframes spin{100%{-moz-transform:rotate(359deg)}}@keyframes spin{100%{transform:rotate(359deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-center-simple.min.css b/lib/pace/pace-theme-center-simple.min.css new file mode 100644 index 0000000..a6dbd9c --- /dev/null +++ b/lib/pace/pace-theme-center-simple.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:2000;position:fixed;margin:auto;top:0;left:0;right:0;bottom:0;height:5px;width:200px;background:#fff;border:1px solid #29d;overflow:hidden}.pace .pace-progress{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);max-width:200px;z-index:2000;display:block;position:absolute;top:0;right:100%;height:100%;width:100%;background:#29d}.pace.pace-inactive{display:none} \ No newline at end of file diff --git a/lib/pace/pace-theme-corner-indicator.min.css b/lib/pace/pace-theme-corner-indicator.min.css new file mode 100644 index 0000000..490db22 --- /dev/null +++ b/lib/pace/pace-theme-corner-indicator.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace .pace-activity{display:block;position:fixed;z-index:2000;top:0;right:0;width:300px;height:300px;background:#29d;-webkit-transition:-webkit-transform .3s;transition:transform .3s;-webkit-transform:translateX(100%) translateY(-100%) rotate(45deg);transform:translateX(100%) translateY(-100%) rotate(45deg);pointer-events:none}.pace.pace-active .pace-activity{-webkit-transform:translateX(50%) translateY(-50%) rotate(45deg);transform:translateX(50%) translateY(-50%) rotate(45deg)}.pace .pace-activity::after,.pace .pace-activity::before{-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;bottom:30px;left:50%;display:block;border:5px solid #fff;border-radius:50%;content:''}.pace .pace-activity::before{margin-left:-40px;width:80px;height:80px;border-right-color:rgba(0,0,0,.2);border-left-color:rgba(0,0,0,.2);-webkit-animation:pace-theme-corner-indicator-spin 3s linear infinite;animation:pace-theme-corner-indicator-spin 3s linear infinite}.pace .pace-activity::after{bottom:50px;margin-left:-20px;width:40px;height:40px;border-top-color:rgba(0,0,0,.2);border-bottom-color:rgba(0,0,0,.2);-webkit-animation:pace-theme-corner-indicator-spin 1s linear infinite;animation:pace-theme-corner-indicator-spin 1s linear infinite}@-webkit-keyframes pace-theme-corner-indicator-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(359deg)}}@keyframes pace-theme-corner-indicator-spin{0%{transform:rotate(0)}100%{transform:rotate(359deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-fill-left.min.css b/lib/pace/pace-theme-fill-left.min.css new file mode 100644 index 0000000..533d55d --- /dev/null +++ b/lib/pace/pace-theme-fill-left.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace-inactive{display:none}.pace .pace-progress{background-color:rgba(34,153,221,.19999999999999996);position:fixed;z-index:-1;top:0;right:100%;bottom:0;width:100%} \ No newline at end of file diff --git a/lib/pace/pace-theme-flash.min.css b/lib/pace/pace-theme-flash.min.css new file mode 100644 index 0000000..35a749d --- /dev/null +++ b/lib/pace/pace-theme-flash.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace-inactive{display:none}.pace .pace-progress{background:#29d;position:fixed;z-index:2000;top:0;right:100%;width:100%;height:2px}.pace .pace-progress-inner{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translate(0,-4px);-moz-transform:rotate(3deg) translate(0,-4px);-ms-transform:rotate(3deg) translate(0,-4px);-o-transform:rotate(3deg) translate(0,-4px);transform:rotate(3deg) translate(0,-4px)}.pace .pace-activity{display:block;position:fixed;z-index:2000;top:15px;right:15px;width:14px;height:14px;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:10px;-webkit-animation:pace-spinner .4s linear infinite;-moz-animation:pace-spinner .4s linear infinite;-ms-animation:pace-spinner .4s linear infinite;-o-animation:pace-spinner .4s linear infinite;animation:pace-spinner .4s linear infinite}@-webkit-keyframes pace-spinner{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes pace-spinner{0%{-moz-transform:rotate(0);transform:rotate(0)}100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes pace-spinner{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes pace-spinner{0%{-ms-transform:rotate(0);transform:rotate(0)}100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes pace-spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-flat-top.min.css b/lib/pace/pace-theme-flat-top.min.css new file mode 100644 index 0000000..6854b8c --- /dev/null +++ b/lib/pace/pace-theme-flat-top.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;position:fixed;top:0;left:0;width:100%;-webkit-transform:translate3d(0,-50px,0);-ms-transform:translate3d(0,-50px,0);transform:translate3d(0,-50px,0);-webkit-transition:-webkit-transform .5s ease-out;-ms-transition:-webkit-transform .5s ease-out;transition:transform .5s ease-out}.pace.pace-active{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.pace .pace-progress{display:block;position:fixed;z-index:2000;top:0;right:100%;width:100%;height:10px;background:#29d;pointer-events:none} diff --git a/lib/pace/pace-theme-loading-bar.min.css b/lib/pace/pace-theme-loading-bar.min.css new file mode 100644 index 0000000..9b30580 --- /dev/null +++ b/lib/pace/pace-theme-loading-bar.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;z-index:2000;position:fixed;margin:auto;top:12px;left:0;right:0;bottom:0;width:200px;height:50px;overflow:hidden}.pace .pace-progress{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;-webkit-background-clip:padding-box;-moz-background-clip:padding;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);display:block;position:absolute;right:100%;margin-right:-7px;width:93%;top:7px;height:14px;font-size:12px;background:#29d;color:#29d;line-height:60px;font-weight:700;font-family:Helvetica,Arial,"Lucida Grande",sans-serif;-webkit-box-shadow:120px 0 #fff,240px 0 #fff;-ms-box-shadow:120px 0 #fff,240px 0 #fff;box-shadow:120px 0 #fff,240px 0 #fff}.pace .pace-progress:after{content:attr(data-progress-text);display:inline-block;position:fixed;width:45px;text-align:right;right:0;padding-right:16px;top:4px}.pace .pace-progress[data-progress-text="0%"]:after{right:-200px}.pace .pace-progress[data-progress-text="1%"]:after{right:-198.14px}.pace .pace-progress[data-progress-text="2%"]:after{right:-196.28px}.pace .pace-progress[data-progress-text="3%"]:after{right:-194.42px}.pace .pace-progress[data-progress-text="4%"]:after{right:-192.56px}.pace .pace-progress[data-progress-text="5%"]:after{right:-190.7px}.pace .pace-progress[data-progress-text="6%"]:after{right:-188.84px}.pace .pace-progress[data-progress-text="7%"]:after{right:-186.98px}.pace .pace-progress[data-progress-text="8%"]:after{right:-185.12px}.pace .pace-progress[data-progress-text="9%"]:after{right:-183.26px}.pace .pace-progress[data-progress-text="10%"]:after{right:-181.4px}.pace .pace-progress[data-progress-text="11%"]:after{right:-179.54px}.pace .pace-progress[data-progress-text="12%"]:after{right:-177.68px}.pace .pace-progress[data-progress-text="13%"]:after{right:-175.82px}.pace .pace-progress[data-progress-text="14%"]:after{right:-173.96px}.pace .pace-progress[data-progress-text="15%"]:after{right:-172.1px}.pace .pace-progress[data-progress-text="16%"]:after{right:-170.24px}.pace .pace-progress[data-progress-text="17%"]:after{right:-168.38px}.pace .pace-progress[data-progress-text="18%"]:after{right:-166.52px}.pace .pace-progress[data-progress-text="19%"]:after{right:-164.66px}.pace .pace-progress[data-progress-text="20%"]:after{right:-162.8px}.pace .pace-progress[data-progress-text="21%"]:after{right:-160.94px}.pace .pace-progress[data-progress-text="22%"]:after{right:-159.08px}.pace .pace-progress[data-progress-text="23%"]:after{right:-157.22px}.pace .pace-progress[data-progress-text="24%"]:after{right:-155.36px}.pace .pace-progress[data-progress-text="25%"]:after{right:-153.5px}.pace .pace-progress[data-progress-text="26%"]:after{right:-151.64px}.pace .pace-progress[data-progress-text="27%"]:after{right:-149.78px}.pace .pace-progress[data-progress-text="28%"]:after{right:-147.92px}.pace .pace-progress[data-progress-text="29%"]:after{right:-146.06px}.pace .pace-progress[data-progress-text="30%"]:after{right:-144.2px}.pace .pace-progress[data-progress-text="31%"]:after{right:-142.34px}.pace .pace-progress[data-progress-text="32%"]:after{right:-140.48px}.pace .pace-progress[data-progress-text="33%"]:after{right:-138.62px}.pace .pace-progress[data-progress-text="34%"]:after{right:-136.76px}.pace .pace-progress[data-progress-text="35%"]:after{right:-134.9px}.pace .pace-progress[data-progress-text="36%"]:after{right:-133.04px}.pace .pace-progress[data-progress-text="37%"]:after{right:-131.18px}.pace .pace-progress[data-progress-text="38%"]:after{right:-129.32px}.pace .pace-progress[data-progress-text="39%"]:after{right:-127.46px}.pace .pace-progress[data-progress-text="40%"]:after{right:-125.6px}.pace .pace-progress[data-progress-text="41%"]:after{right:-123.74px}.pace .pace-progress[data-progress-text="42%"]:after{right:-121.88px}.pace .pace-progress[data-progress-text="43%"]:after{right:-120.02px}.pace .pace-progress[data-progress-text="44%"]:after{right:-118.16px}.pace .pace-progress[data-progress-text="45%"]:after{right:-116.3px}.pace .pace-progress[data-progress-text="46%"]:after{right:-114.44px}.pace .pace-progress[data-progress-text="47%"]:after{right:-112.58px}.pace .pace-progress[data-progress-text="48%"]:after{right:-110.72px}.pace .pace-progress[data-progress-text="49%"]:after{right:-108.86px}.pace .pace-progress[data-progress-text="50%"]:after{right:-107px}.pace .pace-progress[data-progress-text="51%"]:after{right:-105.14px}.pace .pace-progress[data-progress-text="52%"]:after{right:-103.28px}.pace .pace-progress[data-progress-text="53%"]:after{right:-101.42px}.pace .pace-progress[data-progress-text="54%"]:after{right:-99.56px}.pace .pace-progress[data-progress-text="55%"]:after{right:-97.7px}.pace .pace-progress[data-progress-text="56%"]:after{right:-95.84px}.pace .pace-progress[data-progress-text="57%"]:after{right:-93.98px}.pace .pace-progress[data-progress-text="58%"]:after{right:-92.12px}.pace .pace-progress[data-progress-text="59%"]:after{right:-90.26px}.pace .pace-progress[data-progress-text="60%"]:after{right:-88.4px}.pace .pace-progress[data-progress-text="61%"]:after{right:-86.54px}.pace .pace-progress[data-progress-text="62%"]:after{right:-84.68px}.pace .pace-progress[data-progress-text="63%"]:after{right:-82.82px}.pace .pace-progress[data-progress-text="64%"]:after{right:-80.96px}.pace .pace-progress[data-progress-text="65%"]:after{right:-79.1px}.pace .pace-progress[data-progress-text="66%"]:after{right:-77.24px}.pace .pace-progress[data-progress-text="67%"]:after{right:-75.38px}.pace .pace-progress[data-progress-text="68%"]:after{right:-73.52px}.pace .pace-progress[data-progress-text="69%"]:after{right:-71.66px}.pace .pace-progress[data-progress-text="70%"]:after{right:-69.8px}.pace .pace-progress[data-progress-text="71%"]:after{right:-67.94px}.pace .pace-progress[data-progress-text="72%"]:after{right:-66.08px}.pace .pace-progress[data-progress-text="73%"]:after{right:-64.22px}.pace .pace-progress[data-progress-text="74%"]:after{right:-62.36px}.pace .pace-progress[data-progress-text="75%"]:after{right:-60.5px}.pace .pace-progress[data-progress-text="76%"]:after{right:-58.64px}.pace .pace-progress[data-progress-text="77%"]:after{right:-56.78px}.pace .pace-progress[data-progress-text="78%"]:after{right:-54.92px}.pace .pace-progress[data-progress-text="79%"]:after{right:-53.06px}.pace .pace-progress[data-progress-text="80%"]:after{right:-51.2px}.pace .pace-progress[data-progress-text="81%"]:after{right:-49.34px}.pace .pace-progress[data-progress-text="82%"]:after{right:-47.48px}.pace .pace-progress[data-progress-text="83%"]:after{right:-45.62px}.pace .pace-progress[data-progress-text="84%"]:after{right:-43.76px}.pace .pace-progress[data-progress-text="85%"]:after{right:-41.9px}.pace .pace-progress[data-progress-text="86%"]:after{right:-40.04px}.pace .pace-progress[data-progress-text="87%"]:after{right:-38.18px}.pace .pace-progress[data-progress-text="88%"]:after{right:-36.32px}.pace .pace-progress[data-progress-text="89%"]:after{right:-34.46px}.pace .pace-progress[data-progress-text="90%"]:after{right:-32.6px}.pace .pace-progress[data-progress-text="91%"]:after{right:-30.74px}.pace .pace-progress[data-progress-text="92%"]:after{right:-28.88px}.pace .pace-progress[data-progress-text="93%"]:after{right:-27.02px}.pace .pace-progress[data-progress-text="94%"]:after{right:-25.16px}.pace .pace-progress[data-progress-text="95%"]:after{right:-23.3px}.pace .pace-progress[data-progress-text="96%"]:after{right:-21.44px}.pace .pace-progress[data-progress-text="97%"]:after{right:-19.58px}.pace .pace-progress[data-progress-text="98%"]:after{right:-17.72px}.pace .pace-progress[data-progress-text="99%"]:after{right:-15.86px}.pace .pace-progress[data-progress-text="100%"]:after{right:-14px}.pace .pace-activity{position:absolute;width:100%;height:28px;z-index:2001;box-shadow:inset 0 0 0 2px #29d,inset 0 0 0 7px #FFF;border-radius:10px}.pace.pace-inactive{display:none} \ No newline at end of file diff --git a/lib/pace/pace-theme-mac-osx.min.css b/lib/pace/pace-theme-mac-osx.min.css new file mode 100644 index 0000000..4dfbb49 --- /dev/null +++ b/lib/pace/pace-theme-mac-osx.min.css @@ -0,0 +1 @@ +.pace,.pace .pace-progress{width:100%;height:12px;overflow:hidden}.pace,.pace .pace-activity{position:fixed;top:0;left:0}.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:2000;background:#fff}.pace-inactive{display:none}.pace .pace-progress{background-color:#0087E1;position:fixed;top:0;right:100%;-webkit-border-radius:0 0 4px;-moz-border-radius:0 0 4px;-o-border-radius:0 0 4px;border-radius:0 0 4px;-webkit-box-shadow:inset -1px 0 #00558F,inset 0 -1px #00558F,inset 0 2px rgba(255,255,255,.5),inset 0 6px rgba(255,255,255,.3);-moz-box-shadow:inset -1px 0 #00558F,inset 0 -1px #00558F,inset 0 2px rgba(255,255,255,.5),inset 0 6px rgba(255,255,255,.3);-o-box-shadow:inset -1px 0 #00558F,inset 0 -1px #00558F,inset 0 2px rgba(255,255,255,.5),inset 0 6px rgba(255,255,255,.3);box-shadow:inset -1px 0 #00558F,inset 0 -1px #00558F,inset 0 2px rgba(255,255,255,.5),inset 0 6px rgba(255,255,255,.3)}.pace .pace-activity{right:-28px;bottom:0;-webkit-background-image:radial-gradient(rgba(255,255,255,.65) 0,rgba(255,255,255,.15) 100%);-moz-background-image:radial-gradient(rgba(255,255,255,.65) 0,rgba(255,255,255,.15) 100%);-o-background-image:radial-gradient(rgba(255,255,255,.65) 0,rgba(255,255,255,.15) 100%);background-image:radial-gradient(rgba(255,255,255,.65) 0,rgba(255,255,255,.15) 100%);-webkit-background-size:28px 100%;-moz-background-size:28px 100%;-o-background-size:28px 100%;background-size:28px 100%;-webkit-animation:pace-theme-mac-osx-motion .5s linear infinite;-moz-animation:pace-theme-mac-osx-motion .5s linear infinite;-ms-animation:pace-theme-mac-osx-motion .5s linear infinite;-o-animation:pace-theme-mac-osx-motion .5s linear infinite;animation:pace-theme-mac-osx-motion .5s linear infinite}@-webkit-keyframes pace-theme-mac-osx-motion{0%{-webkit-transform:none;transform:none}100%{-webkit-transform:translate(-28px,0);transform:translate(-28px,0)}}@-moz-keyframes pace-theme-mac-osx-motion{0%{-moz-transform:none;transform:none}100%{-moz-transform:translate(-28px,0);transform:translate(-28px,0)}}@-o-keyframes pace-theme-mac-osx-motion{0%{-o-transform:none;transform:none}100%{-o-transform:translate(-28px,0);transform:translate(-28px,0)}}@-ms-keyframes pace-theme-mac-osx-motion{0%{-ms-transform:none;transform:none}100%{-ms-transform:translate(-28px,0);transform:translate(-28px,0)}}@keyframes pace-theme-mac-osx-motion{0%{transform:none}100%{transform:translate(-28px,0)}} \ No newline at end of file diff --git a/lib/pace/pace-theme-material.min.css b/lib/pace/pace-theme-material.min.css new file mode 100644 index 0000000..5f2920b --- /dev/null +++ b/lib/pace/pace-theme-material.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#29d}.pace-progress{position:fixed;z-index:2000;top:50%;left:50%;margin-left:-2.5rem;margin-top:-2.5rem;height:5rem;width:5rem;opacity:1;-webkit-transition:opacity .1s;transition:opacity .1s;-webkit-transform:translate3d(0,0,0)!important;-ms-transform:translate3d(0,0,0)!important;transform:translate3d(0,0,0)!important}.pace-inactive .pace-progress,.pace-progress[data-progress="00"]{opacity:0}.pace-progress:after{height:5rem;width:5rem;text-align:center;line-height:5rem;content:attr(data-progress);display:block;font-size:1.8rem;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:300}.pace-progress .pace-progress-inner{overflow:hidden;position:absolute;width:2.5rem;height:5rem;-webkit-transform-origin:left center;-ms-transform-origin:left center;transform-origin:left center;-webkit-transition:-webkit-transform .1s;transition:transform .1s;left:2.5rem;top:0}.pace-progress .pace-progress-inner:after,.pace-progress .pace-progress-inner:before{position:absolute;width:5rem;height:5rem;content:' ';left:-2.5rem;top:0;box-sizing:border-box;border:1px solid;border-radius:5rem}.pace-progress .pace-progress-inner:before{border-right-color:transparent;border-bottom-color:transparent;-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg)}.pace-progress .pace-progress-inner:after{border-left-color:transparent;border-top-color:transparent;display:none;-webkit-transform:rotate(315deg);-ms-transform:rotate(315deg);transform:rotate(315deg)}.pace-progress[data-progress="00"] .pace-progress-inner:before{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.pace-progress[data-progress="01"] .pace-progress-inner:before{-webkit-transform:rotate(-41deg);-ms-transform:rotate(-41deg);transform:rotate(-41deg)}.pace-progress[data-progress="02"] .pace-progress-inner:before{-webkit-transform:rotate(-38deg);-ms-transform:rotate(-38deg);transform:rotate(-38deg)}.pace-progress[data-progress="03"] .pace-progress-inner:before{-webkit-transform:rotate(-34deg);-ms-transform:rotate(-34deg);transform:rotate(-34deg)}.pace-progress[data-progress="04"] .pace-progress-inner:before{-webkit-transform:rotate(-31deg);-ms-transform:rotate(-31deg);transform:rotate(-31deg)}.pace-progress[data-progress="05"] .pace-progress-inner:before{-webkit-transform:rotate(-27deg);-ms-transform:rotate(-27deg);transform:rotate(-27deg)}.pace-progress[data-progress="06"] .pace-progress-inner:before{-webkit-transform:rotate(-23deg);-ms-transform:rotate(-23deg);transform:rotate(-23deg)}.pace-progress[data-progress="07"] .pace-progress-inner:before{-webkit-transform:rotate(-20deg);-ms-transform:rotate(-20deg);transform:rotate(-20deg)}.pace-progress[data-progress="08"] .pace-progress-inner:before{-webkit-transform:rotate(-16deg);-ms-transform:rotate(-16deg);transform:rotate(-16deg)}.pace-progress[data-progress="09"] .pace-progress-inner:before{-webkit-transform:rotate(-13deg);-ms-transform:rotate(-13deg);transform:rotate(-13deg)}.pace-progress[data-progress="10"] .pace-progress-inner:before{-webkit-transform:rotate(-9deg);-ms-transform:rotate(-9deg);transform:rotate(-9deg)}.pace-progress[data-progress="11"] .pace-progress-inner:before{-webkit-transform:rotate(-5deg);-ms-transform:rotate(-5deg);transform:rotate(-5deg)}.pace-progress[data-progress="12"] .pace-progress-inner:before{-webkit-transform:rotate(-2deg);-ms-transform:rotate(-2deg);transform:rotate(-2deg)}.pace-progress[data-progress="13"] .pace-progress-inner:before{-webkit-transform:rotate(2deg);-ms-transform:rotate(2deg);transform:rotate(2deg)}.pace-progress[data-progress="14"] .pace-progress-inner:before{-webkit-transform:rotate(5deg);-ms-transform:rotate(5deg);transform:rotate(5deg)}.pace-progress[data-progress="15"] .pace-progress-inner:before{-webkit-transform:rotate(9deg);-ms-transform:rotate(9deg);transform:rotate(9deg)}.pace-progress[data-progress="16"] .pace-progress-inner:before{-webkit-transform:rotate(13deg);-ms-transform:rotate(13deg);transform:rotate(13deg)}.pace-progress[data-progress="17"] .pace-progress-inner:before{-webkit-transform:rotate(16deg);-ms-transform:rotate(16deg);transform:rotate(16deg)}.pace-progress[data-progress="18"] .pace-progress-inner:before{-webkit-transform:rotate(20deg);-ms-transform:rotate(20deg);transform:rotate(20deg)}.pace-progress[data-progress="19"] .pace-progress-inner:before{-webkit-transform:rotate(23deg);-ms-transform:rotate(23deg);transform:rotate(23deg)}.pace-progress[data-progress="20"] .pace-progress-inner:before{-webkit-transform:rotate(27deg);-ms-transform:rotate(27deg);transform:rotate(27deg)}.pace-progress[data-progress="21"] .pace-progress-inner:before{-webkit-transform:rotate(31deg);-ms-transform:rotate(31deg);transform:rotate(31deg)}.pace-progress[data-progress="22"] .pace-progress-inner:before{-webkit-transform:rotate(34deg);-ms-transform:rotate(34deg);transform:rotate(34deg)}.pace-progress[data-progress="23"] .pace-progress-inner:before{-webkit-transform:rotate(38deg);-ms-transform:rotate(38deg);transform:rotate(38deg)}.pace-progress[data-progress="24"] .pace-progress-inner:before{-webkit-transform:rotate(41deg);-ms-transform:rotate(41deg);transform:rotate(41deg)}.pace-progress[data-progress="25"] .pace-progress-inner:before{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.pace-progress[data-progress="26"] .pace-progress-inner:before{-webkit-transform:rotate(49deg);-ms-transform:rotate(49deg);transform:rotate(49deg)}.pace-progress[data-progress="27"] .pace-progress-inner:before{-webkit-transform:rotate(52deg);-ms-transform:rotate(52deg);transform:rotate(52deg)}.pace-progress[data-progress="28"] .pace-progress-inner:before{-webkit-transform:rotate(56deg);-ms-transform:rotate(56deg);transform:rotate(56deg)}.pace-progress[data-progress="29"] .pace-progress-inner:before{-webkit-transform:rotate(59deg);-ms-transform:rotate(59deg);transform:rotate(59deg)}.pace-progress[data-progress="30"] .pace-progress-inner:before{-webkit-transform:rotate(63deg);-ms-transform:rotate(63deg);transform:rotate(63deg)}.pace-progress[data-progress="31"] .pace-progress-inner:before{-webkit-transform:rotate(67deg);-ms-transform:rotate(67deg);transform:rotate(67deg)}.pace-progress[data-progress="32"] .pace-progress-inner:before{-webkit-transform:rotate(70deg);-ms-transform:rotate(70deg);transform:rotate(70deg)}.pace-progress[data-progress="33"] .pace-progress-inner:before{-webkit-transform:rotate(74deg);-ms-transform:rotate(74deg);transform:rotate(74deg)}.pace-progress[data-progress="34"] .pace-progress-inner:before{-webkit-transform:rotate(77deg);-ms-transform:rotate(77deg);transform:rotate(77deg)}.pace-progress[data-progress="35"] .pace-progress-inner:before{-webkit-transform:rotate(81deg);-ms-transform:rotate(81deg);transform:rotate(81deg)}.pace-progress[data-progress="36"] .pace-progress-inner:before{-webkit-transform:rotate(85deg);-ms-transform:rotate(85deg);transform:rotate(85deg)}.pace-progress[data-progress="37"] .pace-progress-inner:before{-webkit-transform:rotate(88deg);-ms-transform:rotate(88deg);transform:rotate(88deg)}.pace-progress[data-progress="38"] .pace-progress-inner:before{-webkit-transform:rotate(92deg);-ms-transform:rotate(92deg);transform:rotate(92deg)}.pace-progress[data-progress="39"] .pace-progress-inner:before{-webkit-transform:rotate(95deg);-ms-transform:rotate(95deg);transform:rotate(95deg)}.pace-progress[data-progress="40"] .pace-progress-inner:before{-webkit-transform:rotate(99deg);-ms-transform:rotate(99deg);transform:rotate(99deg)}.pace-progress[data-progress="41"] .pace-progress-inner:before{-webkit-transform:rotate(103deg);-ms-transform:rotate(103deg);transform:rotate(103deg)}.pace-progress[data-progress="42"] .pace-progress-inner:before{-webkit-transform:rotate(106deg);-ms-transform:rotate(106deg);transform:rotate(106deg)}.pace-progress[data-progress="43"] .pace-progress-inner:before{-webkit-transform:rotate(110deg);-ms-transform:rotate(110deg);transform:rotate(110deg)}.pace-progress[data-progress="44"] .pace-progress-inner:before{-webkit-transform:rotate(113deg);-ms-transform:rotate(113deg);transform:rotate(113deg)}.pace-progress[data-progress="45"] .pace-progress-inner:before{-webkit-transform:rotate(117deg);-ms-transform:rotate(117deg);transform:rotate(117deg)}.pace-progress[data-progress="46"] .pace-progress-inner:before{-webkit-transform:rotate(121deg);-ms-transform:rotate(121deg);transform:rotate(121deg)}.pace-progress[data-progress="47"] .pace-progress-inner:before{-webkit-transform:rotate(124deg);-ms-transform:rotate(124deg);transform:rotate(124deg)}.pace-progress[data-progress="48"] .pace-progress-inner:before{-webkit-transform:rotate(128deg);-ms-transform:rotate(128deg);transform:rotate(128deg)}.pace-progress[data-progress="49"] .pace-progress-inner:before{-webkit-transform:rotate(131deg);-ms-transform:rotate(131deg);transform:rotate(131deg)}.pace-progress[data-progress="50"] .pace-progress-inner:before{-webkit-transform:rotate(135deg);-ms-transform:rotate(135deg);transform:rotate(135deg)}.pace-progress[data-progress="50"] .pace-progress-inner:after{-webkit-transform:rotate(315deg);-ms-transform:rotate(315deg);transform:rotate(315deg);display:block}.pace-progress[data-progress="51"] .pace-progress-inner:after{-webkit-transform:rotate(319deg);-ms-transform:rotate(319deg);transform:rotate(319deg);display:block}.pace-progress[data-progress="52"] .pace-progress-inner:after{-webkit-transform:rotate(322deg);-ms-transform:rotate(322deg);transform:rotate(322deg);display:block}.pace-progress[data-progress="53"] .pace-progress-inner:after{-webkit-transform:rotate(326deg);-ms-transform:rotate(326deg);transform:rotate(326deg);display:block}.pace-progress[data-progress="54"] .pace-progress-inner:after{-webkit-transform:rotate(329deg);-ms-transform:rotate(329deg);transform:rotate(329deg);display:block}.pace-progress[data-progress="55"] .pace-progress-inner:after{-webkit-transform:rotate(333deg);-ms-transform:rotate(333deg);transform:rotate(333deg);display:block}.pace-progress[data-progress="56"] .pace-progress-inner:after{-webkit-transform:rotate(337deg);-ms-transform:rotate(337deg);transform:rotate(337deg);display:block}.pace-progress[data-progress="57"] .pace-progress-inner:after{-webkit-transform:rotate(340deg);-ms-transform:rotate(340deg);transform:rotate(340deg);display:block}.pace-progress[data-progress="58"] .pace-progress-inner:after{-webkit-transform:rotate(344deg);-ms-transform:rotate(344deg);transform:rotate(344deg);display:block}.pace-progress[data-progress="59"] .pace-progress-inner:after{-webkit-transform:rotate(347deg);-ms-transform:rotate(347deg);transform:rotate(347deg);display:block}.pace-progress[data-progress="60"] .pace-progress-inner:after{-webkit-transform:rotate(351deg);-ms-transform:rotate(351deg);transform:rotate(351deg);display:block}.pace-progress[data-progress="61"] .pace-progress-inner:after{-webkit-transform:rotate(355deg);-ms-transform:rotate(355deg);transform:rotate(355deg);display:block}.pace-progress[data-progress="62"] .pace-progress-inner:after{-webkit-transform:rotate(358deg);-ms-transform:rotate(358deg);transform:rotate(358deg);display:block}.pace-progress[data-progress="63"] .pace-progress-inner:after{-webkit-transform:rotate(362deg);-ms-transform:rotate(362deg);transform:rotate(362deg);display:block}.pace-progress[data-progress="64"] .pace-progress-inner:after{-webkit-transform:rotate(365deg);-ms-transform:rotate(365deg);transform:rotate(365deg);display:block}.pace-progress[data-progress="65"] .pace-progress-inner:after{-webkit-transform:rotate(369deg);-ms-transform:rotate(369deg);transform:rotate(369deg);display:block}.pace-progress[data-progress="66"] .pace-progress-inner:after{-webkit-transform:rotate(373deg);-ms-transform:rotate(373deg);transform:rotate(373deg);display:block}.pace-progress[data-progress="67"] .pace-progress-inner:after{-webkit-transform:rotate(376deg);-ms-transform:rotate(376deg);transform:rotate(376deg);display:block}.pace-progress[data-progress="68"] .pace-progress-inner:after{-webkit-transform:rotate(380deg);-ms-transform:rotate(380deg);transform:rotate(380deg);display:block}.pace-progress[data-progress="69"] .pace-progress-inner:after{-webkit-transform:rotate(383deg);-ms-transform:rotate(383deg);transform:rotate(383deg);display:block}.pace-progress[data-progress="70"] .pace-progress-inner:after{-webkit-transform:rotate(387deg);-ms-transform:rotate(387deg);transform:rotate(387deg);display:block}.pace-progress[data-progress="71"] .pace-progress-inner:after{-webkit-transform:rotate(391deg);-ms-transform:rotate(391deg);transform:rotate(391deg);display:block}.pace-progress[data-progress="72"] .pace-progress-inner:after{-webkit-transform:rotate(394deg);-ms-transform:rotate(394deg);transform:rotate(394deg);display:block}.pace-progress[data-progress="73"] .pace-progress-inner:after{-webkit-transform:rotate(398deg);-ms-transform:rotate(398deg);transform:rotate(398deg);display:block}.pace-progress[data-progress="74"] .pace-progress-inner:after{-webkit-transform:rotate(401deg);-ms-transform:rotate(401deg);transform:rotate(401deg);display:block}.pace-progress[data-progress="75"] .pace-progress-inner:after{-webkit-transform:rotate(405deg);-ms-transform:rotate(405deg);transform:rotate(405deg);display:block}.pace-progress[data-progress="76"] .pace-progress-inner:after{-webkit-transform:rotate(409deg);-ms-transform:rotate(409deg);transform:rotate(409deg);display:block}.pace-progress[data-progress="77"] .pace-progress-inner:after{-webkit-transform:rotate(412deg);-ms-transform:rotate(412deg);transform:rotate(412deg);display:block}.pace-progress[data-progress="78"] .pace-progress-inner:after{-webkit-transform:rotate(416deg);-ms-transform:rotate(416deg);transform:rotate(416deg);display:block}.pace-progress[data-progress="79"] .pace-progress-inner:after{-webkit-transform:rotate(419deg);-ms-transform:rotate(419deg);transform:rotate(419deg);display:block}.pace-progress[data-progress="80"] .pace-progress-inner:after{-webkit-transform:rotate(423deg);-ms-transform:rotate(423deg);transform:rotate(423deg);display:block}.pace-progress[data-progress="81"] .pace-progress-inner:after{-webkit-transform:rotate(427deg);-ms-transform:rotate(427deg);transform:rotate(427deg);display:block}.pace-progress[data-progress="82"] .pace-progress-inner:after{-webkit-transform:rotate(430deg);-ms-transform:rotate(430deg);transform:rotate(430deg);display:block}.pace-progress[data-progress="83"] .pace-progress-inner:after{-webkit-transform:rotate(434deg);-ms-transform:rotate(434deg);transform:rotate(434deg);display:block}.pace-progress[data-progress="84"] .pace-progress-inner:after{-webkit-transform:rotate(437deg);-ms-transform:rotate(437deg);transform:rotate(437deg);display:block}.pace-progress[data-progress="85"] .pace-progress-inner:after{-webkit-transform:rotate(441deg);-ms-transform:rotate(441deg);transform:rotate(441deg);display:block}.pace-progress[data-progress="86"] .pace-progress-inner:after{-webkit-transform:rotate(445deg);-ms-transform:rotate(445deg);transform:rotate(445deg);display:block}.pace-progress[data-progress="87"] .pace-progress-inner:after{-webkit-transform:rotate(448deg);-ms-transform:rotate(448deg);transform:rotate(448deg);display:block}.pace-progress[data-progress="88"] .pace-progress-inner:after{-webkit-transform:rotate(452deg);-ms-transform:rotate(452deg);transform:rotate(452deg);display:block}.pace-progress[data-progress="89"] .pace-progress-inner:after{-webkit-transform:rotate(455deg);-ms-transform:rotate(455deg);transform:rotate(455deg);display:block}.pace-progress[data-progress="90"] .pace-progress-inner:after{-webkit-transform:rotate(459deg);-ms-transform:rotate(459deg);transform:rotate(459deg);display:block}.pace-progress[data-progress="91"] .pace-progress-inner:after{-webkit-transform:rotate(463deg);-ms-transform:rotate(463deg);transform:rotate(463deg);display:block}.pace-progress[data-progress="92"] .pace-progress-inner:after{-webkit-transform:rotate(466deg);-ms-transform:rotate(466deg);transform:rotate(466deg);display:block}.pace-progress[data-progress="93"] .pace-progress-inner:after{-webkit-transform:rotate(470deg);-ms-transform:rotate(470deg);transform:rotate(470deg);display:block}.pace-progress[data-progress="94"] .pace-progress-inner:after{-webkit-transform:rotate(473deg);-ms-transform:rotate(473deg);transform:rotate(473deg);display:block}.pace-progress[data-progress="95"] .pace-progress-inner:after{-webkit-transform:rotate(477deg);-ms-transform:rotate(477deg);transform:rotate(477deg);display:block}.pace-progress[data-progress="96"] .pace-progress-inner:after{-webkit-transform:rotate(481deg);-ms-transform:rotate(481deg);transform:rotate(481deg);display:block}.pace-progress[data-progress="97"] .pace-progress-inner:after{-webkit-transform:rotate(484deg);-ms-transform:rotate(484deg);transform:rotate(484deg);display:block}.pace-progress[data-progress="98"] .pace-progress-inner:after{-webkit-transform:rotate(488deg);-ms-transform:rotate(488deg);transform:rotate(488deg);display:block}.pace-progress[data-progress="99"] .pace-progress-inner:after{-webkit-transform:rotate(491deg);-ms-transform:rotate(491deg);transform:rotate(491deg);display:block}.pace-progress[data-progress="100"] .pace-progress-inner:after{-webkit-transform:rotate(495deg);-ms-transform:rotate(495deg);transform:rotate(495deg);display:block}.pace-progress[data-progress="00"] .pace-progress-inner{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}.pace-progress[data-progress="01"] .pace-progress-inner{-webkit-transform:rotate(4deg);-ms-transform:rotate(4deg);transform:rotate(4deg)}.pace-progress[data-progress="02"] .pace-progress-inner{-webkit-transform:rotate(7deg);-ms-transform:rotate(7deg);transform:rotate(7deg)}.pace-progress[data-progress="03"] .pace-progress-inner{-webkit-transform:rotate(11deg);-ms-transform:rotate(11deg);transform:rotate(11deg)}.pace-progress[data-progress="04"] .pace-progress-inner{-webkit-transform:rotate(14deg);-ms-transform:rotate(14deg);transform:rotate(14deg)}.pace-progress[data-progress="05"] .pace-progress-inner{-webkit-transform:rotate(18deg);-ms-transform:rotate(18deg);transform:rotate(18deg)}.pace-progress[data-progress="06"] .pace-progress-inner{-webkit-transform:rotate(22deg);-ms-transform:rotate(22deg);transform:rotate(22deg)}.pace-progress[data-progress="07"] .pace-progress-inner{-webkit-transform:rotate(25deg);-ms-transform:rotate(25deg);transform:rotate(25deg)}.pace-progress[data-progress="08"] .pace-progress-inner{-webkit-transform:rotate(29deg);-ms-transform:rotate(29deg);transform:rotate(29deg)}.pace-progress[data-progress="09"] .pace-progress-inner{-webkit-transform:rotate(32deg);-ms-transform:rotate(32deg);transform:rotate(32deg)}.pace-progress[data-progress="10"] .pace-progress-inner{-webkit-transform:rotate(36deg);-ms-transform:rotate(36deg);transform:rotate(36deg)}.pace-progress[data-progress="11"] .pace-progress-inner{-webkit-transform:rotate(40deg);-ms-transform:rotate(40deg);transform:rotate(40deg)}.pace-progress[data-progress="12"] .pace-progress-inner{-webkit-transform:rotate(43deg);-ms-transform:rotate(43deg);transform:rotate(43deg)}.pace-progress[data-progress="13"] .pace-progress-inner{-webkit-transform:rotate(47deg);-ms-transform:rotate(47deg);transform:rotate(47deg)}.pace-progress[data-progress="14"] .pace-progress-inner{-webkit-transform:rotate(50deg);-ms-transform:rotate(50deg);transform:rotate(50deg)}.pace-progress[data-progress="15"] .pace-progress-inner{-webkit-transform:rotate(54deg);-ms-transform:rotate(54deg);transform:rotate(54deg)}.pace-progress[data-progress="16"] .pace-progress-inner{-webkit-transform:rotate(58deg);-ms-transform:rotate(58deg);transform:rotate(58deg)}.pace-progress[data-progress="17"] .pace-progress-inner{-webkit-transform:rotate(61deg);-ms-transform:rotate(61deg);transform:rotate(61deg)}.pace-progress[data-progress="18"] .pace-progress-inner{-webkit-transform:rotate(65deg);-ms-transform:rotate(65deg);transform:rotate(65deg)}.pace-progress[data-progress="19"] .pace-progress-inner{-webkit-transform:rotate(68deg);-ms-transform:rotate(68deg);transform:rotate(68deg)}.pace-progress[data-progress="20"] .pace-progress-inner{-webkit-transform:rotate(72deg);-ms-transform:rotate(72deg);transform:rotate(72deg)}.pace-progress[data-progress="21"] .pace-progress-inner{-webkit-transform:rotate(76deg);-ms-transform:rotate(76deg);transform:rotate(76deg)}.pace-progress[data-progress="22"] .pace-progress-inner{-webkit-transform:rotate(79deg);-ms-transform:rotate(79deg);transform:rotate(79deg)}.pace-progress[data-progress="23"] .pace-progress-inner{-webkit-transform:rotate(83deg);-ms-transform:rotate(83deg);transform:rotate(83deg)}.pace-progress[data-progress="24"] .pace-progress-inner{-webkit-transform:rotate(86deg);-ms-transform:rotate(86deg);transform:rotate(86deg)}.pace-progress[data-progress="25"] .pace-progress-inner{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.pace-progress[data-progress="26"] .pace-progress-inner{-webkit-transform:rotate(94deg);-ms-transform:rotate(94deg);transform:rotate(94deg)}.pace-progress[data-progress="27"] .pace-progress-inner{-webkit-transform:rotate(97deg);-ms-transform:rotate(97deg);transform:rotate(97deg)}.pace-progress[data-progress="28"] .pace-progress-inner{-webkit-transform:rotate(101deg);-ms-transform:rotate(101deg);transform:rotate(101deg)}.pace-progress[data-progress="29"] .pace-progress-inner{-webkit-transform:rotate(104deg);-ms-transform:rotate(104deg);transform:rotate(104deg)}.pace-progress[data-progress="30"] .pace-progress-inner{-webkit-transform:rotate(108deg);-ms-transform:rotate(108deg);transform:rotate(108deg)}.pace-progress[data-progress="31"] .pace-progress-inner{-webkit-transform:rotate(112deg);-ms-transform:rotate(112deg);transform:rotate(112deg)}.pace-progress[data-progress="32"] .pace-progress-inner{-webkit-transform:rotate(115deg);-ms-transform:rotate(115deg);transform:rotate(115deg)}.pace-progress[data-progress="33"] .pace-progress-inner{-webkit-transform:rotate(119deg);-ms-transform:rotate(119deg);transform:rotate(119deg)}.pace-progress[data-progress="34"] .pace-progress-inner{-webkit-transform:rotate(122deg);-ms-transform:rotate(122deg);transform:rotate(122deg)}.pace-progress[data-progress="35"] .pace-progress-inner{-webkit-transform:rotate(126deg);-ms-transform:rotate(126deg);transform:rotate(126deg)}.pace-progress[data-progress="36"] .pace-progress-inner{-webkit-transform:rotate(130deg);-ms-transform:rotate(130deg);transform:rotate(130deg)}.pace-progress[data-progress="37"] .pace-progress-inner{-webkit-transform:rotate(133deg);-ms-transform:rotate(133deg);transform:rotate(133deg)}.pace-progress[data-progress="38"] .pace-progress-inner{-webkit-transform:rotate(137deg);-ms-transform:rotate(137deg);transform:rotate(137deg)}.pace-progress[data-progress="39"] .pace-progress-inner{-webkit-transform:rotate(140deg);-ms-transform:rotate(140deg);transform:rotate(140deg)}.pace-progress[data-progress="40"] .pace-progress-inner{-webkit-transform:rotate(144deg);-ms-transform:rotate(144deg);transform:rotate(144deg)}.pace-progress[data-progress="41"] .pace-progress-inner{-webkit-transform:rotate(148deg);-ms-transform:rotate(148deg);transform:rotate(148deg)}.pace-progress[data-progress="42"] .pace-progress-inner{-webkit-transform:rotate(151deg);-ms-transform:rotate(151deg);transform:rotate(151deg)}.pace-progress[data-progress="43"] .pace-progress-inner{-webkit-transform:rotate(155deg);-ms-transform:rotate(155deg);transform:rotate(155deg)}.pace-progress[data-progress="44"] .pace-progress-inner{-webkit-transform:rotate(158deg);-ms-transform:rotate(158deg);transform:rotate(158deg)}.pace-progress[data-progress="45"] .pace-progress-inner{-webkit-transform:rotate(162deg);-ms-transform:rotate(162deg);transform:rotate(162deg)}.pace-progress[data-progress="46"] .pace-progress-inner{-webkit-transform:rotate(166deg);-ms-transform:rotate(166deg);transform:rotate(166deg)}.pace-progress[data-progress="47"] .pace-progress-inner{-webkit-transform:rotate(169deg);-ms-transform:rotate(169deg);transform:rotate(169deg)}.pace-progress[data-progress="48"] .pace-progress-inner{-webkit-transform:rotate(173deg);-ms-transform:rotate(173deg);transform:rotate(173deg)}.pace-progress[data-progress="49"] .pace-progress-inner{-webkit-transform:rotate(176deg);-ms-transform:rotate(176deg);transform:rotate(176deg)}.pace-progress[data-progress="50"] .pace-progress-inner{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.pace-progress[data-progress="51"] .pace-progress-inner{-webkit-transform:rotate(184deg);-ms-transform:rotate(184deg);transform:rotate(184deg);overflow:visible}.pace-progress[data-progress="52"] .pace-progress-inner{-webkit-transform:rotate(187deg);-ms-transform:rotate(187deg);transform:rotate(187deg);overflow:visible}.pace-progress[data-progress="53"] .pace-progress-inner{-webkit-transform:rotate(191deg);-ms-transform:rotate(191deg);transform:rotate(191deg);overflow:visible}.pace-progress[data-progress="54"] .pace-progress-inner{-webkit-transform:rotate(194deg);-ms-transform:rotate(194deg);transform:rotate(194deg);overflow:visible}.pace-progress[data-progress="55"] .pace-progress-inner{-webkit-transform:rotate(198deg);-ms-transform:rotate(198deg);transform:rotate(198deg);overflow:visible}.pace-progress[data-progress="56"] .pace-progress-inner{-webkit-transform:rotate(202deg);-ms-transform:rotate(202deg);transform:rotate(202deg);overflow:visible}.pace-progress[data-progress="57"] .pace-progress-inner{-webkit-transform:rotate(205deg);-ms-transform:rotate(205deg);transform:rotate(205deg);overflow:visible}.pace-progress[data-progress="58"] .pace-progress-inner{-webkit-transform:rotate(209deg);-ms-transform:rotate(209deg);transform:rotate(209deg);overflow:visible}.pace-progress[data-progress="59"] .pace-progress-inner{-webkit-transform:rotate(212deg);-ms-transform:rotate(212deg);transform:rotate(212deg);overflow:visible}.pace-progress[data-progress="60"] .pace-progress-inner{-webkit-transform:rotate(216deg);-ms-transform:rotate(216deg);transform:rotate(216deg);overflow:visible}.pace-progress[data-progress="61"] .pace-progress-inner{-webkit-transform:rotate(220deg);-ms-transform:rotate(220deg);transform:rotate(220deg);overflow:visible}.pace-progress[data-progress="62"] .pace-progress-inner{-webkit-transform:rotate(223deg);-ms-transform:rotate(223deg);transform:rotate(223deg);overflow:visible}.pace-progress[data-progress="63"] .pace-progress-inner{-webkit-transform:rotate(227deg);-ms-transform:rotate(227deg);transform:rotate(227deg);overflow:visible}.pace-progress[data-progress="64"] .pace-progress-inner{-webkit-transform:rotate(230deg);-ms-transform:rotate(230deg);transform:rotate(230deg);overflow:visible}.pace-progress[data-progress="65"] .pace-progress-inner{-webkit-transform:rotate(234deg);-ms-transform:rotate(234deg);transform:rotate(234deg);overflow:visible}.pace-progress[data-progress="66"] .pace-progress-inner{-webkit-transform:rotate(238deg);-ms-transform:rotate(238deg);transform:rotate(238deg);overflow:visible}.pace-progress[data-progress="67"] .pace-progress-inner{-webkit-transform:rotate(241deg);-ms-transform:rotate(241deg);transform:rotate(241deg);overflow:visible}.pace-progress[data-progress="68"] .pace-progress-inner{-webkit-transform:rotate(245deg);-ms-transform:rotate(245deg);transform:rotate(245deg);overflow:visible}.pace-progress[data-progress="69"] .pace-progress-inner{-webkit-transform:rotate(248deg);-ms-transform:rotate(248deg);transform:rotate(248deg);overflow:visible}.pace-progress[data-progress="70"] .pace-progress-inner{-webkit-transform:rotate(252deg);-ms-transform:rotate(252deg);transform:rotate(252deg);overflow:visible}.pace-progress[data-progress="71"] .pace-progress-inner{-webkit-transform:rotate(256deg);-ms-transform:rotate(256deg);transform:rotate(256deg);overflow:visible}.pace-progress[data-progress="72"] .pace-progress-inner{-webkit-transform:rotate(259deg);-ms-transform:rotate(259deg);transform:rotate(259deg);overflow:visible}.pace-progress[data-progress="73"] .pace-progress-inner{-webkit-transform:rotate(263deg);-ms-transform:rotate(263deg);transform:rotate(263deg);overflow:visible}.pace-progress[data-progress="74"] .pace-progress-inner{-webkit-transform:rotate(266deg);-ms-transform:rotate(266deg);transform:rotate(266deg);overflow:visible}.pace-progress[data-progress="75"] .pace-progress-inner{-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg);overflow:visible}.pace-progress[data-progress="76"] .pace-progress-inner{-webkit-transform:rotate(274deg);-ms-transform:rotate(274deg);transform:rotate(274deg);overflow:visible}.pace-progress[data-progress="77"] .pace-progress-inner{-webkit-transform:rotate(277deg);-ms-transform:rotate(277deg);transform:rotate(277deg);overflow:visible}.pace-progress[data-progress="78"] .pace-progress-inner{-webkit-transform:rotate(281deg);-ms-transform:rotate(281deg);transform:rotate(281deg);overflow:visible}.pace-progress[data-progress="79"] .pace-progress-inner{-webkit-transform:rotate(284deg);-ms-transform:rotate(284deg);transform:rotate(284deg);overflow:visible}.pace-progress[data-progress="80"] .pace-progress-inner{-webkit-transform:rotate(288deg);-ms-transform:rotate(288deg);transform:rotate(288deg);overflow:visible}.pace-progress[data-progress="81"] .pace-progress-inner{-webkit-transform:rotate(292deg);-ms-transform:rotate(292deg);transform:rotate(292deg);overflow:visible}.pace-progress[data-progress="82"] .pace-progress-inner{-webkit-transform:rotate(295deg);-ms-transform:rotate(295deg);transform:rotate(295deg);overflow:visible}.pace-progress[data-progress="83"] .pace-progress-inner{-webkit-transform:rotate(299deg);-ms-transform:rotate(299deg);transform:rotate(299deg);overflow:visible}.pace-progress[data-progress="84"] .pace-progress-inner{-webkit-transform:rotate(302deg);-ms-transform:rotate(302deg);transform:rotate(302deg);overflow:visible}.pace-progress[data-progress="85"] .pace-progress-inner{-webkit-transform:rotate(306deg);-ms-transform:rotate(306deg);transform:rotate(306deg);overflow:visible}.pace-progress[data-progress="86"] .pace-progress-inner{-webkit-transform:rotate(310deg);-ms-transform:rotate(310deg);transform:rotate(310deg);overflow:visible}.pace-progress[data-progress="87"] .pace-progress-inner{-webkit-transform:rotate(313deg);-ms-transform:rotate(313deg);transform:rotate(313deg);overflow:visible}.pace-progress[data-progress="88"] .pace-progress-inner{-webkit-transform:rotate(317deg);-ms-transform:rotate(317deg);transform:rotate(317deg);overflow:visible}.pace-progress[data-progress="89"] .pace-progress-inner{-webkit-transform:rotate(320deg);-ms-transform:rotate(320deg);transform:rotate(320deg);overflow:visible}.pace-progress[data-progress="90"] .pace-progress-inner{-webkit-transform:rotate(324deg);-ms-transform:rotate(324deg);transform:rotate(324deg);overflow:visible}.pace-progress[data-progress="91"] .pace-progress-inner{-webkit-transform:rotate(328deg);-ms-transform:rotate(328deg);transform:rotate(328deg);overflow:visible}.pace-progress[data-progress="92"] .pace-progress-inner{-webkit-transform:rotate(331deg);-ms-transform:rotate(331deg);transform:rotate(331deg);overflow:visible}.pace-progress[data-progress="93"] .pace-progress-inner{-webkit-transform:rotate(335deg);-ms-transform:rotate(335deg);transform:rotate(335deg);overflow:visible}.pace-progress[data-progress="94"] .pace-progress-inner{-webkit-transform:rotate(338deg);-ms-transform:rotate(338deg);transform:rotate(338deg);overflow:visible}.pace-progress[data-progress="95"] .pace-progress-inner{-webkit-transform:rotate(342deg);-ms-transform:rotate(342deg);transform:rotate(342deg);overflow:visible}.pace-progress[data-progress="96"] .pace-progress-inner{-webkit-transform:rotate(346deg);-ms-transform:rotate(346deg);transform:rotate(346deg);overflow:visible}.pace-progress[data-progress="97"] .pace-progress-inner{-webkit-transform:rotate(349deg);-ms-transform:rotate(349deg);transform:rotate(349deg);overflow:visible}.pace-progress[data-progress="98"] .pace-progress-inner{-webkit-transform:rotate(353deg);-ms-transform:rotate(353deg);transform:rotate(353deg);overflow:visible}.pace-progress[data-progress="99"] .pace-progress-inner{-webkit-transform:rotate(356deg);-ms-transform:rotate(356deg);transform:rotate(356deg);overflow:visible}.pace-progress[data-progress="100"] .pace-progress-inner{-webkit-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg);overflow:visible} diff --git a/lib/pace/pace-theme-minimal.min.css b/lib/pace/pace-theme-minimal.min.css new file mode 100644 index 0000000..1c15936 --- /dev/null +++ b/lib/pace/pace-theme-minimal.min.css @@ -0,0 +1 @@ +.pace{-webkit-pointer-events:none;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.pace-inactive{display:none}.pace .pace-progress{background:#29d;position:fixed;z-index:2000;top:0;right:100%;width:100%;height:2px} \ No newline at end of file diff --git a/lib/pace/pace.min.js b/lib/pace/pace.min.js new file mode 100644 index 0000000..234f9b3 --- /dev/null +++ b/lib/pace/pace.min.js @@ -0,0 +1,2 @@ +/*! pace 1.0.2 */ +(function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X=[].slice,Y={}.hasOwnProperty,Z=function(a,b){function c(){this.constructor=a}for(var d in b)Y.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},$=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};for(u={catchupTime:100,initialRate:.03,minTime:250,ghostTime:100,maxProgressPerFrame:20,easeFactor:1.25,startOnPageLoad:!0,restartOnPushState:!0,restartOnRequestAfter:500,target:"body",elements:{checkInterval:100,selectors:["body"]},eventLag:{minSamples:10,sampleCount:3,lagThreshold:3},ajax:{trackMethods:["GET"],trackWebSockets:!0,ignoreURLs:[]}},C=function(){var a;return null!=(a="undefined"!=typeof performance&&null!==performance&&"function"==typeof performance.now?performance.now():void 0)?a:+new Date},E=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,t=window.cancelAnimationFrame||window.mozCancelAnimationFrame,null==E&&(E=function(a){return setTimeout(a,50)},t=function(a){return clearTimeout(a)}),G=function(a){var b,c;return b=C(),(c=function(){var d;return d=C()-b,d>=33?(b=C(),a(d,function(){return E(c)})):setTimeout(c,33-d)})()},F=function(){var a,b,c;return c=arguments[0],b=arguments[1],a=3<=arguments.length?X.call(arguments,2):[],"function"==typeof c[b]?c[b].apply(c,a):c[b]},v=function(){var a,b,c,d,e,f,g;for(b=arguments[0],d=2<=arguments.length?X.call(arguments,1):[],f=0,g=d.length;g>f;f++)if(c=d[f])for(a in c)Y.call(c,a)&&(e=c[a],null!=b[a]&&"object"==typeof b[a]&&null!=e&&"object"==typeof e?v(b[a],e):b[a]=e);return b},q=function(a){var b,c,d,e,f;for(c=b=0,e=0,f=a.length;f>e;e++)d=a[e],c+=Math.abs(d),b++;return c/b},x=function(a,b){var c,d,e;if(null==a&&(a="options"),null==b&&(b=!0),e=document.querySelector("[data-pace-"+a+"]")){if(c=e.getAttribute("data-pace-"+a),!b)return c;try{return JSON.parse(c)}catch(f){return d=f,"undefined"!=typeof console&&null!==console?console.error("Error parsing inline pace options",d):void 0}}},g=function(){function a(){}return a.prototype.on=function(a,b,c,d){var e;return null==d&&(d=!1),null==this.bindings&&(this.bindings={}),null==(e=this.bindings)[a]&&(e[a]=[]),this.bindings[a].push({handler:b,ctx:c,once:d})},a.prototype.once=function(a,b,c){return this.on(a,b,c,!0)},a.prototype.off=function(a,b){var c,d,e;if(null!=(null!=(d=this.bindings)?d[a]:void 0)){if(null==b)return delete this.bindings[a];for(c=0,e=[];cQ;Q++)K=U[Q],D[K]===!0&&(D[K]=u[K]);i=function(a){function b(){return V=b.__super__.constructor.apply(this,arguments)}return Z(b,a),b}(Error),b=function(){function a(){this.progress=0}return a.prototype.getElement=function(){var a;if(null==this.el){if(a=document.querySelector(D.target),!a)throw new i;this.el=document.createElement("div"),this.el.className="pace pace-active",document.body.className=document.body.className.replace(/pace-done/g,""),document.body.className+=" pace-running",this.el.innerHTML='
\n
\n
\n
',null!=a.firstChild?a.insertBefore(this.el,a.firstChild):a.appendChild(this.el)}return this.el},a.prototype.finish=function(){var a;return a=this.getElement(),a.className=a.className.replace("pace-active",""),a.className+=" pace-inactive",document.body.className=document.body.className.replace("pace-running",""),document.body.className+=" pace-done"},a.prototype.update=function(a){return this.progress=a,this.render()},a.prototype.destroy=function(){try{this.getElement().parentNode.removeChild(this.getElement())}catch(a){i=a}return this.el=void 0},a.prototype.render=function(){var a,b,c,d,e,f,g;if(null==document.querySelector(D.target))return!1;for(a=this.getElement(),d="translate3d("+this.progress+"%, 0, 0)",g=["webkitTransform","msTransform","transform"],e=0,f=g.length;f>e;e++)b=g[e],a.children[0].style[b]=d;return(!this.lastRenderedProgress||this.lastRenderedProgress|0!==this.progress|0)&&(a.children[0].setAttribute("data-progress-text",""+(0|this.progress)+"%"),this.progress>=100?c="99":(c=this.progress<10?"0":"",c+=0|this.progress),a.children[0].setAttribute("data-progress",""+c)),this.lastRenderedProgress=this.progress},a.prototype.done=function(){return this.progress>=100},a}(),h=function(){function a(){this.bindings={}}return a.prototype.trigger=function(a,b){var c,d,e,f,g;if(null!=this.bindings[a]){for(f=this.bindings[a],g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(c.call(this,b));return g}},a.prototype.on=function(a,b){var c;return null==(c=this.bindings)[a]&&(c[a]=[]),this.bindings[a].push(b)},a}(),P=window.XMLHttpRequest,O=window.XDomainRequest,N=window.WebSocket,w=function(a,b){var c,d,e;e=[];for(d in b.prototype)try{e.push(null==a[d]&&"function"!=typeof b[d]?"function"==typeof Object.defineProperty?Object.defineProperty(a,d,{get:function(){return b.prototype[d]},configurable:!0,enumerable:!0}):a[d]=b.prototype[d]:void 0)}catch(f){c=f}return e},A=[],j.ignore=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?X.call(arguments,1):[],A.unshift("ignore"),c=b.apply(null,a),A.shift(),c},j.track=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?X.call(arguments,1):[],A.unshift("track"),c=b.apply(null,a),A.shift(),c},J=function(a){var b;if(null==a&&(a="GET"),"track"===A[0])return"force";if(!A.length&&D.ajax){if("socket"===a&&D.ajax.trackWebSockets)return!0;if(b=a.toUpperCase(),$.call(D.ajax.trackMethods,b)>=0)return!0}return!1},k=function(a){function b(){var a,c=this;b.__super__.constructor.apply(this,arguments),a=function(a){var b;return b=a.open,a.open=function(d,e){return J(d)&&c.trigger("request",{type:d,url:e,request:a}),b.apply(a,arguments)}},window.XMLHttpRequest=function(b){var c;return c=new P(b),a(c),c};try{w(window.XMLHttpRequest,P)}catch(d){}if(null!=O){window.XDomainRequest=function(){var b;return b=new O,a(b),b};try{w(window.XDomainRequest,O)}catch(d){}}if(null!=N&&D.ajax.trackWebSockets){window.WebSocket=function(a,b){var d;return d=null!=b?new N(a,b):new N(a),J("socket")&&c.trigger("request",{type:"socket",url:a,protocols:b,request:d}),d};try{w(window.WebSocket,N)}catch(d){}}}return Z(b,a),b}(h),R=null,y=function(){return null==R&&(R=new k),R},I=function(a){var b,c,d,e;for(e=D.ajax.ignoreURLs,c=0,d=e.length;d>c;c++)if(b=e[c],"string"==typeof b){if(-1!==a.indexOf(b))return!0}else if(b.test(a))return!0;return!1},y().on("request",function(b){var c,d,e,f,g;return f=b.type,e=b.request,g=b.url,I(g)?void 0:j.running||D.restartOnRequestAfter===!1&&"force"!==J(f)?void 0:(d=arguments,c=D.restartOnRequestAfter||0,"boolean"==typeof c&&(c=0),setTimeout(function(){var b,c,g,h,i,k;if(b="socket"===f?e.readyState<2:0<(h=e.readyState)&&4>h){for(j.restart(),i=j.sources,k=[],c=0,g=i.length;g>c;c++){if(K=i[c],K instanceof a){K.watch.apply(K,d);break}k.push(void 0)}return k}},c))}),a=function(){function a(){var a=this;this.elements=[],y().on("request",function(){return a.watch.apply(a,arguments)})}return a.prototype.watch=function(a){var b,c,d,e;return d=a.type,b=a.request,e=a.url,I(e)?void 0:(c="socket"===d?new n(b):new o(b),this.elements.push(c))},a}(),o=function(){function a(a){var b,c,d,e,f,g,h=this;if(this.progress=0,null!=window.ProgressEvent)for(c=null,a.addEventListener("progress",function(a){return h.progress=a.lengthComputable?100*a.loaded/a.total:h.progress+(100-h.progress)/2},!1),g=["load","abort","timeout","error"],d=0,e=g.length;e>d;d++)b=g[d],a.addEventListener(b,function(){return h.progress=100},!1);else f=a.onreadystatechange,a.onreadystatechange=function(){var b;return 0===(b=a.readyState)||4===b?h.progress=100:3===a.readyState&&(h.progress=50),"function"==typeof f?f.apply(null,arguments):void 0}}return a}(),n=function(){function a(a){var b,c,d,e,f=this;for(this.progress=0,e=["error","open"],c=0,d=e.length;d>c;c++)b=e[c],a.addEventListener(b,function(){return f.progress=100},!1)}return a}(),d=function(){function a(a){var b,c,d,f;for(null==a&&(a={}),this.elements=[],null==a.selectors&&(a.selectors=[]),f=a.selectors,c=0,d=f.length;d>c;c++)b=f[c],this.elements.push(new e(b))}return a}(),e=function(){function a(a){this.selector=a,this.progress=0,this.check()}return a.prototype.check=function(){var a=this;return document.querySelector(this.selector)?this.done():setTimeout(function(){return a.check()},D.elements.checkInterval)},a.prototype.done=function(){return this.progress=100},a}(),c=function(){function a(){var a,b,c=this;this.progress=null!=(b=this.states[document.readyState])?b:100,a=document.onreadystatechange,document.onreadystatechange=function(){return null!=c.states[document.readyState]&&(c.progress=c.states[document.readyState]),"function"==typeof a?a.apply(null,arguments):void 0}}return a.prototype.states={loading:0,interactive:50,complete:100},a}(),f=function(){function a(){var a,b,c,d,e,f=this;this.progress=0,a=0,e=[],d=0,c=C(),b=setInterval(function(){var g;return g=C()-c-50,c=C(),e.push(g),e.length>D.eventLag.sampleCount&&e.shift(),a=q(e),++d>=D.eventLag.minSamples&&a=100&&(this.done=!0),b===this.last?this.sinceLastUpdate+=a:(this.sinceLastUpdate&&(this.rate=(b-this.last)/this.sinceLastUpdate),this.catchup=(b-this.progress)/D.catchupTime,this.sinceLastUpdate=0,this.last=b),b>this.progress&&(this.progress+=this.catchup*a),c=1-Math.pow(this.progress/100,D.easeFactor),this.progress+=c*this.rate*a,this.progress=Math.min(this.lastProgress+D.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},a}(),L=null,H=null,r=null,M=null,p=null,s=null,j.running=!1,z=function(){return D.restartOnPushState?j.restart():void 0},null!=window.history.pushState&&(T=window.history.pushState,window.history.pushState=function(){return z(),T.apply(window.history,arguments)}),null!=window.history.replaceState&&(W=window.history.replaceState,window.history.replaceState=function(){return z(),W.apply(window.history,arguments)}),l={ajax:a,elements:d,document:c,eventLag:f},(B=function(){var a,c,d,e,f,g,h,i;for(j.sources=L=[],g=["ajax","elements","document","eventLag"],c=0,e=g.length;e>c;c++)a=g[c],D[a]!==!1&&L.push(new l[a](D[a]));for(i=null!=(h=D.extraSources)?h:[],d=0,f=i.length;f>d;d++)K=i[d],L.push(new K(D));return j.bar=r=new b,H=[],M=new m})(),j.stop=function(){return j.trigger("stop"),j.running=!1,r.destroy(),s=!0,null!=p&&("function"==typeof t&&t(p),p=null),B()},j.restart=function(){return j.trigger("restart"),j.stop(),j.start()},j.go=function(){var a;return j.running=!0,r.render(),a=C(),s=!1,p=G(function(b,c){var d,e,f,g,h,i,k,l,n,o,p,q,t,u,v,w;for(l=100-r.progress,e=p=0,f=!0,i=q=0,u=L.length;u>q;i=++q)for(K=L[i],o=null!=H[i]?H[i]:H[i]=[],h=null!=(w=K.elements)?w:[K],k=t=0,v=h.length;v>t;k=++t)g=h[k],n=null!=o[k]?o[k]:o[k]=new m(g),f&=n.done,n.done||(e++,p+=n.tick(b));return d=p/e,r.update(M.tick(b,d)),r.done()||f||s?(r.update(100),j.trigger("done"),setTimeout(function(){return r.finish(),j.running=!1,j.trigger("hide")},Math.max(D.ghostTime,Math.max(D.minTime-(C()-a),0)))):c()})},j.start=function(a){v(D,a),j.running=!0;try{r.render()}catch(b){i=b}return document.querySelector(".pace")?(j.trigger("start"),j.go()):setTimeout(j.start,50)},"function"==typeof define&&define.amd?define(["pace"],function(){return j}):"object"==typeof exports?module.exports=j:D.startOnPageLoad&&j.start()}).call(this); \ No newline at end of file diff --git a/links/index.html b/links/index.html new file mode 100644 index 0000000..ac22ce9 --- /dev/null +++ b/links/index.html @@ -0,0 +1,16 @@ +友情链接 | 随言碎语

随言碎语

咕叽咕叽

友情链接

排名不分先后,每次刷新会随机排列。


留言互换友链 o ((>ω<)) o

友链格式

0%
\ No newline at end of file diff --git a/links/linklist.json b/links/linklist.json new file mode 100644 index 0000000..83fc1f0 --- /dev/null +++ b/links/linklist.json @@ -0,0 +1 @@ +[{"name":"如鱼饮水,冷暖自知","site":"https://wangjiezhe.com","avatar":"https://gravatar.loli.net/avatar/e09cf54e933e5a690716e68961ff3b1c?s=512"},{"name":"如鱼饮水,冷暖自知","site":"https://wangjiezhe.com","avatar":"https://gravatar.loli.net/avatar/e09cf54e933e5a690716e68961ff3b1c?s=512"},{"name":"如鱼饮水,冷暖自知","site":"https://wangjiezhe.com","avatar":"https://gravatar.loli.net/avatar/e09cf54e933e5a690716e68961ff3b1c?s=512"}] \ No newline at end of file diff --git a/placeholder b/placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/search.xml b/search.xml new file mode 100644 index 0000000..5add895 --- /dev/null +++ b/search.xml @@ -0,0 +1,476 @@ + + + + esxi+openwrt+dsm+homeassistant 软路由 all in one + /2023/03/23/esxi+openwrt+dsm+homeassistant-%E8%BD%AF%E8%B7%AF%E7%94%B1all-in-one/ + 软路由 all in one,在J425小主机上安装esxi+openwrt+dsm+homeassistant,集软路由、网盘、智能家居控制于一体。

+ + +

硬件介绍

软件安装

    +
  1. esxi8.0安装
  2. +
  3. esxi+openwrt作为旁路由
  4. +
  5. esxi安装群晖dsm7.1
  6. +
  7. esxi安装homeassistant
  8. +
+]]>
+ + esxi + homeassistant + openwrt + dsm + 软路由 + 群晖 + +
+ + esxi常规配置 + /2023/03/26/esxi%E5%B8%B8%E8%A7%84%E9%85%8D%E7%BD%AE/ + esxi修改网卡顺序、网卡直通、修改安全策略、开机自动启动虚拟机。

+ + +

修改网卡顺序

系统中网卡的显示顺序可能和实际的对应不上,可以修改相关的配置文件,让其能和实际的端口对上。

+

先确定当前的顺序,以及希望修改后的顺序:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
实际网口名称ESXi中默认网口名称希望的网口名称
eth0vmnic1vmnic0
eth1vmnic2vmnic1
eth2vmnic0vmnic2
eth3vmnic3vmnic3
+
    +
  1. 开启维护模式,和ssh连接。

    +
  2. +
  3. 查看系统中当前pci和逻辑pci对应的网卡名称

    +
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias list
    Bus type Bus address Alias
    ------------------------------------
    pci m00008501 vmnic0
    pci m00008901 vmhba0
    pci p0000:04:00.0 vmnic3
    pci s00000003.00 vmnic1
    pci p0000:02:00.0 vmnic2
    logical pci#s00000003.00#0 vmnic1
    logical pci#m00008501#0 vmnic0
    logical pci#m00008901#0 vmhba0
    logical pci#p0000:02:00.0#0 vmnic2
    logical pci#p0000:04:00.0#0 vmnic3

  4. +
  5. 修改网卡名称,这里pci和逻辑pci对应的名称要同时修改,并且要一致。

    +
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic0 --bus-address s00000003.00
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic0 --bus-address "pci#s00000003.00#0"

    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic1 --bus-address p0000:02:00.0
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic1 --bus-address "pci#p0000:02:00.0#0"

    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type pci --alias vmnic2 --bus-address m00008501
    [root@bogon:~] localcli --plugin-dir /usr/lib/vmware/esxcli/int/ deviceInternal alias store --bus-type logical --alias vmnic2 --bus-address "pci#m00008501#0"

  6. +
  7. 重启机器

    +
  8. +
+

网卡直通

安装软路由时,需要将网卡直通,从而发挥网卡的最大性能。

+
    +
  1. 进入esxi的管理页面

    +

    image-20230422142105492

    +
  2. +
+

注:至少要保留一个网口,用来作为esxi的管理网口,否则将无法登录esxi

+
+ +
    +
  1. 选择需要直通的网口,进行切换即可
  2. +
+

修改安全策略

可能会出现虚拟机和esxi之间相互ping不通的情况,这是由于esxi的安全策略导致的

+
    +
  1. 依次点击网络->虚拟交换机->编辑vSwith0

    +

    image-20230422143110862

    +
  2. +
  3. 将安全选项中,混杂模式和伪传输改为接受

    +
  4. +
+

开机自动启动虚拟机

设置开启后自动启动虚拟机,以及启动顺序

+

1.依次点击主机->管理->系统->自动启动->编辑设置,将总开关打开

+

image-20230422143559690

+

2.选择虚拟机,设置是否开机自启、调整启动的顺序和延迟启动时间。

+
    +
  • 注:这里最好错开启动,不要同时启动,由依赖的虚拟机先启动。
  • +
+]]>
+ + esxi + 软路由 + +
+ + esxi安装homeassistant + /2023/03/24/esxi%E5%AE%89%E8%A3%85homeassistant/ + 在esxi上安装homeassistant

+ + +

准备

]]>
+ + esxi + homeassistant + +
+ + esxi+openwrt作为旁路由 + /2023/03/24/esxi%E5%AE%89%E8%A3%85openwrt/ + 在esxi上安装openwrt,并作为旁路由来使用。

+ + +

准备

    +
  • starwindconverter.exe 用来将img转换为VMDK
  • +
  • openwrt-x86-64-generic-squashfs-combined-efi.img.gz openwrt固件包
  • +
+

1. 构建/获取openWRT

这里推荐使用supes.top 自己选择需要的固件,然后进行构建。5分钟左右就能获取到自定义的固件。

+
    +
  1. 访问supes.top 官网
  2. +
+

image-20230422145319548

+
    +
  1. 自己根据需求去构建,或者是直接下载构建好的通用包

    +

    image-20230422145651697

    +
  2. +
+
    +
  • 注:目前免费的用户,一天之内只能构建一次,有需求的可充值解锁。
  • +
+

2. 转换固件为vmdk格式

    +
  1. 解压openwrt-x86-64-generic-squashfs-combined-efi.img.gz

    +
  2. +
  3. 解压后的文件是openwrt-x86-64-generic-squashfs-combined-efi.img,这个格式是无法在esxi中直接使用的,因此需要转一下

    +
  4. +
  5. 安装starwindconverter.exe ,没啥可交代的,一路next即可。

    +
  6. +
  7. 打开安装好的starwindconverter软件,选择local file->next

    +

    image-20230422150336027

    +
  8. +
  9. 选择解压后的openwrt-x86-64-generic-squashfs-combined-efi.img

    +

    image-20230422150500119

    +
  10. +
  11. 还是选择local file

    +
  12. +
+

image-20230422150951371

+
    +
  1. 选择VMDK

    +

    image-20230422151034204

    +
  2. +
  3. 选择ESXI Server image

    +

    image-20230422151136889

    +
  4. +
+

9.选择** ESXI pre-allocates image**

+

image-20230422151215810

+

10.选择输出的路径和名称,点击conver

+

image-20230422151331578

+

11.转换完成后,会出来两个大小不一样的文件

+

image-20230422151557911

+

3. 创建虚拟机

    +
  1. 进入esxi的管理页面,依次点击虚拟机->创建虚拟机

    +

    image-20230422151821830

    +
  2. +
  3. 选择名称和客户机操作系统

    +

    image-20230422152710801

    +
  4. +
+

客户机操作系统系列: 选择Linux,客户机操作系统版本:其他Linux(64位)

+
    +
  1. 选择存储,如果由多块硬盘,可选择安装的位置

    +

    image-20230422152842237

    +
  2. +
  3. 内存设置为1G,删除掉硬盘以及其他不需要的设备

    +

    image-20230422153126229

    +
  4. +
  5. 添加硬盘->现有硬盘

    +

    image-20230422153403639

    +
  6. +
  7. 将转换后的两个vmdk文件全部都上传上去(只会显示1个),然后选择上传的文件

    +

    image-20230422153716292

    +
      +
    • 注:如果需要网卡直通,可点击添加其他设备->PCI设备。

      +
    • +
    • 如果由多个网卡,但是这里无法点击,说明这个设别没有进行直通。如何直通可参考之前的文章 esxi常规配置

      +

      image-20230422154249143

      +
    • +
    +
  8. +
  9. 点击下一步,确认一下配置,无误后点击完成即可。

    +
  10. +
  11. 选中虚拟机,点击打开电源,等待开机

    +

    image-20230422154411639

    +
  12. +
  13. 点击进入操作台,可看到openwrt已经正常启动,在浏览器中输入IP地址即可访问openwrt的管理页面。

    +

    image-20230422154700759

    +
  14. +
+

4. 配置opwrt作为旁路由

由于是作为旁路由来使用的,所有wan口是不需要的,只需要LAN即可。

+
    +
  1. 进入openwrt的管理页面,依次点击网络->接口,将wan和wan6全部删除掉。
  2. +
+

image-20230422161227530

+

注:删除后,不要点击 保存并应用!!! 不要点击 保存并应用!!! 不要点击 保存并应用!!!

+
+ +
    +
  1. 点击设备,选择br-lan,点击配置…
  2. +
+

image-20230422161705488

+
    +
  1. 网桥端口中,将所有的网卡都勾选上

    +

    image-20230422161814059

    +
  2. +
  3. 回到接口页面,编辑lan

    +

    image-20230422161955936

    +
  4. +
  5. 确认里面的设备是br-lan

    +

    image-20230422162141208

    +
  6. +
  7. 保存后,点击最外层的保存并应用

    +

    image-20230422162251244

    +
  8. +
  9. 网络连接正常后,配置自己需要的服务,然后需要这些服务的设备,将openwrt作为网关就可以了。

    +
  10. +
+

5. 问题

    +
  1. 为什么不作为主路由使用,而是选择旁路由?

    +
    1。主要还是看各自的需要来决定的,各有利弊。
    2.对我来说,只是想用一下它的插件功能,例如广告拦截,proxy等。
    3.即便是软路由整体挂了,也不会影响家里的其他设别的正常使用。
  2. +
  3. 如何修改openwrt的地址?

    +
    1.修改lan口的ip地址

    [root@OpenWrt:03:52 PM ~] # cat /etc/config/network

    ....

    config interface 'lan'
    option device 'br-lan'
    option proto 'static'
    option netmask '255.255.255.0'
    option ip6assign '60'
    option ipaddr '10.1.100.254'
    option gateway '10.1.100.1'
    option dns '223.5.5.5'
    option delegate '0'

    ....

    2. 改完后保存退出,并reboot重启
  4. +
  5. 网卡直通后,无法访问openwrt的管理页面?

    +
  6. +
+
多张网卡直通后,可能会造成网卡识别混乱。
如果当前无法访问,把网线拔了,可换个网口再试试,肯定会有一个是能够访问的。
+ +]]>
+ + esxi + openwrt + 软路由 + 旁路由 + +
+ + esxi安装群晖dsm7.1 + /2023/03/24/esxi%E5%AE%89%E8%A3%85%E7%BE%A4%E6%99%96dsm7.1/ + 在esxi上安装DSM

+ + +

准备

]]>
+ + esxi + 群晖 + DSM + +
+ + esxi8.0安装 + /2023/03/23/esxi8.0%E5%AE%89%E8%A3%85/ + esxi 8.0的安装。

+ + + + +

准备工具

硬件:

+
    +
  • 8G以上U盘一个
  • +
  • 待安装的主机一套
  • +
+

软件:

+
    +
  • rufus-3.15p.exe 用来刻录镜像

    +
  • +
  • VMware-VMvisor-Installer-8.0.0-21203435.x86_64-Dell_Customized-A03.iso

    +

    注:这里使用的是DELL定制版本,其他版本可从官网下载。操作步骤都是一样的

    +
  • +
+

刻录镜像到启动U盘

    +
  1. 打开rufus-3.15p.exe
    image-20230422123404610
  2. +
  3. 依次选择U盘,选择镜像文件,点击开始。
  4. +
  5. 写入完成后拔下U盘。
  6. +
+

安装ESXI8.0

    +
  1. 将写好的U盘插到机器上,开机进入bios页面,选择从U盘启动。

    +
  2. +
  3. 在加载页面按 SHIFT+O (5秒倒计时结束前按)

    +

    image-20230422124229021

    +
  4. +
  5. 输入autoParititionOSDataSize=8192设置缓存大小

    +

    image-20230422130103695

    +
      +
    • 注:如果不设置的话,默认是划分120G
    • +
    +
  6. +
  7. 等待页面加载

    +

    image-20230422130452177

    +
  8. +
  9. 按回车确定,然后F11接受协议。

    +

    image-20230422130636232

    +
  10. +
  11. 选择安装的硬盘,建议安装到SSD盘

    +

    image-20230422131134063

    +
  12. +
  13. 如果之前安装过,会让选择安装方式。如果之前的不想要的,就直接选择第三个覆盖安装。(按空格选中,回车确定)

    +

    image-20230422131415703

    +
  14. +
  15. 键盘选择US Default

    +

    image-20230422131519284

    +
  16. +
  17. 设置root密码,并确认安装

    +

    image-20230422131707324

    +
  18. +
  19. 安装完成后,会提示拔出U盘并重启

    +

    image-20230422131850437

    +
  20. +
  21. 重启后显示下图的页面即表示成功了

    +

    image-20230422131945389

    +
  22. +
+

给ESXi 设置为静态 IP

    +
  1. 按 F2 进入,提示需要输入账户密码,用户名为 root,密码为刚刚安装时设置的密码,然后回车。

    +

    image-20230422132154911

    +
  2. +
  3. 选择**configure management network **

    +

    image-20230422132512778

    +
  4. +
  5. 然后选择 IPV4 configuration 回车

    +

    image-20230422132558114

    +
  6. +
  7. 接着移动光标到第三项,随后按空格键确定选择

    +
  8. +
  9. 接着填入你需要设置的 ESXi 静态 IP 地址。

    +

    image-20230422132853991

    +
  10. +
+

第一行填入 esxi 的静态 IP,第二行填入子网掩码 255.255.255.0,第三行填写路由器的网关地址,设置好后回车即可。

+
    +
  1. 打开浏览器,输入管理地址即可访问esxi系统

    +

    image-20230422133642869

    +
  2. +
+

设置管理网口(多网卡)

如果有多张网卡,可以指定哪个网口可以访问esxi的管理页面,没有指定的将无法访问。

+
    +
  1. F2进入后,依次选择**configure management network **->**Network Adapters **

    +

    image-20230422133918448

    +
  2. +
  3. 选择网卡,这里可以选择多个,如果只选择了某一个,以后就只有插在这个网口上的机器能访问管理页面。

    +

    image-20230422134113958

    +
  4. +
+]]>
+ + esxi + 软路由 + +
+ + VMware安装centos7 + /2020/01/03/VMware%E5%AE%89%E8%A3%85centos7/ + 在VMware Workstation上安装centos。

+ + + + +

1. 准备:

    +
  • VMware Workstation

    +
  • +
  • 镜像文件:CentOS-7-x86_64-bin-DVD1.iso

    +
  • +
+

2. 新建虚拟机

    +
  1. 新建虚拟机,选择自定义

    +
  2. +
  3. 硬盘兼容性–默认

    +
  4. +
+

image-20230422105921574

+
    +
  1. 稍后安装操作系统(需要在虚拟机安装完成之后,删除不需要的硬件,所以稍后安装操作系统)

    +
  2. +
  3. 择客户端操作系统:客户机操作系统–Linux版本centos 64位

    +
  4. +
  5. 处理器配置(CPU)和内存,按需要配置

    +
  6. +
  7. 网络类型–桥接网络(可以使虚拟机与主机使用同一网络)

    +
  8. +
+
    +
  • 注:若是NAT和仅主机模式,需要注意网卡的地址,创建的虚拟机和所使用的网卡在同一个网段。
  • +
+
    +
  1. 选择I/O控制器类型、磁盘类型和创建新的虚拟磁盘(一般默认就行)

    +
  2. +
  3. 指定磁盘容量(不低于20G)

    +
  4. +
  5. 指定磁盘文件(.vmdk)文件

    +
  6. +
  7. 完成后,删除不必要的设备

    +

    image-20230422111309578

    +
  8. +
  9. 选中CD/DVD,使用ISO镜像文件-选择镜像文件

    +

    image-20230422111531776

    +
  10. +
+

12.确定后,打开这个虚拟机的电源

+

image-20230422114456361

+

3. 进入centos7安装页面

    +
  1. 选择install centos7
  2. +
+

image-20230422111901398

+
    +
  1. 设置语言–使用中文-简体中文–点击继续
  2. +
+

image-20230422114739708

+
    +
  • 注:如果这里选择了中文简体,那么键盘布局一定要选择英文
  • +
+
    +
  1. 进一步设置要安装的信息

    +

    image-20230422115039348

    +

    软件选择:这里我们选择最小化安装,即只有最基础的系统,没有桌面

    +

    image-20230422115156841

    +
  2. +
  3. 系统安装位置,点进去进行自定义分区(如果没有特别的要求,默认分区也行)

    +

    image-20230422115350829
    4.1 若需要自主分区,点击我要配置分区
    image-20230422115507917
    4.2 选择标准分组,点击**+**
    image-20230422115613958
    4.3 依次添加新挂载点:/boot;swap;/;
    image-20230422115944392
    注:

    +
      +
    • /boot 分区:是引导分区;作用:系统启动,在boot分区存放着grub,内核文件等,一般200M就够了。
    • +
    • swap交换分区:内存扩展分区;一般也就2G 。
    • +
    • / 根目录:10G左右,数据一般也不会直接放在根目录下。
    • +
    +

    4.4 点击完成,接受更改即可。

    +

    image-20230422120644423

    +
  4. +
  5. 关掉KDUMP

    +

    image-20230422120802249

    +
  6. +
  7. 配置网络和主机名

    +

    image-20230422120925893

    +

    网络要根据自己的环境和需求去配置,配置后点击保存即可。

    +
  8. +
  9. 安全策略保持默认的即可,直接点击开始安装

    +

    image-20230422121138262

    +
  10. +
  11. 设置用户名和密码(主要是设置root密码,创建用户可以不做)

    +

    image-20230422121219185

    +

    点击root密码,输入密码点击完成。

    +

    image-20230422121357933

    +
  12. +
  13. 点击重启,等待系统安装完成即可使用了

    +

    image-20230422121530317

    +
  14. +
+]]>
+ + VMware + centos + +
+ + Hello World + /2019/12/30/hello-world/ + 欢迎来到我的博客,这是我的第一篇博客,由hexo+next构建。

+]]>
+
+
diff --git a/tags/VMware/index.html b/tags/VMware/index.html new file mode 100644 index 0000000..7d69b68 --- /dev/null +++ b/tags/VMware/index.html @@ -0,0 +1,16 @@ +标签: VMware | 随言碎语

随言碎语

咕叽咕叽

VMware 标签

2020
0%
\ No newline at end of file diff --git a/tags/centos/index.html b/tags/centos/index.html new file mode 100644 index 0000000..706d40c --- /dev/null +++ b/tags/centos/index.html @@ -0,0 +1,16 @@ +标签: centos | 随言碎语

随言碎语

咕叽咕叽

centos 标签

2020
0%
\ No newline at end of file diff --git a/tags/dsm/index.html b/tags/dsm/index.html new file mode 100644 index 0000000..9d31bf5 --- /dev/null +++ b/tags/dsm/index.html @@ -0,0 +1,16 @@ +标签: DSM | 随言碎语

随言碎语

咕叽咕叽

DSM 标签

2023
0%
\ No newline at end of file diff --git a/tags/esxi/index.html b/tags/esxi/index.html new file mode 100644 index 0000000..231485e --- /dev/null +++ b/tags/esxi/index.html @@ -0,0 +1,16 @@ +标签: esxi | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/homeassistant/index.html b/tags/homeassistant/index.html new file mode 100644 index 0000000..247245c --- /dev/null +++ b/tags/homeassistant/index.html @@ -0,0 +1,16 @@ +标签: homeassistant | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/index.html b/tags/index.html new file mode 100644 index 0000000..717c2c6 --- /dev/null +++ b/tags/index.html @@ -0,0 +1,16 @@ +tags | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/openwrt/index.html b/tags/openwrt/index.html new file mode 100644 index 0000000..74b616a --- /dev/null +++ b/tags/openwrt/index.html @@ -0,0 +1,16 @@ +标签: openwrt | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/旁路由/index.html b/tags/旁路由/index.html new file mode 100644 index 0000000..0abd1f2 --- /dev/null +++ b/tags/旁路由/index.html @@ -0,0 +1,16 @@ +标签: 旁路由 | 随言碎语

随言碎语

咕叽咕叽

旁路由 标签

2023
0%
\ No newline at end of file diff --git a/tags/群晖/index.html b/tags/群晖/index.html new file mode 100644 index 0000000..d7ca537 --- /dev/null +++ b/tags/群晖/index.html @@ -0,0 +1,16 @@ +标签: 群晖 | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file diff --git a/tags/软路由/index.html b/tags/软路由/index.html new file mode 100644 index 0000000..3ddf5ef --- /dev/null +++ b/tags/软路由/index.html @@ -0,0 +1,16 @@ +标签: 软路由 | 随言碎语

随言碎语

咕叽咕叽

0%
\ No newline at end of file