diff --git a/README.md b/README.md
index 792c459..0f1146c 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,26 @@
# 编程导航
-> 最专业灵活的导航站点,发现优质编程学习资源!微信公众号『 编程导航 』
+> 最专业灵活的编程导航站,发现优质编程学习资源!微信公众号『 编程导航 』
-在线网站:https://www.code-nav.cn
+包含多个子项目,都开源给大家学习,使用这套代码,你也能轻松开发多端适配网站!
+编程导航主站 - 发现优质编程资源:https://www.code-nav.cn
+编程导航主页 - 程序员必备主页:https://home.code-nav.cn
-本项目是『 编程导航 』网站的开源版本,使用这套代码,你也能轻松开发多端适配网站!
-
-**当然目前代码中保留了部分业务隐私,后续会逐渐公开~**
+编程导航文档 - 项目使用指南和详情:https://doc.code-nav.cn
## 项目展示
-![编程导航](./doc/codeNav.png)
+[编程导航主站 - 发现优质编程资源](https://www.code-nav.cn)
+
+![推荐资源](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-recommend.png)
+
+[编程导航主页 - 程序员必备主页](https://home.code-nav.cn)
-![轻松生成你的专属炫酷主页](./doc/codeNavSelf.png)
+![透明主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home.png)
@@ -24,24 +28,28 @@
总是有很多学编程的朋友问我 “有没有学 xx 的资源”、“我需要 xx 资源,能发我一份么”。
-在重复接收到这样的讯息后,我发现如今编程资源获取的大环境雾气重重,有一些不太好的现象:
+在重复接收类似讯息后,我陷入深思。
-1. 很多名不副实的编程资源被捧上了天,一叶障目
-2. 好的编程资源被商业利益化,利用信息差,将本来免费的资源进行贩卖
+如今编程资源获取的大环境雾气重重,有很多不太好的现象:
+
+1. 很多名不副实的编程资源被捧上了天,名人效应、一叶障目
+2. 好的编程资源被商业利益化,很多人利用信息差,将本来免费的资源进行贩卖
3. 好的编程资源由于作者不出名,没有被人发现
4. 网上的编程资源非常零散,真实性、有效性很不确定
-意识到这些问题后,作为一个开发者,我可以做些什么?继续去网上搜好的资源,然后传到网盘上,分享给大家?
+意识到这些问题后,作为一个开发者,我可以做些什么? 继续去网上搜好的资源,然后传到网盘上,分享给大家?
+
+一个人的力量终归渺小,好的编程资源环境需要大家的共同努力。
-一个人的力量终归是渺小的,好的编程资源环境需要大家的共同努力。
+这是『 编程导航 』问世的原因:**提供人人皆可推荐的编程资源导航平台,帮助大家发现优质编程资源。**
-**这是『 编程导航 』问世的原因,提供一个人人皆可推荐的编程资源导航平台,帮助大家发现优质编程资源。**
+本质是 **资源碎片 => 列表化 => 文档化 => 系统化** 的过程。就像准备复习面试题一样,有人给你分享单一的面试题目(碎片)、有人分享题目列表(列表化)、有人分享一本面试小书(文档化),而这些在灵活性上远远不如一个 “可搜索”、“可复用”、“可量化” 、“可定制” 的 **资源系统**。
-本质是 **资源碎片 => 列表化 => 文档化 => 系统化** 的过程。就像准备复习面试题一样,有人给你分享单一的面试题目(碎片)、有人分享题目列表(列表化)、有人分享一本面试小书(文档化),而这些在灵活性上远远不如一个 “可搜索”、“可复用”、“可量化” 、“可定制” 的**资源系统**。
+**想象一下,当你想要学习算法时,在系统上轻轻一点,优质算法学习资源尽收眼底,不是很棒么?**
-**想象一下,当你想要学习算法时,在系统上轻轻一点,所有的优质算法学习资源尽收眼底,不是很棒么?**
+作者在腾讯顶着上班的压力,熬了一个月的大夜,终于完成了基础版本,欢迎大家体验、推荐资源、提出意见!
-作者现在就职腾讯,是一名全栈开发工程师,顶着上班的压力,熬了一个月的大夜,终于做出了一个基础版本,欢迎大家体验、推荐资源、提出意见!觉得不错的话,分享给身边的朋友吧~
+整个项目也开源给大家,可供学习。觉得不错的话,求个 star、分享给身边的朋友吧,这对我非常重要 😭 有你们的支持才有前进的动力!
@@ -57,168 +65,44 @@
-## 已有功能
-
-1. 优质资源推荐
-2. 资源全局搜索
-3. 资源添加
-4. 资源详情及相似推荐
-5. 个人主页,兴趣设置
-6. 喜欢、分享
-7. 生成定制主页
-8. 一键登录
-
-
-
-## 快速开始
-
-**请保证 Node.js 版本 > 10** ⚠️
-
-1. 下载项目到本地
-
- ```bash
- git clone https://github.com/liyupi/code-nav.git
- ```
-
-2. 安装依赖
-
- ```bash
- npm install
- ```
-
-3. 本地启动项目
-
- ```bash
- npm run start
- ```
-
-4. 点击右下角 `Umi UI` 按钮,可快速新建页面,海量模板供选择。
-
-
-
- ![仅开发环境可见的 Umi UI 按钮](./doc/umiButton.png)
-
- ![从模板新建页面](./doc/umiTmp.png)
-
- 如果模板图标无法加载,请在本地配置 hosts:`151.101.64.133 raw.githubusercontent.com`
-
- **新建页面后,如果要在菜单列表中显示,要在 `config/menu.tsx` 中添加配置。**
-
-5. 打包构建
-
- ```bash
- npm run build
- ```
-
- 会生成 dist 目录,可以通过 [serve 工具 ](https://www.npmjs.com/package/serve)本地启动 server 快速浏览。
-
-6. 部署
-
- 提供多种部署方式:
-
- 1. 容器(推荐):项目已提供 `Dockerfile` 可以轻松构建 `Docker` 镜像,并将容器部署在[云托管服务](https://cloud.tencent.com/document/product/876/46901)中,实现动态扩缩容。
- 2. 目录:直接将 `dist` 目录放到 `Nginx` 等 web 服务器上,配置 `nginx.conf` 即可。
- 3. 静态站点托管:可以直接将 `dist` 目录发布到[静态站点托管](https://cloud.tencent.com/document/product/876/46900)中,有 CDN 支持
-
-
-
-## 技术栈
+## 项目生态
-### 前端
+编程导航不仅仅是一个项目,而是以 "帮助大家发现优质编程资源,提升效率" 为目标的完整生态。
-前端使用 [Ant Design Pro V4](https://pro.ant.design/docs/getting-started-cn/) 后台管理模板,提升了百倍开发效率,**但是也踩了不少坑**~
+1. [编程导航主站](https://www.code-nav.cn) 🏡
-1. [Umi](https://umijs.org/zh-CN) + React 前端框架
-2. [Ant Design](https://ant.design/index-cn) 组件库 + [Ant Design Pro 高级组件](https://procomponents.ant.design/components)
-3. [Dva](https://dvajs.com/) 数据状态管理
-4. [Less](http://lesscss.cn/) CSS 预处理语言
-5. TypeScript 静态类型检查
+ 发现优质编程学习资源。可以检索自己需要的资源、分享好的资源,并对他人推荐的资源进行评价。好的资源会被更多人发现,让更多同学感受到技术带来的美好。
+2. [编程导航主页](https://home.code-nav.cn) 🔍
+ 极简的浏览器主页,支持万能搜索,提升效率,还可以定制壁纸和主页站点。
-### 后端
+3. [审核中心](https://doc.code-nav.cn/project/code-nav-review) 👮
-后端使用 [腾讯云云开发](https://cloud.tencent.com/product/tcb),全量上云,充分利用了腾讯云提供的云计算能力。
+ 提供资源、评论等内容的审核功能。
-1. 云数据库:配合 SDK 使用,无需编写重复的增删改查,提高开发效率,自动备份
-2. 云存储:配合 SDK 使用,易接入
-3. 云函数:开发复杂的函数,Serverless 架构,无需自行管理,可开放 Http 访问服务
-4. 云托管:容器技术,弹性伸缩、动态扩缩容
-5. 腾讯云 CMS 开箱即用的后台管理
+4. [编程导航文档](https://doc.code-nav.cn) 📚
-
+ 编程导航项目的使用指南和详细介绍。
-## 目录结构
-
-```
-.
-├── Dockerfile 容器构建文件
-├── Dockerfile.build 容器构建文件(包含 npm 打包流程)
-├── README.md 项目说明
-├── cloudbaserc.json 腾讯云云开发文件,需要用 tcb 根据自己的环境生成
-├── cloudfunctions 后端云函数
-│ └── helloworld
-├── config 配置
-│ ├── config.ts 全局配置
-│ ├── defaultSettings.ts 框架默认设置
-│ ├── menu.tsx 菜单列表
-│ ├── proxy.ts 代理
-│ └── routes.ts 定义路由
-├── docker 容器所需配置文件
-│ └── nginx.conf 服务器配置
-├── jsconfig.json 编译配置
-├── mock 假数据
-│ ├── forms.ts
-│ ├── resources.ts
-│ ├── tags.ts
-│ └── user.ts
-├── package.json 包管理文件
-├── public 公共目录
-│ └── logo.png
-├── src 前端项目主目录
-│ ├── assets 资源文件
-│ ├── cardList.less 卡片样式
-│ ├── components 组件
-│ ├── constant 常量
-│ ├── global.less 全局样式
-│ ├── global.tsx 全局入口
-│ ├── layouts 布局
-│ ├── manifest.json
-│ ├── models 数据模型
-│ ├── pages 页面
-│ ├── service-worker.js 缓存
-│ ├── services 业务请求
-│ ├── tcb.js 腾讯云云开发 SDK
-│ ├── typings.d.ts 类型定义
-│ └── utils 工具
-└── tsconfig.json
-```
+5. [微信公众号服务端](https://doc.code-nav.cn/project/code-nav-mp-server) 💻
-
+ 对接编程导航公众号,提供获取动态码、关注回复、动态菜单等功能。
-## 测试
+6. [编程导航微信公众号](https://doc.code-nav.cn/author)
-1. 前端使用 “伪 Mock 数据” 测试,如果使用 `UMI UI` 新建页面,框架将提供真实 Mock 测试数据。
-2. 如果使用腾讯云开发,可以在本地通过 `tcb` 命令测试云函数
+ 定期分享、介绍和评测优质编程资源,不要错过!
-```bash
-tcb fn run --name --params
-```
-
-
-
-## 开发技巧
-
-1. 使用全局 `LoadingLayout` 实现云开发、自动登录等前置条件加载
+7. 编程导航小程序(特喵的没过审,待调整)
## 版本
-| 日期 | 版本 | 开源率 | 详情 |
-| ------------------- | ---------- | ------ | -------- |
-| 2021 年 01 月 10 日 | 0.0.1 内测 | 70% | 首次开源 |
-
+| 日期 | 版本 | 详情 |
+| ------------------- | ---------- | ------------------------------------------------ |
+| 2021 年 01 月 10 日 | 0.0.1 内测 | 编程导航主站基本功能完成 |
+| 2021 年 01 月 20 日 | 0.0.2 公测 | 编程导航主站、编程导航主页、微信服务端上线,开源 |
diff --git a/.editorconfig b/code-nav-doc/.editorconfig
old mode 100644
new mode 100755
similarity index 100%
rename from .editorconfig
rename to code-nav-doc/.editorconfig
diff --git a/code-nav-doc/.fatherrc.ts b/code-nav-doc/.fatherrc.ts
new file mode 100644
index 0000000..cc3a27b
--- /dev/null
+++ b/code-nav-doc/.fatherrc.ts
@@ -0,0 +1,4 @@
+export default {
+ esm: 'rollup',
+ cjs: 'rollup',
+};
diff --git a/code-nav-doc/.gitignore b/code-nav-doc/.gitignore
new file mode 100644
index 0000000..82cff45
--- /dev/null
+++ b/code-nav-doc/.gitignore
@@ -0,0 +1,25 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/npm-debug.log*
+/yarn-error.log
+/yarn.lock
+/package-lock.json
+
+# production
+/dist
+/docs-dist
+
+# misc
+.DS_Store
+
+# umi
+.umi
+.umi-production
+.umi-test
+.env.local
+
+# ide
+/.vscode
+/.idea
diff --git a/code-nav-doc/.prettierignore b/code-nav-doc/.prettierignore
new file mode 100644
index 0000000..ecb24d3
--- /dev/null
+++ b/code-nav-doc/.prettierignore
@@ -0,0 +1,7 @@
+**/*.svg
+**/*.ejs
+**/*.html
+package.json
+.umi
+.umi-production
+.umi-test
diff --git a/code-nav-doc/.prettierrc b/code-nav-doc/.prettierrc
new file mode 100644
index 0000000..94beb14
--- /dev/null
+++ b/code-nav-doc/.prettierrc
@@ -0,0 +1,11 @@
+{
+ "singleQuote": true,
+ "trailingComma": "all",
+ "printWidth": 80,
+ "overrides": [
+ {
+ "files": ".prettierrc",
+ "options": { "parser": "json" }
+ }
+ ]
+}
diff --git a/code-nav-doc/.umirc.ts b/code-nav-doc/.umirc.ts
new file mode 100644
index 0000000..8cdcedb
--- /dev/null
+++ b/code-nav-doc/.umirc.ts
@@ -0,0 +1,22 @@
+import {defineConfig} from 'dumi';
+
+export default defineConfig({
+ title: '编程导航',
+ favicon: 'https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/img/1610990261129-favicon.png',
+ logo: 'https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/img/1610990216593-logo.3c8859f8.png',
+ outputPath: 'docs-dist',
+ mode: 'site',
+ analytics: {
+ baidu: 'eb44917eec45fb8f09c3ae111c5e62bc',
+ },
+ metas: [
+ {
+ name: 'keywords',
+ content: '编程,程序员,导航,资源,主页,编程导航'
+ },
+ {
+ name: 'description',
+ content: '编程导航,文档,最专业的程序员导航网站,发现优质编程学习资源,定制你的程序员必备主页,公众号编程导航'
+ },
+ ],
+});
diff --git a/code-nav-doc/README.md b/code-nav-doc/README.md
new file mode 100644
index 0000000..fa92a5e
--- /dev/null
+++ b/code-nav-doc/README.md
@@ -0,0 +1,27 @@
+# code-nav-doc
+
+## Getting Started
+
+Install dependencies,
+
+```bash
+$ npm i
+```
+
+Start the dev server,
+
+```bash
+$ npm start
+```
+
+Build documentation,
+
+```bash
+$ npm run docs:build
+```
+
+Build library via `father-build`,
+
+```bash
+$ npm run build
+```
diff --git a/code-nav-doc/docs/Author/index.md b/code-nav-doc/docs/Author/index.md
new file mode 100644
index 0000000..0621df4
--- /dev/null
+++ b/code-nav-doc/docs/Author/index.md
@@ -0,0 +1,27 @@
+---
+nav:
+ title: 作者
+ path: /author
+ order: 6
+toc: menu
+---
+
+# 关于作者
+
+作者正在腾讯打工,是一名全栈工程师,致力技术分享。
+
+全网 ID:程序员鱼皮、编程导航
+
+## 联系作者
+
+项目贡献、合作共进、交个朋友,戳作者微信叭,请备注来意!(上班比较忙未及时回复还请见谅)
+
+**编程导航微信**
+
+![编程导航微信](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/wechat.jpg)
+
+**编程导航公众号**
+
+![编程导航公众号](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/qrcode.jpg)
+
+
diff --git a/code-nav-doc/docs/GitHub/index.md b/code-nav-doc/docs/GitHub/index.md
new file mode 100644
index 0000000..229e0f2
--- /dev/null
+++ b/code-nav-doc/docs/GitHub/index.md
@@ -0,0 +1,6 @@
+---
+nav:
+ title: GitHub
+ path: https://github.com/liyupi/code-nav
+ order: 7
+---
diff --git a/code-nav-doc/docs/Guide/captcha.md b/code-nav-doc/docs/Guide/captcha.md
new file mode 100644
index 0000000..763ffd2
--- /dev/null
+++ b/code-nav-doc/docs/Guide/captcha.md
@@ -0,0 +1,17 @@
+---
+toc: menu
+order: 1
+---
+
+# 获取动态码
+
+动态码用于登录编程导航、永久解锁主页模板等。
+
+**1. 扫码关注微信公众号『 编程导航 』**
+
+![编程导航二维码](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/qrcode.jpg)
+
+**2. 在公众号内点击 "一键登录" 或回复 "登录" 获取**
+
+
+
diff --git a/code-nav-doc/docs/Guide/feedback.md b/code-nav-doc/docs/Guide/feedback.md
new file mode 100644
index 0000000..9c3e95f
--- /dev/null
+++ b/code-nav-doc/docs/Guide/feedback.md
@@ -0,0 +1,10 @@
+---
+toc: menu
+order: 5
+---
+
+# 意见反馈
+
+欢迎 [联系作者](/author) 或 [直接提交产品反馈意见](https://support.qq.com/products/303921)
+
+感之不尽!
diff --git a/code-nav-doc/docs/Guide/index.md b/code-nav-doc/docs/Guide/index.md
new file mode 100644
index 0000000..b80f9f9
--- /dev/null
+++ b/code-nav-doc/docs/Guide/index.md
@@ -0,0 +1,69 @@
+---
+nav:
+ title: 指南
+ path: /guide
+ order: 1
+toc: menu
+order: 0
+---
+
+# 编程导航
+
+> 发现优质编程学习资源,微信公众号『 编程导航 』
+
+[编程导航主站 - 发现优质编程资源](https://www.code-nav.cn)
+
+[编程导航主页 - 程序员必备主页](https://home.code-nav.cn)
+
+[文档](https://doc.code-nav.cn)
+
+## 写在前面
+
+总是有很多学编程的朋友问我 “有没有学 xx 的资源”、“我需要 xx 资源,能发我一份么”。
+
+在重复接收类似讯息后,我陷入深思。
+
+如今编程资源获取的大环境雾气重重,有很多不太好的现象:
+
+1. 很多名不副实的编程资源被捧上了天,名人效应、一叶障目
+2. 好的编程资源被商业利益化,很多人利用信息差,将本来免费的资源进行贩卖
+3. 好的编程资源由于作者不出名,没有被人发现
+4. 网上的编程资源非常零散,真实性、有效性很不确定
+
+意识到这些问题后,作为一个开发者,我可以做些什么? 继续去网上搜好的资源,然后传到网盘上,分享给大家?
+
+一个人的力量终归渺小,好的编程资源环境需要大家的共同努力。
+
+这是『 编程导航 』问世的原因:**提供人人皆可推荐的编程资源导航平台,帮助大家发现优质编程资源。**
+
+本质是 **资源碎片 => 列表化 => 文档化 => 系统化** 的过程。就像准备复习面试题一样,有人给你分享单一的面试题目(碎片)、有人分享题目列表(列表化)、有人分享一本面试小书(文档化),而这些在灵活性上远远不如一个 “可搜索”、“可复用”、“可量化” 、“可定制” 的 **资源系统**。
+
+**想象一下,当你想要学习算法时,在系统上轻轻一点,优质算法学习资源尽收眼底,不是很棒么?**
+
+作者在腾讯顶着上班的压力,熬了一个月的大夜,终于完成了基础版本,欢迎大家体验、推荐资源、提出意见!
+
+整个项目也几乎完全开源给大家,可供学习。觉得不错的话,求个 star、分享给身边的朋友吧,这对我非常重要 😭 有你们的支持才有前进的动力!
+
+## 项目展示
+
+[编程导航主站 - 发现优质编程资源](https://www.code-nav.cn)
+
+![推荐资源](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-recommend.png)
+
+[编程导航主页 - 程序员必备主页](https://home.code-nav.cn)
+
+![透明主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home.png)
+
+## QA
+
+1. Q:编程类导航网站都烂大街了,为什么还要做导航?
+
+ A:大多数编程导航网年久失修,虽然也有不错的导航,但是在搜索、归类上比较局限,而且没有自主推荐、收藏等功能,不具备可持续发展性。
+
+2. Q:资源太多的话,会不会同样让人眼花缭乱,不知道看哪个?
+
+ A:现在编程资源非常多,肯定会出现这种情况,这也是我们做 **系统** 而不是整理文档的原因。
+ 可以通过评分、评论、排序、推荐等方式提高精准度,大家觉得好的资源才会有更多被发现的机会!
+
+
+
diff --git a/code-nav-doc/docs/Guide/qa.md b/code-nav-doc/docs/Guide/qa.md
new file mode 100644
index 0000000..6b58d2c
--- /dev/null
+++ b/code-nav-doc/docs/Guide/qa.md
@@ -0,0 +1,7 @@
+---
+toc: menu
+order: 3
+---
+
+# QA
+
diff --git a/code-nav-doc/docs/Guide/setNav.md b/code-nav-doc/docs/Guide/setNav.md
new file mode 100644
index 0000000..1bce2d2
--- /dev/null
+++ b/code-nav-doc/docs/Guide/setNav.md
@@ -0,0 +1,12 @@
+---
+toc: menu
+order: 2
+---
+
+# 设置主页
+
+## Chrome
+
+## Firefox 火狐
+
+
diff --git a/code-nav-doc/docs/Prize/index.md b/code-nav-doc/docs/Prize/index.md
new file mode 100644
index 0000000..a2fb49e
--- /dev/null
+++ b/code-nav-doc/docs/Prize/index.md
@@ -0,0 +1,37 @@
+---
+nav:
+ title: 激励
+ path: /prize
+ order: 5
+toc: menu
+---
+
+# 激励
+
+好的编程生态需要大家的共同努力!⛽️️
+
+为鼓励大家分享编程资源,我们设定了积分等级系统,可以通过如下途径获取积分,达到指定等级后可以领取对应奖励。
+
+也期待有更多志同道合的朋友加入项目团队或贡献。
+您的大名将会出现在致谢名单中、收获更多积分、专属称号、可在简历中写上项目、得到更多的资源和流量扶持等。
+最关键的是,能提升技术实力!
+
+## 获取积分
+
+1. 推荐资源
+2. 评论
+3. 分享
+4. [成为版主,收割积分](./author)
+5. [优质作者,收割积分](./author)
+
+
+## 贡献方式
+
+目前有下面几种贡献方式,欢迎 [联系作者](./author) 进行贡献!
+
+1. 编程导航主站界面优化方案
+2. 编程导航主页模板
+3. 积极推荐资源、或帮忙推广
+
+
+
diff --git a/code-nav-doc/docs/Project/codeNavDoc.md b/code-nav-doc/docs/Project/codeNavDoc.md
new file mode 100644
index 0000000..ce064e6
--- /dev/null
+++ b/code-nav-doc/docs/Project/codeNavDoc.md
@@ -0,0 +1,66 @@
+---
+toc: menu
+---
+
+# 编程导航文档
+
+[在线访问](https://doc.code-nav.cn)
+
+编程导航项目的使用指南和详细介绍。
+
+## 项目展示
+
+主页
+
+![编程导航文档主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-doc.png)
+
+## 快速开始
+
+**请保证 Node.js 版本 > 10** ⚠️
+
+1. 下载项目到本地
+
+ ```bash
+ git clone https://github.com/liyupi/code-nav.git
+ ```
+
+2. 进入目录,安装依赖
+
+ ```bash
+ cd code-nav-doc
+ npm install
+ ```
+
+3. 本地启动项目
+
+ ```bash
+ npm run start
+ ```
+
+4. 打包构建
+
+ ```bash
+ npm run docs:build
+ ```
+
+ 会生成 `docs-dist` 目录,可以通过 [serve 工具](https://www.npmjs.com/package/serve) 本地启动 server 快速浏览。
+
+5. 部署
+
+ 利用腾讯云静态站点托管:可以直接将 `docs-dist` 目录发布到 [静态站点托管](https://cloud.tencent.com/document/product/876/46900) 中,有 CDN 支持
+
+ ```bash
+ tcb hosting deploy . -e envId
+ ```
+
+## 技术选型
+
+### 前端
+
+基于 [dumi](https://d.umijs.org/zh-CN) 文档生成工具
+
+### 后端
+
+1. [腾讯云云存储](https://cloud.tencent.com/document/product/876/19352) 存放图片,CDN 加速
+2. [Vercel](https://vercel.com/) 部署静态文档网站
+
diff --git a/code-nav-doc/docs/Project/codeNavHome.md b/code-nav-doc/docs/Project/codeNavHome.md
new file mode 100644
index 0000000..1112c0c
--- /dev/null
+++ b/code-nav-doc/docs/Project/codeNavHome.md
@@ -0,0 +1,107 @@
+---
+toc: menu
+order: 2
+---
+
+# 编程导航主页
+
+[在线访问](https://home.code-nav.cn)
+
+极简的浏览器主页,支持万能搜索,提升效率,还可以定制壁纸和主页站点。
+
+## 项目展示
+
+透明主页
+
+![透明主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home.png)
+
+白底主页
+
+![白底主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-white.png)
+
+万能搜索
+
+
+
+万能搜索结果页
+
+![万能搜索结果页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-searchAll.png)
+
+切换壁纸
+
+![切换壁纸](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-covers.png)
+
+随机壁纸
+
+![随机壁纸](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-cover-random.png)
+
+动态壁纸
+
+![动态壁纸](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-cover.png)
+
+## 已有功能
+
+1. 切换搜索
+2. 万能搜索
+3. 切换壁纸
+4. 动态壁纸
+5. 随机壁纸
+6. 透明模式
+
+## 快速开始
+
+**请保证 Node.js 版本 > 10** ⚠️
+
+1. 下载项目到本地
+
+ ```bash
+ git clone https://github.com/liyupi/code-nav.git
+ ```
+
+2. 进入目录,安装依赖
+
+ ```bash
+ cd code-nav-home
+ npm install
+ ```
+
+3. 本地启动项目
+
+ ```bash
+ npm run start
+ ```
+
+4. 打包构建
+
+ ```bash
+ npm run build
+ ```
+
+ 会生成 dist 目录,可以通过 [serve 工具](https://www.npmjs.com/package/serve) 本地启动 server 快速浏览。
+
+5. 部署
+
+ 利用腾讯云静态站点托管:可以直接将 `dist` 目录发布到 [静态站点托管](https://cloud.tencent.com/document/product/876/46900) 中,有 CDN 支持
+
+ ```bash
+ tcb hosting deploy . -e envId
+ ```
+
+## 技术选型
+
+### 前端
+
+基于 [React-Static](https://github.com/react-static/react-static) 静态站点生成框架开发
+
+1. React + React-Static
+2. [Ant Design](https://ant.design/index-cn) 组件库 + [Ant Design Pro 高级组件](https://procomponents.ant.design/components)
+3. ESLint 检查
+4. 随机壁纸使用搏天 API 接口 + JsonBird 代理跨域
+5. 使用 iframe 实现壁纸切换和万能搜索
+
+### 后端
+
+后端使用 [腾讯云云开发](https://cloud.tencent.com/product/tcb),全量上云,充分利用了腾讯云提供的云计算能力。
+
+1. 静态网站托管:CDN 全站加速,一键部署
+
diff --git a/code-nav-doc/docs/Project/codeNavMain.md b/code-nav-doc/docs/Project/codeNavMain.md
new file mode 100644
index 0000000..34c663d
--- /dev/null
+++ b/code-nav-doc/docs/Project/codeNavMain.md
@@ -0,0 +1,179 @@
+---
+toc: menu
+order: 1
+---
+
+# 编程导航主站
+
+[在线访问](https://www.code-nav.cn)
+
+最专业灵活的编程导航站点,帮助大家发现优质编程学习资源。
+
+可以检索自己需要的资源、分享好资源、评价资源。好的资源会被更多人发现,共同感受技术带来的美好。
+
+本项目是『 编程导航 』网站的开源版本,使用这套代码,你也能轻松开发多端适配网站!
+
+## 项目展示
+
+推荐资源
+
+![推荐资源](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-recommend.png)
+
+资源大全
+
+![资源大全](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-resources.png)
+
+收藏夹
+
+![收藏夹](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-favour.png)
+
+资源详情
+
+![资源详情](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-detail.png)
+
+评论区
+
+![评论区](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-comment.png)
+
+## 已有功能
+
+1. 优质资源推荐
+2. 资源全局搜索
+3. 资源添加
+4. 资源详情及相似推荐
+5. 个人主页、兴趣设置
+6. 喜欢、分享、浏览量统计
+7. 生成定制主页
+8. 评论区
+
+## 快速开始
+
+**请保证 Node.js 版本 > 10** ⚠️
+
+1. 下载项目到本地
+
+ ```bash
+ git clone https://github.com/liyupi/code-nav.git
+ ```
+
+2. 进入目录,安装依赖
+
+ ```bash
+ cd code-nav-main
+ npm install
+ ```
+
+3. 本地启动项目
+
+ ```bash
+ npm run start
+ ```
+
+4. 点击右下角 `Umi UI` 按钮,可快速新建页面,海量模板供选择。
+
+ 如果模板图标无法加载,请在本地配置 hosts:`151.101.64.133 raw.githubusercontent.com`
+
+ **新建页面后,如果要在菜单列表中显示,要在 `config/menu.tsx` 中添加配置。**
+
+5. 打包构建
+
+ ```bash
+ npm run build
+ ```
+
+ 会生成 dist 目录,可以通过 [serve 工具 ](https://www.npmjs.com/package/serve)本地启动 server 快速浏览。
+
+6. 部署
+
+ 提供多种部署方式:
+
+ 1. 容器(推荐):项目已提供 `Dockerfile` 可以轻松构建 `Docker` 镜像,并将容器部署在[云托管服务](https://cloud.tencent.com/document/product/876/46901)中,实现动态扩缩容。
+ 2. 目录:直接将 `dist` 目录放到 `Nginx` 等 web 服务器上,配置 `nginx.conf` 即可。
+ 3. 静态站点托管:可以直接将 `dist` 目录发布到[静态站点托管](https://cloud.tencent.com/document/product/876/46900)中,有 CDN 支持
+
+
+## 技术选型
+
+### 前端
+
+前端使用 [Ant Design Pro V4](https://pro.ant.design/docs/getting-started-cn/) 后台管理模板,提升了百倍开发效率,**但是也踩了不少坑**~
+
+1. [Umi](https://umijs.org/zh-CN) + React 前端框架
+2. [Ant Design](https://ant.design/index-cn) 组件库 + [Ant Design Pro 高级组件](https://procomponents.ant.design/components)
+3. [Dva](https://dvajs.com/) 数据状态管理
+4. [Less](http://lesscss.cn/) CSS 预处理语言
+5. TypeScript 静态类型检查
+
+
+### 后端
+
+后端使用 [腾讯云云开发](https://cloud.tencent.com/product/tcb),全量上云,充分利用了腾讯云提供的云计算能力。
+
+1. 云数据库:配合 SDK 使用,无需编写重复的增删改查,提高开发效率,自动备份
+2. 云存储:配合 SDK 使用,易接入
+3. 云函数:开发复杂的函数,Serverless 架构,无需自行管理,可开放 Http 访问服务
+4. 云托管:容器技术,弹性伸缩、动态扩缩容
+5. 腾讯云 CMS 开箱即用的后台管理
+
+
+## 目录结构
+
+```
+.
+├── Dockerfile 容器构建文件
+├── Dockerfile.build 容器构建文件(包含 npm 打包流程)
+├── README.md 项目说明
+├── cloudbaserc.json 腾讯云云开发文件,需要用 tcb 根据自己的环境生成
+├── cloudfunctions 后端云函数
+│ └── helloworld
+├── config 配置
+│ ├── config.ts 全局配置
+│ ├── defaultSettings.ts 框架默认设置
+│ ├── menu.tsx 菜单列表
+│ ├── proxy.ts 代理
+│ └── routes.ts 定义路由
+├── docker 容器所需配置文件
+│ └── nginx.conf 服务器配置
+├── jsconfig.json 编译配置
+├── mock 假数据
+│ ├── forms.ts
+│ ├── resources.ts
+│ ├── tags.ts
+│ └── user.ts
+├── package.json 包管理文件
+├── public 公共目录
+│ └── logo.png
+├── src 前端项目主目录
+│ ├── assets 资源文件
+│ ├── cardList.less 卡片样式
+│ ├── components 组件
+│ ├── constant 常量
+│ ├── global.less 全局样式
+│ ├── global.tsx 全局入口
+│ ├── layouts 布局
+│ ├── manifest.json
+│ ├── models 数据模型
+│ ├── pages 页面
+│ ├── service-worker.js 缓存
+│ ├── services 业务请求
+│ ├── tcb.js 腾讯云云开发 SDK
+│ ├── typings.d.ts 类型定义
+│ └── utils 工具
+└── tsconfig.json
+```
+
+
+## 测试
+
+1. 前端使用 “伪 Mock 数据” 测试,如果使用 `UMI UI` 新建页面,框架将提供真实 Mock 测试数据。
+2. 如果使用腾讯云开发,可以在本地通过 `tcb` 命令测试云函数
+
+```bash
+tcb fn run --name --params
+```
+
+## 开发技巧
+
+1. 使用全局 `LoadingLayout` 实现云开发、自动登录等前置条件加载
+
+
diff --git a/code-nav-doc/docs/Project/codeNavMpServer.md b/code-nav-doc/docs/Project/codeNavMpServer.md
new file mode 100644
index 0000000..5451405
--- /dev/null
+++ b/code-nav-doc/docs/Project/codeNavMpServer.md
@@ -0,0 +1,40 @@
+---
+toc: menu
+---
+
+# 微信公众号服务端
+
+对接编程导航公众号,提供获取动态码、关注回复、动态菜单等功能。
+
+## 项目展示
+
+
+
+## 已有功能
+
+1. 关注后回复消息
+2. 收到消息后回复消息
+3. 点击菜单获取动态码
+
+## 快速开始
+
+1. 下载项目
+2. 使用 IDEA 打开项目,修改 `resources/application` 文件的公众号配置,进入公众号后台获取:
+
+ ```properties
+ wx.mp.appId=
+ wx.mp.secret=
+ wx.mp.token=
+ wx.mp.aesKey=
+ ```
+
+3. 使用 `spring-boot:build-image` 构建,在 target 目录下能看到生成的 jar 包
+4. 可以在服务器启动 jar 包,或直接用 Dockerfile 构建镜像部署在容器中(推荐腾讯云云托管)
+
+## 技术选型
+
+1. [WxJava](https://github.com/Wechat-Group/WxJava) 微信公众号后台开发类库
+2. SpringBoot
+3. Maven 包管理
+4. 腾讯云开发云函数 + 云托管
+5. Logback 日志
diff --git a/code-nav-doc/docs/Project/codeNavReview.md b/code-nav-doc/docs/Project/codeNavReview.md
new file mode 100644
index 0000000..804eee8
--- /dev/null
+++ b/code-nav-doc/docs/Project/codeNavReview.md
@@ -0,0 +1,12 @@
+---
+toc: menu
+---
+
+# 审核中心
+
+提供资源、评论等内容的审核功能。
+
+## 已有功能
+
+1. 审核资源
+2. 审核评论
diff --git a/code-nav-doc/docs/Project/index.md b/code-nav-doc/docs/Project/index.md
new file mode 100644
index 0000000..0a8bf29
--- /dev/null
+++ b/code-nav-doc/docs/Project/index.md
@@ -0,0 +1,52 @@
+---
+nav:
+ title: 项目
+ path: /project
+ order: 3
+toc: menu
+order: 0
+---
+
+# 项目
+
+编程导航不仅仅是一个项目,而是以 "帮助大家发现优质编程资源,提升效率" 为目标的完整生态。
+
+下面介绍编程导航生态的整体技术选型,以及每个子项目的技术架构和本地运行构建方式,便于大家学习,**甚至可以直接轻松地自行搭建类似站点!**
+
+
+## 整体技术选型
+
+项目前端采用 React 框架,后端全量上腾讯云,充分利用云开发提供的云函数、云数据库、云存储、静态站点 CDN、云托管动态扩缩容等能力。
+
+
+## 子项目
+
+> 点击下方标题链接查看子项目详情
+
+
+1. [编程导航主站](project/code-nav-main) 🏡
+
+ 发现优质编程学习资源。可以检索自己需要的资源、分享好的资源,并对他人推荐的资源进行评价。好的资源会被更多人发现,让更多同学感受到技术带来的美好。
+
+2. [编程导航主页](project/code-nav-home) 🔍
+
+ 极简的浏览器主页,支持万能搜索,提升效率,还可以定制壁纸和主页站点。
+
+3. [审核中心](project/code-nav-review) 👮
+
+ 提供资源、评论等内容的审核功能。
+
+4. [编程导航文档](project/code-nav-doc) 📚
+
+ 编程导航项目的使用指南和详细介绍。
+
+5. [微信公众号服务端](project/code-nav-mp-server) 💻
+
+ 对接编程导航公众号,提供获取动态码、关注回复、动态菜单等功能。
+
+6. 编程导航微信公众号
+
+ 定期分享、介绍和评测优质编程资源,不要错过!
+
+7. 编程导航小程序(特喵的没过审,待调整)
+
diff --git a/code-nav-doc/docs/Release/index.md b/code-nav-doc/docs/Release/index.md
new file mode 100644
index 0000000..05006ae
--- /dev/null
+++ b/code-nav-doc/docs/Release/index.md
@@ -0,0 +1,12 @@
+---
+nav:
+ title: 更新日志
+ path: https://github.com/liyupi/code-nav/releases/
+ order: 10
+---
+
+## Foo
+
+Demo:
+
+More skills for writing demo: https://d.umijs.org/guide/demo-principle
diff --git a/code-nav-doc/docs/assets/code-nav-comment.png b/code-nav-doc/docs/assets/code-nav-comment.png
new file mode 100644
index 0000000..9abb69b
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-comment.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-detail.png b/code-nav-doc/docs/assets/code-nav-detail.png
new file mode 100644
index 0000000..fd5999f
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-detail.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-doc.png b/code-nav-doc/docs/assets/code-nav-doc.png
new file mode 100644
index 0000000..512d951
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-doc.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-favour.png b/code-nav-doc/docs/assets/code-nav-favour.png
new file mode 100644
index 0000000..198ab7a
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-favour.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-home-cover-random.png b/code-nav-doc/docs/assets/code-nav-home-cover-random.png
new file mode 100644
index 0000000..061580e
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-home-cover-random.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-home-cover.png b/code-nav-doc/docs/assets/code-nav-home-cover.png
new file mode 100644
index 0000000..872c6b4
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-home-cover.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-home-covers.png b/code-nav-doc/docs/assets/code-nav-home-covers.png
new file mode 100644
index 0000000..ca9ee2d
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-home-covers.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-home-search.png b/code-nav-doc/docs/assets/code-nav-home-search.png
new file mode 100644
index 0000000..b42e28c
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-home-search.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-home-searchAll.png b/code-nav-doc/docs/assets/code-nav-home-searchAll.png
new file mode 100644
index 0000000..11114f1
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-home-searchAll.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-home-white.png b/code-nav-doc/docs/assets/code-nav-home-white.png
new file mode 100644
index 0000000..8cb5691
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-home-white.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-home.png b/code-nav-doc/docs/assets/code-nav-home.png
new file mode 100644
index 0000000..5fdfcdd
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-home.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-recommend.png b/code-nav-doc/docs/assets/code-nav-recommend.png
new file mode 100644
index 0000000..7c5fd23
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-recommend.png differ
diff --git a/code-nav-doc/docs/assets/code-nav-resources.png b/code-nav-doc/docs/assets/code-nav-resources.png
new file mode 100644
index 0000000..4616c3a
Binary files /dev/null and b/code-nav-doc/docs/assets/code-nav-resources.png differ
diff --git a/code-nav-doc/docs/assets/login.jpeg b/code-nav-doc/docs/assets/login.jpeg
new file mode 100644
index 0000000..29a8abc
Binary files /dev/null and b/code-nav-doc/docs/assets/login.jpeg differ
diff --git a/code-nav-doc/docs/assets/qrcode.jpg b/code-nav-doc/docs/assets/qrcode.jpg
new file mode 100644
index 0000000..1831898
Binary files /dev/null and b/code-nav-doc/docs/assets/qrcode.jpg differ
diff --git a/code-nav-doc/docs/assets/wechat.jpg b/code-nav-doc/docs/assets/wechat.jpg
new file mode 100644
index 0000000..91f3602
Binary files /dev/null and b/code-nav-doc/docs/assets/wechat.jpg differ
diff --git a/code-nav-doc/docs/index.md b/code-nav-doc/docs/index.md
new file mode 100644
index 0000000..e0aee9b
--- /dev/null
+++ b/code-nav-doc/docs/index.md
@@ -0,0 +1,61 @@
+---
+title: 编程导航文档
+hero:
+ title: 编程导航文档
+ desc: 📚 编程导航项目的使用指南和详细介绍
+ actions:
+ - text: 开始阅读
+ link: /guide
+features:
+ - icon: https://gw.alipayobjects.com/zos/bmw-prod/d60657df-0822-4631-9d7c-e7a869c2f21c/k79dmz3q_w126_h126.png
+ title: 发现资源
+ desc: 轻轻一点,优质编程资源尽收眼底
+ link: https://www.code-nav.cn
+ - icon: https://gw.alipayobjects.com/zos/bmw-prod/3863e74a-7870-4874-b1e1-00a8cdf47684/kj9t7ww3_w144_h144.png
+ title: 极简主页
+ desc: 专为程序员定制的主页,酷炫方便
+ link: https://home.code-nav.cn
+ - icon: https://gw.alipayobjects.com/zos/bmw-prod/f093e060-726e-471c-a53e-e988ed3f560c/kj9t9sk7_w144_h144.png
+ title: 多端适配
+ desc: PC、移动端均可获得较好体验
+ link: https://www.code-nav.cn
+ - icon: https://gw.alipayobjects.com/zos/bmw-prod/d1ee0c6f-5aed-4a45-a507-339a4bfe076c/k7bjsocq_w144_h144.png
+ title: 开源可控
+ desc: 整个系统开源,可供学习,欢迎改进
+ link: https://github.com/liyupi/code-nav
+ - icon: https://gw.alipayobjects.com/zos/bmw-prod/881dc458-f20b-407b-947a-95104b5ec82b/k79dm8ih_w144_h144.png
+ title: 开箱即用
+ desc: 开源代码可在本地直接运行,灵活部署
+ link: https://github.com/liyupi/code-nav
+ - icon: https://gw.alipayobjects.com/zos/bmw-prod/b3e102cd-5dad-4046-a02a-be33241d1cc7/kj9t8oji_w144_h144.png
+ title: 全民共建
+ desc: 人人皆可推荐,帮助他人,获取激励
+ link: https://www.code-nav.cn
+footer: Open-source MIT Licensed | Copyright © 2021
Powered by [编程导航](https://www.code-nav.cn)
+---
+
+## 项目简介
+
+帮助大家发现优质编程学习资源,提高效率!当前主要有 2 个项目:
+
+[编程导航主站 - 发现优质编程资源](https://www.code-nav.cn)
+
+![推荐资源](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-recommend.png)
+
+[编程导航主页 - 程序员必备主页](https://home.code-nav.cn)
+
+![透明主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home.png)
+
+
+## 反馈与共建
+
+请访问 [GitHub](https://github.com/liyupi/code-nav)、关注编程导航公众号、或 [联系作者](./author) 微信加入交流群,
+也可以 [直接提交产品反馈意见](https://support.qq.com/products/303921) ~ 感之不尽
+
+**编程导航公众号**
+
+![编程导航公众号](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/qrcode.jpg)
+
+**编程导航微信**
+
+![编程导航微信](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/wechat.jpg)
diff --git a/code-nav-doc/package.json b/code-nav-doc/package.json
new file mode 100644
index 0000000..9bde1a8
--- /dev/null
+++ b/code-nav-doc/package.json
@@ -0,0 +1,43 @@
+{
+ "private": true,
+ "name": "code-nav-doc",
+ "version": "1.0.0",
+ "scripts": {
+ "start": "dumi dev",
+ "docs:build": "dumi build",
+ "docs:deploy": "gh-pages -d docs-dist",
+ "build": "father-build",
+ "deploy": "npm run docs:build && npm run docs:deploy",
+ "release": "npm run build && npm publish",
+ "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"",
+ "test": "umi-test",
+ "test:coverage": "umi-test --coverage"
+ },
+ "main": "dist/index.js",
+ "module": "dist/index.esm.js",
+ "typings": "dist/index.d.ts",
+ "gitHooks": {
+ "pre-commit": "lint-staged"
+ },
+ "lint-staged": {
+ "*.{js,jsx,less,md,json}": [
+ "prettier --write"
+ ],
+ "*.ts?(x)": [
+ "prettier --parser=typescript --write"
+ ]
+ },
+ "dependencies": {
+ "@umijs/plugin-analytics": "^0.2.2",
+ "react": "^16.12.0"
+ },
+ "devDependencies": {
+ "@umijs/test": "^3.0.5",
+ "dumi": "^1.1.2",
+ "father-build": "^1.19.1",
+ "gh-pages": "^3.0.0",
+ "lint-staged": "^10.0.7",
+ "prettier": "^1.19.1",
+ "yorkie": "^2.0.0"
+ }
+}
diff --git a/code-nav-doc/tsconfig.json b/code-nav-doc/tsconfig.json
new file mode 100644
index 0000000..de15e0a
--- /dev/null
+++ b/code-nav-doc/tsconfig.json
@@ -0,0 +1,29 @@
+{
+ "compilerOptions": {
+ "target": "esnext",
+ "module": "esnext",
+ "moduleResolution": "node",
+ "importHelpers": true,
+ "jsx": "react",
+ "esModuleInterop": true,
+ "sourceMap": true,
+ "baseUrl": "./",
+ "strict": true,
+ "paths": {
+ "@/*": ["src/*"],
+ "@@/*": ["src/.umi/*"]
+ },
+ "allowSyntheticDefaultImports": true
+ },
+ "exclude": [
+ "node_modules",
+ "lib",
+ "es",
+ "dist",
+ "typings",
+ "**/__test__",
+ "test",
+ "docs",
+ "tests"
+ ]
+}
diff --git a/code-nav-doc/typings.d.ts b/code-nav-doc/typings.d.ts
new file mode 100644
index 0000000..71e0e9f
--- /dev/null
+++ b/code-nav-doc/typings.d.ts
@@ -0,0 +1,2 @@
+declare module '*.css';
+declare module '*.less';
diff --git a/code-nav-home/.babelrc b/code-nav-home/.babelrc
new file mode 100644
index 0000000..17f8a99
--- /dev/null
+++ b/code-nav-home/.babelrc
@@ -0,0 +1,3 @@
+{
+ "presets": ["react-static/babel-preset.js"]
+}
diff --git a/code-nav-home/.editorconfig b/code-nav-home/.editorconfig
new file mode 100644
index 0000000..7e3649a
--- /dev/null
+++ b/code-nav-home/.editorconfig
@@ -0,0 +1,16 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab
diff --git a/code-nav-home/.eslintrc b/code-nav-home/.eslintrc
new file mode 100644
index 0000000..5e603ec
--- /dev/null
+++ b/code-nav-home/.eslintrc
@@ -0,0 +1,3 @@
+{
+ "extends": "react-app"
+}
diff --git a/code-nav-home/.gitignore b/code-nav-home/.gitignore
new file mode 100644
index 0000000..be4f857
--- /dev/null
+++ b/code-nav-home/.gitignore
@@ -0,0 +1,43 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+tmp
+artifacts
+
+# dependencies
+**/node_modules
+# roadhog-api-doc ignore
+/src/utils/request-temp.js
+_roadhog-api-doc
+
+# production
+/dist
+/.vscode
+
+# misc
+.DS_Store
+npm-debug.log*
+yarn-error.log
+
+/coverage
+.idea
+yarn.lock
+package-lock.json
+*bak
+.vscode
+
+# visual studio code
+.history
+*.log
+functions/*
+.temp/**
+
+# umi
+.umi
+.umi-production
+
+# screenshot
+screenshot
+.firebase
+.eslintcache
+
+build
diff --git a/code-nav-home/README.md b/code-nav-home/README.md
new file mode 100644
index 0000000..40086d5
--- /dev/null
+++ b/code-nav-home/README.md
@@ -0,0 +1,102 @@
+# 编程导航主页
+
+[在线访问](https://home.code-nav.cn)
+
+极简的浏览器主页,支持万能搜索,提升效率,还可以定制壁纸和主页站点。
+
+## 项目展示
+
+透明主页
+
+![透明主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home.png)
+
+白底主页
+
+![白底主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-white.png)
+
+万能搜索
+
+
+
+万能搜索结果页
+
+![万能搜索结果页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-searchAll.png)
+
+切换壁纸
+
+![切换壁纸](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-covers.png)
+
+随机壁纸
+
+![随机壁纸](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-cover-random.png)
+
+动态壁纸
+
+![动态壁纸](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-home-cover.png)
+
+## 已有功能
+
+1. 切换搜索
+2. 万能搜索
+3. 切换壁纸
+4. 动态壁纸
+5. 随机壁纸
+6. 透明模式
+
+## 快速开始
+
+**请保证 Node.js 版本 > 10** ⚠️
+
+1. 下载项目到本地
+
+ ```bash
+ git clone https://github.com/liyupi/code-nav.git
+ ```
+
+2. 进入目录,安装依赖
+
+ ```bash
+ cd code-nav-home
+ npm install
+ ```
+
+3. 本地启动项目
+
+ ```bash
+ npm run start
+ ```
+
+4. 打包构建
+
+ ```bash
+ npm run build
+ ```
+
+ 会生成 dist 目录,可以通过 [serve 工具](https://www.npmjs.com/package/serve) 本地启动 server 快速浏览。
+
+5. 部署
+
+ 利用腾讯云静态站点托管:可以直接将 `dist` 目录发布到 [静态站点托管](https://cloud.tencent.com/document/product/876/46900) 中,有 CDN 支持
+
+ ```bash
+ tcb hosting deploy . -e envId
+ ```
+
+## 技术选型
+
+### 前端
+
+基于 [React-Static](https://github.com/react-static/react-static) 静态站点生成框架开发
+
+1. React + React-Static
+2. [Ant Design](https://ant.design/index-cn) 组件库 + [Ant Design Pro 高级组件](https://procomponents.ant.design/components)
+3. ESLint 检查
+4. 随机壁纸使用搏天 API 接口 + JsonBird 代理跨域
+5. 使用 iframe 实现壁纸切换和万能搜索
+
+### 后端
+
+后端使用 [腾讯云云开发](https://cloud.tencent.com/product/tcb),全量上云,充分利用了腾讯云提供的云计算能力。
+
+1. 静态网站托管:CDN 全站加速,一键部署
+
diff --git a/code-nav-home/covers/comic/cover_1.jpg b/code-nav-home/covers/comic/cover_1.jpg
new file mode 100644
index 0000000..2617c15
Binary files /dev/null and b/code-nav-home/covers/comic/cover_1.jpg differ
diff --git a/code-nav-home/covers/comic/cover_10.jpg b/code-nav-home/covers/comic/cover_10.jpg
new file mode 100644
index 0000000..6af4fb8
Binary files /dev/null and b/code-nav-home/covers/comic/cover_10.jpg differ
diff --git a/code-nav-home/covers/comic/cover_11.jpg b/code-nav-home/covers/comic/cover_11.jpg
new file mode 100644
index 0000000..1aaf884
Binary files /dev/null and b/code-nav-home/covers/comic/cover_11.jpg differ
diff --git a/code-nav-home/covers/comic/cover_12.jpg b/code-nav-home/covers/comic/cover_12.jpg
new file mode 100644
index 0000000..41400a7
Binary files /dev/null and b/code-nav-home/covers/comic/cover_12.jpg differ
diff --git a/code-nav-home/covers/comic/cover_2.jpg b/code-nav-home/covers/comic/cover_2.jpg
new file mode 100644
index 0000000..2e1fc77
Binary files /dev/null and b/code-nav-home/covers/comic/cover_2.jpg differ
diff --git a/code-nav-home/covers/comic/cover_3.jpg b/code-nav-home/covers/comic/cover_3.jpg
new file mode 100644
index 0000000..15a4af7
Binary files /dev/null and b/code-nav-home/covers/comic/cover_3.jpg differ
diff --git a/code-nav-home/covers/comic/cover_4.jpg b/code-nav-home/covers/comic/cover_4.jpg
new file mode 100644
index 0000000..3a8c5a4
Binary files /dev/null and b/code-nav-home/covers/comic/cover_4.jpg differ
diff --git a/code-nav-home/covers/comic/cover_5.jpg b/code-nav-home/covers/comic/cover_5.jpg
new file mode 100644
index 0000000..2d76b69
Binary files /dev/null and b/code-nav-home/covers/comic/cover_5.jpg differ
diff --git a/code-nav-home/covers/comic/cover_6.jpg b/code-nav-home/covers/comic/cover_6.jpg
new file mode 100644
index 0000000..7a2ff15
Binary files /dev/null and b/code-nav-home/covers/comic/cover_6.jpg differ
diff --git a/code-nav-home/covers/comic/cover_7.jpg b/code-nav-home/covers/comic/cover_7.jpg
new file mode 100644
index 0000000..7b3b506
Binary files /dev/null and b/code-nav-home/covers/comic/cover_7.jpg differ
diff --git a/code-nav-home/covers/comic/cover_8.jpg b/code-nav-home/covers/comic/cover_8.jpg
new file mode 100644
index 0000000..1628247
Binary files /dev/null and b/code-nav-home/covers/comic/cover_8.jpg differ
diff --git a/code-nav-home/covers/comic/cover_9.jpg b/code-nav-home/covers/comic/cover_9.jpg
new file mode 100644
index 0000000..7563714
Binary files /dev/null and b/code-nav-home/covers/comic/cover_9.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_1.jpg b/code-nav-home/covers/comic/preview/cover_1.jpg
new file mode 100644
index 0000000..3dc47d8
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_1.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_10.jpg b/code-nav-home/covers/comic/preview/cover_10.jpg
new file mode 100644
index 0000000..833c69b
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_10.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_11.jpg b/code-nav-home/covers/comic/preview/cover_11.jpg
new file mode 100644
index 0000000..359244d
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_11.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_12.jpg b/code-nav-home/covers/comic/preview/cover_12.jpg
new file mode 100644
index 0000000..a654574
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_12.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_2.jpg b/code-nav-home/covers/comic/preview/cover_2.jpg
new file mode 100644
index 0000000..549cf12
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_2.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_3.jpg b/code-nav-home/covers/comic/preview/cover_3.jpg
new file mode 100644
index 0000000..a930eb9
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_3.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_4.jpg b/code-nav-home/covers/comic/preview/cover_4.jpg
new file mode 100644
index 0000000..3bbdd4c
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_4.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_5.jpg b/code-nav-home/covers/comic/preview/cover_5.jpg
new file mode 100644
index 0000000..de8eb6b
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_5.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_6.jpg b/code-nav-home/covers/comic/preview/cover_6.jpg
new file mode 100644
index 0000000..734f94c
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_6.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_7.jpg b/code-nav-home/covers/comic/preview/cover_7.jpg
new file mode 100644
index 0000000..8a07653
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_7.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_8.jpg b/code-nav-home/covers/comic/preview/cover_8.jpg
new file mode 100644
index 0000000..82c5cf3
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_8.jpg differ
diff --git a/code-nav-home/covers/comic/preview/cover_9.jpg b/code-nav-home/covers/comic/preview/cover_9.jpg
new file mode 100644
index 0000000..281b4af
Binary files /dev/null and b/code-nav-home/covers/comic/preview/cover_9.jpg differ
diff --git "a/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/LDR_RGB1_0.png" "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/LDR_RGB1_0.png"
new file mode 100644
index 0000000..685f0e5
Binary files /dev/null and "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/LDR_RGB1_0.png" differ
diff --git "a/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/dat.gui.min.js" "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/dat.gui.min.js"
new file mode 100644
index 0000000..881c322
--- /dev/null
+++ "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/dat.gui.min.js"
@@ -0,0 +1,13 @@
+/**
+ * dat-gui JavaScript Controller Library
+ * http://code.google.com/p/dat-gui
+ *
+ * Copyright 2011 Data Arts Team, Google Creative Lab
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.dat={})}(this,function(e){"use strict";function t(e,t){var n=e.__state.conversionName.toString(),o=Math.round(e.r),i=Math.round(e.g),r=Math.round(e.b),s=e.a,a=Math.round(e.h),l=e.s.toFixed(1),d=e.v.toFixed(1);if(t||"THREE_CHAR_HEX"===n||"SIX_CHAR_HEX"===n){for(var c=e.hex.toString(16);c.length<6;)c="0"+c;return"#"+c}return"CSS_RGB"===n?"rgb("+o+","+i+","+r+")":"CSS_RGBA"===n?"rgba("+o+","+i+","+r+","+s+")":"HEX"===n?"0x"+e.hex.toString(16):"RGB_ARRAY"===n?"["+o+","+i+","+r+"]":"RGBA_ARRAY"===n?"["+o+","+i+","+r+","+s+"]":"RGB_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+"}":"RGBA_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+",a:"+s+"}":"HSV_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+"}":"HSVA_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+",a:"+s+"}":"unknown format"}function n(e,t,n){Object.defineProperty(e,t,{get:function(){return"RGB"===this.__state.space?this.__state[t]:(I.recalculateRGB(this,t,n),this.__state[t])},set:function(e){"RGB"!==this.__state.space&&(I.recalculateRGB(this,t,n),this.__state.space="RGB"),this.__state[t]=e}})}function o(e,t){Object.defineProperty(e,t,{get:function(){return"HSV"===this.__state.space?this.__state[t]:(I.recalculateHSV(this),this.__state[t])},set:function(e){"HSV"!==this.__state.space&&(I.recalculateHSV(this),this.__state.space="HSV"),this.__state[t]=e}})}function i(e){if("0"===e||S.isUndefined(e))return 0;var t=e.match(U);return S.isNull(t)?0:parseFloat(t[1])}function r(e){var t=e.toString();return t.indexOf(".")>-1?t.length-t.indexOf(".")-1:0}function s(e,t){var n=Math.pow(10,t);return Math.round(e*n)/n}function a(e,t,n,o,i){return o+(e-t)/(n-t)*(i-o)}function l(e,t,n,o){e.style.background="",S.each(ee,function(i){e.style.cssText+="background: "+i+"linear-gradient("+t+", "+n+" 0%, "+o+" 100%); "})}function d(e){e.style.background="",e.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",e.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}function c(e,t,n){var o=document.createElement("li");return t&&o.appendChild(t),n?e.__ul.insertBefore(o,n):e.__ul.appendChild(o),e.onResize(),o}function u(e){X.unbind(window,"resize",e.__resizeHandler),e.saveToLocalStorageIfPossible&&X.unbind(window,"unload",e.saveToLocalStorageIfPossible)}function _(e,t){var n=e.__preset_select[e.__preset_select.selectedIndex];n.innerHTML=t?n.value+"*":n.value}function h(e,t,n){if(n.__li=t,n.__gui=e,S.extend(n,{options:function(t){if(arguments.length>1){var o=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:o,factoryArgs:[S.toArray(arguments)]})}if(S.isArray(t)||S.isObject(t)){var i=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:i,factoryArgs:[t]})}},name:function(e){return n.__li.firstElementChild.firstElementChild.innerHTML=e,n},listen:function(){return n.__gui.listen(n),n},remove:function(){return n.__gui.remove(n),n}}),n instanceof q){var o=new Q(n.object,n.property,{min:n.__min,max:n.__max,step:n.__step});S.each(["updateDisplay","onChange","onFinishChange","step"],function(e){var t=n[e],i=o[e];n[e]=o[e]=function(){var e=Array.prototype.slice.call(arguments);return i.apply(o,e),t.apply(n,e)}}),X.addClass(t,"has-slider"),n.domElement.insertBefore(o.domElement,n.domElement.firstElementChild)}else if(n instanceof Q){var i=function(t){if(S.isNumber(n.__min)&&S.isNumber(n.__max)){var o=n.__li.firstElementChild.firstElementChild.innerHTML,i=n.__gui.__listening.indexOf(n)>-1;n.remove();var r=f(e,n.object,n.property,{before:n.__li.nextElementSibling,factoryArgs:[n.__min,n.__max,n.__step]});return r.name(o),i&&r.listen(),r}return t};n.min=S.compose(i,n.min),n.max=S.compose(i,n.max)}else n instanceof K?(X.bind(t,"click",function(){X.fakeEvent(n.__checkbox,"click")}),X.bind(n.__checkbox,"click",function(e){e.stopPropagation()})):n instanceof Z?(X.bind(t,"click",function(){X.fakeEvent(n.__button,"click")}),X.bind(t,"mouseover",function(){X.addClass(n.__button,"hover")}),X.bind(t,"mouseout",function(){X.removeClass(n.__button,"hover")})):n instanceof $&&(X.addClass(t,"color"),n.updateDisplay=S.compose(function(e){return t.style.borderLeftColor=n.__color.toString(),e},n.updateDisplay),n.updateDisplay());n.setValue=S.compose(function(t){return e.getRoot().__preset_select&&n.isModified()&&_(e.getRoot(),!0),t},n.setValue)}function p(e,t){var n=e.getRoot(),o=n.__rememberedObjects.indexOf(t.object);if(-1!==o){var i=n.__rememberedObjectIndecesToControllers[o];if(void 0===i&&(i={},n.__rememberedObjectIndecesToControllers[o]=i),i[t.property]=t,n.load&&n.load.remembered){var r=n.load.remembered,s=void 0;if(r[e.preset])s=r[e.preset];else{if(!r[se])return;s=r[se]}if(s[o]&&void 0!==s[o][t.property]){var a=s[o][t.property];t.initialValue=a,t.setValue(a)}}}}function f(e,t,n,o){if(void 0===t[n])throw new Error('Object "'+t+'" has no property "'+n+'"');var i=void 0;if(o.color)i=new $(t,n);else{var r=[t,n].concat(o.factoryArgs);i=ne.apply(e,r)}o.before instanceof z&&(o.before=o.before.__li),p(e,i),X.addClass(i.domElement,"c");var s=document.createElement("span");X.addClass(s,"property-name"),s.innerHTML=i.property;var a=document.createElement("div");a.appendChild(s),a.appendChild(i.domElement);var l=c(e,a,o.before);return X.addClass(l,he.CLASS_CONTROLLER_ROW),i instanceof $?X.addClass(l,"color"):X.addClass(l,H(i.getValue())),h(e,l,i),e.__controllers.push(i),i}function m(e,t){return document.location.href+"."+t}function g(e,t,n){var o=document.createElement("option");o.innerHTML=t,o.value=t,e.__preset_select.appendChild(o),n&&(e.__preset_select.selectedIndex=e.__preset_select.length-1)}function b(e,t){t.style.display=e.useLocalStorage?"block":"none"}function v(e){var t=e.__save_row=document.createElement("li");X.addClass(e.domElement,"has-save"),e.__ul.insertBefore(t,e.__ul.firstChild),X.addClass(t,"save-row");var n=document.createElement("span");n.innerHTML=" ",X.addClass(n,"button gears");var o=document.createElement("span");o.innerHTML="Save",X.addClass(o,"button"),X.addClass(o,"save");var i=document.createElement("span");i.innerHTML="New",X.addClass(i,"button"),X.addClass(i,"save-as");var r=document.createElement("span");r.innerHTML="Revert",X.addClass(r,"button"),X.addClass(r,"revert");var s=e.__preset_select=document.createElement("select");if(e.load&&e.load.remembered?S.each(e.load.remembered,function(t,n){g(e,n,n===e.preset)}):g(e,se,!1),X.bind(s,"change",function(){for(var t=0;t=0;n--)t=[e[n].apply(this,t)];return t[0]}},each:function(e,t,n){if(e)if(A&&e.forEach&&e.forEach===A)e.forEach(t,n);else if(e.length===e.length+0){var o=void 0,i=void 0;for(o=0,i=e.length;o1?S.toArray(arguments):arguments[0];return S.each(O,function(t){if(t.litmus(e))return S.each(t.conversions,function(t,n){if(T=t.read(e),!1===L&&!1!==T)return L=T,T.conversionName=n,T.conversion=t,S.BREAK}),S.BREAK}),L},B=void 0,N={hsv_to_rgb:function(e,t,n){var o=Math.floor(e/60)%6,i=e/60-Math.floor(e/60),r=n*(1-t),s=n*(1-i*t),a=n*(1-(1-i)*t),l=[[n,a,r],[s,n,r],[r,n,a],[r,s,n],[a,r,n],[n,r,s]][o];return{r:255*l[0],g:255*l[1],b:255*l[2]}},rgb_to_hsv:function(e,t,n){var o=Math.min(e,t,n),i=Math.max(e,t,n),r=i-o,s=void 0,a=void 0;return 0===i?{h:NaN,s:0,v:0}:(a=r/i,s=e===i?(t-n)/r:t===i?2+(n-e)/r:4+(e-t)/r,(s/=6)<0&&(s+=1),{h:360*s,s:a,v:i/255})},rgb_to_hex:function(e,t,n){var o=this.hex_with_component(0,2,e);return o=this.hex_with_component(o,1,t),o=this.hex_with_component(o,0,n)},component_from_hex:function(e,t){return e>>8*t&255},hex_with_component:function(e,t,n){return n<<(B=8*t)|e&~(255<this.__max&&(n=this.__max),void 0!==this.__step&&n%this.__step!=0&&(n=Math.round(n/this.__step)*this.__step),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,n)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=r(e),this}}]),t}(),Q=function(e){function t(e,n,o){function i(){l.__onFinishChange&&l.__onFinishChange.call(l,l.getValue())}function r(e){var t=d-e.clientY;l.setValue(l.getValue()+t*l.__impliedStep),d=e.clientY}function s(){X.unbind(window,"mousemove",r),X.unbind(window,"mouseup",s),i()}F(this,t);var a=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,o));a.__truncationSuspended=!1;var l=a,d=void 0;return a.__input=document.createElement("input"),a.__input.setAttribute("type","text"),X.bind(a.__input,"change",function(){var e=parseFloat(l.__input.value);S.isNaN(e)||l.setValue(e)}),X.bind(a.__input,"blur",function(){i()}),X.bind(a.__input,"mousedown",function(e){X.bind(window,"mousemove",r),X.bind(window,"mouseup",s),d=e.clientY}),X.bind(a.__input,"keydown",function(e){13===e.keyCode&&(l.__truncationSuspended=!0,this.blur(),l.__truncationSuspended=!1,i())}),a.updateDisplay(),a.domElement.appendChild(a.__input),a}return D(t,W),P(t,[{key:"updateDisplay",value:function(){return this.__input.value=this.__truncationSuspended?this.getValue():s(this.getValue(),this.__precision),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),q=function(e){function t(e,n,o,i,r){function s(e){e.preventDefault();var t=_.__background.getBoundingClientRect();return _.setValue(a(e.clientX,t.left,t.right,_.__min,_.__max)),!1}function l(){X.unbind(window,"mousemove",s),X.unbind(window,"mouseup",l),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}function d(e){var t=e.touches[0].clientX,n=_.__background.getBoundingClientRect();_.setValue(a(t,n.left,n.right,_.__min,_.__max))}function c(){X.unbind(window,"touchmove",d),X.unbind(window,"touchend",c),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}F(this,t);var u=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,{min:o,max:i,step:r})),_=u;return u.__background=document.createElement("div"),u.__foreground=document.createElement("div"),X.bind(u.__background,"mousedown",function(e){document.activeElement.blur(),X.bind(window,"mousemove",s),X.bind(window,"mouseup",l),s(e)}),X.bind(u.__background,"touchstart",function(e){1===e.touches.length&&(X.bind(window,"touchmove",d),X.bind(window,"touchend",c),d(e))}),X.addClass(u.__background,"slider"),X.addClass(u.__foreground,"slider-fg"),u.updateDisplay(),u.__background.appendChild(u.__foreground),u.domElement.appendChild(u.__background),u}return D(t,W),P(t,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),Z=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=i;return i.__button=document.createElement("div"),i.__button.innerHTML=void 0===o?"Fire":o,X.bind(i.__button,"click",function(e){return e.preventDefault(),r.fire(),!1}),X.addClass(i.__button,"button"),i.domElement.appendChild(i.__button),i}return D(t,z),P(t,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),t}(),$=function(e){function t(e,n){function o(e){u(e),X.bind(window,"mousemove",u),X.bind(window,"touchmove",u),X.bind(window,"mouseup",r),X.bind(window,"touchend",r)}function i(e){_(e),X.bind(window,"mousemove",_),X.bind(window,"touchmove",_),X.bind(window,"mouseup",s),X.bind(window,"touchend",s)}function r(){X.unbind(window,"mousemove",u),X.unbind(window,"touchmove",u),X.unbind(window,"mouseup",r),X.unbind(window,"touchend",r),c()}function s(){X.unbind(window,"mousemove",_),X.unbind(window,"touchmove",_),X.unbind(window,"mouseup",s),X.unbind(window,"touchend",s),c()}function a(){var e=R(this.value);!1!==e?(p.__color.__state=e,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function c(){p.__onFinishChange&&p.__onFinishChange.call(p,p.__color.toOriginal())}function u(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__saturation_field.getBoundingClientRect(),n=e.touches&&e.touches[0]||e,o=n.clientX,i=n.clientY,r=(o-t.left)/(t.right-t.left),s=1-(i-t.top)/(t.bottom-t.top);return s>1?s=1:s<0&&(s=0),r>1?r=1:r<0&&(r=0),p.__color.v=s,p.__color.s=r,p.setValue(p.__color.toOriginal()),!1}function _(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__hue_field.getBoundingClientRect(),n=1-((e.touches&&e.touches[0]||e).clientY-t.top)/(t.bottom-t.top);return n>1?n=1:n<0&&(n=0),p.__color.h=360*n,p.setValue(p.__color.toOriginal()),!1}F(this,t);var h=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n));h.__color=new I(h.getValue()),h.__temp=new I(0);var p=h;h.domElement=document.createElement("div"),X.makeSelectable(h.domElement,!1),h.__selector=document.createElement("div"),h.__selector.className="selector",h.__saturation_field=document.createElement("div"),h.__saturation_field.className="saturation-field",h.__field_knob=document.createElement("div"),h.__field_knob.className="field-knob",h.__field_knob_border="2px solid ",h.__hue_knob=document.createElement("div"),h.__hue_knob.className="hue-knob",h.__hue_field=document.createElement("div"),h.__hue_field.className="hue-field",h.__input=document.createElement("input"),h.__input.type="text",h.__input_textShadow="0 1px 1px ",X.bind(h.__input,"keydown",function(e){13===e.keyCode&&a.call(this)}),X.bind(h.__input,"blur",a),X.bind(h.__selector,"mousedown",function(){X.addClass(this,"drag").bind(window,"mouseup",function(){X.removeClass(p.__selector,"drag")})}),X.bind(h.__selector,"touchstart",function(){X.addClass(this,"drag").bind(window,"touchend",function(){X.removeClass(p.__selector,"drag")})});var f=document.createElement("div");return S.extend(h.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),S.extend(h.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:h.__field_knob_border+(h.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),S.extend(h.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),S.extend(h.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),S.extend(f.style,{width:"100%",height:"100%",background:"none"}),l(f,"top","rgba(0,0,0,0)","#000"),S.extend(h.__hue_field.style,{width:"15px",height:"100px",border:"1px solid #555",cursor:"ns-resize",position:"absolute",top:"3px",right:"3px"}),d(h.__hue_field),S.extend(h.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:h.__input_textShadow+"rgba(0,0,0,0.7)"}),X.bind(h.__saturation_field,"mousedown",o),X.bind(h.__saturation_field,"touchstart",o),X.bind(h.__field_knob,"mousedown",o),X.bind(h.__field_knob,"touchstart",o),X.bind(h.__hue_field,"mousedown",i),X.bind(h.__hue_field,"touchstart",i),h.__saturation_field.appendChild(f),h.__selector.appendChild(h.__field_knob),h.__selector.appendChild(h.__saturation_field),h.__selector.appendChild(h.__hue_field),h.__hue_field.appendChild(h.__hue_knob),h.domElement.appendChild(h.__input),h.domElement.appendChild(h.__selector),h.updateDisplay(),h}return D(t,z),P(t,[{key:"updateDisplay",value:function(){var e=R(this.getValue());if(!1!==e){var t=!1;S.each(I.COMPONENTS,function(n){if(!S.isUndefined(e[n])&&!S.isUndefined(this.__color.__state[n])&&e[n]!==this.__color.__state[n])return t=!0,{}},this),t&&S.extend(this.__color.__state,e)}S.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var n=this.__color.v<.5||this.__color.s>.5?255:0,o=255-n;S.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toHexString(),border:this.__field_knob_border+"rgb("+n+","+n+","+n+")"}),this.__hue_knob.style.marginTop=100*(1-this.__color.h/360)+"px",this.__temp.s=1,this.__temp.v=1,l(this.__saturation_field,"left","#fff",this.__temp.toHexString()),this.__input.value=this.__color.toString(),S.extend(this.__input.style,{backgroundColor:this.__color.toHexString(),color:"rgb("+n+","+n+","+n+")",textShadow:this.__input_textShadow+"rgba("+o+","+o+","+o+",.7)"})}}]),t}(),ee=["-moz-","-o-","-webkit-","-ms-",""],te={load:function(e,t){var n=t||document,o=n.createElement("link");o.type="text/css",o.rel="stylesheet",o.href=e,n.getElementsByTagName("head")[0].appendChild(o)},inject:function(e,t){var n=t||document,o=document.createElement("style");o.type="text/css",o.innerHTML=e;var i=n.getElementsByTagName("head")[0];try{i.appendChild(o)}catch(e){}}},ne=function(e,t){var n=e[t];return S.isArray(arguments[2])||S.isObject(arguments[2])?new Y(e,t,arguments[2]):S.isNumber(n)?S.isNumber(arguments[2])&&S.isNumber(arguments[3])?S.isNumber(arguments[4])?new q(e,t,arguments[2],arguments[3],arguments[4]):new q(e,t,arguments[2],arguments[3]):S.isNumber(arguments[4])?new Q(e,t,{min:arguments[2],max:arguments[3],step:arguments[4]}):new Q(e,t,{min:arguments[2],max:arguments[3]}):S.isString(n)?new J(e,t):S.isFunction(n)?new Z(e,t,""):S.isBoolean(n)?new K(e,t):null},oe=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)},ie=function(){function e(){F(this,e),this.backgroundElement=document.createElement("div"),S.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear",transition:"opacity 0.2s linear"}),X.makeFullscreen(this.backgroundElement),this.backgroundElement.style.position="fixed",this.domElement=document.createElement("div"),S.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear",transition:"transform 0.2s ease-out, opacity 0.2s linear"}),document.body.appendChild(this.backgroundElement),document.body.appendChild(this.domElement);var t=this;X.bind(this.backgroundElement,"click",function(){t.hide()})}return P(e,[{key:"show",value:function(){var e=this;this.backgroundElement.style.display="block",this.domElement.style.display="block",this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)",this.layout(),S.defer(function(){e.backgroundElement.style.opacity=1,e.domElement.style.opacity=1,e.domElement.style.webkitTransform="scale(1)"})}},{key:"hide",value:function(){var e=this,t=function t(){e.domElement.style.display="none",e.backgroundElement.style.display="none",X.unbind(e.domElement,"webkitTransitionEnd",t),X.unbind(e.domElement,"transitionend",t),X.unbind(e.domElement,"oTransitionEnd",t)};X.bind(this.domElement,"webkitTransitionEnd",t),X.bind(this.domElement,"transitionend",t),X.bind(this.domElement,"oTransitionEnd",t),this.backgroundElement.style.opacity=0,this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)"}},{key:"layout",value:function(){this.domElement.style.left=window.innerWidth/2-X.getWidth(this.domElement)/2+"px",this.domElement.style.top=window.innerHeight/2-X.getHeight(this.domElement)/2+"px"}}]),e}(),re=function(e){if(e&&"undefined"!=typeof window){var t=document.createElement("style");return t.setAttribute("type","text/css"),t.innerHTML=e,document.head.appendChild(t),e}}(".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n");te.inject(re);var se="Default",ae=function(){try{return!!window.localStorage}catch(e){return!1}}(),le=void 0,de=!0,ce=void 0,ue=!1,_e=[],he=function e(t){var n=this,o=t||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),X.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],o=S.defaults(o,{closeOnTop:!1,autoPlace:!0,width:e.DEFAULT_WIDTH}),o=S.defaults(o,{resizable:o.autoPlace,hideable:o.autoPlace}),S.isUndefined(o.load)?o.load={preset:se}:o.preset&&(o.load.preset=o.preset),S.isUndefined(o.parent)&&o.hideable&&_e.push(this),o.resizable=S.isUndefined(o.parent)&&o.resizable,o.autoPlace&&S.isUndefined(o.scrollable)&&(o.scrollable=!0);var i=ae&&"true"===localStorage.getItem(m(this,"isLocal")),r=void 0,s=void 0;if(Object.defineProperties(this,{parent:{get:function(){return o.parent}},scrollable:{get:function(){return o.scrollable}},autoPlace:{get:function(){return o.autoPlace}},closeOnTop:{get:function(){return o.closeOnTop}},preset:{get:function(){return n.parent?n.getRoot().preset:o.load.preset},set:function(e){n.parent?n.getRoot().preset=e:o.load.preset=e,E(this),n.revert()}},width:{get:function(){return o.width},set:function(e){o.width=e,w(n,e)}},name:{get:function(){return o.name},set:function(e){o.name=e,s&&(s.innerHTML=o.name)}},closed:{get:function(){return o.closed},set:function(t){o.closed=t,o.closed?X.addClass(n.__ul,e.CLASS_CLOSED):X.removeClass(n.__ul,e.CLASS_CLOSED),this.onResize(),n.__closeButton&&(n.__closeButton.innerHTML=t?e.TEXT_OPEN:e.TEXT_CLOSED)}},load:{get:function(){return o.load}},useLocalStorage:{get:function(){return i},set:function(e){ae&&(i=e,e?X.bind(window,"unload",r):X.unbind(window,"unload",r),localStorage.setItem(m(n,"isLocal"),e))}}}),S.isUndefined(o.parent)){if(o.closed=!1,X.addClass(this.domElement,e.CLASS_MAIN),X.makeSelectable(this.domElement,!1),ae&&i){n.useLocalStorage=!0;var a=localStorage.getItem(m(this,"gui"));a&&(o.load=JSON.parse(a))}this.__closeButton=document.createElement("div"),this.__closeButton.innerHTML=e.TEXT_CLOSED,X.addClass(this.__closeButton,e.CLASS_CLOSE_BUTTON),o.closeOnTop?(X.addClass(this.__closeButton,e.CLASS_CLOSE_TOP),this.domElement.insertBefore(this.__closeButton,this.domElement.childNodes[0])):(X.addClass(this.__closeButton,e.CLASS_CLOSE_BOTTOM),this.domElement.appendChild(this.__closeButton)),X.bind(this.__closeButton,"click",function(){n.closed=!n.closed})}else{void 0===o.closed&&(o.closed=!0);var l=document.createTextNode(o.name);X.addClass(l,"controller-name"),s=c(n,l);X.addClass(this.__ul,e.CLASS_CLOSED),X.addClass(s,"title"),X.bind(s,"click",function(e){return e.preventDefault(),n.closed=!n.closed,!1}),o.closed||(this.closed=!1)}o.autoPlace&&(S.isUndefined(o.parent)&&(de&&(ce=document.createElement("div"),X.addClass(ce,"dg"),X.addClass(ce,e.CLASS_AUTO_PLACE_CONTAINER),document.body.appendChild(ce),de=!1),ce.appendChild(this.domElement),X.addClass(this.domElement,e.CLASS_AUTO_PLACE)),this.parent||w(n,o.width)),this.__resizeHandler=function(){n.onResizeDebounced()},X.bind(window,"resize",this.__resizeHandler),X.bind(this.__ul,"webkitTransitionEnd",this.__resizeHandler),X.bind(this.__ul,"transitionend",this.__resizeHandler),X.bind(this.__ul,"oTransitionEnd",this.__resizeHandler),this.onResize(),o.resizable&&y(this),r=function(){ae&&"true"===localStorage.getItem(m(n,"isLocal"))&&localStorage.setItem(m(n,"gui"),JSON.stringify(n.getSaveObject()))},this.saveToLocalStorageIfPossible=r,o.parent||function(){var e=n.getRoot();e.width+=1,S.defer(function(){e.width-=1})}()};he.toggleHide=function(){ue=!ue,S.each(_e,function(e){e.domElement.style.display=ue?"none":""})},he.CLASS_AUTO_PLACE="a",he.CLASS_AUTO_PLACE_CONTAINER="ac",he.CLASS_MAIN="main",he.CLASS_CONTROLLER_ROW="cr",he.CLASS_TOO_TALL="taller-than-window",he.CLASS_CLOSED="closed",he.CLASS_CLOSE_BUTTON="close-button",he.CLASS_CLOSE_TOP="close-top",he.CLASS_CLOSE_BOTTOM="close-bottom",he.CLASS_DRAG="drag",he.DEFAULT_WIDTH=245,he.TEXT_CLOSED="Close Controls",he.TEXT_OPEN="Open Controls",he._keydownHandler=function(e){"text"===document.activeElement.type||72!==e.which&&72!==e.keyCode||he.toggleHide()},X.bind(window,"keydown",he._keydownHandler,!1),S.extend(he.prototype,{add:function(e,t){return f(this,e,t,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(e,t){return f(this,e,t,{color:!0})},remove:function(e){this.__ul.removeChild(e.__li),this.__controllers.splice(this.__controllers.indexOf(e),1);var t=this;S.defer(function(){t.onResize()})},destroy:function(){if(this.parent)throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");this.autoPlace&&ce.removeChild(this.domElement);var e=this;S.each(this.__folders,function(t){e.removeFolder(t)}),X.unbind(window,"keydown",he._keydownHandler,!1),u(this)},addFolder:function(e){if(void 0!==this.__folders[e])throw new Error('You already have a folder in this GUI by the name "'+e+'"');var t={name:e,parent:this};t.autoPlace=this.autoPlace,this.load&&this.load.folders&&this.load.folders[e]&&(t.closed=this.load.folders[e].closed,t.load=this.load.folders[e]);var n=new he(t);this.__folders[e]=n;var o=c(this,n.domElement);return X.addClass(o,"folder"),n},removeFolder:function(e){this.__ul.removeChild(e.domElement.parentElement),delete this.__folders[e.name],this.load&&this.load.folders&&this.load.folders[e.name]&&delete this.load.folders[e.name],u(e);var t=this;S.each(e.__folders,function(t){e.removeFolder(t)}),S.defer(function(){t.onResize()})},open:function(){this.closed=!1},close:function(){this.closed=!0},onResize:function(){var e=this.getRoot();if(e.scrollable){var t=X.getOffset(e.__ul).top,n=0;S.each(e.__ul.childNodes,function(t){e.autoPlace&&t===e.__save_row||(n+=X.getHeight(t))}),window.innerHeight-t-20\n\n Here\'s the new load parameter for your GUI
\'s constructor:\n\n \n\n \n\n
Automatically save\n values to
localStorage
on exit.\n\n
The values saved to localStorage
will\n override those passed to dat.GUI
\'s constructor. This makes it\n easier to work incrementally, but localStorage
is fragile,\n and your friends may not see the same values you do.\n\n
\n\n
\n\n'),this.parent)throw new Error("You can only call remember on a top level GUI.");var e=this;S.each(Array.prototype.slice.call(arguments),function(t){0===e.__rememberedObjects.length&&v(e),-1===e.__rememberedObjects.indexOf(t)&&e.__rememberedObjects.push(t)}),this.autoPlace&&w(this,this.width)},getRoot:function(){for(var e=this;e.parent;)e=e.parent;return e},getSaveObject:function(){var e=this.load;return e.closed=this.closed,this.__rememberedObjects.length>0&&(e.preset=this.preset,e.remembered||(e.remembered={}),e.remembered[this.preset]=x(this)),e.folders={},S.each(this.__folders,function(t,n){e.folders[n]=t.getSaveObject()}),e},save:function(){this.load.remembered||(this.load.remembered={}),this.load.remembered[this.preset]=x(this),_(this,!1),this.saveToLocalStorageIfPossible()},saveAs:function(e){this.load.remembered||(this.load.remembered={},this.load.remembered[se]=x(this,!0)),this.load.remembered[e]=x(this),this.preset=e,g(this,e,!0),this.saveToLocalStorageIfPossible()},revert:function(e){S.each(this.__controllers,function(t){this.getRoot().load.remembered?p(e||this.getRoot(),t):t.setValue(t.initialValue),t.__onFinishChange&&t.__onFinishChange.call(t,t.getValue())},this),S.each(this.__folders,function(e){e.revert(e)}),e||_(this.getRoot(),!1)},listen:function(e){var t=0===this.__listening.length;this.__listening.push(e),t&&C(this.__listening)},updateDisplay:function(){S.each(this.__controllers,function(e){e.updateDisplay()}),S.each(this.__folders,function(e){e.updateDisplay()})}});var pe={Color:I,math:N,interpret:R},fe={Controller:z,BooleanController:K,OptionController:Y,StringController:J,NumberController:W,NumberControllerBox:Q,NumberControllerSlider:q,FunctionController:Z,ColorController:$},me={dom:X},ge={GUI:he},be=he,ve={color:pe,controllers:fe,dom:me,gui:ge,GUI:be};e.color=pe,e.controllers=fe,e.dom=me,e.gui=ge,e.GUI=be,e.default=ve,Object.defineProperty(e,"__esModule",{value:!0})});
\ No newline at end of file
diff --git "a/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/index.html" "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/index.html"
new file mode 100644
index 0000000..444493d
--- /dev/null
+++ "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/index.html"
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+ WebGL Fluid Simulation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/preview.jpg" "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/preview.jpg"
new file mode 100644
index 0000000..542cb3c
Binary files /dev/null and "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/preview.jpg" differ
diff --git "a/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/script.js" "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/script.js"
new file mode 100644
index 0000000..df8a7dc
--- /dev/null
+++ "b/code-nav-home/covers/dynamic/02-\344\270\203\345\275\251\344\272\221\351\233\276/script.js"
@@ -0,0 +1,1499 @@
+'use strict';
+
+const canvas = document.getElementsByTagName('canvas')[0];
+canvas.width = canvas.clientWidth;
+canvas.height = canvas.clientHeight;
+
+Array.prototype.getRandom = function() {
+ return this[Math.floor(Math.random() * this.length)];
+};
+
+let splatColors = [{ r: 0, g: 0.15, b: 0 }];
+
+let idleSplats;
+
+function idleSplatsFunction() {
+ multipleSplats(parseInt(Math.random() * config.RANDOM_AMOUNT) + (config.RANDOM_AMOUNT / 2) + 1);
+}
+
+let config = {
+ SIM_RESOLUTION: 256,
+ DYE_RESOLUTION: 1024,
+ DENSITY_DISSIPATION: 0.97,
+ VELOCITY_DISSIPATION: 0.98,
+ PRESSURE_DISSIPATION: 0.8,
+ PRESSURE_ITERATIONS: 20,
+ CURL: 30,
+ SPLAT_RADIUS: 0.3,
+ SHADING: true,
+ COLORFUL: true,
+ PAUSED: false,
+ BACK_COLOR: { r: 0, g: 0, b: 0 },
+ TRANSPARENT: false,
+ BLOOM: true,
+ BLOOM_ITERATIONS: 8,
+ BLOOM_RESOLUTION: 256,
+ BLOOM_INTENSITY: 0.8,
+ BLOOM_THRESHOLD: 0.6,
+ BLOOM_SOFT_KNEE: 0.7,
+ POINTER_COLOR: [{ r: 0, g: 0.15, b: 0 }],
+ SOUND_SENSITIVITY: 0.25,
+ AUDIO_RESPONSIVE: true,
+ FREQ_RANGE: 8,
+ FREQ_RANGE_START: 0,
+ IDLE_SPLATS: false,
+ RANDOM_AMOUNT: 10,
+ RANDOM_INTERVAL: 1,
+ SPLAT_ON_CLICK: true,
+ SHOW_MOUSE_MOVEMENT: true
+};
+
+document.addEventListener("DOMContentLoaded", () => {
+ window.wallpaperPropertyListener = {
+ applyUserProperties: (properties) => {
+ if (properties.bloom_intensity) config.BLOOM_INTENSITY = properties.bloom_intensity.value;
+ if (properties.bloom_threshold) config.BLOOM_THRESHOLD = properties.bloom_threshold.value;
+ if (properties.colorful) config.COLORFUL = properties.colorful.value;
+ if (properties.density_diffusion) config.DENSITY_DISSIPATION = properties.density_diffusion.value;
+ if (properties.enable_bloom) config.BLOOM = properties.enable_bloom.value;
+ if (properties.paused) config.PAUSED = properties.paused.value;
+ if (properties.pressure_diffusion) config.PRESSURE_DISSIPATION = properties.pressure_diffusion.value;
+ if (properties.shading) config.SHADING = properties.shading.value;
+ if (properties.splat_radius) config.SPLAT_RADIUS = properties.splat_radius.value;
+ if (properties.velocity_diffusion) config.VELOCITY_DISSIPATION = properties.velocity_diffusion.value;
+ if (properties.vorticity) config.CURL = properties.vorticity.value;
+ if (properties.sound_sensitivity) config.SOUND_SENSITIVITY = properties.sound_sensitivity.value;
+ if (properties.audio_responsive) config.AUDIO_RESPONSIVE = properties.audio_responsive.value;
+ if (properties.simulation_resolution) {
+ config.SIM_RESOLUTION = properties.simulation_resolution.value;
+ initFramebuffers();
+ }
+ if (properties.dye_resolution) {
+ config.DYE_RESOLUTION = properties.dye_resolution.value;
+ initFramebuffers();
+ }
+ if (properties.splat_color) {
+ splatColors[0] = rgbToPointerColor(properties.splat_color.value);
+ if (!config.COLORFUL) config.POINTER_COLOR = [splatColors[0]];
+ }
+ if (properties.splat_color_2) splatColors[1] = rgbToPointerColor(properties.splat_color_2.value);
+ if (properties.splat_color_3) splatColors[2] = rgbToPointerColor(properties.splat_color_3.value);
+ if (properties.splat_color_4) splatColors[3] = rgbToPointerColor(properties.splat_color_4.value);
+ if (properties.splat_color_5) splatColors[4] = rgbToPointerColor(properties.splat_color_5.value);
+ if (properties.background_color) {
+ let c = properties.background_color.value.split(" "),
+ r = Math.floor(c[0]*255),
+ g = Math.floor(c[1]*255),
+ b = Math.floor(c[2]*255);
+ document.body.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
+ config.BACK_COLOR.r = r;
+ config.BACK_COLOR.g = g;
+ config.BACK_COLOR.b = b;
+ }
+ if (properties.more_colors && !properties.more_colors.value) {
+ config.POINTER_COLOR = [splatColors[0]];
+ } else if (properties.more_colors && properties.more_colors.value) {
+ config.POINTER_COLOR = splatColors;
+ }
+ if (properties.use_background_image) config.TRANSPARENT = properties.use_background_image.value;
+ if (properties.background_image) canvas.style.backgroundImage = `url("file:///${properties.background_image.value}")`;
+ if (properties.repeat_background) canvas.style.backgroundRepeat = properties.repeat_background.value ? "repeat" : "no-repeat";
+ if (properties.background_image_size) canvas.style.backgroundSize = properties.background_image_size.value;
+ if (properties.frequency_range) {
+ config.FREQ_RANGE = properties.frequency_range.value;
+
+ if (config.FREQ_RANGE + config.FREQ_RANGE_START > 61) {
+ config.FREQ_RANGE_START = 62 - config.FREQ_RANGE;
+ }
+ }
+ if (properties.frequency_range_start) {
+ if (config.FREQ_RANGE + properties.frequency_range_start.value > 61) {
+ config.FREQ_RANGE_START = 62 - config.FREQ_RANGE;
+ } else {
+ config.FREQ_RANGE_START = properties.frequency_range_start.value;
+ }
+ }
+ if (properties.idle_random_splats) {
+ config.IDLE_SPLATS = properties.idle_random_splats.value;
+ if (properties.idle_random_splats.value) {
+ idleSplats = setInterval(idleSplatsFunction, config.RANDOM_INTERVAL * 1000);
+ } else {
+ clearInterval(idleSplats);
+ }
+ }
+ if (properties.random_splat_interval) {
+ config.RANDOM_INTERVAL = properties.random_splat_interval.value;
+ if (config.IDLE_SPLATS) {
+ clearInterval(idleSplats);
+ idleSplats = setInterval(idleSplatsFunction, config.RANDOM_INTERVAL * 1000);
+ }
+ }
+ if (properties.random_splat_amount) {
+ config.RANDOM_AMOUNT = properties.random_splat_amount.value;
+ if (config.IDLE_SPLATS) {
+ clearInterval(idleSplats);
+ idleSplats = setInterval(idleSplatsFunction, config.RANDOM_INTERVAL * 1000);
+ }
+ }
+ if (properties.splat_on_click) config.SPLAT_ON_CLICK = properties.splat_on_click.value;
+ if (properties.show_mouse_movement) config.SHOW_MOUSE_MOVEMENT = properties.show_mouse_movement.value;
+ }
+ };
+
+ window.wallpaperRegisterAudioListener((audioArray) => {
+ if (!config.AUDIO_RESPONSIVE) return;
+ if (audioArray[0] > 5) return;
+
+ let bass = 0.0;
+ let half = Math.floor(audioArray.length / 2);
+
+ for (let i = 0; i <= config.FREQ_RANGE; i++) {
+ bass += audioArray[i + config.FREQ_RANGE_START];
+ bass += audioArray[half + (i + config.FREQ_RANGE_START)];
+ }
+ bass /= (config.FREQ_RANGE * 2);
+ multipleSplats(Math.floor((bass * config.SOUND_SENSITIVITY) * 10));
+ });
+});
+
+function indexOfMax(arr) {
+ if (arr.length === 0) {
+ return -1;
+ }
+
+ var max = arr[0];
+ var maxIndex = 0;
+
+ for (var i = 1; i < arr.length; i++) {
+ if (arr[i] > max) {
+ maxIndex = i;
+ max = arr[i];
+ }
+ }
+
+ return maxIndex;
+}
+
+class pointerPrototype {
+ constructor() {
+ this.id = -1;
+ this.x = 0;
+ this.y = 0;
+ this.dx = 0;
+ this.dy = 0;
+ this.down = false;
+ this.moved = false;
+ this.color = config.COLORFUL ? generateColor() : config.POINTER_COLOR.getRandom();
+ }
+}
+
+let pointers = [];
+let splatStack = [];
+let bloomFramebuffers = [];
+pointers.push(new pointerPrototype());
+
+const { gl, ext } = getWebGLContext(canvas);
+
+if (isMobile())
+ config.SHADING = false;
+if (!ext.supportLinearFiltering)
+{
+ config.SHADING = false;
+ config.BLOOM = false;
+}
+
+// startGUI();
+
+function getWebGLContext (canvas) {
+ const params = { alpha: true, depth: false, stencil: false, antialias: false, preserveDrawingBuffer: false };
+
+ let gl = canvas.getContext('webgl2', params);
+ const isWebGL2 = !!gl;
+ if (!isWebGL2)
+ gl = canvas.getContext('webgl', params) || canvas.getContext('experimental-webgl', params);
+
+ let halfFloat;
+ let supportLinearFiltering;
+ if (isWebGL2) {
+ gl.getExtension('EXT_color_buffer_float');
+ supportLinearFiltering = gl.getExtension('OES_texture_float_linear');
+ } else {
+ halfFloat = gl.getExtension('OES_texture_half_float');
+ supportLinearFiltering = gl.getExtension('OES_texture_half_float_linear');
+ }
+
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+
+ const halfFloatTexType = isWebGL2 ? gl.HALF_FLOAT : halfFloat.HALF_FLOAT_OES;
+ let formatRGBA;
+ let formatRG;
+ let formatR;
+
+ if (isWebGL2)
+ {
+ formatRGBA = getSupportedFormat(gl, gl.RGBA16F, gl.RGBA, halfFloatTexType);
+ formatRG = getSupportedFormat(gl, gl.RG16F, gl.RG, halfFloatTexType);
+ formatR = getSupportedFormat(gl, gl.R16F, gl.RED, halfFloatTexType);
+ }
+ else
+ {
+ formatRGBA = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType);
+ formatRG = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType);
+ formatR = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType);
+ }
+
+ return {
+ gl,
+ ext: {
+ formatRGBA,
+ formatRG,
+ formatR,
+ halfFloatTexType,
+ supportLinearFiltering
+ }
+ };
+}
+
+function getSupportedFormat (gl, internalFormat, format, type)
+{
+ if (!supportRenderTextureFormat(gl, internalFormat, format, type))
+ {
+ switch (internalFormat)
+ {
+ case gl.R16F:
+ return getSupportedFormat(gl, gl.RG16F, gl.RG, type);
+ case gl.RG16F:
+ return getSupportedFormat(gl, gl.RGBA16F, gl.RGBA, type);
+ default:
+ return null;
+ }
+ }
+
+ return {
+ internalFormat,
+ format
+ }
+}
+
+function supportRenderTextureFormat (gl, internalFormat, format, type) {
+ let texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 4, 4, 0, format, type, null);
+
+ let fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+
+ const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (status != gl.FRAMEBUFFER_COMPLETE)
+ return false;
+ return true;
+}
+
+function startGUI () {
+ var gui = new dat.GUI({ width: 300 });
+ gui.add(config, 'SIM_RESOLUTION', { '32': 32, '64': 64, '128': 128, '256': 256 }).name('sim resolution').onFinishChange(initFramebuffers);
+ gui.add(config, 'DYE_RESOLUTION', { '128': 128, '256': 256, '512': 512, '1024': 1024 }).name('dye resolution').onFinishChange(initFramebuffers);
+ gui.add(config, 'DENSITY_DISSIPATION', 0.9, 1.0).name('density diffusion');
+ gui.add(config, 'VELOCITY_DISSIPATION', 0.9, 1.0).name('velocity diffusion');
+ gui.add(config, 'PRESSURE_DISSIPATION', 0.0, 1.0).name('pressure diffusion');
+ gui.add(config, 'CURL', 0, 50).name('vorticity').step(1);
+ gui.add(config, 'SPLAT_RADIUS', 0.01, 1.0).name('splat radius');
+ gui.add(config, 'SHADING').name('shading');
+ gui.add(config, 'COLORFUL').name('colorful');
+ gui.add(config, 'PAUSED').name('paused').listen();
+
+ gui.add({ fun: () => {
+ splatStack.push(parseInt(Math.random() * 20) + 5);
+ } }, 'fun').name('Random splats');
+
+ let bloomFolder = gui.addFolder('Bloom');
+ bloomFolder.add(config, 'BLOOM').name('enabled');
+ bloomFolder.add(config, 'BLOOM_INTENSITY', 0.1, 2.0).name('intensity');
+ bloomFolder.add(config, 'BLOOM_THRESHOLD', 0.0, 1.0).name('threshold');
+
+ let captureFolder = gui.addFolder('Capture');
+ captureFolder.addColor(config, 'BACK_COLOR').name('background color');
+ captureFolder.add(config, 'TRANSPARENT').name('transparent');
+ captureFolder.add({ fun: captureScreenshot }, 'fun').name('take screenshot');
+
+ let github = gui.add({ fun : () => {
+ window.open('https://github.com/PavelDoGreat/WebGL-Fluid-Simulation');
+ } }, 'fun').name('Github');
+ github.__li.className = 'cr function bigFont';
+ github.__li.style.borderLeft = '3px solid #8C8C8C';
+ let githubIcon = document.createElement('span');
+ github.domElement.parentElement.appendChild(githubIcon);
+ githubIcon.className = 'icon github';
+
+ let twitter = gui.add({ fun : () => {
+ window.open('https://twitter.com/PavelDoGreat');
+ } }, 'fun').name('Twitter');
+ twitter.__li.className = 'cr function bigFont';
+ twitter.__li.style.borderLeft = '3px solid #8C8C8C';
+ let twitterIcon = document.createElement('span');
+ twitter.domElement.parentElement.appendChild(twitterIcon);
+ twitterIcon.className = 'icon twitter';
+
+ let discord = gui.add({ fun : () => {
+ window.open('https://discordapp.com/invite/CeqZDDE');
+ } }, 'fun').name('Discord');
+ discord.__li.className = 'cr function bigFont';
+ discord.__li.style.borderLeft = '3px solid #8C8C8C';
+ let discordIcon = document.createElement('span');
+ discord.domElement.parentElement.appendChild(discordIcon);
+ discordIcon.className = 'icon discord';
+
+ let app = gui.add({ fun : () => {
+ window.open('http://onelink.to/5b58bn');
+ } }, 'fun').name('Check out new improved version');
+ app.__li.className = 'cr function appBigFont';
+ app.__li.style.borderLeft = '3px solid #00FF7F';
+ let appIcon = document.createElement('span');
+ app.domElement.parentElement.appendChild(appIcon);
+ appIcon.className = 'icon app';
+
+ if (isMobile())
+ gui.close();
+}
+
+function captureScreenshot () {
+ colorProgram.bind();
+ gl.uniform4f(colorProgram.uniforms.color, 0, 0, 0, 1);
+ blit(density.write.fbo);
+
+ render(density.write.fbo);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, density.write.fbo);
+
+ let length = dyeWidth * dyeHeight * 4;
+ let pixels = new Float32Array(length);
+ gl.readPixels(0, 0, dyeWidth, dyeHeight, gl.RGBA, gl.FLOAT, pixels);
+
+ let newPixels = new Uint8Array(length);
+
+ let id = 0;
+ for (let i = dyeHeight - 1; i >= 0; i--) {
+ for (let j = 0; j < dyeWidth; j++) {
+ let nid = i * dyeWidth * 4 + j * 4;
+ newPixels[nid + 0] = clamp01(pixels[id + 0]) * 255;
+ newPixels[nid + 1] = clamp01(pixels[id + 1]) * 255;
+ newPixels[nid + 2] = clamp01(pixels[id + 2]) * 255;
+ newPixels[nid + 3] = clamp01(pixels[id + 3]) * 255;
+ id += 4;
+ }
+ }
+
+ let captureCanvas = document.createElement('canvas');
+ let ctx = captureCanvas.getContext('2d');
+ captureCanvas.width = dyeWidth;
+ captureCanvas.height = dyeHeight;
+
+ let imageData = ctx.createImageData(dyeWidth, dyeHeight);
+ imageData.data.set(newPixels);
+ ctx.putImageData(imageData, 0, 0);
+ let datauri = captureCanvas.toDataURL();
+
+ downloadURI("fluid.png", datauri);
+
+ URL.revokeObjectURL(datauri);
+}
+
+function clamp01 (input) {
+ return Math.min(Math.max(input, 0), 1);
+}
+
+function downloadURI (filename, uri) {
+ let link = document.createElement("a");
+ link.download = filename;
+ link.href = uri;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+}
+
+function isMobile () {
+ return /Mobi|Android/i.test(navigator.userAgent);
+}
+
+class GLProgram {
+ constructor (vertexShader, fragmentShader) {
+ this.uniforms = {};
+ this.program = gl.createProgram();
+
+ gl.attachShader(this.program, vertexShader);
+ gl.attachShader(this.program, fragmentShader);
+ gl.linkProgram(this.program);
+
+ if (!gl.getProgramParameter(this.program, gl.LINK_STATUS))
+ throw gl.getProgramInfoLog(this.program);
+
+ const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);
+ for (let i = 0; i < uniformCount; i++) {
+ const uniformName = gl.getActiveUniform(this.program, i).name;
+ this.uniforms[uniformName] = gl.getUniformLocation(this.program, uniformName);
+ }
+ }
+
+ bind () {
+ gl.useProgram(this.program);
+ }
+}
+
+function compileShader (type, source) {
+ const shader = gl.createShader(type);
+ gl.shaderSource(shader, source);
+ gl.compileShader(shader);
+
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
+ throw gl.getShaderInfoLog(shader);
+
+ return shader;
+};
+
+const baseVertexShader = compileShader(gl.VERTEX_SHADER, `
+ precision highp float;
+
+ attribute vec2 aPosition;
+ varying vec2 vUv;
+ varying vec2 vL;
+ varying vec2 vR;
+ varying vec2 vT;
+ varying vec2 vB;
+ uniform vec2 texelSize;
+
+ void main () {
+ vUv = aPosition * 0.5 + 0.5;
+ vL = vUv - vec2(texelSize.x, 0.0);
+ vR = vUv + vec2(texelSize.x, 0.0);
+ vT = vUv + vec2(0.0, texelSize.y);
+ vB = vUv - vec2(0.0, texelSize.y);
+ gl_Position = vec4(aPosition, 0.0, 1.0);
+ }
+`);
+
+const clearShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision mediump float;
+ precision mediump sampler2D;
+
+ varying highp vec2 vUv;
+ uniform sampler2D uTexture;
+ uniform float value;
+
+ void main () {
+ gl_FragColor = value * texture2D(uTexture, vUv);
+ }
+`);
+
+const colorShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision mediump float;
+
+ uniform vec4 color;
+
+ void main () {
+ gl_FragColor = color;
+ }
+`);
+
+const backgroundShader = compileShader(gl.FRAGMENT_SHADER, `
+ void main () {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ }
+`);
+
+const displayShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision highp float;
+ precision highp sampler2D;
+
+ varying vec2 vUv;
+ uniform sampler2D uTexture;
+
+ void main () {
+ vec3 C = texture2D(uTexture, vUv).rgb;
+ float a = max(C.r, max(C.g, C.b));
+ gl_FragColor = vec4(C, a);
+ }
+`);
+
+const displayBloomShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision highp float;
+ precision highp sampler2D;
+
+ varying vec2 vUv;
+ uniform sampler2D uTexture;
+ uniform sampler2D uBloom;
+ uniform sampler2D uDithering;
+ uniform vec2 ditherScale;
+
+ void main () {
+ vec3 C = texture2D(uTexture, vUv).rgb;
+ vec3 bloom = texture2D(uBloom, vUv).rgb;
+ bloom = pow(bloom.rgb, vec3(1.0 / 2.2));
+ C += bloom;
+ float a = max(C.r, max(C.g, C.b));
+ gl_FragColor = vec4(C, a);
+ }
+`);
+
+const displayShadingShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision highp float;
+ precision highp sampler2D;
+
+ varying vec2 vUv;
+ varying vec2 vL;
+ varying vec2 vR;
+ varying vec2 vT;
+ varying vec2 vB;
+ uniform sampler2D uTexture;
+ uniform vec2 texelSize;
+
+ void main () {
+ vec3 L = texture2D(uTexture, vL).rgb;
+ vec3 R = texture2D(uTexture, vR).rgb;
+ vec3 T = texture2D(uTexture, vT).rgb;
+ vec3 B = texture2D(uTexture, vB).rgb;
+ vec3 C = texture2D(uTexture, vUv).rgb;
+
+ float dx = length(R) - length(L);
+ float dy = length(T) - length(B);
+
+ vec3 n = normalize(vec3(dx, dy, length(texelSize)));
+ vec3 l = vec3(0.0, 0.0, 1.0);
+
+ float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);
+ C.rgb *= diffuse;
+
+ float a = max(C.r, max(C.g, C.b));
+ gl_FragColor = vec4(C, a);
+ }
+`);
+
+const displayBloomShadingShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision highp float;
+ precision highp sampler2D;
+
+ varying vec2 vUv;
+ varying vec2 vL;
+ varying vec2 vR;
+ varying vec2 vT;
+ varying vec2 vB;
+ uniform sampler2D uTexture;
+ uniform sampler2D uBloom;
+ uniform sampler2D uDithering;
+ uniform vec2 ditherScale;
+ uniform vec2 texelSize;
+
+ void main () {
+ vec3 L = texture2D(uTexture, vL).rgb;
+ vec3 R = texture2D(uTexture, vR).rgb;
+ vec3 T = texture2D(uTexture, vT).rgb;
+ vec3 B = texture2D(uTexture, vB).rgb;
+ vec3 C = texture2D(uTexture, vUv).rgb;
+
+ float dx = length(R) - length(L);
+ float dy = length(T) - length(B);
+
+ vec3 n = normalize(vec3(dx, dy, length(texelSize)));
+ vec3 l = vec3(0.0, 0.0, 1.0);
+
+ float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);
+ C *= diffuse;
+
+ vec3 bloom = texture2D(uBloom, vUv).rgb;
+ bloom = pow(bloom.rgb, vec3(1.0 / 2.2));
+ C += bloom;
+
+ float a = max(C.r, max(C.g, C.b));
+ gl_FragColor = vec4(C, a);
+ }
+`);
+
+const bloomPrefilterShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision mediump float;
+ precision mediump sampler2D;
+
+ varying vec2 vUv;
+ uniform sampler2D uTexture;
+ uniform vec3 curve;
+ uniform float threshold;
+
+ void main () {
+ vec3 c = texture2D(uTexture, vUv).rgb;
+ float br = max(c.r, max(c.g, c.b));
+ float rq = clamp(br - curve.x, 0.0, curve.y);
+ rq = curve.z * rq * rq;
+ c *= max(rq, br - threshold) / max(br, 0.0001);
+ gl_FragColor = vec4(c, 0.0);
+ }
+`);
+
+const bloomBlurShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision mediump float;
+ precision mediump sampler2D;
+
+ varying vec2 vL;
+ varying vec2 vR;
+ varying vec2 vT;
+ varying vec2 vB;
+ uniform sampler2D uTexture;
+
+ void main () {
+ vec4 sum = vec4(0.0);
+ sum += texture2D(uTexture, vL);
+ sum += texture2D(uTexture, vR);
+ sum += texture2D(uTexture, vT);
+ sum += texture2D(uTexture, vB);
+ sum *= 0.25;
+ gl_FragColor = sum;
+ }
+`);
+
+const bloomFinalShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision mediump float;
+ precision mediump sampler2D;
+
+ varying vec2 vL;
+ varying vec2 vR;
+ varying vec2 vT;
+ varying vec2 vB;
+ uniform sampler2D uTexture;
+ uniform float intensity;
+
+ void main () {
+ vec4 sum = vec4(0.0);
+ sum += texture2D(uTexture, vL);
+ sum += texture2D(uTexture, vR);
+ sum += texture2D(uTexture, vT);
+ sum += texture2D(uTexture, vB);
+ sum *= 0.25;
+ gl_FragColor = sum * intensity;
+ }
+`);
+
+const splatShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision highp float;
+ precision highp sampler2D;
+
+ varying vec2 vUv;
+ uniform sampler2D uTarget;
+ uniform float aspectRatio;
+ uniform vec3 color;
+ uniform vec2 point;
+ uniform float radius;
+
+ void main () {
+ vec2 p = vUv - point.xy;
+ p.x *= aspectRatio;
+ vec3 splat = exp(-dot(p, p) / radius) * color;
+ vec3 base = texture2D(uTarget, vUv).xyz;
+ gl_FragColor = vec4(base + splat, 1.0);
+ }
+`);
+
+const advectionManualFilteringShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision highp float;
+ precision highp sampler2D;
+
+ varying vec2 vUv;
+ uniform sampler2D uVelocity;
+ uniform sampler2D uSource;
+ uniform vec2 texelSize;
+ uniform vec2 dyeTexelSize;
+ uniform float dt;
+ uniform float dissipation;
+
+ vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) {
+ vec2 st = uv / tsize - 0.5;
+
+ vec2 iuv = floor(st);
+ vec2 fuv = fract(st);
+
+ vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize);
+ vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize);
+ vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize);
+ vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize);
+
+ return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y);
+ }
+
+ void main () {
+ vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize;
+ gl_FragColor = dissipation * bilerp(uSource, coord, dyeTexelSize);
+ gl_FragColor.a = 1.0;
+ }
+`);
+
+const advectionShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision highp float;
+ precision highp sampler2D;
+
+ varying vec2 vUv;
+ uniform sampler2D uVelocity;
+ uniform sampler2D uSource;
+ uniform vec2 texelSize;
+ uniform float dt;
+ uniform float dissipation;
+
+ void main () {
+ vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
+ gl_FragColor = dissipation * texture2D(uSource, coord);
+ gl_FragColor.a = 1.0;
+ }
+`);
+
+const divergenceShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision mediump float;
+ precision mediump sampler2D;
+
+ varying highp vec2 vUv;
+ varying highp vec2 vL;
+ varying highp vec2 vR;
+ varying highp vec2 vT;
+ varying highp vec2 vB;
+ uniform sampler2D uVelocity;
+
+ void main () {
+ float L = texture2D(uVelocity, vL).x;
+ float R = texture2D(uVelocity, vR).x;
+ float T = texture2D(uVelocity, vT).y;
+ float B = texture2D(uVelocity, vB).y;
+
+ vec2 C = texture2D(uVelocity, vUv).xy;
+ if (vL.x < 0.0) { L = -C.x; }
+ if (vR.x > 1.0) { R = -C.x; }
+ if (vT.y > 1.0) { T = -C.y; }
+ if (vB.y < 0.0) { B = -C.y; }
+
+ float div = 0.5 * (R - L + T - B);
+ gl_FragColor = vec4(div, 0.0, 0.0, 1.0);
+ }
+`);
+
+const curlShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision mediump float;
+ precision mediump sampler2D;
+
+ varying highp vec2 vUv;
+ varying highp vec2 vL;
+ varying highp vec2 vR;
+ varying highp vec2 vT;
+ varying highp vec2 vB;
+ uniform sampler2D uVelocity;
+
+ void main () {
+ float L = texture2D(uVelocity, vL).y;
+ float R = texture2D(uVelocity, vR).y;
+ float T = texture2D(uVelocity, vT).x;
+ float B = texture2D(uVelocity, vB).x;
+ float vorticity = R - L - T + B;
+ gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0);
+ }
+`);
+
+const vorticityShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision highp float;
+ precision highp sampler2D;
+
+ varying vec2 vUv;
+ varying vec2 vL;
+ varying vec2 vR;
+ varying vec2 vT;
+ varying vec2 vB;
+ uniform sampler2D uVelocity;
+ uniform sampler2D uCurl;
+ uniform float curl;
+ uniform float dt;
+
+ void main () {
+ float L = texture2D(uCurl, vL).x;
+ float R = texture2D(uCurl, vR).x;
+ float T = texture2D(uCurl, vT).x;
+ float B = texture2D(uCurl, vB).x;
+ float C = texture2D(uCurl, vUv).x;
+
+ vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));
+ force /= length(force) + 0.0001;
+ force *= curl * C;
+ force.y *= -1.0;
+
+ vec2 vel = texture2D(uVelocity, vUv).xy;
+ gl_FragColor = vec4(vel + force * dt, 0.0, 1.0);
+ }
+`);
+
+const pressureShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision mediump float;
+ precision mediump sampler2D;
+
+ varying highp vec2 vUv;
+ varying highp vec2 vL;
+ varying highp vec2 vR;
+ varying highp vec2 vT;
+ varying highp vec2 vB;
+ uniform sampler2D uPressure;
+ uniform sampler2D uDivergence;
+
+ vec2 boundary (vec2 uv) {
+ return uv;
+ // uncomment if you use wrap or repeat texture mode
+ // uv = min(max(uv, 0.0), 1.0);
+ // return uv;
+ }
+
+ void main () {
+ float L = texture2D(uPressure, boundary(vL)).x;
+ float R = texture2D(uPressure, boundary(vR)).x;
+ float T = texture2D(uPressure, boundary(vT)).x;
+ float B = texture2D(uPressure, boundary(vB)).x;
+ float C = texture2D(uPressure, vUv).x;
+ float divergence = texture2D(uDivergence, vUv).x;
+ float pressure = (L + R + B + T - divergence) * 0.25;
+ gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0);
+ }
+`);
+
+const gradientSubtractShader = compileShader(gl.FRAGMENT_SHADER, `
+ precision mediump float;
+ precision mediump sampler2D;
+
+ varying highp vec2 vUv;
+ varying highp vec2 vL;
+ varying highp vec2 vR;
+ varying highp vec2 vT;
+ varying highp vec2 vB;
+ uniform sampler2D uPressure;
+ uniform sampler2D uVelocity;
+
+ vec2 boundary (vec2 uv) {
+ return uv;
+ // uv = min(max(uv, 0.0), 1.0);
+ // return uv;
+ }
+
+ void main () {
+ float L = texture2D(uPressure, boundary(vL)).x;
+ float R = texture2D(uPressure, boundary(vR)).x;
+ float T = texture2D(uPressure, boundary(vT)).x;
+ float B = texture2D(uPressure, boundary(vB)).x;
+ vec2 velocity = texture2D(uVelocity, vUv).xy;
+ velocity.xy -= vec2(R - L, T - B);
+ gl_FragColor = vec4(velocity, 0.0, 1.0);
+ }
+`);
+
+const blit = (() => {
+ gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), gl.STATIC_DRAW);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 0, 2, 3]), gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
+ gl.enableVertexAttribArray(0);
+
+ return (destination) => {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, destination);
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+ }
+})();
+
+let simWidth;
+let simHeight;
+let dyeWidth;
+let dyeHeight;
+let density;
+let velocity;
+let divergence;
+let curl;
+let pressure;
+let bloom;
+
+let ditheringTexture = createTextureAsync('LDR_RGB1_0.png');
+
+const clearProgram = new GLProgram(baseVertexShader, clearShader);
+const colorProgram = new GLProgram(baseVertexShader, colorShader);
+const backgroundProgram = new GLProgram(baseVertexShader, backgroundShader);
+const displayProgram = new GLProgram(baseVertexShader, displayShader);
+const displayBloomProgram = new GLProgram(baseVertexShader, displayBloomShader);
+const displayShadingProgram = new GLProgram(baseVertexShader, displayShadingShader);
+const displayBloomShadingProgram = new GLProgram(baseVertexShader, displayBloomShadingShader);
+const bloomPrefilterProgram = new GLProgram(baseVertexShader, bloomPrefilterShader);
+const bloomBlurProgram = new GLProgram(baseVertexShader, bloomBlurShader);
+const bloomFinalProgram = new GLProgram(baseVertexShader, bloomFinalShader);
+const splatProgram = new GLProgram(baseVertexShader, splatShader);
+const advectionProgram = new GLProgram(baseVertexShader, ext.supportLinearFiltering ? advectionShader : advectionManualFilteringShader);
+const divergenceProgram = new GLProgram(baseVertexShader, divergenceShader);
+const curlProgram = new GLProgram(baseVertexShader, curlShader);
+const vorticityProgram = new GLProgram(baseVertexShader, vorticityShader);
+const pressureProgram = new GLProgram(baseVertexShader, pressureShader);
+const gradienSubtractProgram = new GLProgram(baseVertexShader, gradientSubtractShader);
+
+function initFramebuffers () {
+ let simRes = getResolution(config.SIM_RESOLUTION);
+ let dyeRes = getResolution(config.DYE_RESOLUTION);
+
+ simWidth = simRes.width;
+ simHeight = simRes.height;
+ dyeWidth = dyeRes.width;
+ dyeHeight = dyeRes.height;
+
+ const texType = ext.halfFloatTexType;
+ const rgba = ext.formatRGBA;
+ const rg = ext.formatRG;
+ const r = ext.formatR;
+ const filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST;
+
+ if (density == null)
+ density = createDoubleFBO(dyeWidth, dyeHeight, rgba.internalFormat, rgba.format, texType, filtering);
+ else
+ density = resizeDoubleFBO(density, dyeWidth, dyeHeight, rgba.internalFormat, rgba.format, texType, filtering);
+
+ if (velocity == null)
+ velocity = createDoubleFBO(simWidth, simHeight, rg.internalFormat, rg.format, texType, filtering);
+ else
+ velocity = resizeDoubleFBO(velocity, simWidth, simHeight, rg.internalFormat, rg.format, texType, filtering);
+
+ divergence = createFBO (simWidth, simHeight, r.internalFormat, r.format, texType, gl.NEAREST);
+ curl = createFBO (simWidth, simHeight, r.internalFormat, r.format, texType, gl.NEAREST);
+ pressure = createDoubleFBO(simWidth, simHeight, r.internalFormat, r.format, texType, gl.NEAREST);
+
+ initBloomFramebuffers();
+}
+
+function initBloomFramebuffers () {
+ let res = getResolution(config.BLOOM_RESOLUTION);
+
+ const texType = ext.halfFloatTexType;
+ const rgba = ext.formatRGBA;
+ const filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST;
+
+ bloom = createFBO(res.width, res.height, rgba.internalFormat, rgba.format, texType, filtering);
+
+ bloomFramebuffers.length = 0;
+ for (let i = 0; i < config.BLOOM_ITERATIONS; i++)
+ {
+ let width = res.width >> (i + 1);
+ let height = res.height >> (i + 1);
+
+ if (width < 2 || height < 2) break;
+
+ let fbo = createFBO(width, height, rgba.internalFormat, rgba.format, texType, filtering);
+ bloomFramebuffers.push(fbo);
+ }
+}
+
+function createFBO (w, h, internalFormat, format, type, param) {
+ gl.activeTexture(gl.TEXTURE0);
+ let texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, param);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, param);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, w, h, 0, format, type, null);
+
+ let fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.viewport(0, 0, w, h);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ return {
+ texture,
+ fbo,
+ width: w,
+ height: h,
+ attach (id) {
+ gl.activeTexture(gl.TEXTURE0 + id);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ return id;
+ }
+ };
+}
+
+function createDoubleFBO (w, h, internalFormat, format, type, param) {
+ let fbo1 = createFBO(w, h, internalFormat, format, type, param);
+ let fbo2 = createFBO(w, h, internalFormat, format, type, param);
+
+ return {
+ get read () {
+ return fbo1;
+ },
+ set read (value) {
+ fbo1 = value;
+ },
+ get write () {
+ return fbo2;
+ },
+ set write (value) {
+ fbo2 = value;
+ },
+ swap () {
+ let temp = fbo1;
+ fbo1 = fbo2;
+ fbo2 = temp;
+ }
+ }
+}
+
+function resizeFBO (target, w, h, internalFormat, format, type, param) {
+ let newFBO = createFBO(w, h, internalFormat, format, type, param);
+ clearProgram.bind();
+ gl.uniform1i(clearProgram.uniforms.uTexture, target.attach(0));
+ gl.uniform1f(clearProgram.uniforms.value, 1);
+ blit(newFBO.fbo);
+ return newFBO;
+}
+
+function resizeDoubleFBO (target, w, h, internalFormat, format, type, param) {
+ target.read = resizeFBO(target.read, w, h, internalFormat, format, type, param);
+ target.write = createFBO(w, h, internalFormat, format, type, param);
+ return target;
+}
+
+function createTextureAsync (url) {
+ let texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([255, 255, 255]));
+
+ let obj = {
+ texture,
+ width: 1,
+ height: 1,
+ attach (id) {
+ gl.activeTexture(gl.TEXTURE0 + id);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ return id;
+ }
+ };
+
+ let image = new Image();
+ image.onload = () => {
+ obj.width = image.width;
+ obj.height = image.height;
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
+ };
+ image.src = url;
+
+ return obj;
+}
+
+initFramebuffers();
+multipleSplats(parseInt(Math.random() * 20) + 3);
+
+let lastColorChangeTime = Date.now();
+
+update();
+
+function update () {
+ resizeCanvas();
+ input();
+ if (!config.PAUSED)
+ step(0.016);
+ render(null);
+ requestAnimationFrame(update);
+}
+
+function input () {
+ if (splatStack.length > 0)
+ multipleSplats(splatStack.pop());
+
+ for (let i = 0; i < pointers.length; i++) {
+ const p = pointers[i];
+ if (p.moved) {
+ splat(p.x, p.y, p.dx, p.dy, p.color);
+ p.moved = false;
+ }
+ }
+
+ if (lastColorChangeTime + 100 < Date.now())
+ {
+ lastColorChangeTime = Date.now();
+ for (let i = 0; i < pointers.length; i++) {
+ const p = pointers[i];
+ p.color = config.COLORFUL ? generateColor() : config.POINTER_COLOR.getRandom();
+ }
+ }
+}
+
+function step (dt) {
+ gl.disable(gl.BLEND);
+ gl.viewport(0, 0, simWidth, simHeight);
+
+ curlProgram.bind();
+ gl.uniform2f(curlProgram.uniforms.texelSize, 1.0 / simWidth, 1.0 / simHeight);
+ gl.uniform1i(curlProgram.uniforms.uVelocity, velocity.read.attach(0));
+ blit(curl.fbo);
+
+ vorticityProgram.bind();
+ gl.uniform2f(vorticityProgram.uniforms.texelSize, 1.0 / simWidth, 1.0 / simHeight);
+ gl.uniform1i(vorticityProgram.uniforms.uVelocity, velocity.read.attach(0));
+ gl.uniform1i(vorticityProgram.uniforms.uCurl, curl.attach(1));
+ gl.uniform1f(vorticityProgram.uniforms.curl, config.CURL);
+ gl.uniform1f(vorticityProgram.uniforms.dt, dt);
+ blit(velocity.write.fbo);
+ velocity.swap();
+
+ divergenceProgram.bind();
+ gl.uniform2f(divergenceProgram.uniforms.texelSize, 1.0 / simWidth, 1.0 / simHeight);
+ gl.uniform1i(divergenceProgram.uniforms.uVelocity, velocity.read.attach(0));
+ blit(divergence.fbo);
+
+ clearProgram.bind();
+ gl.uniform1i(clearProgram.uniforms.uTexture, pressure.read.attach(0));
+ gl.uniform1f(clearProgram.uniforms.value, config.PRESSURE_DISSIPATION);
+ blit(pressure.write.fbo);
+ pressure.swap();
+
+ pressureProgram.bind();
+ gl.uniform2f(pressureProgram.uniforms.texelSize, 1.0 / simWidth, 1.0 / simHeight);
+ gl.uniform1i(pressureProgram.uniforms.uDivergence, divergence.attach(0));
+ for (let i = 0; i < config.PRESSURE_ITERATIONS; i++) {
+ gl.uniform1i(pressureProgram.uniforms.uPressure, pressure.read.attach(1));
+ blit(pressure.write.fbo);
+ pressure.swap();
+ }
+
+ gradienSubtractProgram.bind();
+ gl.uniform2f(gradienSubtractProgram.uniforms.texelSize, 1.0 / simWidth, 1.0 / simHeight);
+ gl.uniform1i(gradienSubtractProgram.uniforms.uPressure, pressure.read.attach(0));
+ gl.uniform1i(gradienSubtractProgram.uniforms.uVelocity, velocity.read.attach(1));
+ blit(velocity.write.fbo);
+ velocity.swap();
+
+ advectionProgram.bind();
+ gl.uniform2f(advectionProgram.uniforms.texelSize, 1.0 / simWidth, 1.0 / simHeight);
+ if (!ext.supportLinearFiltering)
+ gl.uniform2f(advectionProgram.uniforms.dyeTexelSize, 1.0 / simWidth, 1.0 / simHeight);
+ let velocityId = velocity.read.attach(0);
+ gl.uniform1i(advectionProgram.uniforms.uVelocity, velocityId);
+ gl.uniform1i(advectionProgram.uniforms.uSource, velocityId);
+ gl.uniform1f(advectionProgram.uniforms.dt, dt);
+ gl.uniform1f(advectionProgram.uniforms.dissipation, config.VELOCITY_DISSIPATION);
+ blit(velocity.write.fbo);
+ velocity.swap();
+
+ gl.viewport(0, 0, dyeWidth, dyeHeight);
+
+ if (!ext.supportLinearFiltering)
+ gl.uniform2f(advectionProgram.uniforms.dyeTexelSize, 1.0 / dyeWidth, 1.0 / dyeHeight);
+ gl.uniform1i(advectionProgram.uniforms.uVelocity, velocity.read.attach(0));
+ gl.uniform1i(advectionProgram.uniforms.uSource, density.read.attach(1));
+ gl.uniform1f(advectionProgram.uniforms.dissipation, config.DENSITY_DISSIPATION);
+ blit(density.write.fbo);
+ density.swap();
+}
+
+function render (target) {
+ if (config.BLOOM)
+ applyBloom(density.read, bloom);
+
+ if (target == null || !config.TRANSPARENT) {
+ gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
+ gl.enable(gl.BLEND);
+ }
+ else {
+ gl.disable(gl.BLEND);
+ }
+
+ let width = target == null ? gl.drawingBufferWidth : dyeWidth;
+ let height = target == null ? gl.drawingBufferHeight : dyeHeight;
+
+ gl.viewport(0, 0, width, height);
+
+ if (!config.TRANSPARENT) {
+ colorProgram.bind();
+ let bc = config.BACK_COLOR;
+ gl.uniform4f(colorProgram.uniforms.color, bc.r / 255, bc.g / 255, bc.b / 255, 1);
+ blit(target);
+ }
+
+ if (target == null && config.TRANSPARENT) {
+ backgroundProgram.bind();
+ gl.uniform1f(backgroundProgram.uniforms.aspectRatio, canvas.width / canvas.height);
+ blit(null);
+ }
+
+ if (config.SHADING) {
+ let program = config.BLOOM ? displayBloomShadingProgram : displayShadingProgram;
+ program.bind();
+ gl.uniform2f(program.uniforms.texelSize, 1.0 / width, 1.0 / height);
+ gl.uniform1i(program.uniforms.uTexture, density.read.attach(0));
+ if (config.BLOOM) {
+ gl.uniform1i(program.uniforms.uBloom, bloom.attach(1));
+ gl.uniform1i(program.uniforms.uDithering, ditheringTexture.attach(2));
+ let scale = getTextureScale(ditheringTexture, width, height);
+ gl.uniform2f(program.uniforms.ditherScale, scale.x, scale.y);
+ }
+ }
+ else {
+ let program = config.BLOOM ? displayBloomProgram : displayProgram;
+ program.bind();
+ gl.uniform1i(program.uniforms.uTexture, density.read.attach(0));
+ if (config.BLOOM) {
+ gl.uniform1i(program.uniforms.uBloom, bloom.attach(1));
+ gl.uniform1i(program.uniforms.uDithering, ditheringTexture.attach(2));
+ let scale = getTextureScale(ditheringTexture, width, height);
+ gl.uniform2f(program.uniforms.ditherScale, scale.x, scale.y);
+ }
+ }
+
+ blit(target);
+}
+
+function applyBloom (source, destination) {
+ if (bloomFramebuffers.length < 2)
+ return;
+
+ let last = destination;
+
+ gl.disable(gl.BLEND);
+ bloomPrefilterProgram.bind();
+ let knee = config.BLOOM_THRESHOLD * config.BLOOM_SOFT_KNEE + 0.0001;
+ let curve0 = config.BLOOM_THRESHOLD - knee;
+ let curve1 = knee * 2;
+ let curve2 = 0.25 / knee;
+ gl.uniform3f(bloomPrefilterProgram.uniforms.curve, curve0, curve1, curve2);
+ gl.uniform1f(bloomPrefilterProgram.uniforms.threshold, config.BLOOM_THRESHOLD);
+ gl.uniform1i(bloomPrefilterProgram.uniforms.uTexture, source.attach(0));
+ gl.viewport(0, 0, last.width, last.height);
+ blit(last.fbo);
+
+ bloomBlurProgram.bind();
+ for (let i = 0; i < bloomFramebuffers.length; i++) {
+ let dest = bloomFramebuffers[i];
+ gl.uniform2f(bloomBlurProgram.uniforms.texelSize, 1.0 / last.width, 1.0 / last.height);
+ gl.uniform1i(bloomBlurProgram.uniforms.uTexture, last.attach(0));
+ gl.viewport(0, 0, dest.width, dest.height);
+ blit(dest.fbo);
+ last = dest;
+ }
+
+ gl.blendFunc(gl.ONE, gl.ONE);
+ gl.enable(gl.BLEND);
+
+ for (let i = bloomFramebuffers.length - 2; i >= 0; i--) {
+ let baseTex = bloomFramebuffers[i];
+ gl.uniform2f(bloomBlurProgram.uniforms.texelSize, 1.0 / last.width, 1.0 / last.height);
+ gl.uniform1i(bloomBlurProgram.uniforms.uTexture, last.attach(0));
+ gl.viewport(0, 0, baseTex.width, baseTex.height);
+ blit(baseTex.fbo);
+ last = baseTex;
+ }
+
+ gl.disable(gl.BLEND);
+ bloomFinalProgram.bind();
+ gl.uniform2f(bloomFinalProgram.uniforms.texelSize, 1.0 / last.width, 1.0 / last.height);
+ gl.uniform1i(bloomFinalProgram.uniforms.uTexture, last.attach(0));
+ gl.uniform1f(bloomFinalProgram.uniforms.intensity, config.BLOOM_INTENSITY);
+ gl.viewport(0, 0, destination.width, destination.height);
+ blit(destination.fbo);
+}
+
+function splat (x, y, dx, dy, color) {
+ gl.viewport(0, 0, simWidth, simHeight);
+ splatProgram.bind();
+ gl.uniform1i(splatProgram.uniforms.uTarget, velocity.read.attach(0));
+ gl.uniform1f(splatProgram.uniforms.aspectRatio, canvas.width / canvas.height);
+ gl.uniform2f(splatProgram.uniforms.point, x / canvas.width, 1.0 - y / canvas.height);
+ gl.uniform3f(splatProgram.uniforms.color, dx, -dy, 1.0);
+ gl.uniform1f(splatProgram.uniforms.radius, config.SPLAT_RADIUS / 100.0);
+ blit(velocity.write.fbo);
+ velocity.swap();
+
+ gl.viewport(0, 0, dyeWidth, dyeHeight);
+ gl.uniform1i(splatProgram.uniforms.uTarget, density.read.attach(0));
+ gl.uniform3f(splatProgram.uniforms.color, color.r, color.g, color.b);
+ blit(density.write.fbo);
+ density.swap();
+}
+
+function multipleSplats (amount) {
+ for (let i = 0; i < amount; i++) {
+ const color = config.COLORFUL ? generateColor() : Object.assign({}, config.POINTER_COLOR.getRandom());
+ color.r *= 10.0;
+ color.g *= 10.0;
+ color.b *= 10.0;
+ const x = canvas.width * Math.random();
+ const y = canvas.height * Math.random();
+ const dx = 1000 * (Math.random() - 0.5);
+ const dy = 1000 * (Math.random() - 0.5);
+ splat(x, y, dx, dy, color);
+ }
+}
+
+function resizeCanvas () {
+ if (canvas.width != canvas.clientWidth || canvas.height != canvas.clientHeight) {
+ canvas.width = canvas.clientWidth;
+ canvas.height = canvas.clientHeight;
+ initFramebuffers();
+ }
+}
+
+canvas.addEventListener('mousemove', e => {
+ if (!config.SHOW_MOUSE_MOVEMENT) return;
+ pointers[0].moved = true;
+ pointers[0].dx = (e.offsetX - pointers[0].x) * 5.0;
+ pointers[0].dy = (e.offsetY - pointers[0].y) * 5.0;
+ pointers[0].x = e.offsetX;
+ pointers[0].y = e.offsetY;
+});
+
+canvas.addEventListener('touchmove', e => {
+ e.preventDefault();
+ const touches = e.targetTouches;
+ for (let i = 0; i < touches.length; i++) {
+ let pointer = pointers[i];
+ pointer.moved = pointer.down;
+ pointer.dx = (touches[i].pageX - pointer.x) * 8.0;
+ pointer.dy = (touches[i].pageY - pointer.y) * 8.0;
+ pointer.x = touches[i].pageX;
+ pointer.y = touches[i].pageY;
+ }
+}, false);
+
+canvas.addEventListener('mouseenter', () => {
+ pointers[0].down = true;
+ pointers[0].color = config.POINTER_COLOR.getRandom();
+});
+
+canvas.addEventListener('touchstart', e => {
+ if (!config.SPLAT_ON_CLICK) return;
+ e.preventDefault();
+ const touches = e.targetTouches;
+ for (let i = 0; i < touches.length; i++) {
+ if (i >= pointers.length)
+ pointers.push(new pointerPrototype());
+
+ pointers[i].id = touches[i].identifier;
+ pointers[i].down = true;
+ pointers[i].x = touches[i].pageX;
+ pointers[i].y = touches[i].pageY;
+ pointers[i].color = config.POINTER_COLOR.getRandom();
+ }
+});
+
+canvas.addEventListener("mousedown", () => {
+ if (!config.SPLAT_ON_CLICK) return;
+ multipleSplats(parseInt(Math.random() * 20) + 5);
+});
+
+window.addEventListener('mouseleave', () => {
+ pointers[0].down = false;
+});
+
+window.addEventListener('touchend', e => {
+ const touches = e.changedTouches;
+ for (let i = 0; i < touches.length; i++)
+ for (let j = 0; j < pointers.length; j++)
+ if (touches[i].identifier == pointers[j].id)
+ pointers[j].down = false;
+});
+
+window.addEventListener('keydown', e => {
+ if (e.code === 'KeyP')
+ config.PAUSED = !config.PAUSED;
+ if (e.key === ' ')
+ splatStack.push(parseInt(Math.random() * 20) + 5);
+});
+
+function generateColor () {
+ let c = HSVtoRGB(Math.random(), 1.0, 1.0);
+ c.r *= 0.15;
+ c.g *= 0.15;
+ c.b *= 0.15;
+ return c;
+}
+
+function HSVtoRGB (h, s, v) {
+ let r, g, b, i, f, p, q, t;
+ i = Math.floor(h * 6);
+ f = h * 6 - i;
+ p = v * (1 - s);
+ q = v * (1 - f * s);
+ t = v * (1 - (1 - f) * s);
+
+ switch (i % 6) {
+ case 0: r = v, g = t, b = p; break;
+ case 1: r = q, g = v, b = p; break;
+ case 2: r = p, g = v, b = t; break;
+ case 3: r = p, g = q, b = v; break;
+ case 4: r = t, g = p, b = v; break;
+ case 5: r = v, g = p, b = q; break;
+ }
+
+ return {
+ r,
+ g,
+ b
+ };
+}
+
+function RGBToHue(r, g, b) {
+ // Find greatest and smallest channel values
+ let cmin = Math.min(r,g,b),
+ cmax = Math.max(r,g,b),
+ delta = cmax - cmin,
+ h = 0,
+ s = 0,
+ l = 0;
+
+ // Calculate hue
+ // No difference
+ if (delta == 0)
+ h = 0;
+ // Red is max
+ else if (cmax == r)
+ h = ((g - b) / delta) % 6;
+ // Green is max
+ else if (cmax == g)
+ h = (b - r) / delta + 2;
+ // Blue is max
+ else
+ h = (r - g) / delta + 4;
+
+ h = Math.round(h * 60);
+
+ // Make negative hues positive behind 360°
+ if (h < 0)
+ h += 360;
+
+ return h;
+}
+
+function getResolution (resolution) {
+ let aspectRatio = gl.drawingBufferWidth / gl.drawingBufferHeight;
+ if (aspectRatio < 1)
+ aspectRatio = 1.0 / aspectRatio;
+
+ let max = Math.round(resolution * aspectRatio);
+ let min = Math.round(resolution);
+
+ if (gl.drawingBufferWidth > gl.drawingBufferHeight)
+ return { width: max, height: min };
+ else
+ return { width: min, height: max };
+}
+
+function getTextureScale (texture, width, height) {
+ return {
+ x: width / texture.width,
+ y: height / texture.height
+ };
+}
+
+function rgbToPointerColor(color) {
+ let c = color.split(" ");
+ let hue = RGBToHue(c[0], c[1], c[2]);
+ let c2 = HSVtoRGB(hue/360, 1.0, 1.0);
+ c2.r *= 0.15;
+ c2.g *= 0.15;
+ c2.b *= 0.15;
+ return c2;
+}
diff --git "a/code-nav-home/covers/dynamic/14-\347\202\253\345\275\251\346\263\241\346\263\241/css/style.css" "b/code-nav-home/covers/dynamic/14-\347\202\253\345\275\251\346\263\241\346\263\241/css/style.css"
new file mode 100644
index 0000000..0c43c25
--- /dev/null
+++ "b/code-nav-home/covers/dynamic/14-\347\202\253\345\275\251\346\263\241\346\263\241/css/style.css"
@@ -0,0 +1,6 @@
+html, body {
+
+ background: #f2f2f2;
+ overflow: hidden;
+ margin: 0;
+}
diff --git "a/code-nav-home/covers/dynamic/14-\347\202\253\345\275\251\346\263\241\346\263\241/index.html" "b/code-nav-home/covers/dynamic/14-\347\202\253\345\275\251\346\263\241\346\263\241/index.html"
new file mode 100644
index 0000000..76a5306
--- /dev/null
+++ "b/code-nav-home/covers/dynamic/14-\347\202\253\345\275\251\346\263\241\346\263\241/index.html"
@@ -0,0 +1,146 @@
+
+
+
+ Fun Particles
+
+
+
+
+
+
+
+
diff --git "a/code-nav-home/covers/dynamic/14-\347\202\253\345\275\251\346\263\241\346\263\241/js/sketch.min.js" "b/code-nav-home/covers/dynamic/14-\347\202\253\345\275\251\346\263\241\346\263\241/js/sketch.min.js"
new file mode 100644
index 0000000..69f7a81
--- /dev/null
+++ "b/code-nav-home/covers/dynamic/14-\347\202\253\345\275\251\346\263\241\346\263\241/js/sketch.min.js"
@@ -0,0 +1,2 @@
+/* Copyright (C) 2013 Justin Windle, http://soulwire.co.uk */
+!function(e,t){"object"==typeof exports?module.exports=t(e,e.document):"function"==typeof define&&define.amd?define(function(){return t(e,e.document)}):e.Sketch=t(e,e.document)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(e){return"[object Array]"==Object.prototype.toString.call(e)}function o(e){return"function"==typeof e}function r(e){return"number"==typeof e}function i(e){return"string"==typeof e}function u(e){return C[e]||String.fromCharCode(e)}function a(e,t,n){for(var o in t)!n&&o in e||(e[o]=t[o]);return e}function c(e,t){return function(){e.apply(t,arguments)}}function l(e){var t={};for(var n in e)"webkitMovementX"!==n&&"webkitMovementY"!==n&&(o(e[n])?t[n]=c(e[n],e):t[n]=e[n]);return t}function s(e){function t(t){o(t)&&t.apply(e,[].splice.call(arguments,1))}function n(e){for(_=0;_
+
+
+
+
+ 创建图片
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-01/index.html b/code-nav-home/covers/dynamic/cover-01/index.html
new file mode 100644
index 0000000..a660fe2
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-01/index.html
@@ -0,0 +1,368 @@
+
+
+
+
+
+
+ 编程导航 - 樱花少女
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-01/js/index.js b/code-nav-home/covers/dynamic/cover-01/js/index.js
new file mode 100644
index 0000000..56f7df1
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-01/js/index.js
@@ -0,0 +1,802 @@
+// Utilities
+var Vector3 = {};
+var Matrix44 = {};
+Vector3.create = function(x, y, z) {
+ return {'x':x, 'y':y, 'z':z};
+};
+Vector3.dot = function (v0, v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
+};
+Vector3.cross = function (v, v0, v1) {
+ v.x = v0.y * v1.z - v0.z * v1.y;
+ v.y = v0.z * v1.x - v0.x * v1.z;
+ v.z = v0.x * v1.y - v0.y * v1.x;
+};
+Vector3.normalize = function (v) {
+ var l = v.x * v.x + v.y * v.y + v.z * v.z;
+ if(l > 0.00001) {
+ l = 1.0 / Math.sqrt(l);
+ v.x *= l;
+ v.y *= l;
+ v.z *= l;
+ }
+};
+Vector3.arrayForm = function(v) {
+ if(v.array) {
+ v.array[0] = v.x;
+ v.array[1] = v.y;
+ v.array[2] = v.z;
+ }
+ else {
+ v.array = new Float32Array([v.x, v.y, v.z]);
+ }
+ return v.array;
+};
+Matrix44.createIdentity = function () {
+ return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
+};
+Matrix44.loadProjection = function (m, aspect, vdeg, near, far) {
+ var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0;
+ var w = h * aspect;
+
+ m[0] = 2.0 * near / w;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+
+ m[4] = 0.0;
+ m[5] = 2.0 * near / h;
+ m[6] = 0.0;
+ m[7] = 0.0;
+
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = -(far + near) / (far - near);
+ m[11] = -1.0;
+
+ m[12] = 0.0;
+ m[13] = 0.0;
+ m[14] = -2.0 * far * near / (far - near);
+ m[15] = 0.0;
+};
+Matrix44.loadLookAt = function (m, vpos, vlook, vup) {
+ var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z);
+ Vector3.normalize(frontv);
+ var sidev = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(sidev, vup, frontv);
+ Vector3.normalize(sidev);
+ var topv = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(topv, frontv, sidev);
+ Vector3.normalize(topv);
+
+ m[0] = sidev.x;
+ m[1] = topv.x;
+ m[2] = frontv.x;
+ m[3] = 0.0;
+
+ m[4] = sidev.y;
+ m[5] = topv.y;
+ m[6] = frontv.y;
+ m[7] = 0.0;
+
+ m[8] = sidev.z;
+ m[9] = topv.z;
+ m[10] = frontv.z;
+ m[11] = 0.0;
+
+ m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]);
+ m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]);
+ m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]);
+ m[15] = 1.0;
+};
+
+//
+var timeInfo = {
+ 'start':0, 'prev':0, // Date
+ 'delta':0, 'elapsed':0 // Number(sec)
+};
+
+//
+var gl;
+var renderSpec = {
+ 'width':0,
+ 'height':0,
+ 'aspect':1,
+ 'array':new Float32Array(3),
+ 'halfWidth':0,
+ 'halfHeight':0,
+ 'halfArray':new Float32Array(3)
+ // and some render targets. see setViewport()
+};
+renderSpec.setSize = function(w, h) {
+ renderSpec.width = w;
+ renderSpec.height = h;
+ renderSpec.aspect = renderSpec.width / renderSpec.height;
+ renderSpec.array[0] = renderSpec.width;
+ renderSpec.array[1] = renderSpec.height;
+ renderSpec.array[2] = renderSpec.aspect;
+
+ renderSpec.halfWidth = Math.floor(w / 2);
+ renderSpec.halfHeight = Math.floor(h / 2);
+ renderSpec.halfArray[0] = renderSpec.halfWidth;
+ renderSpec.halfArray[1] = renderSpec.halfHeight;
+ renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight;
+};
+
+function deleteRenderTarget(rt) {
+ gl.deleteFramebuffer(rt.frameBuffer);
+ gl.deleteRenderbuffer(rt.renderBuffer);
+ gl.deleteTexture(rt.texture);
+}
+
+function createRenderTarget(w, h) {
+ var ret = {
+ 'width':w,
+ 'height':h,
+ 'sizeArray':new Float32Array([w, h, w / h]),
+ 'dtxArray':new Float32Array([1.0 / w, 1.0 / h])
+ };
+ ret.frameBuffer = gl.createFramebuffer();
+ ret.renderBuffer = gl.createRenderbuffer();
+ ret.texture = gl.createTexture();
+
+ gl.bindTexture(gl.TEXTURE_2D, ret.texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer);
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ return ret;
+}
+
+function compileShader(shtype, shsrc) {
+ var retsh = gl.createShader(shtype);
+
+ gl.shaderSource(retsh, shsrc);
+ gl.compileShader(retsh);
+
+ if(!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) {
+ var errlog = gl.getShaderInfoLog(retsh);
+ gl.deleteShader(retsh);
+ console.error(errlog);
+ return null;
+ }
+ return retsh;
+}
+
+function createShader(vtxsrc, frgsrc, uniformlist, attrlist) {
+ var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc);
+ var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc);
+
+ if(vsh == null || fsh == null) {
+ return null;
+ }
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vsh);
+ gl.attachShader(prog, fsh);
+
+ gl.deleteShader(vsh);
+ gl.deleteShader(fsh);
+
+ gl.linkProgram(prog);
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var errlog = gl.getProgramInfoLog(prog);
+ console.error(errlog);
+ return null;
+ }
+
+ if(uniformlist) {
+ prog.uniforms = {};
+ for(var i = 0; i < uniformlist.length; i++) {
+ prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]);
+ }
+ }
+
+ if(attrlist) {
+ prog.attributes = {};
+ for(var i = 0; i < attrlist.length; i++) {
+ var attr = attrlist[i];
+ prog.attributes[attr] = gl.getAttribLocation(prog, attr);
+ }
+ }
+
+ return prog;
+}
+
+function useShader(prog) {
+ gl.useProgram(prog);
+ for(var attr in prog.attributes) {
+ gl.enableVertexAttribArray(prog.attributes[attr]);;
+ }
+}
+
+function unuseShader(prog) {
+ for(var attr in prog.attributes) {
+ gl.disableVertexAttribArray(prog.attributes[attr]);;
+ }
+ gl.useProgram(null);
+}
+
+/////
+var projection = {
+ 'angle':60,
+ 'nearfar':new Float32Array([0.1, 100.0]),
+ 'matrix':Matrix44.createIdentity()
+};
+var camera = {
+ 'position':Vector3.create(0, 0, 100),
+ 'lookat':Vector3.create(0, 0, 0),
+ 'up':Vector3.create(0, 1, 0),
+ 'dof':Vector3.create(10.0, 4.0, 8.0),
+ 'matrix':Matrix44.createIdentity()
+};
+
+var pointFlower = {};
+var meshFlower = {};
+var sceneStandBy = false;
+
+var BlossomParticle = function () {
+ this.velocity = new Array(3);
+ this.rotation = new Array(3);
+ this.position = new Array(3);
+ this.euler = new Array(3);
+ this.size = 1.0;
+ this.alpha = 1.0;
+ this.zkey = 0.0;
+};
+
+BlossomParticle.prototype.setVelocity = function (vx, vy, vz) {
+ this.velocity[0] = vx;
+ this.velocity[1] = vy;
+ this.velocity[2] = vz;
+};
+
+BlossomParticle.prototype.setRotation = function (rx, ry, rz) {
+ this.rotation[0] = rx;
+ this.rotation[1] = ry;
+ this.rotation[2] = rz;
+};
+
+BlossomParticle.prototype.setPosition = function (nx, ny, nz) {
+ this.position[0] = nx;
+ this.position[1] = ny;
+ this.position[2] = nz;
+};
+
+BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) {
+ this.euler[0] = rx;
+ this.euler[1] = ry;
+ this.euler[2] = rz;
+};
+
+BlossomParticle.prototype.setSize = function (s) {
+ this.size = s;
+};
+
+BlossomParticle.prototype.update = function (dt, et) {
+ this.position[0] += this.velocity[0] * dt;
+ this.position[1] += this.velocity[1] * dt;
+ this.position[2] += this.velocity[2] * dt;
+
+ this.euler[0] += this.rotation[0] * dt;
+ this.euler[1] += this.rotation[1] * dt;
+ this.euler[2] += this.rotation[2] * dt;
+};
+
+function createPointFlowers() {
+ // get point sizes
+ var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
+ renderSpec.pointSize = {'min':prm[0], 'max':prm[1]};
+
+ var vtxsrc = document.getElementById("sakura_point_vsh").textContent;
+ var frgsrc = document.getElementById("sakura_point_fsh").textContent;
+
+ pointFlower.program = createShader(
+ vtxsrc, frgsrc,
+ ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'],
+ ['aPosition', 'aEuler', 'aMisc']
+ );
+
+ useShader(pointFlower.program);
+ pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]);
+ pointFlower.fader = Vector3.create(0.0, 10.0, 0.0);
+
+ // paramerters: velocity[3], rotate[3]
+ pointFlower.numFlowers = 300;
+ pointFlower.particles = new Array(pointFlower.numFlowers);
+ // vertex attributes {position[3], euler_xyz[3], size[1]}
+ pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2));
+ pointFlower.positionArrayOffset = 0;
+ pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3;
+ pointFlower.miscArrayOffset = pointFlower.numFlowers * 6;
+
+ pointFlower.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ unuseShader(pointFlower.program);
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ pointFlower.particles[i] = new BlossomParticle();
+ }
+}
+
+function initPointFlowers() {
+ //area
+ pointFlower.area = Vector3.create(20.0, 20.0, 20.0);
+ pointFlower.area.x = pointFlower.area.y * renderSpec.aspect;
+
+ pointFlower.fader.x = 10.0; //env fade start
+ pointFlower.fader.y = pointFlower.area.z; //env fade half
+ pointFlower.fader.z = 0.1; //near fade start
+
+ //particles
+ var PI2 = Math.PI * 2.0;
+ var tmpv3 = Vector3.create(0, 0, 0);
+ var tmpv = 0;
+ var symmetryrand = function() {return (Math.random() * 2.0 - 1.0);};
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var tmpprtcl = pointFlower.particles[i];
+
+ //velocity
+ tmpv3.x = symmetryrand() * 0.3 + 0.8;
+ tmpv3.y = symmetryrand() * 0.2 - 1.0;
+ tmpv3.z = symmetryrand() * 0.3 + 0.5;
+ Vector3.normalize(tmpv3);
+ tmpv = 2.0 + Math.random() * 1.0;
+ tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv);
+
+ //rotation
+ tmpprtcl.setRotation(
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5
+ );
+
+ //position
+ tmpprtcl.setPosition(
+ symmetryrand() * pointFlower.area.x,
+ symmetryrand() * pointFlower.area.y,
+ symmetryrand() * pointFlower.area.z
+ );
+
+ //euler
+ tmpprtcl.setEulerAngles(
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0
+ );
+
+ //size
+ tmpprtcl.setSize(0.9 + Math.random() * 0.1);
+ }
+}
+
+function renderPointFlowers() {
+ //update
+ var PI2 = Math.PI * 2.0;
+ var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z];
+ var repeatPos = function (prt, cmp, limit) {
+ if(Math.abs(prt.position[cmp]) - prt.size * 0.5 > limit) {
+ //out of area
+ if(prt.position[cmp] > 0) {
+ prt.position[cmp] -= limit * 2.0;
+ }
+ else {
+ prt.position[cmp] += limit * 2.0;
+ }
+ }
+ };
+ var repeatEuler = function (prt, cmp) {
+ prt.euler[cmp] = prt.euler[cmp] % PI2;
+ if(prt.euler[cmp] < 0.0) {
+ prt.euler[cmp] += PI2;
+ }
+ };
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ prtcl.update(timeInfo.delta, timeInfo.elapsed);
+ repeatPos(prtcl, 0, pointFlower.area.x);
+ repeatPos(prtcl, 1, pointFlower.area.y);
+ repeatPos(prtcl, 2, pointFlower.area.z);
+ repeatEuler(prtcl, 0);
+ repeatEuler(prtcl, 1);
+ repeatEuler(prtcl, 2);
+
+ prtcl.alpha = 1.0;//(pointFlower.area.z - prtcl.position[2]) * 0.5;
+
+ prtcl.zkey = (camera.matrix[2] * prtcl.position[0]
+ + camera.matrix[6] * prtcl.position[1]
+ + camera.matrix[10] * prtcl.position[2]
+ + camera.matrix[14]);
+ }
+
+ // sort
+ pointFlower.particles.sort(function(p0, p1){return p0.zkey - p1.zkey;});
+
+ // update data
+ var ipos = pointFlower.positionArrayOffset;
+ var ieuler = pointFlower.eulerArrayOffset;
+ var imisc = pointFlower.miscArrayOffset;
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ pointFlower.dataArray[ipos] = prtcl.position[0];
+ pointFlower.dataArray[ipos + 1] = prtcl.position[1];
+ pointFlower.dataArray[ipos + 2] = prtcl.position[2];
+ ipos += 3;
+ pointFlower.dataArray[ieuler] = prtcl.euler[0];
+ pointFlower.dataArray[ieuler + 1] = prtcl.euler[1];
+ pointFlower.dataArray[ieuler + 2] = prtcl.euler[2];
+ ieuler += 3;
+ pointFlower.dataArray[imisc] = prtcl.size;
+ pointFlower.dataArray[imisc + 1] = prtcl.alpha;
+ imisc += 2;
+ }
+
+ //draw
+ gl.enable(gl.BLEND);
+ //gl.disable(gl.DEPTH_TEST);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ var prog = pointFlower.program;
+ useShader(prog);
+
+ gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix);
+ gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+ gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof));
+ gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader));
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+
+ gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+
+ // doubler
+ for(var i = 1; i < 2; i++) {
+ var zpos = i * -2.0;
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+ }
+
+ //main
+ pointFlower.offset[0] = 0.0;
+ pointFlower.offset[1] = 0.0;
+ pointFlower.offset[2] = 0.0;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(prog);
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+}
+
+// effects
+//common util
+function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) {
+ var ret = {};
+ var unifs = ['uResolution', 'uSrc', 'uDelta'];
+ if(exunifs) {
+ unifs = unifs.concat(exunifs);
+ }
+ var attrs = ['aPosition'];
+ if(exattrs) {
+ attrs = attrs.concat(exattrs);
+ }
+
+ ret.program = createShader(vtxsrc, frgsrc, unifs, attrs);
+ useShader(ret.program);
+
+ ret.dataArray = new Float32Array([
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0
+ ]);
+ ret.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(ret.program);
+
+ return ret;
+}
+
+// basic usage
+// useEffect(prog, srctex({'texture':texid, 'dtxArray':(f32)[dtx, dty]})); //basic initialize
+// gl.uniform**(...); //additional uniforms
+// drawEffect()
+// unuseEffect(prog)
+// TEXTURE0 makes src
+function useEffect(fxobj, srctex) {
+ var prog = fxobj.program;
+ useShader(prog);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+
+ if(srctex != null) {
+ gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray);
+ gl.uniform1i(prog.uniforms.uSrc, 0);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, srctex.texture);
+ }
+}
+function drawEffect(fxobj) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer);
+ gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+}
+function unuseEffect(fxobj) {
+ unuseShader(fxobj.program);
+}
+
+var effectLib = {};
+function createEffectLib() {
+
+ var vtxsrc, frgsrc;
+ //common
+ var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent;
+
+ //background
+ frgsrc = document.getElementById("bg_fsh").textContent;
+ effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null);
+
+ // make brightpixels buffer
+ frgsrc = document.getElementById("fx_brightbuf_fsh").textContent;
+ effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null);
+
+ // direction blur
+ frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent;
+ effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null);
+
+ //final composite
+ vtxsrc = document.getElementById("pp_final_vsh").textContent;
+ frgsrc = document.getElementById("pp_final_fsh").textContent;
+ effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null);
+}
+
+// background
+function createBackground() {
+ //console.log("create background");
+}
+function initBackground() {
+ //console.log("init background");
+}
+function renderBackground() {
+ gl.disable(gl.DEPTH_TEST);
+
+ useEffect(effectLib.sceneBg, null);
+ gl.uniform2f(effectLib.sceneBg.program.uniforms.uTimes, timeInfo.elapsed, timeInfo.delta);
+ drawEffect(effectLib.sceneBg);
+ unuseEffect(effectLib.sceneBg);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+// post process
+var postProcess = {};
+function createPostProcess() {
+ //console.log("create post process");
+}
+function initPostProcess() {
+ //console.log("init post process");
+}
+
+function renderPostProcess() {
+ gl.enable(gl.TEXTURE_2D);
+ gl.disable(gl.DEPTH_TEST);
+ var bindRT = function (rt, isclear) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer);
+ gl.viewport(0, 0, rt.width, rt.height);
+ if(isclear) {
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+ };
+
+ //make bright buff
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.mkBrightBuf, renderSpec.mainRT);
+ drawEffect(effectLib.mkBrightBuf);
+ unuseEffect(effectLib.mkBrightBuf);
+
+ // make bloom
+ for(var i = 0; i < 2; i++) {
+ var p = 1.5 + 1 * i;
+ var s = 2.0 + 1 * i;
+ bindRT(renderSpec.wHalfRT1, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT0);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT1);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+ }
+
+ //display
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ useEffect(effectLib.finalComp, renderSpec.mainRT);
+ gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture);
+ drawEffect(effectLib.finalComp);
+ unuseEffect(effectLib.finalComp);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+/////
+var SceneEnv = {};
+function createScene() {
+ createEffectLib();
+ createBackground();
+ createPointFlowers();
+ createPostProcess();
+ sceneStandBy = true;
+}
+
+function initScene() {
+ initBackground();
+ initPointFlowers();
+ initPostProcess();
+
+ //camera.position.z = 17.320508;
+ camera.position.z = pointFlower.area.z + projection.nearfar[0];
+ projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0;
+ Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]);
+}
+
+function renderScene() {
+ //draw
+ Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ //gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer);
+ gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height);
+ gl.clearColor(0.005, 0, 0.05, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ renderBackground();
+ renderPointFlowers();
+ renderPostProcess();
+}
+
+/////
+function onResize(e) {
+ makeCanvasFullScreen(document.getElementById("sakura"));
+ setViewports();
+ if(sceneStandBy) {
+ initScene();
+ }
+}
+
+function setViewports() {
+ renderSpec.setSize(gl.canvas.width, gl.canvas.height);
+
+ gl.clearColor(0.2, 0.2, 0.5, 1.0);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+
+ var rtfunc = function (rtname, rtw, rth) {
+ var rt = renderSpec[rtname];
+ if(rt) deleteRenderTarget(rt);
+ renderSpec[rtname] = createRenderTarget(rtw, rth);
+ };
+ rtfunc('mainRT', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT0', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT1', renderSpec.width, renderSpec.height);
+ rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight);
+ rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight);
+}
+
+function render() {
+ renderScene();
+}
+
+var animating = true;
+function toggleAnimation(elm) {
+ animating ^= true;
+ if(animating) animate();
+ if(elm) {
+ elm.innerHTML = animating? "Stop":"Start";
+ }
+}
+
+function stepAnimation() {
+ if(!animating) animate();
+}
+
+function animate() {
+ var curdate = new Date();
+ timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0;
+ timeInfo.delta = (curdate - timeInfo.prev) / 1000.0;
+ timeInfo.prev = curdate;
+
+ if(animating) requestAnimationFrame(animate);
+ render();
+}
+
+function makeCanvasFullScreen(canvas) {
+ var b = document.body;
+ var d = document.documentElement;
+ fullw = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth);
+ fullh = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight);
+ canvas.width = fullw;
+ canvas.height = fullh;
+}
+
+window.addEventListener('load', function(e) {
+ var canvas = document.getElementById("sakura");
+ try {
+ makeCanvasFullScreen(canvas);
+ gl = canvas.getContext('experimental-webgl');
+ } catch(e) {
+ alert("WebGL not supported." + e);
+ console.error(e);
+ return;
+ }
+
+ window.addEventListener('resize', onResize);
+
+ setViewports();
+ createScene();
+ initScene();
+
+ timeInfo.start = new Date();
+ timeInfo.prev = timeInfo.start;
+ animate();
+});
+
+//set window.requestAnimationFrame
+(function (w, r) {
+ w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
+})(window, 'equestAnimationFrame');
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-01/preview.jpg b/code-nav-home/covers/dynamic/cover-01/preview.jpg
new file mode 100644
index 0000000..220ec3f
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-01/preview.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-02/index.html b/code-nav-home/covers/dynamic/cover-02/index.html
new file mode 100644
index 0000000..3654b39
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-02/index.html
@@ -0,0 +1,132 @@
+
+
+
+
+
+ 编程导航 - 点线联结
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-02/particle.js b/code-nav-home/covers/dynamic/cover-02/particle.js
new file mode 100644
index 0000000..e239a06
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-02/particle.js
@@ -0,0 +1,100 @@
+var particle={
+ x:0,
+ y:0,
+ vx:0,
+ vy:0,
+ mass:1,
+ radius:0,
+ friction:1,
+ gravity:0,
+ mass:1,
+ springs:null,
+
+ create:function(x,y,speed,direction,grav){
+ var obj=Object.create(this);
+ obj.x=x;
+ obj.y=y;
+ obj.vx=Math.cos(direction)*speed;
+ obj.vy=Math.sin(direction)*speed;
+ obj.gravity=grav||0;
+ obj.springs=[];
+ return obj;
+ },
+ addSpring:function(point,k,length){
+ this.removeSpring(point);
+ this.springs.push({
+ point:point,
+ k:k,
+ length:length||0,
+ });
+ },
+ removeSpring:function(point){
+ for(var i=0;i
+
+
+
+
+
+ 雪花初音
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-03/js/jquery.min.js b/code-nav-home/covers/dynamic/cover-03/js/jquery.min.js
new file mode 100644
index 0000000..198b3ff
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-03/js/jquery.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.1 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;ca",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o=""+"",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
+f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,""],thead:[1,""],tr:[2,""],td:[3,""],col:[2,""],area:[1,""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
+{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>$2>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-04/js/index.js b/code-nav-home/covers/dynamic/cover-04/js/index.js
new file mode 100644
index 0000000..0fcda8d
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-04/js/index.js
@@ -0,0 +1,802 @@
+// Utilities
+var Vector3 = {};
+var Matrix44 = {};
+Vector3.create = function(x, y, z) {
+ return {'x':x, 'y':y, 'z':z};
+};
+Vector3.dot = function (v0, v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
+};
+Vector3.cross = function (v, v0, v1) {
+ v.x = v0.y * v1.z - v0.z * v1.y;
+ v.y = v0.z * v1.x - v0.x * v1.z;
+ v.z = v0.x * v1.y - v0.y * v1.x;
+};
+Vector3.normalize = function (v) {
+ var l = v.x * v.x + v.y * v.y + v.z * v.z;
+ if(l > 0.00001) {
+ l = 1.0 / Math.sqrt(l);
+ v.x *= l;
+ v.y *= l;
+ v.z *= l;
+ }
+};
+Vector3.arrayForm = function(v) {
+ if(v.array) {
+ v.array[0] = v.x;
+ v.array[1] = v.y;
+ v.array[2] = v.z;
+ }
+ else {
+ v.array = new Float32Array([v.x, v.y, v.z]);
+ }
+ return v.array;
+};
+Matrix44.createIdentity = function () {
+ return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
+};
+Matrix44.loadProjection = function (m, aspect, vdeg, near, far) {
+ var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0;
+ var w = h * aspect;
+
+ m[0] = 2.0 * near / w;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+
+ m[4] = 0.0;
+ m[5] = 2.0 * near / h;
+ m[6] = 0.0;
+ m[7] = 0.0;
+
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = -(far + near) / (far - near);
+ m[11] = -1.0;
+
+ m[12] = 0.0;
+ m[13] = 0.0;
+ m[14] = -2.0 * far * near / (far - near);
+ m[15] = 0.0;
+};
+Matrix44.loadLookAt = function (m, vpos, vlook, vup) {
+ var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z);
+ Vector3.normalize(frontv);
+ var sidev = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(sidev, vup, frontv);
+ Vector3.normalize(sidev);
+ var topv = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(topv, frontv, sidev);
+ Vector3.normalize(topv);
+
+ m[0] = sidev.x;
+ m[1] = topv.x;
+ m[2] = frontv.x;
+ m[3] = 0.0;
+
+ m[4] = sidev.y;
+ m[5] = topv.y;
+ m[6] = frontv.y;
+ m[7] = 0.0;
+
+ m[8] = sidev.z;
+ m[9] = topv.z;
+ m[10] = frontv.z;
+ m[11] = 0.0;
+
+ m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]);
+ m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]);
+ m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]);
+ m[15] = 1.0;
+};
+
+//
+var timeInfo = {
+ 'start':0, 'prev':0, // Date
+ 'delta':0, 'elapsed':0 // Number(sec)
+};
+
+//
+var gl;
+var renderSpec = {
+ 'width':0,
+ 'height':0,
+ 'aspect':1,
+ 'array':new Float32Array(3),
+ 'halfWidth':0,
+ 'halfHeight':0,
+ 'halfArray':new Float32Array(3)
+ // and some render targets. see setViewport()
+};
+renderSpec.setSize = function(w, h) {
+ renderSpec.width = w;
+ renderSpec.height = h;
+ renderSpec.aspect = renderSpec.width / renderSpec.height;
+ renderSpec.array[0] = renderSpec.width;
+ renderSpec.array[1] = renderSpec.height;
+ renderSpec.array[2] = renderSpec.aspect;
+
+ renderSpec.halfWidth = Math.floor(w / 2);
+ renderSpec.halfHeight = Math.floor(h / 2);
+ renderSpec.halfArray[0] = renderSpec.halfWidth;
+ renderSpec.halfArray[1] = renderSpec.halfHeight;
+ renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight;
+};
+
+function deleteRenderTarget(rt) {
+ gl.deleteFramebuffer(rt.frameBuffer);
+ gl.deleteRenderbuffer(rt.renderBuffer);
+ gl.deleteTexture(rt.texture);
+}
+
+function createRenderTarget(w, h) {
+ var ret = {
+ 'width':w,
+ 'height':h,
+ 'sizeArray':new Float32Array([w, h, w / h]),
+ 'dtxArray':new Float32Array([1.0 / w, 1.0 / h])
+ };
+ ret.frameBuffer = gl.createFramebuffer();
+ ret.renderBuffer = gl.createRenderbuffer();
+ ret.texture = gl.createTexture();
+
+ gl.bindTexture(gl.TEXTURE_2D, ret.texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer);
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ return ret;
+}
+
+function compileShader(shtype, shsrc) {
+ var retsh = gl.createShader(shtype);
+
+ gl.shaderSource(retsh, shsrc);
+ gl.compileShader(retsh);
+
+ if(!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) {
+ var errlog = gl.getShaderInfoLog(retsh);
+ gl.deleteShader(retsh);
+ console.error(errlog);
+ return null;
+ }
+ return retsh;
+}
+
+function createShader(vtxsrc, frgsrc, uniformlist, attrlist) {
+ var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc);
+ var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc);
+
+ if(vsh == null || fsh == null) {
+ return null;
+ }
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vsh);
+ gl.attachShader(prog, fsh);
+
+ gl.deleteShader(vsh);
+ gl.deleteShader(fsh);
+
+ gl.linkProgram(prog);
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var errlog = gl.getProgramInfoLog(prog);
+ console.error(errlog);
+ return null;
+ }
+
+ if(uniformlist) {
+ prog.uniforms = {};
+ for(var i = 0; i < uniformlist.length; i++) {
+ prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]);
+ }
+ }
+
+ if(attrlist) {
+ prog.attributes = {};
+ for(var i = 0; i < attrlist.length; i++) {
+ var attr = attrlist[i];
+ prog.attributes[attr] = gl.getAttribLocation(prog, attr);
+ }
+ }
+
+ return prog;
+}
+
+function useShader(prog) {
+ gl.useProgram(prog);
+ for(var attr in prog.attributes) {
+ gl.enableVertexAttribArray(prog.attributes[attr]);;
+ }
+}
+
+function unuseShader(prog) {
+ for(var attr in prog.attributes) {
+ gl.disableVertexAttribArray(prog.attributes[attr]);;
+ }
+ gl.useProgram(null);
+}
+
+/////
+var projection = {
+ 'angle':60,
+ 'nearfar':new Float32Array([0.1, 100.0]),
+ 'matrix':Matrix44.createIdentity()
+};
+var camera = {
+ 'position':Vector3.create(0, 0, 100),
+ 'lookat':Vector3.create(0, 0, 0),
+ 'up':Vector3.create(0, 1, 0),
+ 'dof':Vector3.create(10.0, 4.0, 8.0),
+ 'matrix':Matrix44.createIdentity()
+};
+
+var pointFlower = {};
+var meshFlower = {};
+var sceneStandBy = false;
+
+var BlossomParticle = function () {
+ this.velocity = new Array(3);
+ this.rotation = new Array(3);
+ this.position = new Array(3);
+ this.euler = new Array(3);
+ this.size = 1.0;
+ this.alpha = 1.0;
+ this.zkey = 0.0;
+};
+
+BlossomParticle.prototype.setVelocity = function (vx, vy, vz) {
+ this.velocity[0] = vx;
+ this.velocity[1] = vy;
+ this.velocity[2] = vz;
+};
+
+BlossomParticle.prototype.setRotation = function (rx, ry, rz) {
+ this.rotation[0] = rx;
+ this.rotation[1] = ry;
+ this.rotation[2] = rz;
+};
+
+BlossomParticle.prototype.setPosition = function (nx, ny, nz) {
+ this.position[0] = nx;
+ this.position[1] = ny;
+ this.position[2] = nz;
+};
+
+BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) {
+ this.euler[0] = rx;
+ this.euler[1] = ry;
+ this.euler[2] = rz;
+};
+
+BlossomParticle.prototype.setSize = function (s) {
+ this.size = s;
+};
+
+BlossomParticle.prototype.update = function (dt, et) {
+ this.position[0] += this.velocity[0] * dt;
+ this.position[1] += this.velocity[1] * dt;
+ this.position[2] += this.velocity[2] * dt;
+
+ this.euler[0] += this.rotation[0] * dt;
+ this.euler[1] += this.rotation[1] * dt;
+ this.euler[2] += this.rotation[2] * dt;
+};
+
+function createPointFlowers() {
+ // get point sizes
+ var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
+ renderSpec.pointSize = {'min':prm[0], 'max':prm[1]};
+
+ var vtxsrc = document.getElementById("sakura_point_vsh").textContent;
+ var frgsrc = document.getElementById("sakura_point_fsh").textContent;
+
+ pointFlower.program = createShader(
+ vtxsrc, frgsrc,
+ ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'],
+ ['aPosition', 'aEuler', 'aMisc']
+ );
+
+ useShader(pointFlower.program);
+ pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]);
+ pointFlower.fader = Vector3.create(0.0, 10.0, 0.0);
+
+ // paramerters: velocity[3], rotate[3]
+ pointFlower.numFlowers = 300;
+ pointFlower.particles = new Array(pointFlower.numFlowers);
+ // vertex attributes {position[3], euler_xyz[3], size[1]}
+ pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2));
+ pointFlower.positionArrayOffset = 0;
+ pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3;
+ pointFlower.miscArrayOffset = pointFlower.numFlowers * 6;
+
+ pointFlower.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ unuseShader(pointFlower.program);
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ pointFlower.particles[i] = new BlossomParticle();
+ }
+}
+
+function initPointFlowers() {
+ //area
+ pointFlower.area = Vector3.create(20.0, 20.0, 20.0);
+ pointFlower.area.x = pointFlower.area.y * renderSpec.aspect;
+
+ pointFlower.fader.x = 10.0; //env fade start
+ pointFlower.fader.y = pointFlower.area.z; //env fade half
+ pointFlower.fader.z = 0.1; //near fade start
+
+ //particles
+ var PI2 = Math.PI * 2.0;
+ var tmpv3 = Vector3.create(0, 0, 0);
+ var tmpv = 0;
+ var symmetryrand = function() {return (Math.random() * 2.0 - 1.0);};
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var tmpprtcl = pointFlower.particles[i];
+
+ //velocity
+ tmpv3.x = symmetryrand() * 0.3 - 0.8;
+ tmpv3.y = symmetryrand() * 0.2 - 1.0;
+ tmpv3.z = symmetryrand() * 0.3 - 0.5;
+ Vector3.normalize(tmpv3);
+ tmpv = 2.0 + Math.random() * 1.0;
+ tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv);
+
+ //rotation
+ tmpprtcl.setRotation(
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5
+ );
+
+ //position
+ tmpprtcl.setPosition(
+ symmetryrand() * pointFlower.area.x,
+ symmetryrand() * pointFlower.area.y,
+ symmetryrand() * pointFlower.area.z
+ );
+
+ //euler
+ tmpprtcl.setEulerAngles(
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0
+ );
+
+ //size
+ tmpprtcl.setSize(0.9 + Math.random() * 0.1);
+ }
+}
+
+function renderPointFlowers() {
+ //update
+ var PI2 = Math.PI * 2.0;
+ var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z];
+ var repeatPos = function (prt, cmp, limit) {
+ if(Math.abs(prt.position[cmp]) - prt.size * 0.5 > limit) {
+ //out of area
+ if(prt.position[cmp] > 0) {
+ prt.position[cmp] -= limit * 2.0;
+ }
+ else {
+ prt.position[cmp] += limit * 2.0;
+ }
+ }
+ };
+ var repeatEuler = function (prt, cmp) {
+ prt.euler[cmp] = prt.euler[cmp] % PI2;
+ if(prt.euler[cmp] < 0.0) {
+ prt.euler[cmp] += PI2;
+ }
+ };
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ prtcl.update(timeInfo.delta, timeInfo.elapsed);
+ repeatPos(prtcl, 0, pointFlower.area.x);
+ repeatPos(prtcl, 1, pointFlower.area.y);
+ repeatPos(prtcl, 2, pointFlower.area.z);
+ repeatEuler(prtcl, 0);
+ repeatEuler(prtcl, 1);
+ repeatEuler(prtcl, 2);
+
+ prtcl.alpha = 1.0;//(pointFlower.area.z - prtcl.position[2]) * 0.5;
+
+ prtcl.zkey = (camera.matrix[2] * prtcl.position[0]
+ + camera.matrix[6] * prtcl.position[1]
+ + camera.matrix[10] * prtcl.position[2]
+ + camera.matrix[14]);
+ }
+
+ // sort
+ pointFlower.particles.sort(function(p0, p1){return p0.zkey - p1.zkey;});
+
+ // update data
+ var ipos = pointFlower.positionArrayOffset;
+ var ieuler = pointFlower.eulerArrayOffset;
+ var imisc = pointFlower.miscArrayOffset;
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ pointFlower.dataArray[ipos] = prtcl.position[0];
+ pointFlower.dataArray[ipos + 1] = prtcl.position[1];
+ pointFlower.dataArray[ipos + 2] = prtcl.position[2];
+ ipos += 3;
+ pointFlower.dataArray[ieuler] = prtcl.euler[0];
+ pointFlower.dataArray[ieuler + 1] = prtcl.euler[1];
+ pointFlower.dataArray[ieuler + 2] = prtcl.euler[2];
+ ieuler += 3;
+ pointFlower.dataArray[imisc] = prtcl.size;
+ pointFlower.dataArray[imisc + 1] = prtcl.alpha;
+ imisc += 2;
+ }
+
+ //draw
+ gl.enable(gl.BLEND);
+ //gl.disable(gl.DEPTH_TEST);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ var prog = pointFlower.program;
+ useShader(prog);
+
+ gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix);
+ gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+ gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof));
+ gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader));
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+
+ gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+
+ // doubler
+ for(var i = 1; i < 2; i++) {
+ var zpos = i * -2.0;
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+ }
+
+ //main
+ pointFlower.offset[0] = 0.0;
+ pointFlower.offset[1] = 0.0;
+ pointFlower.offset[2] = 0.0;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(prog);
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+}
+
+// effects
+//common util
+function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) {
+ var ret = {};
+ var unifs = ['uResolution', 'uSrc', 'uDelta'];
+ if(exunifs) {
+ unifs = unifs.concat(exunifs);
+ }
+ var attrs = ['aPosition'];
+ if(exattrs) {
+ attrs = attrs.concat(exattrs);
+ }
+
+ ret.program = createShader(vtxsrc, frgsrc, unifs, attrs);
+ useShader(ret.program);
+
+ ret.dataArray = new Float32Array([
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0
+ ]);
+ ret.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(ret.program);
+
+ return ret;
+}
+
+// basic usage
+// useEffect(prog, srctex({'texture':texid, 'dtxArray':(f32)[dtx, dty]})); //basic initialize
+// gl.uniform**(...); //additional uniforms
+// drawEffect()
+// unuseEffect(prog)
+// TEXTURE0 makes src
+function useEffect(fxobj, srctex) {
+ var prog = fxobj.program;
+ useShader(prog);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+
+ if(srctex != null) {
+ gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray);
+ gl.uniform1i(prog.uniforms.uSrc, 0);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, srctex.texture);
+ }
+}
+function drawEffect(fxobj) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer);
+ gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+}
+function unuseEffect(fxobj) {
+ unuseShader(fxobj.program);
+}
+
+var effectLib = {};
+function createEffectLib() {
+
+ var vtxsrc, frgsrc;
+ //common
+ var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent;
+
+ //background
+ frgsrc = document.getElementById("bg_fsh").textContent;
+ effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null);
+
+ // make brightpixels buffer
+ frgsrc = document.getElementById("fx_brightbuf_fsh").textContent;
+ effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null);
+
+ // direction blur
+ frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent;
+ effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null);
+
+ //final composite
+ vtxsrc = document.getElementById("pp_final_vsh").textContent;
+ frgsrc = document.getElementById("pp_final_fsh").textContent;
+ effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null);
+}
+
+// background
+function createBackground() {
+ //console.log("create background");
+}
+function initBackground() {
+ //console.log("init background");
+}
+function renderBackground() {
+ gl.disable(gl.DEPTH_TEST);
+
+ useEffect(effectLib.sceneBg, null);
+ gl.uniform2f(effectLib.sceneBg.program.uniforms.uTimes, timeInfo.elapsed, timeInfo.delta);
+ drawEffect(effectLib.sceneBg);
+ unuseEffect(effectLib.sceneBg);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+// post process
+var postProcess = {};
+function createPostProcess() {
+ //console.log("create post process");
+}
+function initPostProcess() {
+ //console.log("init post process");
+}
+
+function renderPostProcess() {
+ gl.enable(gl.TEXTURE_2D);
+ gl.disable(gl.DEPTH_TEST);
+ var bindRT = function (rt, isclear) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer);
+ gl.viewport(0, 0, rt.width, rt.height);
+ if(isclear) {
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+ };
+
+ //make bright buff
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.mkBrightBuf, renderSpec.mainRT);
+ drawEffect(effectLib.mkBrightBuf);
+ unuseEffect(effectLib.mkBrightBuf);
+
+ // make bloom
+ for(var i = 0; i < 2; i++) {
+ var p = 1.5 + 1 * i;
+ var s = 2.0 + 1 * i;
+ bindRT(renderSpec.wHalfRT1, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT0);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT1);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+ }
+
+ //display
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ useEffect(effectLib.finalComp, renderSpec.mainRT);
+ gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture);
+ drawEffect(effectLib.finalComp);
+ unuseEffect(effectLib.finalComp);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+/////
+var SceneEnv = {};
+function createScene() {
+ createEffectLib();
+ createBackground();
+ createPointFlowers();
+ createPostProcess();
+ sceneStandBy = true;
+}
+
+function initScene() {
+ initBackground();
+ initPointFlowers();
+ initPostProcess();
+
+ //camera.position.z = 17.320508;
+ camera.position.z = pointFlower.area.z + projection.nearfar[0];
+ projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0;
+ Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]);
+}
+
+function renderScene() {
+ //draw
+ Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ //gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer);
+ gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height);
+ gl.clearColor(0.005, 0, 0.05, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ renderBackground();
+ renderPointFlowers();
+ renderPostProcess();
+}
+
+/////
+function onResize(e) {
+ makeCanvasFullScreen(document.getElementById("sakura"));
+ setViewports();
+ if(sceneStandBy) {
+ initScene();
+ }
+}
+
+function setViewports() {
+ renderSpec.setSize(gl.canvas.width, gl.canvas.height);
+
+ gl.clearColor(0.2, 0.2, 0.5, 1.0);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+
+ var rtfunc = function (rtname, rtw, rth) {
+ var rt = renderSpec[rtname];
+ if(rt) deleteRenderTarget(rt);
+ renderSpec[rtname] = createRenderTarget(rtw, rth);
+ };
+ rtfunc('mainRT', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT0', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT1', renderSpec.width, renderSpec.height);
+ rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight);
+ rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight);
+}
+
+function render() {
+ renderScene();
+}
+
+var animating = true;
+function toggleAnimation(elm) {
+ animating ^= true;
+ if(animating) animate();
+ if(elm) {
+ elm.innerHTML = animating? "Stop":"Start";
+ }
+}
+
+function stepAnimation() {
+ if(!animating) animate();
+}
+
+function animate() {
+ var curdate = new Date();
+ timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0;
+ timeInfo.delta = (curdate - timeInfo.prev) / 1000.0;
+ timeInfo.prev = curdate;
+
+ if(animating) requestAnimationFrame(animate);
+ render();
+}
+
+function makeCanvasFullScreen(canvas) {
+ var b = document.body;
+ var d = document.documentElement;
+ fullw = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth);
+ fullh = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight);
+ canvas.width = fullw;
+ canvas.height = fullh;
+}
+
+window.addEventListener('load', function(e) {
+ var canvas = document.getElementById("sakura");
+ try {
+ makeCanvasFullScreen(canvas);
+ gl = canvas.getContext('experimental-webgl');
+ } catch(e) {
+ alert("WebGL not supported." + e);
+ console.error(e);
+ return;
+ }
+
+ window.addEventListener('resize', onResize);
+
+ setViewports();
+ createScene();
+ initScene();
+
+ timeInfo.start = new Date();
+ timeInfo.prev = timeInfo.start;
+ animate();
+});
+
+//set window.requestAnimationFrame
+(function (w, r) {
+ w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
+})(window, 'equestAnimationFrame');
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-04/preview.jpg b/code-nav-home/covers/dynamic/cover-04/preview.jpg
new file mode 100644
index 0000000..005ae08
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-04/preview.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/blur_h_bloom.dxs b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/blur_h_bloom.dxs
new file mode 100644
index 0000000..a033325
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/blur_h_bloom.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/combine.dxs b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/combine.dxs
new file mode 100644
index 0000000..446b6ef
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/combine.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_eighth_blur_v.dxs b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_eighth_blur_v.dxs
new file mode 100644
index 0000000..ccf12f9
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_eighth_blur_v.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_quarter.dxs b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_quarter.dxs
new file mode 100644
index 0000000..1d3c945
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_quarter.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/fade.dxs b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/fade.dxs
new file mode 100644
index 0000000..14203c3
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/fade.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-05/1.jpg b/code-nav-home/covers/dynamic/cover-05/1.jpg
new file mode 100644
index 0000000..3203190
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-05/1.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-05/index.html b/code-nav-home/covers/dynamic/cover-05/index.html
new file mode 100644
index 0000000..d0a89e3
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-05/index.html
@@ -0,0 +1,378 @@
+
+
+
+
+
+
+ 编程导航 - 冲田总司樱花飘落
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-05/js/index.js b/code-nav-home/covers/dynamic/cover-05/js/index.js
new file mode 100644
index 0000000..0fcda8d
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-05/js/index.js
@@ -0,0 +1,802 @@
+// Utilities
+var Vector3 = {};
+var Matrix44 = {};
+Vector3.create = function(x, y, z) {
+ return {'x':x, 'y':y, 'z':z};
+};
+Vector3.dot = function (v0, v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
+};
+Vector3.cross = function (v, v0, v1) {
+ v.x = v0.y * v1.z - v0.z * v1.y;
+ v.y = v0.z * v1.x - v0.x * v1.z;
+ v.z = v0.x * v1.y - v0.y * v1.x;
+};
+Vector3.normalize = function (v) {
+ var l = v.x * v.x + v.y * v.y + v.z * v.z;
+ if(l > 0.00001) {
+ l = 1.0 / Math.sqrt(l);
+ v.x *= l;
+ v.y *= l;
+ v.z *= l;
+ }
+};
+Vector3.arrayForm = function(v) {
+ if(v.array) {
+ v.array[0] = v.x;
+ v.array[1] = v.y;
+ v.array[2] = v.z;
+ }
+ else {
+ v.array = new Float32Array([v.x, v.y, v.z]);
+ }
+ return v.array;
+};
+Matrix44.createIdentity = function () {
+ return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
+};
+Matrix44.loadProjection = function (m, aspect, vdeg, near, far) {
+ var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0;
+ var w = h * aspect;
+
+ m[0] = 2.0 * near / w;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+
+ m[4] = 0.0;
+ m[5] = 2.0 * near / h;
+ m[6] = 0.0;
+ m[7] = 0.0;
+
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = -(far + near) / (far - near);
+ m[11] = -1.0;
+
+ m[12] = 0.0;
+ m[13] = 0.0;
+ m[14] = -2.0 * far * near / (far - near);
+ m[15] = 0.0;
+};
+Matrix44.loadLookAt = function (m, vpos, vlook, vup) {
+ var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z);
+ Vector3.normalize(frontv);
+ var sidev = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(sidev, vup, frontv);
+ Vector3.normalize(sidev);
+ var topv = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(topv, frontv, sidev);
+ Vector3.normalize(topv);
+
+ m[0] = sidev.x;
+ m[1] = topv.x;
+ m[2] = frontv.x;
+ m[3] = 0.0;
+
+ m[4] = sidev.y;
+ m[5] = topv.y;
+ m[6] = frontv.y;
+ m[7] = 0.0;
+
+ m[8] = sidev.z;
+ m[9] = topv.z;
+ m[10] = frontv.z;
+ m[11] = 0.0;
+
+ m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]);
+ m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]);
+ m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]);
+ m[15] = 1.0;
+};
+
+//
+var timeInfo = {
+ 'start':0, 'prev':0, // Date
+ 'delta':0, 'elapsed':0 // Number(sec)
+};
+
+//
+var gl;
+var renderSpec = {
+ 'width':0,
+ 'height':0,
+ 'aspect':1,
+ 'array':new Float32Array(3),
+ 'halfWidth':0,
+ 'halfHeight':0,
+ 'halfArray':new Float32Array(3)
+ // and some render targets. see setViewport()
+};
+renderSpec.setSize = function(w, h) {
+ renderSpec.width = w;
+ renderSpec.height = h;
+ renderSpec.aspect = renderSpec.width / renderSpec.height;
+ renderSpec.array[0] = renderSpec.width;
+ renderSpec.array[1] = renderSpec.height;
+ renderSpec.array[2] = renderSpec.aspect;
+
+ renderSpec.halfWidth = Math.floor(w / 2);
+ renderSpec.halfHeight = Math.floor(h / 2);
+ renderSpec.halfArray[0] = renderSpec.halfWidth;
+ renderSpec.halfArray[1] = renderSpec.halfHeight;
+ renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight;
+};
+
+function deleteRenderTarget(rt) {
+ gl.deleteFramebuffer(rt.frameBuffer);
+ gl.deleteRenderbuffer(rt.renderBuffer);
+ gl.deleteTexture(rt.texture);
+}
+
+function createRenderTarget(w, h) {
+ var ret = {
+ 'width':w,
+ 'height':h,
+ 'sizeArray':new Float32Array([w, h, w / h]),
+ 'dtxArray':new Float32Array([1.0 / w, 1.0 / h])
+ };
+ ret.frameBuffer = gl.createFramebuffer();
+ ret.renderBuffer = gl.createRenderbuffer();
+ ret.texture = gl.createTexture();
+
+ gl.bindTexture(gl.TEXTURE_2D, ret.texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer);
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ return ret;
+}
+
+function compileShader(shtype, shsrc) {
+ var retsh = gl.createShader(shtype);
+
+ gl.shaderSource(retsh, shsrc);
+ gl.compileShader(retsh);
+
+ if(!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) {
+ var errlog = gl.getShaderInfoLog(retsh);
+ gl.deleteShader(retsh);
+ console.error(errlog);
+ return null;
+ }
+ return retsh;
+}
+
+function createShader(vtxsrc, frgsrc, uniformlist, attrlist) {
+ var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc);
+ var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc);
+
+ if(vsh == null || fsh == null) {
+ return null;
+ }
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vsh);
+ gl.attachShader(prog, fsh);
+
+ gl.deleteShader(vsh);
+ gl.deleteShader(fsh);
+
+ gl.linkProgram(prog);
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var errlog = gl.getProgramInfoLog(prog);
+ console.error(errlog);
+ return null;
+ }
+
+ if(uniformlist) {
+ prog.uniforms = {};
+ for(var i = 0; i < uniformlist.length; i++) {
+ prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]);
+ }
+ }
+
+ if(attrlist) {
+ prog.attributes = {};
+ for(var i = 0; i < attrlist.length; i++) {
+ var attr = attrlist[i];
+ prog.attributes[attr] = gl.getAttribLocation(prog, attr);
+ }
+ }
+
+ return prog;
+}
+
+function useShader(prog) {
+ gl.useProgram(prog);
+ for(var attr in prog.attributes) {
+ gl.enableVertexAttribArray(prog.attributes[attr]);;
+ }
+}
+
+function unuseShader(prog) {
+ for(var attr in prog.attributes) {
+ gl.disableVertexAttribArray(prog.attributes[attr]);;
+ }
+ gl.useProgram(null);
+}
+
+/////
+var projection = {
+ 'angle':60,
+ 'nearfar':new Float32Array([0.1, 100.0]),
+ 'matrix':Matrix44.createIdentity()
+};
+var camera = {
+ 'position':Vector3.create(0, 0, 100),
+ 'lookat':Vector3.create(0, 0, 0),
+ 'up':Vector3.create(0, 1, 0),
+ 'dof':Vector3.create(10.0, 4.0, 8.0),
+ 'matrix':Matrix44.createIdentity()
+};
+
+var pointFlower = {};
+var meshFlower = {};
+var sceneStandBy = false;
+
+var BlossomParticle = function () {
+ this.velocity = new Array(3);
+ this.rotation = new Array(3);
+ this.position = new Array(3);
+ this.euler = new Array(3);
+ this.size = 1.0;
+ this.alpha = 1.0;
+ this.zkey = 0.0;
+};
+
+BlossomParticle.prototype.setVelocity = function (vx, vy, vz) {
+ this.velocity[0] = vx;
+ this.velocity[1] = vy;
+ this.velocity[2] = vz;
+};
+
+BlossomParticle.prototype.setRotation = function (rx, ry, rz) {
+ this.rotation[0] = rx;
+ this.rotation[1] = ry;
+ this.rotation[2] = rz;
+};
+
+BlossomParticle.prototype.setPosition = function (nx, ny, nz) {
+ this.position[0] = nx;
+ this.position[1] = ny;
+ this.position[2] = nz;
+};
+
+BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) {
+ this.euler[0] = rx;
+ this.euler[1] = ry;
+ this.euler[2] = rz;
+};
+
+BlossomParticle.prototype.setSize = function (s) {
+ this.size = s;
+};
+
+BlossomParticle.prototype.update = function (dt, et) {
+ this.position[0] += this.velocity[0] * dt;
+ this.position[1] += this.velocity[1] * dt;
+ this.position[2] += this.velocity[2] * dt;
+
+ this.euler[0] += this.rotation[0] * dt;
+ this.euler[1] += this.rotation[1] * dt;
+ this.euler[2] += this.rotation[2] * dt;
+};
+
+function createPointFlowers() {
+ // get point sizes
+ var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
+ renderSpec.pointSize = {'min':prm[0], 'max':prm[1]};
+
+ var vtxsrc = document.getElementById("sakura_point_vsh").textContent;
+ var frgsrc = document.getElementById("sakura_point_fsh").textContent;
+
+ pointFlower.program = createShader(
+ vtxsrc, frgsrc,
+ ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'],
+ ['aPosition', 'aEuler', 'aMisc']
+ );
+
+ useShader(pointFlower.program);
+ pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]);
+ pointFlower.fader = Vector3.create(0.0, 10.0, 0.0);
+
+ // paramerters: velocity[3], rotate[3]
+ pointFlower.numFlowers = 300;
+ pointFlower.particles = new Array(pointFlower.numFlowers);
+ // vertex attributes {position[3], euler_xyz[3], size[1]}
+ pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2));
+ pointFlower.positionArrayOffset = 0;
+ pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3;
+ pointFlower.miscArrayOffset = pointFlower.numFlowers * 6;
+
+ pointFlower.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ unuseShader(pointFlower.program);
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ pointFlower.particles[i] = new BlossomParticle();
+ }
+}
+
+function initPointFlowers() {
+ //area
+ pointFlower.area = Vector3.create(20.0, 20.0, 20.0);
+ pointFlower.area.x = pointFlower.area.y * renderSpec.aspect;
+
+ pointFlower.fader.x = 10.0; //env fade start
+ pointFlower.fader.y = pointFlower.area.z; //env fade half
+ pointFlower.fader.z = 0.1; //near fade start
+
+ //particles
+ var PI2 = Math.PI * 2.0;
+ var tmpv3 = Vector3.create(0, 0, 0);
+ var tmpv = 0;
+ var symmetryrand = function() {return (Math.random() * 2.0 - 1.0);};
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var tmpprtcl = pointFlower.particles[i];
+
+ //velocity
+ tmpv3.x = symmetryrand() * 0.3 - 0.8;
+ tmpv3.y = symmetryrand() * 0.2 - 1.0;
+ tmpv3.z = symmetryrand() * 0.3 - 0.5;
+ Vector3.normalize(tmpv3);
+ tmpv = 2.0 + Math.random() * 1.0;
+ tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv);
+
+ //rotation
+ tmpprtcl.setRotation(
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5
+ );
+
+ //position
+ tmpprtcl.setPosition(
+ symmetryrand() * pointFlower.area.x,
+ symmetryrand() * pointFlower.area.y,
+ symmetryrand() * pointFlower.area.z
+ );
+
+ //euler
+ tmpprtcl.setEulerAngles(
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0
+ );
+
+ //size
+ tmpprtcl.setSize(0.9 + Math.random() * 0.1);
+ }
+}
+
+function renderPointFlowers() {
+ //update
+ var PI2 = Math.PI * 2.0;
+ var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z];
+ var repeatPos = function (prt, cmp, limit) {
+ if(Math.abs(prt.position[cmp]) - prt.size * 0.5 > limit) {
+ //out of area
+ if(prt.position[cmp] > 0) {
+ prt.position[cmp] -= limit * 2.0;
+ }
+ else {
+ prt.position[cmp] += limit * 2.0;
+ }
+ }
+ };
+ var repeatEuler = function (prt, cmp) {
+ prt.euler[cmp] = prt.euler[cmp] % PI2;
+ if(prt.euler[cmp] < 0.0) {
+ prt.euler[cmp] += PI2;
+ }
+ };
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ prtcl.update(timeInfo.delta, timeInfo.elapsed);
+ repeatPos(prtcl, 0, pointFlower.area.x);
+ repeatPos(prtcl, 1, pointFlower.area.y);
+ repeatPos(prtcl, 2, pointFlower.area.z);
+ repeatEuler(prtcl, 0);
+ repeatEuler(prtcl, 1);
+ repeatEuler(prtcl, 2);
+
+ prtcl.alpha = 1.0;//(pointFlower.area.z - prtcl.position[2]) * 0.5;
+
+ prtcl.zkey = (camera.matrix[2] * prtcl.position[0]
+ + camera.matrix[6] * prtcl.position[1]
+ + camera.matrix[10] * prtcl.position[2]
+ + camera.matrix[14]);
+ }
+
+ // sort
+ pointFlower.particles.sort(function(p0, p1){return p0.zkey - p1.zkey;});
+
+ // update data
+ var ipos = pointFlower.positionArrayOffset;
+ var ieuler = pointFlower.eulerArrayOffset;
+ var imisc = pointFlower.miscArrayOffset;
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ pointFlower.dataArray[ipos] = prtcl.position[0];
+ pointFlower.dataArray[ipos + 1] = prtcl.position[1];
+ pointFlower.dataArray[ipos + 2] = prtcl.position[2];
+ ipos += 3;
+ pointFlower.dataArray[ieuler] = prtcl.euler[0];
+ pointFlower.dataArray[ieuler + 1] = prtcl.euler[1];
+ pointFlower.dataArray[ieuler + 2] = prtcl.euler[2];
+ ieuler += 3;
+ pointFlower.dataArray[imisc] = prtcl.size;
+ pointFlower.dataArray[imisc + 1] = prtcl.alpha;
+ imisc += 2;
+ }
+
+ //draw
+ gl.enable(gl.BLEND);
+ //gl.disable(gl.DEPTH_TEST);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ var prog = pointFlower.program;
+ useShader(prog);
+
+ gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix);
+ gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+ gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof));
+ gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader));
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+
+ gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+
+ // doubler
+ for(var i = 1; i < 2; i++) {
+ var zpos = i * -2.0;
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+ }
+
+ //main
+ pointFlower.offset[0] = 0.0;
+ pointFlower.offset[1] = 0.0;
+ pointFlower.offset[2] = 0.0;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(prog);
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+}
+
+// effects
+//common util
+function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) {
+ var ret = {};
+ var unifs = ['uResolution', 'uSrc', 'uDelta'];
+ if(exunifs) {
+ unifs = unifs.concat(exunifs);
+ }
+ var attrs = ['aPosition'];
+ if(exattrs) {
+ attrs = attrs.concat(exattrs);
+ }
+
+ ret.program = createShader(vtxsrc, frgsrc, unifs, attrs);
+ useShader(ret.program);
+
+ ret.dataArray = new Float32Array([
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0
+ ]);
+ ret.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(ret.program);
+
+ return ret;
+}
+
+// basic usage
+// useEffect(prog, srctex({'texture':texid, 'dtxArray':(f32)[dtx, dty]})); //basic initialize
+// gl.uniform**(...); //additional uniforms
+// drawEffect()
+// unuseEffect(prog)
+// TEXTURE0 makes src
+function useEffect(fxobj, srctex) {
+ var prog = fxobj.program;
+ useShader(prog);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+
+ if(srctex != null) {
+ gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray);
+ gl.uniform1i(prog.uniforms.uSrc, 0);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, srctex.texture);
+ }
+}
+function drawEffect(fxobj) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer);
+ gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+}
+function unuseEffect(fxobj) {
+ unuseShader(fxobj.program);
+}
+
+var effectLib = {};
+function createEffectLib() {
+
+ var vtxsrc, frgsrc;
+ //common
+ var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent;
+
+ //background
+ frgsrc = document.getElementById("bg_fsh").textContent;
+ effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null);
+
+ // make brightpixels buffer
+ frgsrc = document.getElementById("fx_brightbuf_fsh").textContent;
+ effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null);
+
+ // direction blur
+ frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent;
+ effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null);
+
+ //final composite
+ vtxsrc = document.getElementById("pp_final_vsh").textContent;
+ frgsrc = document.getElementById("pp_final_fsh").textContent;
+ effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null);
+}
+
+// background
+function createBackground() {
+ //console.log("create background");
+}
+function initBackground() {
+ //console.log("init background");
+}
+function renderBackground() {
+ gl.disable(gl.DEPTH_TEST);
+
+ useEffect(effectLib.sceneBg, null);
+ gl.uniform2f(effectLib.sceneBg.program.uniforms.uTimes, timeInfo.elapsed, timeInfo.delta);
+ drawEffect(effectLib.sceneBg);
+ unuseEffect(effectLib.sceneBg);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+// post process
+var postProcess = {};
+function createPostProcess() {
+ //console.log("create post process");
+}
+function initPostProcess() {
+ //console.log("init post process");
+}
+
+function renderPostProcess() {
+ gl.enable(gl.TEXTURE_2D);
+ gl.disable(gl.DEPTH_TEST);
+ var bindRT = function (rt, isclear) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer);
+ gl.viewport(0, 0, rt.width, rt.height);
+ if(isclear) {
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+ };
+
+ //make bright buff
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.mkBrightBuf, renderSpec.mainRT);
+ drawEffect(effectLib.mkBrightBuf);
+ unuseEffect(effectLib.mkBrightBuf);
+
+ // make bloom
+ for(var i = 0; i < 2; i++) {
+ var p = 1.5 + 1 * i;
+ var s = 2.0 + 1 * i;
+ bindRT(renderSpec.wHalfRT1, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT0);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT1);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+ }
+
+ //display
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ useEffect(effectLib.finalComp, renderSpec.mainRT);
+ gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture);
+ drawEffect(effectLib.finalComp);
+ unuseEffect(effectLib.finalComp);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+/////
+var SceneEnv = {};
+function createScene() {
+ createEffectLib();
+ createBackground();
+ createPointFlowers();
+ createPostProcess();
+ sceneStandBy = true;
+}
+
+function initScene() {
+ initBackground();
+ initPointFlowers();
+ initPostProcess();
+
+ //camera.position.z = 17.320508;
+ camera.position.z = pointFlower.area.z + projection.nearfar[0];
+ projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0;
+ Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]);
+}
+
+function renderScene() {
+ //draw
+ Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ //gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer);
+ gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height);
+ gl.clearColor(0.005, 0, 0.05, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ renderBackground();
+ renderPointFlowers();
+ renderPostProcess();
+}
+
+/////
+function onResize(e) {
+ makeCanvasFullScreen(document.getElementById("sakura"));
+ setViewports();
+ if(sceneStandBy) {
+ initScene();
+ }
+}
+
+function setViewports() {
+ renderSpec.setSize(gl.canvas.width, gl.canvas.height);
+
+ gl.clearColor(0.2, 0.2, 0.5, 1.0);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+
+ var rtfunc = function (rtname, rtw, rth) {
+ var rt = renderSpec[rtname];
+ if(rt) deleteRenderTarget(rt);
+ renderSpec[rtname] = createRenderTarget(rtw, rth);
+ };
+ rtfunc('mainRT', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT0', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT1', renderSpec.width, renderSpec.height);
+ rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight);
+ rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight);
+}
+
+function render() {
+ renderScene();
+}
+
+var animating = true;
+function toggleAnimation(elm) {
+ animating ^= true;
+ if(animating) animate();
+ if(elm) {
+ elm.innerHTML = animating? "Stop":"Start";
+ }
+}
+
+function stepAnimation() {
+ if(!animating) animate();
+}
+
+function animate() {
+ var curdate = new Date();
+ timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0;
+ timeInfo.delta = (curdate - timeInfo.prev) / 1000.0;
+ timeInfo.prev = curdate;
+
+ if(animating) requestAnimationFrame(animate);
+ render();
+}
+
+function makeCanvasFullScreen(canvas) {
+ var b = document.body;
+ var d = document.documentElement;
+ fullw = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth);
+ fullh = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight);
+ canvas.width = fullw;
+ canvas.height = fullh;
+}
+
+window.addEventListener('load', function(e) {
+ var canvas = document.getElementById("sakura");
+ try {
+ makeCanvasFullScreen(canvas);
+ gl = canvas.getContext('experimental-webgl');
+ } catch(e) {
+ alert("WebGL not supported." + e);
+ console.error(e);
+ return;
+ }
+
+ window.addEventListener('resize', onResize);
+
+ setViewports();
+ createScene();
+ initScene();
+
+ timeInfo.start = new Date();
+ timeInfo.prev = timeInfo.start;
+ animate();
+});
+
+//set window.requestAnimationFrame
+(function (w, r) {
+ w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
+})(window, 'equestAnimationFrame');
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-05/preview.jpg b/code-nav-home/covers/dynamic/cover-05/preview.jpg
new file mode 100644
index 0000000..20151c6
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-05/preview.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/blur_h_bloom.dxs b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/blur_h_bloom.dxs
new file mode 100644
index 0000000..a033325
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/blur_h_bloom.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/combine.dxs b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/combine.dxs
new file mode 100644
index 0000000..446b6ef
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/combine.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_eighth_blur_v.dxs b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_eighth_blur_v.dxs
new file mode 100644
index 0000000..ccf12f9
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_eighth_blur_v.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_quarter.dxs b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_quarter.dxs
new file mode 100644
index 0000000..1d3c945
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_quarter.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/fade.dxs b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/fade.dxs
new file mode 100644
index 0000000..14203c3
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/fade.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-06/O.jpg b/code-nav-home/covers/dynamic/cover-06/O.jpg
new file mode 100644
index 0000000..47d2a7a
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-06/O.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-06/index.html b/code-nav-home/covers/dynamic/cover-06/index.html
new file mode 100644
index 0000000..2380fdd
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-06/index.html
@@ -0,0 +1,1175 @@
+
+
+
+
+
+ 编程导航 - 冲田总司樱花飘落
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-06/preview.png b/code-nav-home/covers/dynamic/cover-06/preview.png
new file mode 100644
index 0000000..63e6a3a
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-06/preview.png differ
diff --git a/code-nav-home/covers/dynamic/cover-07/1.jpg b/code-nav-home/covers/dynamic/cover-07/1.jpg
new file mode 100644
index 0000000..3e23e52
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-07/1.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-07/index.html b/code-nav-home/covers/dynamic/cover-07/index.html
new file mode 100644
index 0000000..c7852cd
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-07/index.html
@@ -0,0 +1,344 @@
+
+
+
+
+
+
+ 编程导航 - 蕾姆樱花
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-07/js/index.js b/code-nav-home/covers/dynamic/cover-07/js/index.js
new file mode 100644
index 0000000..56f7df1
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-07/js/index.js
@@ -0,0 +1,802 @@
+// Utilities
+var Vector3 = {};
+var Matrix44 = {};
+Vector3.create = function(x, y, z) {
+ return {'x':x, 'y':y, 'z':z};
+};
+Vector3.dot = function (v0, v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
+};
+Vector3.cross = function (v, v0, v1) {
+ v.x = v0.y * v1.z - v0.z * v1.y;
+ v.y = v0.z * v1.x - v0.x * v1.z;
+ v.z = v0.x * v1.y - v0.y * v1.x;
+};
+Vector3.normalize = function (v) {
+ var l = v.x * v.x + v.y * v.y + v.z * v.z;
+ if(l > 0.00001) {
+ l = 1.0 / Math.sqrt(l);
+ v.x *= l;
+ v.y *= l;
+ v.z *= l;
+ }
+};
+Vector3.arrayForm = function(v) {
+ if(v.array) {
+ v.array[0] = v.x;
+ v.array[1] = v.y;
+ v.array[2] = v.z;
+ }
+ else {
+ v.array = new Float32Array([v.x, v.y, v.z]);
+ }
+ return v.array;
+};
+Matrix44.createIdentity = function () {
+ return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
+};
+Matrix44.loadProjection = function (m, aspect, vdeg, near, far) {
+ var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0;
+ var w = h * aspect;
+
+ m[0] = 2.0 * near / w;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+
+ m[4] = 0.0;
+ m[5] = 2.0 * near / h;
+ m[6] = 0.0;
+ m[7] = 0.0;
+
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = -(far + near) / (far - near);
+ m[11] = -1.0;
+
+ m[12] = 0.0;
+ m[13] = 0.0;
+ m[14] = -2.0 * far * near / (far - near);
+ m[15] = 0.0;
+};
+Matrix44.loadLookAt = function (m, vpos, vlook, vup) {
+ var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z);
+ Vector3.normalize(frontv);
+ var sidev = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(sidev, vup, frontv);
+ Vector3.normalize(sidev);
+ var topv = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(topv, frontv, sidev);
+ Vector3.normalize(topv);
+
+ m[0] = sidev.x;
+ m[1] = topv.x;
+ m[2] = frontv.x;
+ m[3] = 0.0;
+
+ m[4] = sidev.y;
+ m[5] = topv.y;
+ m[6] = frontv.y;
+ m[7] = 0.0;
+
+ m[8] = sidev.z;
+ m[9] = topv.z;
+ m[10] = frontv.z;
+ m[11] = 0.0;
+
+ m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]);
+ m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]);
+ m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]);
+ m[15] = 1.0;
+};
+
+//
+var timeInfo = {
+ 'start':0, 'prev':0, // Date
+ 'delta':0, 'elapsed':0 // Number(sec)
+};
+
+//
+var gl;
+var renderSpec = {
+ 'width':0,
+ 'height':0,
+ 'aspect':1,
+ 'array':new Float32Array(3),
+ 'halfWidth':0,
+ 'halfHeight':0,
+ 'halfArray':new Float32Array(3)
+ // and some render targets. see setViewport()
+};
+renderSpec.setSize = function(w, h) {
+ renderSpec.width = w;
+ renderSpec.height = h;
+ renderSpec.aspect = renderSpec.width / renderSpec.height;
+ renderSpec.array[0] = renderSpec.width;
+ renderSpec.array[1] = renderSpec.height;
+ renderSpec.array[2] = renderSpec.aspect;
+
+ renderSpec.halfWidth = Math.floor(w / 2);
+ renderSpec.halfHeight = Math.floor(h / 2);
+ renderSpec.halfArray[0] = renderSpec.halfWidth;
+ renderSpec.halfArray[1] = renderSpec.halfHeight;
+ renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight;
+};
+
+function deleteRenderTarget(rt) {
+ gl.deleteFramebuffer(rt.frameBuffer);
+ gl.deleteRenderbuffer(rt.renderBuffer);
+ gl.deleteTexture(rt.texture);
+}
+
+function createRenderTarget(w, h) {
+ var ret = {
+ 'width':w,
+ 'height':h,
+ 'sizeArray':new Float32Array([w, h, w / h]),
+ 'dtxArray':new Float32Array([1.0 / w, 1.0 / h])
+ };
+ ret.frameBuffer = gl.createFramebuffer();
+ ret.renderBuffer = gl.createRenderbuffer();
+ ret.texture = gl.createTexture();
+
+ gl.bindTexture(gl.TEXTURE_2D, ret.texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer);
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ return ret;
+}
+
+function compileShader(shtype, shsrc) {
+ var retsh = gl.createShader(shtype);
+
+ gl.shaderSource(retsh, shsrc);
+ gl.compileShader(retsh);
+
+ if(!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) {
+ var errlog = gl.getShaderInfoLog(retsh);
+ gl.deleteShader(retsh);
+ console.error(errlog);
+ return null;
+ }
+ return retsh;
+}
+
+function createShader(vtxsrc, frgsrc, uniformlist, attrlist) {
+ var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc);
+ var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc);
+
+ if(vsh == null || fsh == null) {
+ return null;
+ }
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vsh);
+ gl.attachShader(prog, fsh);
+
+ gl.deleteShader(vsh);
+ gl.deleteShader(fsh);
+
+ gl.linkProgram(prog);
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var errlog = gl.getProgramInfoLog(prog);
+ console.error(errlog);
+ return null;
+ }
+
+ if(uniformlist) {
+ prog.uniforms = {};
+ for(var i = 0; i < uniformlist.length; i++) {
+ prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]);
+ }
+ }
+
+ if(attrlist) {
+ prog.attributes = {};
+ for(var i = 0; i < attrlist.length; i++) {
+ var attr = attrlist[i];
+ prog.attributes[attr] = gl.getAttribLocation(prog, attr);
+ }
+ }
+
+ return prog;
+}
+
+function useShader(prog) {
+ gl.useProgram(prog);
+ for(var attr in prog.attributes) {
+ gl.enableVertexAttribArray(prog.attributes[attr]);;
+ }
+}
+
+function unuseShader(prog) {
+ for(var attr in prog.attributes) {
+ gl.disableVertexAttribArray(prog.attributes[attr]);;
+ }
+ gl.useProgram(null);
+}
+
+/////
+var projection = {
+ 'angle':60,
+ 'nearfar':new Float32Array([0.1, 100.0]),
+ 'matrix':Matrix44.createIdentity()
+};
+var camera = {
+ 'position':Vector3.create(0, 0, 100),
+ 'lookat':Vector3.create(0, 0, 0),
+ 'up':Vector3.create(0, 1, 0),
+ 'dof':Vector3.create(10.0, 4.0, 8.0),
+ 'matrix':Matrix44.createIdentity()
+};
+
+var pointFlower = {};
+var meshFlower = {};
+var sceneStandBy = false;
+
+var BlossomParticle = function () {
+ this.velocity = new Array(3);
+ this.rotation = new Array(3);
+ this.position = new Array(3);
+ this.euler = new Array(3);
+ this.size = 1.0;
+ this.alpha = 1.0;
+ this.zkey = 0.0;
+};
+
+BlossomParticle.prototype.setVelocity = function (vx, vy, vz) {
+ this.velocity[0] = vx;
+ this.velocity[1] = vy;
+ this.velocity[2] = vz;
+};
+
+BlossomParticle.prototype.setRotation = function (rx, ry, rz) {
+ this.rotation[0] = rx;
+ this.rotation[1] = ry;
+ this.rotation[2] = rz;
+};
+
+BlossomParticle.prototype.setPosition = function (nx, ny, nz) {
+ this.position[0] = nx;
+ this.position[1] = ny;
+ this.position[2] = nz;
+};
+
+BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) {
+ this.euler[0] = rx;
+ this.euler[1] = ry;
+ this.euler[2] = rz;
+};
+
+BlossomParticle.prototype.setSize = function (s) {
+ this.size = s;
+};
+
+BlossomParticle.prototype.update = function (dt, et) {
+ this.position[0] += this.velocity[0] * dt;
+ this.position[1] += this.velocity[1] * dt;
+ this.position[2] += this.velocity[2] * dt;
+
+ this.euler[0] += this.rotation[0] * dt;
+ this.euler[1] += this.rotation[1] * dt;
+ this.euler[2] += this.rotation[2] * dt;
+};
+
+function createPointFlowers() {
+ // get point sizes
+ var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
+ renderSpec.pointSize = {'min':prm[0], 'max':prm[1]};
+
+ var vtxsrc = document.getElementById("sakura_point_vsh").textContent;
+ var frgsrc = document.getElementById("sakura_point_fsh").textContent;
+
+ pointFlower.program = createShader(
+ vtxsrc, frgsrc,
+ ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'],
+ ['aPosition', 'aEuler', 'aMisc']
+ );
+
+ useShader(pointFlower.program);
+ pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]);
+ pointFlower.fader = Vector3.create(0.0, 10.0, 0.0);
+
+ // paramerters: velocity[3], rotate[3]
+ pointFlower.numFlowers = 300;
+ pointFlower.particles = new Array(pointFlower.numFlowers);
+ // vertex attributes {position[3], euler_xyz[3], size[1]}
+ pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2));
+ pointFlower.positionArrayOffset = 0;
+ pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3;
+ pointFlower.miscArrayOffset = pointFlower.numFlowers * 6;
+
+ pointFlower.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ unuseShader(pointFlower.program);
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ pointFlower.particles[i] = new BlossomParticle();
+ }
+}
+
+function initPointFlowers() {
+ //area
+ pointFlower.area = Vector3.create(20.0, 20.0, 20.0);
+ pointFlower.area.x = pointFlower.area.y * renderSpec.aspect;
+
+ pointFlower.fader.x = 10.0; //env fade start
+ pointFlower.fader.y = pointFlower.area.z; //env fade half
+ pointFlower.fader.z = 0.1; //near fade start
+
+ //particles
+ var PI2 = Math.PI * 2.0;
+ var tmpv3 = Vector3.create(0, 0, 0);
+ var tmpv = 0;
+ var symmetryrand = function() {return (Math.random() * 2.0 - 1.0);};
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var tmpprtcl = pointFlower.particles[i];
+
+ //velocity
+ tmpv3.x = symmetryrand() * 0.3 + 0.8;
+ tmpv3.y = symmetryrand() * 0.2 - 1.0;
+ tmpv3.z = symmetryrand() * 0.3 + 0.5;
+ Vector3.normalize(tmpv3);
+ tmpv = 2.0 + Math.random() * 1.0;
+ tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv);
+
+ //rotation
+ tmpprtcl.setRotation(
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5
+ );
+
+ //position
+ tmpprtcl.setPosition(
+ symmetryrand() * pointFlower.area.x,
+ symmetryrand() * pointFlower.area.y,
+ symmetryrand() * pointFlower.area.z
+ );
+
+ //euler
+ tmpprtcl.setEulerAngles(
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0
+ );
+
+ //size
+ tmpprtcl.setSize(0.9 + Math.random() * 0.1);
+ }
+}
+
+function renderPointFlowers() {
+ //update
+ var PI2 = Math.PI * 2.0;
+ var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z];
+ var repeatPos = function (prt, cmp, limit) {
+ if(Math.abs(prt.position[cmp]) - prt.size * 0.5 > limit) {
+ //out of area
+ if(prt.position[cmp] > 0) {
+ prt.position[cmp] -= limit * 2.0;
+ }
+ else {
+ prt.position[cmp] += limit * 2.0;
+ }
+ }
+ };
+ var repeatEuler = function (prt, cmp) {
+ prt.euler[cmp] = prt.euler[cmp] % PI2;
+ if(prt.euler[cmp] < 0.0) {
+ prt.euler[cmp] += PI2;
+ }
+ };
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ prtcl.update(timeInfo.delta, timeInfo.elapsed);
+ repeatPos(prtcl, 0, pointFlower.area.x);
+ repeatPos(prtcl, 1, pointFlower.area.y);
+ repeatPos(prtcl, 2, pointFlower.area.z);
+ repeatEuler(prtcl, 0);
+ repeatEuler(prtcl, 1);
+ repeatEuler(prtcl, 2);
+
+ prtcl.alpha = 1.0;//(pointFlower.area.z - prtcl.position[2]) * 0.5;
+
+ prtcl.zkey = (camera.matrix[2] * prtcl.position[0]
+ + camera.matrix[6] * prtcl.position[1]
+ + camera.matrix[10] * prtcl.position[2]
+ + camera.matrix[14]);
+ }
+
+ // sort
+ pointFlower.particles.sort(function(p0, p1){return p0.zkey - p1.zkey;});
+
+ // update data
+ var ipos = pointFlower.positionArrayOffset;
+ var ieuler = pointFlower.eulerArrayOffset;
+ var imisc = pointFlower.miscArrayOffset;
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ pointFlower.dataArray[ipos] = prtcl.position[0];
+ pointFlower.dataArray[ipos + 1] = prtcl.position[1];
+ pointFlower.dataArray[ipos + 2] = prtcl.position[2];
+ ipos += 3;
+ pointFlower.dataArray[ieuler] = prtcl.euler[0];
+ pointFlower.dataArray[ieuler + 1] = prtcl.euler[1];
+ pointFlower.dataArray[ieuler + 2] = prtcl.euler[2];
+ ieuler += 3;
+ pointFlower.dataArray[imisc] = prtcl.size;
+ pointFlower.dataArray[imisc + 1] = prtcl.alpha;
+ imisc += 2;
+ }
+
+ //draw
+ gl.enable(gl.BLEND);
+ //gl.disable(gl.DEPTH_TEST);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ var prog = pointFlower.program;
+ useShader(prog);
+
+ gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix);
+ gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+ gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof));
+ gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader));
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+
+ gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+
+ // doubler
+ for(var i = 1; i < 2; i++) {
+ var zpos = i * -2.0;
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+ }
+
+ //main
+ pointFlower.offset[0] = 0.0;
+ pointFlower.offset[1] = 0.0;
+ pointFlower.offset[2] = 0.0;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(prog);
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+}
+
+// effects
+//common util
+function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) {
+ var ret = {};
+ var unifs = ['uResolution', 'uSrc', 'uDelta'];
+ if(exunifs) {
+ unifs = unifs.concat(exunifs);
+ }
+ var attrs = ['aPosition'];
+ if(exattrs) {
+ attrs = attrs.concat(exattrs);
+ }
+
+ ret.program = createShader(vtxsrc, frgsrc, unifs, attrs);
+ useShader(ret.program);
+
+ ret.dataArray = new Float32Array([
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0
+ ]);
+ ret.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(ret.program);
+
+ return ret;
+}
+
+// basic usage
+// useEffect(prog, srctex({'texture':texid, 'dtxArray':(f32)[dtx, dty]})); //basic initialize
+// gl.uniform**(...); //additional uniforms
+// drawEffect()
+// unuseEffect(prog)
+// TEXTURE0 makes src
+function useEffect(fxobj, srctex) {
+ var prog = fxobj.program;
+ useShader(prog);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+
+ if(srctex != null) {
+ gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray);
+ gl.uniform1i(prog.uniforms.uSrc, 0);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, srctex.texture);
+ }
+}
+function drawEffect(fxobj) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer);
+ gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+}
+function unuseEffect(fxobj) {
+ unuseShader(fxobj.program);
+}
+
+var effectLib = {};
+function createEffectLib() {
+
+ var vtxsrc, frgsrc;
+ //common
+ var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent;
+
+ //background
+ frgsrc = document.getElementById("bg_fsh").textContent;
+ effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null);
+
+ // make brightpixels buffer
+ frgsrc = document.getElementById("fx_brightbuf_fsh").textContent;
+ effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null);
+
+ // direction blur
+ frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent;
+ effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null);
+
+ //final composite
+ vtxsrc = document.getElementById("pp_final_vsh").textContent;
+ frgsrc = document.getElementById("pp_final_fsh").textContent;
+ effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null);
+}
+
+// background
+function createBackground() {
+ //console.log("create background");
+}
+function initBackground() {
+ //console.log("init background");
+}
+function renderBackground() {
+ gl.disable(gl.DEPTH_TEST);
+
+ useEffect(effectLib.sceneBg, null);
+ gl.uniform2f(effectLib.sceneBg.program.uniforms.uTimes, timeInfo.elapsed, timeInfo.delta);
+ drawEffect(effectLib.sceneBg);
+ unuseEffect(effectLib.sceneBg);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+// post process
+var postProcess = {};
+function createPostProcess() {
+ //console.log("create post process");
+}
+function initPostProcess() {
+ //console.log("init post process");
+}
+
+function renderPostProcess() {
+ gl.enable(gl.TEXTURE_2D);
+ gl.disable(gl.DEPTH_TEST);
+ var bindRT = function (rt, isclear) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer);
+ gl.viewport(0, 0, rt.width, rt.height);
+ if(isclear) {
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+ };
+
+ //make bright buff
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.mkBrightBuf, renderSpec.mainRT);
+ drawEffect(effectLib.mkBrightBuf);
+ unuseEffect(effectLib.mkBrightBuf);
+
+ // make bloom
+ for(var i = 0; i < 2; i++) {
+ var p = 1.5 + 1 * i;
+ var s = 2.0 + 1 * i;
+ bindRT(renderSpec.wHalfRT1, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT0);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT1);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+ }
+
+ //display
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ useEffect(effectLib.finalComp, renderSpec.mainRT);
+ gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture);
+ drawEffect(effectLib.finalComp);
+ unuseEffect(effectLib.finalComp);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+/////
+var SceneEnv = {};
+function createScene() {
+ createEffectLib();
+ createBackground();
+ createPointFlowers();
+ createPostProcess();
+ sceneStandBy = true;
+}
+
+function initScene() {
+ initBackground();
+ initPointFlowers();
+ initPostProcess();
+
+ //camera.position.z = 17.320508;
+ camera.position.z = pointFlower.area.z + projection.nearfar[0];
+ projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0;
+ Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]);
+}
+
+function renderScene() {
+ //draw
+ Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ //gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer);
+ gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height);
+ gl.clearColor(0.005, 0, 0.05, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ renderBackground();
+ renderPointFlowers();
+ renderPostProcess();
+}
+
+/////
+function onResize(e) {
+ makeCanvasFullScreen(document.getElementById("sakura"));
+ setViewports();
+ if(sceneStandBy) {
+ initScene();
+ }
+}
+
+function setViewports() {
+ renderSpec.setSize(gl.canvas.width, gl.canvas.height);
+
+ gl.clearColor(0.2, 0.2, 0.5, 1.0);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+
+ var rtfunc = function (rtname, rtw, rth) {
+ var rt = renderSpec[rtname];
+ if(rt) deleteRenderTarget(rt);
+ renderSpec[rtname] = createRenderTarget(rtw, rth);
+ };
+ rtfunc('mainRT', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT0', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT1', renderSpec.width, renderSpec.height);
+ rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight);
+ rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight);
+}
+
+function render() {
+ renderScene();
+}
+
+var animating = true;
+function toggleAnimation(elm) {
+ animating ^= true;
+ if(animating) animate();
+ if(elm) {
+ elm.innerHTML = animating? "Stop":"Start";
+ }
+}
+
+function stepAnimation() {
+ if(!animating) animate();
+}
+
+function animate() {
+ var curdate = new Date();
+ timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0;
+ timeInfo.delta = (curdate - timeInfo.prev) / 1000.0;
+ timeInfo.prev = curdate;
+
+ if(animating) requestAnimationFrame(animate);
+ render();
+}
+
+function makeCanvasFullScreen(canvas) {
+ var b = document.body;
+ var d = document.documentElement;
+ fullw = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth);
+ fullh = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight);
+ canvas.width = fullw;
+ canvas.height = fullh;
+}
+
+window.addEventListener('load', function(e) {
+ var canvas = document.getElementById("sakura");
+ try {
+ makeCanvasFullScreen(canvas);
+ gl = canvas.getContext('experimental-webgl');
+ } catch(e) {
+ alert("WebGL not supported." + e);
+ console.error(e);
+ return;
+ }
+
+ window.addEventListener('resize', onResize);
+
+ setViewports();
+ createScene();
+ initScene();
+
+ timeInfo.start = new Date();
+ timeInfo.prev = timeInfo.start;
+ animate();
+});
+
+//set window.requestAnimationFrame
+(function (w, r) {
+ w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
+})(window, 'equestAnimationFrame');
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-07/preview.jpg b/code-nav-home/covers/dynamic/cover-07/preview.jpg
new file mode 100644
index 0000000..6ef61db
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-07/preview.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-08/1.jpg b/code-nav-home/covers/dynamic/cover-08/1.jpg
new file mode 100644
index 0000000..a1f2d75
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-08/1.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-08/index.html b/code-nav-home/covers/dynamic/cover-08/index.html
new file mode 100644
index 0000000..69fa930
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-08/index.html
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+ 编程导航 - 吾王 Saber
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-08/js/index.js b/code-nav-home/covers/dynamic/cover-08/js/index.js
new file mode 100644
index 0000000..0fcda8d
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-08/js/index.js
@@ -0,0 +1,802 @@
+// Utilities
+var Vector3 = {};
+var Matrix44 = {};
+Vector3.create = function(x, y, z) {
+ return {'x':x, 'y':y, 'z':z};
+};
+Vector3.dot = function (v0, v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
+};
+Vector3.cross = function (v, v0, v1) {
+ v.x = v0.y * v1.z - v0.z * v1.y;
+ v.y = v0.z * v1.x - v0.x * v1.z;
+ v.z = v0.x * v1.y - v0.y * v1.x;
+};
+Vector3.normalize = function (v) {
+ var l = v.x * v.x + v.y * v.y + v.z * v.z;
+ if(l > 0.00001) {
+ l = 1.0 / Math.sqrt(l);
+ v.x *= l;
+ v.y *= l;
+ v.z *= l;
+ }
+};
+Vector3.arrayForm = function(v) {
+ if(v.array) {
+ v.array[0] = v.x;
+ v.array[1] = v.y;
+ v.array[2] = v.z;
+ }
+ else {
+ v.array = new Float32Array([v.x, v.y, v.z]);
+ }
+ return v.array;
+};
+Matrix44.createIdentity = function () {
+ return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
+};
+Matrix44.loadProjection = function (m, aspect, vdeg, near, far) {
+ var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0;
+ var w = h * aspect;
+
+ m[0] = 2.0 * near / w;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+
+ m[4] = 0.0;
+ m[5] = 2.0 * near / h;
+ m[6] = 0.0;
+ m[7] = 0.0;
+
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = -(far + near) / (far - near);
+ m[11] = -1.0;
+
+ m[12] = 0.0;
+ m[13] = 0.0;
+ m[14] = -2.0 * far * near / (far - near);
+ m[15] = 0.0;
+};
+Matrix44.loadLookAt = function (m, vpos, vlook, vup) {
+ var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z);
+ Vector3.normalize(frontv);
+ var sidev = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(sidev, vup, frontv);
+ Vector3.normalize(sidev);
+ var topv = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(topv, frontv, sidev);
+ Vector3.normalize(topv);
+
+ m[0] = sidev.x;
+ m[1] = topv.x;
+ m[2] = frontv.x;
+ m[3] = 0.0;
+
+ m[4] = sidev.y;
+ m[5] = topv.y;
+ m[6] = frontv.y;
+ m[7] = 0.0;
+
+ m[8] = sidev.z;
+ m[9] = topv.z;
+ m[10] = frontv.z;
+ m[11] = 0.0;
+
+ m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]);
+ m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]);
+ m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]);
+ m[15] = 1.0;
+};
+
+//
+var timeInfo = {
+ 'start':0, 'prev':0, // Date
+ 'delta':0, 'elapsed':0 // Number(sec)
+};
+
+//
+var gl;
+var renderSpec = {
+ 'width':0,
+ 'height':0,
+ 'aspect':1,
+ 'array':new Float32Array(3),
+ 'halfWidth':0,
+ 'halfHeight':0,
+ 'halfArray':new Float32Array(3)
+ // and some render targets. see setViewport()
+};
+renderSpec.setSize = function(w, h) {
+ renderSpec.width = w;
+ renderSpec.height = h;
+ renderSpec.aspect = renderSpec.width / renderSpec.height;
+ renderSpec.array[0] = renderSpec.width;
+ renderSpec.array[1] = renderSpec.height;
+ renderSpec.array[2] = renderSpec.aspect;
+
+ renderSpec.halfWidth = Math.floor(w / 2);
+ renderSpec.halfHeight = Math.floor(h / 2);
+ renderSpec.halfArray[0] = renderSpec.halfWidth;
+ renderSpec.halfArray[1] = renderSpec.halfHeight;
+ renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight;
+};
+
+function deleteRenderTarget(rt) {
+ gl.deleteFramebuffer(rt.frameBuffer);
+ gl.deleteRenderbuffer(rt.renderBuffer);
+ gl.deleteTexture(rt.texture);
+}
+
+function createRenderTarget(w, h) {
+ var ret = {
+ 'width':w,
+ 'height':h,
+ 'sizeArray':new Float32Array([w, h, w / h]),
+ 'dtxArray':new Float32Array([1.0 / w, 1.0 / h])
+ };
+ ret.frameBuffer = gl.createFramebuffer();
+ ret.renderBuffer = gl.createRenderbuffer();
+ ret.texture = gl.createTexture();
+
+ gl.bindTexture(gl.TEXTURE_2D, ret.texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer);
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ return ret;
+}
+
+function compileShader(shtype, shsrc) {
+ var retsh = gl.createShader(shtype);
+
+ gl.shaderSource(retsh, shsrc);
+ gl.compileShader(retsh);
+
+ if(!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) {
+ var errlog = gl.getShaderInfoLog(retsh);
+ gl.deleteShader(retsh);
+ console.error(errlog);
+ return null;
+ }
+ return retsh;
+}
+
+function createShader(vtxsrc, frgsrc, uniformlist, attrlist) {
+ var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc);
+ var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc);
+
+ if(vsh == null || fsh == null) {
+ return null;
+ }
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vsh);
+ gl.attachShader(prog, fsh);
+
+ gl.deleteShader(vsh);
+ gl.deleteShader(fsh);
+
+ gl.linkProgram(prog);
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var errlog = gl.getProgramInfoLog(prog);
+ console.error(errlog);
+ return null;
+ }
+
+ if(uniformlist) {
+ prog.uniforms = {};
+ for(var i = 0; i < uniformlist.length; i++) {
+ prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]);
+ }
+ }
+
+ if(attrlist) {
+ prog.attributes = {};
+ for(var i = 0; i < attrlist.length; i++) {
+ var attr = attrlist[i];
+ prog.attributes[attr] = gl.getAttribLocation(prog, attr);
+ }
+ }
+
+ return prog;
+}
+
+function useShader(prog) {
+ gl.useProgram(prog);
+ for(var attr in prog.attributes) {
+ gl.enableVertexAttribArray(prog.attributes[attr]);;
+ }
+}
+
+function unuseShader(prog) {
+ for(var attr in prog.attributes) {
+ gl.disableVertexAttribArray(prog.attributes[attr]);;
+ }
+ gl.useProgram(null);
+}
+
+/////
+var projection = {
+ 'angle':60,
+ 'nearfar':new Float32Array([0.1, 100.0]),
+ 'matrix':Matrix44.createIdentity()
+};
+var camera = {
+ 'position':Vector3.create(0, 0, 100),
+ 'lookat':Vector3.create(0, 0, 0),
+ 'up':Vector3.create(0, 1, 0),
+ 'dof':Vector3.create(10.0, 4.0, 8.0),
+ 'matrix':Matrix44.createIdentity()
+};
+
+var pointFlower = {};
+var meshFlower = {};
+var sceneStandBy = false;
+
+var BlossomParticle = function () {
+ this.velocity = new Array(3);
+ this.rotation = new Array(3);
+ this.position = new Array(3);
+ this.euler = new Array(3);
+ this.size = 1.0;
+ this.alpha = 1.0;
+ this.zkey = 0.0;
+};
+
+BlossomParticle.prototype.setVelocity = function (vx, vy, vz) {
+ this.velocity[0] = vx;
+ this.velocity[1] = vy;
+ this.velocity[2] = vz;
+};
+
+BlossomParticle.prototype.setRotation = function (rx, ry, rz) {
+ this.rotation[0] = rx;
+ this.rotation[1] = ry;
+ this.rotation[2] = rz;
+};
+
+BlossomParticle.prototype.setPosition = function (nx, ny, nz) {
+ this.position[0] = nx;
+ this.position[1] = ny;
+ this.position[2] = nz;
+};
+
+BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) {
+ this.euler[0] = rx;
+ this.euler[1] = ry;
+ this.euler[2] = rz;
+};
+
+BlossomParticle.prototype.setSize = function (s) {
+ this.size = s;
+};
+
+BlossomParticle.prototype.update = function (dt, et) {
+ this.position[0] += this.velocity[0] * dt;
+ this.position[1] += this.velocity[1] * dt;
+ this.position[2] += this.velocity[2] * dt;
+
+ this.euler[0] += this.rotation[0] * dt;
+ this.euler[1] += this.rotation[1] * dt;
+ this.euler[2] += this.rotation[2] * dt;
+};
+
+function createPointFlowers() {
+ // get point sizes
+ var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
+ renderSpec.pointSize = {'min':prm[0], 'max':prm[1]};
+
+ var vtxsrc = document.getElementById("sakura_point_vsh").textContent;
+ var frgsrc = document.getElementById("sakura_point_fsh").textContent;
+
+ pointFlower.program = createShader(
+ vtxsrc, frgsrc,
+ ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'],
+ ['aPosition', 'aEuler', 'aMisc']
+ );
+
+ useShader(pointFlower.program);
+ pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]);
+ pointFlower.fader = Vector3.create(0.0, 10.0, 0.0);
+
+ // paramerters: velocity[3], rotate[3]
+ pointFlower.numFlowers = 300;
+ pointFlower.particles = new Array(pointFlower.numFlowers);
+ // vertex attributes {position[3], euler_xyz[3], size[1]}
+ pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2));
+ pointFlower.positionArrayOffset = 0;
+ pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3;
+ pointFlower.miscArrayOffset = pointFlower.numFlowers * 6;
+
+ pointFlower.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ unuseShader(pointFlower.program);
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ pointFlower.particles[i] = new BlossomParticle();
+ }
+}
+
+function initPointFlowers() {
+ //area
+ pointFlower.area = Vector3.create(20.0, 20.0, 20.0);
+ pointFlower.area.x = pointFlower.area.y * renderSpec.aspect;
+
+ pointFlower.fader.x = 10.0; //env fade start
+ pointFlower.fader.y = pointFlower.area.z; //env fade half
+ pointFlower.fader.z = 0.1; //near fade start
+
+ //particles
+ var PI2 = Math.PI * 2.0;
+ var tmpv3 = Vector3.create(0, 0, 0);
+ var tmpv = 0;
+ var symmetryrand = function() {return (Math.random() * 2.0 - 1.0);};
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var tmpprtcl = pointFlower.particles[i];
+
+ //velocity
+ tmpv3.x = symmetryrand() * 0.3 - 0.8;
+ tmpv3.y = symmetryrand() * 0.2 - 1.0;
+ tmpv3.z = symmetryrand() * 0.3 - 0.5;
+ Vector3.normalize(tmpv3);
+ tmpv = 2.0 + Math.random() * 1.0;
+ tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv);
+
+ //rotation
+ tmpprtcl.setRotation(
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5
+ );
+
+ //position
+ tmpprtcl.setPosition(
+ symmetryrand() * pointFlower.area.x,
+ symmetryrand() * pointFlower.area.y,
+ symmetryrand() * pointFlower.area.z
+ );
+
+ //euler
+ tmpprtcl.setEulerAngles(
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0
+ );
+
+ //size
+ tmpprtcl.setSize(0.9 + Math.random() * 0.1);
+ }
+}
+
+function renderPointFlowers() {
+ //update
+ var PI2 = Math.PI * 2.0;
+ var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z];
+ var repeatPos = function (prt, cmp, limit) {
+ if(Math.abs(prt.position[cmp]) - prt.size * 0.5 > limit) {
+ //out of area
+ if(prt.position[cmp] > 0) {
+ prt.position[cmp] -= limit * 2.0;
+ }
+ else {
+ prt.position[cmp] += limit * 2.0;
+ }
+ }
+ };
+ var repeatEuler = function (prt, cmp) {
+ prt.euler[cmp] = prt.euler[cmp] % PI2;
+ if(prt.euler[cmp] < 0.0) {
+ prt.euler[cmp] += PI2;
+ }
+ };
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ prtcl.update(timeInfo.delta, timeInfo.elapsed);
+ repeatPos(prtcl, 0, pointFlower.area.x);
+ repeatPos(prtcl, 1, pointFlower.area.y);
+ repeatPos(prtcl, 2, pointFlower.area.z);
+ repeatEuler(prtcl, 0);
+ repeatEuler(prtcl, 1);
+ repeatEuler(prtcl, 2);
+
+ prtcl.alpha = 1.0;//(pointFlower.area.z - prtcl.position[2]) * 0.5;
+
+ prtcl.zkey = (camera.matrix[2] * prtcl.position[0]
+ + camera.matrix[6] * prtcl.position[1]
+ + camera.matrix[10] * prtcl.position[2]
+ + camera.matrix[14]);
+ }
+
+ // sort
+ pointFlower.particles.sort(function(p0, p1){return p0.zkey - p1.zkey;});
+
+ // update data
+ var ipos = pointFlower.positionArrayOffset;
+ var ieuler = pointFlower.eulerArrayOffset;
+ var imisc = pointFlower.miscArrayOffset;
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ pointFlower.dataArray[ipos] = prtcl.position[0];
+ pointFlower.dataArray[ipos + 1] = prtcl.position[1];
+ pointFlower.dataArray[ipos + 2] = prtcl.position[2];
+ ipos += 3;
+ pointFlower.dataArray[ieuler] = prtcl.euler[0];
+ pointFlower.dataArray[ieuler + 1] = prtcl.euler[1];
+ pointFlower.dataArray[ieuler + 2] = prtcl.euler[2];
+ ieuler += 3;
+ pointFlower.dataArray[imisc] = prtcl.size;
+ pointFlower.dataArray[imisc + 1] = prtcl.alpha;
+ imisc += 2;
+ }
+
+ //draw
+ gl.enable(gl.BLEND);
+ //gl.disable(gl.DEPTH_TEST);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ var prog = pointFlower.program;
+ useShader(prog);
+
+ gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix);
+ gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+ gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof));
+ gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader));
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+
+ gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+
+ // doubler
+ for(var i = 1; i < 2; i++) {
+ var zpos = i * -2.0;
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+ }
+
+ //main
+ pointFlower.offset[0] = 0.0;
+ pointFlower.offset[1] = 0.0;
+ pointFlower.offset[2] = 0.0;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(prog);
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+}
+
+// effects
+//common util
+function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) {
+ var ret = {};
+ var unifs = ['uResolution', 'uSrc', 'uDelta'];
+ if(exunifs) {
+ unifs = unifs.concat(exunifs);
+ }
+ var attrs = ['aPosition'];
+ if(exattrs) {
+ attrs = attrs.concat(exattrs);
+ }
+
+ ret.program = createShader(vtxsrc, frgsrc, unifs, attrs);
+ useShader(ret.program);
+
+ ret.dataArray = new Float32Array([
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0
+ ]);
+ ret.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(ret.program);
+
+ return ret;
+}
+
+// basic usage
+// useEffect(prog, srctex({'texture':texid, 'dtxArray':(f32)[dtx, dty]})); //basic initialize
+// gl.uniform**(...); //additional uniforms
+// drawEffect()
+// unuseEffect(prog)
+// TEXTURE0 makes src
+function useEffect(fxobj, srctex) {
+ var prog = fxobj.program;
+ useShader(prog);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+
+ if(srctex != null) {
+ gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray);
+ gl.uniform1i(prog.uniforms.uSrc, 0);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, srctex.texture);
+ }
+}
+function drawEffect(fxobj) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer);
+ gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+}
+function unuseEffect(fxobj) {
+ unuseShader(fxobj.program);
+}
+
+var effectLib = {};
+function createEffectLib() {
+
+ var vtxsrc, frgsrc;
+ //common
+ var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent;
+
+ //background
+ frgsrc = document.getElementById("bg_fsh").textContent;
+ effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null);
+
+ // make brightpixels buffer
+ frgsrc = document.getElementById("fx_brightbuf_fsh").textContent;
+ effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null);
+
+ // direction blur
+ frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent;
+ effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null);
+
+ //final composite
+ vtxsrc = document.getElementById("pp_final_vsh").textContent;
+ frgsrc = document.getElementById("pp_final_fsh").textContent;
+ effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null);
+}
+
+// background
+function createBackground() {
+ //console.log("create background");
+}
+function initBackground() {
+ //console.log("init background");
+}
+function renderBackground() {
+ gl.disable(gl.DEPTH_TEST);
+
+ useEffect(effectLib.sceneBg, null);
+ gl.uniform2f(effectLib.sceneBg.program.uniforms.uTimes, timeInfo.elapsed, timeInfo.delta);
+ drawEffect(effectLib.sceneBg);
+ unuseEffect(effectLib.sceneBg);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+// post process
+var postProcess = {};
+function createPostProcess() {
+ //console.log("create post process");
+}
+function initPostProcess() {
+ //console.log("init post process");
+}
+
+function renderPostProcess() {
+ gl.enable(gl.TEXTURE_2D);
+ gl.disable(gl.DEPTH_TEST);
+ var bindRT = function (rt, isclear) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer);
+ gl.viewport(0, 0, rt.width, rt.height);
+ if(isclear) {
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+ };
+
+ //make bright buff
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.mkBrightBuf, renderSpec.mainRT);
+ drawEffect(effectLib.mkBrightBuf);
+ unuseEffect(effectLib.mkBrightBuf);
+
+ // make bloom
+ for(var i = 0; i < 2; i++) {
+ var p = 1.5 + 1 * i;
+ var s = 2.0 + 1 * i;
+ bindRT(renderSpec.wHalfRT1, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT0);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT1);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+ }
+
+ //display
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ useEffect(effectLib.finalComp, renderSpec.mainRT);
+ gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture);
+ drawEffect(effectLib.finalComp);
+ unuseEffect(effectLib.finalComp);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+/////
+var SceneEnv = {};
+function createScene() {
+ createEffectLib();
+ createBackground();
+ createPointFlowers();
+ createPostProcess();
+ sceneStandBy = true;
+}
+
+function initScene() {
+ initBackground();
+ initPointFlowers();
+ initPostProcess();
+
+ //camera.position.z = 17.320508;
+ camera.position.z = pointFlower.area.z + projection.nearfar[0];
+ projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0;
+ Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]);
+}
+
+function renderScene() {
+ //draw
+ Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ //gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer);
+ gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height);
+ gl.clearColor(0.005, 0, 0.05, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ renderBackground();
+ renderPointFlowers();
+ renderPostProcess();
+}
+
+/////
+function onResize(e) {
+ makeCanvasFullScreen(document.getElementById("sakura"));
+ setViewports();
+ if(sceneStandBy) {
+ initScene();
+ }
+}
+
+function setViewports() {
+ renderSpec.setSize(gl.canvas.width, gl.canvas.height);
+
+ gl.clearColor(0.2, 0.2, 0.5, 1.0);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+
+ var rtfunc = function (rtname, rtw, rth) {
+ var rt = renderSpec[rtname];
+ if(rt) deleteRenderTarget(rt);
+ renderSpec[rtname] = createRenderTarget(rtw, rth);
+ };
+ rtfunc('mainRT', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT0', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT1', renderSpec.width, renderSpec.height);
+ rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight);
+ rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight);
+}
+
+function render() {
+ renderScene();
+}
+
+var animating = true;
+function toggleAnimation(elm) {
+ animating ^= true;
+ if(animating) animate();
+ if(elm) {
+ elm.innerHTML = animating? "Stop":"Start";
+ }
+}
+
+function stepAnimation() {
+ if(!animating) animate();
+}
+
+function animate() {
+ var curdate = new Date();
+ timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0;
+ timeInfo.delta = (curdate - timeInfo.prev) / 1000.0;
+ timeInfo.prev = curdate;
+
+ if(animating) requestAnimationFrame(animate);
+ render();
+}
+
+function makeCanvasFullScreen(canvas) {
+ var b = document.body;
+ var d = document.documentElement;
+ fullw = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth);
+ fullh = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight);
+ canvas.width = fullw;
+ canvas.height = fullh;
+}
+
+window.addEventListener('load', function(e) {
+ var canvas = document.getElementById("sakura");
+ try {
+ makeCanvasFullScreen(canvas);
+ gl = canvas.getContext('experimental-webgl');
+ } catch(e) {
+ alert("WebGL not supported." + e);
+ console.error(e);
+ return;
+ }
+
+ window.addEventListener('resize', onResize);
+
+ setViewports();
+ createScene();
+ initScene();
+
+ timeInfo.start = new Date();
+ timeInfo.prev = timeInfo.start;
+ animate();
+});
+
+//set window.requestAnimationFrame
+(function (w, r) {
+ w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
+})(window, 'equestAnimationFrame');
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-08/preview.jpg b/code-nav-home/covers/dynamic/cover-08/preview.jpg
new file mode 100644
index 0000000..633e423
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-08/preview.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/blur_h_bloom.dxs b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/blur_h_bloom.dxs
new file mode 100644
index 0000000..a033325
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/blur_h_bloom.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/combine.dxs b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/combine.dxs
new file mode 100644
index 0000000..446b6ef
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/combine.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_eighth_blur_v.dxs b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_eighth_blur_v.dxs
new file mode 100644
index 0000000..ccf12f9
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_eighth_blur_v.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_quarter.dxs b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_quarter.dxs
new file mode 100644
index 0000000..1d3c945
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_quarter.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/fade.dxs b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/fade.dxs
new file mode 100644
index 0000000..14203c3
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/fade.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-09/1.jpg b/code-nav-home/covers/dynamic/cover-09/1.jpg
new file mode 100644
index 0000000..0118b91
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-09/1.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-09/index.html b/code-nav-home/covers/dynamic/cover-09/index.html
new file mode 100644
index 0000000..ff88721
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-09/index.html
@@ -0,0 +1,359 @@
+
+
+
+
+
+
+ 编程导航 - 阴阳师神乐
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-09/js/index.js b/code-nav-home/covers/dynamic/cover-09/js/index.js
new file mode 100644
index 0000000..56f7df1
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-09/js/index.js
@@ -0,0 +1,802 @@
+// Utilities
+var Vector3 = {};
+var Matrix44 = {};
+Vector3.create = function(x, y, z) {
+ return {'x':x, 'y':y, 'z':z};
+};
+Vector3.dot = function (v0, v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
+};
+Vector3.cross = function (v, v0, v1) {
+ v.x = v0.y * v1.z - v0.z * v1.y;
+ v.y = v0.z * v1.x - v0.x * v1.z;
+ v.z = v0.x * v1.y - v0.y * v1.x;
+};
+Vector3.normalize = function (v) {
+ var l = v.x * v.x + v.y * v.y + v.z * v.z;
+ if(l > 0.00001) {
+ l = 1.0 / Math.sqrt(l);
+ v.x *= l;
+ v.y *= l;
+ v.z *= l;
+ }
+};
+Vector3.arrayForm = function(v) {
+ if(v.array) {
+ v.array[0] = v.x;
+ v.array[1] = v.y;
+ v.array[2] = v.z;
+ }
+ else {
+ v.array = new Float32Array([v.x, v.y, v.z]);
+ }
+ return v.array;
+};
+Matrix44.createIdentity = function () {
+ return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
+};
+Matrix44.loadProjection = function (m, aspect, vdeg, near, far) {
+ var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0;
+ var w = h * aspect;
+
+ m[0] = 2.0 * near / w;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+
+ m[4] = 0.0;
+ m[5] = 2.0 * near / h;
+ m[6] = 0.0;
+ m[7] = 0.0;
+
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = -(far + near) / (far - near);
+ m[11] = -1.0;
+
+ m[12] = 0.0;
+ m[13] = 0.0;
+ m[14] = -2.0 * far * near / (far - near);
+ m[15] = 0.0;
+};
+Matrix44.loadLookAt = function (m, vpos, vlook, vup) {
+ var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z);
+ Vector3.normalize(frontv);
+ var sidev = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(sidev, vup, frontv);
+ Vector3.normalize(sidev);
+ var topv = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(topv, frontv, sidev);
+ Vector3.normalize(topv);
+
+ m[0] = sidev.x;
+ m[1] = topv.x;
+ m[2] = frontv.x;
+ m[3] = 0.0;
+
+ m[4] = sidev.y;
+ m[5] = topv.y;
+ m[6] = frontv.y;
+ m[7] = 0.0;
+
+ m[8] = sidev.z;
+ m[9] = topv.z;
+ m[10] = frontv.z;
+ m[11] = 0.0;
+
+ m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]);
+ m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]);
+ m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]);
+ m[15] = 1.0;
+};
+
+//
+var timeInfo = {
+ 'start':0, 'prev':0, // Date
+ 'delta':0, 'elapsed':0 // Number(sec)
+};
+
+//
+var gl;
+var renderSpec = {
+ 'width':0,
+ 'height':0,
+ 'aspect':1,
+ 'array':new Float32Array(3),
+ 'halfWidth':0,
+ 'halfHeight':0,
+ 'halfArray':new Float32Array(3)
+ // and some render targets. see setViewport()
+};
+renderSpec.setSize = function(w, h) {
+ renderSpec.width = w;
+ renderSpec.height = h;
+ renderSpec.aspect = renderSpec.width / renderSpec.height;
+ renderSpec.array[0] = renderSpec.width;
+ renderSpec.array[1] = renderSpec.height;
+ renderSpec.array[2] = renderSpec.aspect;
+
+ renderSpec.halfWidth = Math.floor(w / 2);
+ renderSpec.halfHeight = Math.floor(h / 2);
+ renderSpec.halfArray[0] = renderSpec.halfWidth;
+ renderSpec.halfArray[1] = renderSpec.halfHeight;
+ renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight;
+};
+
+function deleteRenderTarget(rt) {
+ gl.deleteFramebuffer(rt.frameBuffer);
+ gl.deleteRenderbuffer(rt.renderBuffer);
+ gl.deleteTexture(rt.texture);
+}
+
+function createRenderTarget(w, h) {
+ var ret = {
+ 'width':w,
+ 'height':h,
+ 'sizeArray':new Float32Array([w, h, w / h]),
+ 'dtxArray':new Float32Array([1.0 / w, 1.0 / h])
+ };
+ ret.frameBuffer = gl.createFramebuffer();
+ ret.renderBuffer = gl.createRenderbuffer();
+ ret.texture = gl.createTexture();
+
+ gl.bindTexture(gl.TEXTURE_2D, ret.texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer);
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ return ret;
+}
+
+function compileShader(shtype, shsrc) {
+ var retsh = gl.createShader(shtype);
+
+ gl.shaderSource(retsh, shsrc);
+ gl.compileShader(retsh);
+
+ if(!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) {
+ var errlog = gl.getShaderInfoLog(retsh);
+ gl.deleteShader(retsh);
+ console.error(errlog);
+ return null;
+ }
+ return retsh;
+}
+
+function createShader(vtxsrc, frgsrc, uniformlist, attrlist) {
+ var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc);
+ var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc);
+
+ if(vsh == null || fsh == null) {
+ return null;
+ }
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vsh);
+ gl.attachShader(prog, fsh);
+
+ gl.deleteShader(vsh);
+ gl.deleteShader(fsh);
+
+ gl.linkProgram(prog);
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var errlog = gl.getProgramInfoLog(prog);
+ console.error(errlog);
+ return null;
+ }
+
+ if(uniformlist) {
+ prog.uniforms = {};
+ for(var i = 0; i < uniformlist.length; i++) {
+ prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]);
+ }
+ }
+
+ if(attrlist) {
+ prog.attributes = {};
+ for(var i = 0; i < attrlist.length; i++) {
+ var attr = attrlist[i];
+ prog.attributes[attr] = gl.getAttribLocation(prog, attr);
+ }
+ }
+
+ return prog;
+}
+
+function useShader(prog) {
+ gl.useProgram(prog);
+ for(var attr in prog.attributes) {
+ gl.enableVertexAttribArray(prog.attributes[attr]);;
+ }
+}
+
+function unuseShader(prog) {
+ for(var attr in prog.attributes) {
+ gl.disableVertexAttribArray(prog.attributes[attr]);;
+ }
+ gl.useProgram(null);
+}
+
+/////
+var projection = {
+ 'angle':60,
+ 'nearfar':new Float32Array([0.1, 100.0]),
+ 'matrix':Matrix44.createIdentity()
+};
+var camera = {
+ 'position':Vector3.create(0, 0, 100),
+ 'lookat':Vector3.create(0, 0, 0),
+ 'up':Vector3.create(0, 1, 0),
+ 'dof':Vector3.create(10.0, 4.0, 8.0),
+ 'matrix':Matrix44.createIdentity()
+};
+
+var pointFlower = {};
+var meshFlower = {};
+var sceneStandBy = false;
+
+var BlossomParticle = function () {
+ this.velocity = new Array(3);
+ this.rotation = new Array(3);
+ this.position = new Array(3);
+ this.euler = new Array(3);
+ this.size = 1.0;
+ this.alpha = 1.0;
+ this.zkey = 0.0;
+};
+
+BlossomParticle.prototype.setVelocity = function (vx, vy, vz) {
+ this.velocity[0] = vx;
+ this.velocity[1] = vy;
+ this.velocity[2] = vz;
+};
+
+BlossomParticle.prototype.setRotation = function (rx, ry, rz) {
+ this.rotation[0] = rx;
+ this.rotation[1] = ry;
+ this.rotation[2] = rz;
+};
+
+BlossomParticle.prototype.setPosition = function (nx, ny, nz) {
+ this.position[0] = nx;
+ this.position[1] = ny;
+ this.position[2] = nz;
+};
+
+BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) {
+ this.euler[0] = rx;
+ this.euler[1] = ry;
+ this.euler[2] = rz;
+};
+
+BlossomParticle.prototype.setSize = function (s) {
+ this.size = s;
+};
+
+BlossomParticle.prototype.update = function (dt, et) {
+ this.position[0] += this.velocity[0] * dt;
+ this.position[1] += this.velocity[1] * dt;
+ this.position[2] += this.velocity[2] * dt;
+
+ this.euler[0] += this.rotation[0] * dt;
+ this.euler[1] += this.rotation[1] * dt;
+ this.euler[2] += this.rotation[2] * dt;
+};
+
+function createPointFlowers() {
+ // get point sizes
+ var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
+ renderSpec.pointSize = {'min':prm[0], 'max':prm[1]};
+
+ var vtxsrc = document.getElementById("sakura_point_vsh").textContent;
+ var frgsrc = document.getElementById("sakura_point_fsh").textContent;
+
+ pointFlower.program = createShader(
+ vtxsrc, frgsrc,
+ ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'],
+ ['aPosition', 'aEuler', 'aMisc']
+ );
+
+ useShader(pointFlower.program);
+ pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]);
+ pointFlower.fader = Vector3.create(0.0, 10.0, 0.0);
+
+ // paramerters: velocity[3], rotate[3]
+ pointFlower.numFlowers = 300;
+ pointFlower.particles = new Array(pointFlower.numFlowers);
+ // vertex attributes {position[3], euler_xyz[3], size[1]}
+ pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2));
+ pointFlower.positionArrayOffset = 0;
+ pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3;
+ pointFlower.miscArrayOffset = pointFlower.numFlowers * 6;
+
+ pointFlower.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ unuseShader(pointFlower.program);
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ pointFlower.particles[i] = new BlossomParticle();
+ }
+}
+
+function initPointFlowers() {
+ //area
+ pointFlower.area = Vector3.create(20.0, 20.0, 20.0);
+ pointFlower.area.x = pointFlower.area.y * renderSpec.aspect;
+
+ pointFlower.fader.x = 10.0; //env fade start
+ pointFlower.fader.y = pointFlower.area.z; //env fade half
+ pointFlower.fader.z = 0.1; //near fade start
+
+ //particles
+ var PI2 = Math.PI * 2.0;
+ var tmpv3 = Vector3.create(0, 0, 0);
+ var tmpv = 0;
+ var symmetryrand = function() {return (Math.random() * 2.0 - 1.0);};
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var tmpprtcl = pointFlower.particles[i];
+
+ //velocity
+ tmpv3.x = symmetryrand() * 0.3 + 0.8;
+ tmpv3.y = symmetryrand() * 0.2 - 1.0;
+ tmpv3.z = symmetryrand() * 0.3 + 0.5;
+ Vector3.normalize(tmpv3);
+ tmpv = 2.0 + Math.random() * 1.0;
+ tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv);
+
+ //rotation
+ tmpprtcl.setRotation(
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5
+ );
+
+ //position
+ tmpprtcl.setPosition(
+ symmetryrand() * pointFlower.area.x,
+ symmetryrand() * pointFlower.area.y,
+ symmetryrand() * pointFlower.area.z
+ );
+
+ //euler
+ tmpprtcl.setEulerAngles(
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0
+ );
+
+ //size
+ tmpprtcl.setSize(0.9 + Math.random() * 0.1);
+ }
+}
+
+function renderPointFlowers() {
+ //update
+ var PI2 = Math.PI * 2.0;
+ var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z];
+ var repeatPos = function (prt, cmp, limit) {
+ if(Math.abs(prt.position[cmp]) - prt.size * 0.5 > limit) {
+ //out of area
+ if(prt.position[cmp] > 0) {
+ prt.position[cmp] -= limit * 2.0;
+ }
+ else {
+ prt.position[cmp] += limit * 2.0;
+ }
+ }
+ };
+ var repeatEuler = function (prt, cmp) {
+ prt.euler[cmp] = prt.euler[cmp] % PI2;
+ if(prt.euler[cmp] < 0.0) {
+ prt.euler[cmp] += PI2;
+ }
+ };
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ prtcl.update(timeInfo.delta, timeInfo.elapsed);
+ repeatPos(prtcl, 0, pointFlower.area.x);
+ repeatPos(prtcl, 1, pointFlower.area.y);
+ repeatPos(prtcl, 2, pointFlower.area.z);
+ repeatEuler(prtcl, 0);
+ repeatEuler(prtcl, 1);
+ repeatEuler(prtcl, 2);
+
+ prtcl.alpha = 1.0;//(pointFlower.area.z - prtcl.position[2]) * 0.5;
+
+ prtcl.zkey = (camera.matrix[2] * prtcl.position[0]
+ + camera.matrix[6] * prtcl.position[1]
+ + camera.matrix[10] * prtcl.position[2]
+ + camera.matrix[14]);
+ }
+
+ // sort
+ pointFlower.particles.sort(function(p0, p1){return p0.zkey - p1.zkey;});
+
+ // update data
+ var ipos = pointFlower.positionArrayOffset;
+ var ieuler = pointFlower.eulerArrayOffset;
+ var imisc = pointFlower.miscArrayOffset;
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ pointFlower.dataArray[ipos] = prtcl.position[0];
+ pointFlower.dataArray[ipos + 1] = prtcl.position[1];
+ pointFlower.dataArray[ipos + 2] = prtcl.position[2];
+ ipos += 3;
+ pointFlower.dataArray[ieuler] = prtcl.euler[0];
+ pointFlower.dataArray[ieuler + 1] = prtcl.euler[1];
+ pointFlower.dataArray[ieuler + 2] = prtcl.euler[2];
+ ieuler += 3;
+ pointFlower.dataArray[imisc] = prtcl.size;
+ pointFlower.dataArray[imisc + 1] = prtcl.alpha;
+ imisc += 2;
+ }
+
+ //draw
+ gl.enable(gl.BLEND);
+ //gl.disable(gl.DEPTH_TEST);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ var prog = pointFlower.program;
+ useShader(prog);
+
+ gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix);
+ gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+ gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof));
+ gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader));
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+
+ gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+
+ // doubler
+ for(var i = 1; i < 2; i++) {
+ var zpos = i * -2.0;
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+ }
+
+ //main
+ pointFlower.offset[0] = 0.0;
+ pointFlower.offset[1] = 0.0;
+ pointFlower.offset[2] = 0.0;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(prog);
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+}
+
+// effects
+//common util
+function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) {
+ var ret = {};
+ var unifs = ['uResolution', 'uSrc', 'uDelta'];
+ if(exunifs) {
+ unifs = unifs.concat(exunifs);
+ }
+ var attrs = ['aPosition'];
+ if(exattrs) {
+ attrs = attrs.concat(exattrs);
+ }
+
+ ret.program = createShader(vtxsrc, frgsrc, unifs, attrs);
+ useShader(ret.program);
+
+ ret.dataArray = new Float32Array([
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0
+ ]);
+ ret.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(ret.program);
+
+ return ret;
+}
+
+// basic usage
+// useEffect(prog, srctex({'texture':texid, 'dtxArray':(f32)[dtx, dty]})); //basic initialize
+// gl.uniform**(...); //additional uniforms
+// drawEffect()
+// unuseEffect(prog)
+// TEXTURE0 makes src
+function useEffect(fxobj, srctex) {
+ var prog = fxobj.program;
+ useShader(prog);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+
+ if(srctex != null) {
+ gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray);
+ gl.uniform1i(prog.uniforms.uSrc, 0);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, srctex.texture);
+ }
+}
+function drawEffect(fxobj) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer);
+ gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+}
+function unuseEffect(fxobj) {
+ unuseShader(fxobj.program);
+}
+
+var effectLib = {};
+function createEffectLib() {
+
+ var vtxsrc, frgsrc;
+ //common
+ var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent;
+
+ //background
+ frgsrc = document.getElementById("bg_fsh").textContent;
+ effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null);
+
+ // make brightpixels buffer
+ frgsrc = document.getElementById("fx_brightbuf_fsh").textContent;
+ effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null);
+
+ // direction blur
+ frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent;
+ effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null);
+
+ //final composite
+ vtxsrc = document.getElementById("pp_final_vsh").textContent;
+ frgsrc = document.getElementById("pp_final_fsh").textContent;
+ effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null);
+}
+
+// background
+function createBackground() {
+ //console.log("create background");
+}
+function initBackground() {
+ //console.log("init background");
+}
+function renderBackground() {
+ gl.disable(gl.DEPTH_TEST);
+
+ useEffect(effectLib.sceneBg, null);
+ gl.uniform2f(effectLib.sceneBg.program.uniforms.uTimes, timeInfo.elapsed, timeInfo.delta);
+ drawEffect(effectLib.sceneBg);
+ unuseEffect(effectLib.sceneBg);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+// post process
+var postProcess = {};
+function createPostProcess() {
+ //console.log("create post process");
+}
+function initPostProcess() {
+ //console.log("init post process");
+}
+
+function renderPostProcess() {
+ gl.enable(gl.TEXTURE_2D);
+ gl.disable(gl.DEPTH_TEST);
+ var bindRT = function (rt, isclear) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer);
+ gl.viewport(0, 0, rt.width, rt.height);
+ if(isclear) {
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+ };
+
+ //make bright buff
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.mkBrightBuf, renderSpec.mainRT);
+ drawEffect(effectLib.mkBrightBuf);
+ unuseEffect(effectLib.mkBrightBuf);
+
+ // make bloom
+ for(var i = 0; i < 2; i++) {
+ var p = 1.5 + 1 * i;
+ var s = 2.0 + 1 * i;
+ bindRT(renderSpec.wHalfRT1, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT0);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT1);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+ }
+
+ //display
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ useEffect(effectLib.finalComp, renderSpec.mainRT);
+ gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture);
+ drawEffect(effectLib.finalComp);
+ unuseEffect(effectLib.finalComp);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+/////
+var SceneEnv = {};
+function createScene() {
+ createEffectLib();
+ createBackground();
+ createPointFlowers();
+ createPostProcess();
+ sceneStandBy = true;
+}
+
+function initScene() {
+ initBackground();
+ initPointFlowers();
+ initPostProcess();
+
+ //camera.position.z = 17.320508;
+ camera.position.z = pointFlower.area.z + projection.nearfar[0];
+ projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0;
+ Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]);
+}
+
+function renderScene() {
+ //draw
+ Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ //gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer);
+ gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height);
+ gl.clearColor(0.005, 0, 0.05, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ renderBackground();
+ renderPointFlowers();
+ renderPostProcess();
+}
+
+/////
+function onResize(e) {
+ makeCanvasFullScreen(document.getElementById("sakura"));
+ setViewports();
+ if(sceneStandBy) {
+ initScene();
+ }
+}
+
+function setViewports() {
+ renderSpec.setSize(gl.canvas.width, gl.canvas.height);
+
+ gl.clearColor(0.2, 0.2, 0.5, 1.0);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+
+ var rtfunc = function (rtname, rtw, rth) {
+ var rt = renderSpec[rtname];
+ if(rt) deleteRenderTarget(rt);
+ renderSpec[rtname] = createRenderTarget(rtw, rth);
+ };
+ rtfunc('mainRT', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT0', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT1', renderSpec.width, renderSpec.height);
+ rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight);
+ rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight);
+}
+
+function render() {
+ renderScene();
+}
+
+var animating = true;
+function toggleAnimation(elm) {
+ animating ^= true;
+ if(animating) animate();
+ if(elm) {
+ elm.innerHTML = animating? "Stop":"Start";
+ }
+}
+
+function stepAnimation() {
+ if(!animating) animate();
+}
+
+function animate() {
+ var curdate = new Date();
+ timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0;
+ timeInfo.delta = (curdate - timeInfo.prev) / 1000.0;
+ timeInfo.prev = curdate;
+
+ if(animating) requestAnimationFrame(animate);
+ render();
+}
+
+function makeCanvasFullScreen(canvas) {
+ var b = document.body;
+ var d = document.documentElement;
+ fullw = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth);
+ fullh = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight);
+ canvas.width = fullw;
+ canvas.height = fullh;
+}
+
+window.addEventListener('load', function(e) {
+ var canvas = document.getElementById("sakura");
+ try {
+ makeCanvasFullScreen(canvas);
+ gl = canvas.getContext('experimental-webgl');
+ } catch(e) {
+ alert("WebGL not supported." + e);
+ console.error(e);
+ return;
+ }
+
+ window.addEventListener('resize', onResize);
+
+ setViewports();
+ createScene();
+ initScene();
+
+ timeInfo.start = new Date();
+ timeInfo.prev = timeInfo.start;
+ animate();
+});
+
+//set window.requestAnimationFrame
+(function (w, r) {
+ w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
+})(window, 'equestAnimationFrame');
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-09/preview.jpg b/code-nav-home/covers/dynamic/cover-09/preview.jpg
new file mode 100644
index 0000000..d562119
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-09/preview.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-10/images/1.png b/code-nav-home/covers/dynamic/cover-10/images/1.png
new file mode 100644
index 0000000..94cf96e
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-10/images/1.png differ
diff --git a/code-nav-home/covers/dynamic/cover-10/images/Mask.png b/code-nav-home/covers/dynamic/cover-10/images/Mask.png
new file mode 100644
index 0000000..6c3d5fb
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-10/images/Mask.png differ
diff --git a/code-nav-home/covers/dynamic/cover-10/index.html b/code-nav-home/covers/dynamic/cover-10/index.html
new file mode 100644
index 0000000..778c9ab
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-10/index.html
@@ -0,0 +1,398 @@
+
+
+
+
+
+ 编程导航 - Saber Lily
+
+
+ Test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-10/js/glUtils.js b/code-nav-home/covers/dynamic/cover-10/js/glUtils.js
new file mode 100644
index 0000000..ac3b802
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-10/js/glUtils.js
@@ -0,0 +1,193 @@
+// augment Sylvester some
+Matrix.Translation = function (v)
+{
+ if (v.elements.length == 2) {
+ var r = Matrix.I(3);
+ r.elements[2][0] = v.elements[0];
+ r.elements[2][1] = v.elements[1];
+ return r;
+ }
+
+ if (v.elements.length == 3) {
+ var r = Matrix.I(4);
+ r.elements[0][3] = v.elements[0];
+ r.elements[1][3] = v.elements[1];
+ r.elements[2][3] = v.elements[2];
+ return r;
+ }
+
+ throw "Invalid length for Translation";
+}
+
+Matrix.prototype.flatten = function ()
+{
+ var result = [];
+ if (this.elements.length == 0)
+ return [];
+
+
+ for (var j = 0; j < this.elements[0].length; j++)
+ for (var i = 0; i < this.elements.length; i++)
+ result.push(this.elements[i][j]);
+ return result;
+}
+
+Matrix.prototype.ensure4x4 = function()
+{
+ if (this.elements.length == 4 &&
+ this.elements[0].length == 4)
+ return this;
+
+ if (this.elements.length > 4 ||
+ this.elements[0].length > 4)
+ return null;
+
+ for (var i = 0; i < this.elements.length; i++) {
+ for (var j = this.elements[i].length; j < 4; j++) {
+ if (i == j)
+ this.elements[i].push(1);
+ else
+ this.elements[i].push(0);
+ }
+ }
+
+ for (var i = this.elements.length; i < 4; i++) {
+ if (i == 0)
+ this.elements.push([1, 0, 0, 0]);
+ else if (i == 1)
+ this.elements.push([0, 1, 0, 0]);
+ else if (i == 2)
+ this.elements.push([0, 0, 1, 0]);
+ else if (i == 3)
+ this.elements.push([0, 0, 0, 1]);
+ }
+
+ return this;
+};
+
+Matrix.prototype.make3x3 = function()
+{
+ if (this.elements.length != 4 ||
+ this.elements[0].length != 4)
+ return null;
+
+ return Matrix.create([[this.elements[0][0], this.elements[0][1], this.elements[0][2]],
+ [this.elements[1][0], this.elements[1][1], this.elements[1][2]],
+ [this.elements[2][0], this.elements[2][1], this.elements[2][2]]]);
+};
+
+Vector.prototype.flatten = function ()
+{
+ return this.elements;
+};
+
+function mht(m) {
+ var s = "";
+ if (m.length == 16) {
+ for (var i = 0; i < 4; i++) {
+ s += "[" + m[i*4+0].toFixed(4) + "," + m[i*4+1].toFixed(4) + "," + m[i*4+2].toFixed(4) + "," + m[i*4+3].toFixed(4) + "]
";
+ }
+ } else if (m.length == 9) {
+ for (var i = 0; i < 3; i++) {
+ s += "[" + m[i*3+0].toFixed(4) + "," + m[i*3+1].toFixed(4) + "," + m[i*3+2].toFixed(4) + "]
";
+ }
+ } else {
+ return m.toString();
+ }
+ return s;
+}
+
+//
+// gluLookAt
+//
+function makeLookAt(ex, ey, ez,
+ cx, cy, cz,
+ ux, uy, uz)
+{
+ var eye = $V([ex, ey, ez]);
+ var center = $V([cx, cy, cz]);
+ var up = $V([ux, uy, uz]);
+
+ var mag;
+
+ var z = eye.subtract(center).toUnitVector();
+ var x = up.cross(z).toUnitVector();
+ var y = z.cross(x).toUnitVector();
+
+ var m = $M([[x.e(1), x.e(2), x.e(3), 0],
+ [y.e(1), y.e(2), y.e(3), 0],
+ [z.e(1), z.e(2), z.e(3), 0],
+ [0, 0, 0, 1]]);
+
+ var t = $M([[1, 0, 0, -ex],
+ [0, 1, 0, -ey],
+ [0, 0, 1, -ez],
+ [0, 0, 0, 1]]);
+ return m.x(t);
+}
+
+//
+// glOrtho
+//
+function makeOrtho(left, right,
+ bottom, top,
+ znear, zfar)
+{
+ var tx = -(right+left)/(right-left);
+ var ty = -(top+bottom)/(top-bottom);
+ var tz = -(zfar+znear)/(zfar-znear);
+
+ return $M([[2/(right-left), 0, 0, tx],
+ [0, 2/(top-bottom), 0, ty],
+ [0, 0, -2/(zfar-znear), tz],
+ [0, 0, 0, 1]]);
+}
+
+//
+// gluPerspective
+//
+function makePerspective(fovy, aspect, znear, zfar)
+{
+ var ymax = znear * Math.tan(fovy * Math.PI / 360.0);
+ var ymin = -ymax;
+ var xmin = ymin * aspect;
+ var xmax = ymax * aspect;
+
+ return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar);
+}
+
+//
+// glFrustum
+//
+function makeFrustum(left, right,
+ bottom, top,
+ znear, zfar)
+{
+ var X = 2*znear/(right-left);
+ var Y = 2*znear/(top-bottom);
+ var A = (right+left)/(right-left);
+ var B = (top+bottom)/(top-bottom);
+ var C = -(zfar+znear)/(zfar-znear);
+ var D = -2*zfar*znear/(zfar-znear);
+
+ return $M([[X, 0, A, 0],
+ [0, Y, B, 0],
+ [0, 0, C, D],
+ [0, 0, -1, 0]]);
+}
+
+//
+// glOrtho
+//
+function makeOrtho(left, right, bottom, top, znear, zfar)
+{
+ var tx = - (right + left) / (right - left);
+ var ty = - (top + bottom) / (top - bottom);
+ var tz = - (zfar + znear) / (zfar - znear);
+
+ return $M([[2 / (right - left), 0, 0, tx],
+ [0, 2 / (top - bottom), 0, ty],
+ [0, 0, -2 / (zfar - znear), tz],
+ [0, 0, 0, 1]]);
+}
+
diff --git a/code-nav-home/covers/dynamic/cover-10/js/main.js b/code-nav-home/covers/dynamic/cover-10/js/main.js
new file mode 100644
index 0000000..5ed8ec4
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-10/js/main.js
@@ -0,0 +1,1069 @@
+/*
+Copyright (c) 2017 by Iluvatar@steam (https://steamcommunity.com/id/IIIuvatar/)
+
+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.
+*/
+
+var maskVerticesBuffer;
+var maskVerticesTextureCoordBuffer;
+var maskVerticesIndexBuffer;
+var maskRotation = 0.0;
+
+var maskImage;
+var maskTexture;
+
+var mvMatrix;
+var shaderProgram;
+var vertexPositionAttribute;
+var textureCoordAttribute;
+var perspectiveMatrix;
+
+var Vector3 = {};
+var Matrix44 = {};
+
+var flowerNumber = 2000;
+var currentMusic = "0";
+
+window.wallpaperPropertyListener = {
+ applyUserProperties: function (properties) {
+ if (properties.fNumber) {
+ flowerNumber=properties.fNumber.value;
+ createScene()
+ setViewports();
+ if(sceneStandBy) {
+ initScene();
+ }
+ }
+ if (properties.musicCombo) {
+ if (currentMusic == "0")
+ {
+ //do nothing
+ }
+ else
+ {
+ var Music=document.getElementById("music");
+ Music.pause();
+ }
+ if (properties.musicCombo.value == "0")
+ {
+ currentMusic="0";
+ }
+ else
+ {
+ currentMusic=properties.musicCombo.value;
+ var music=document.getElementById("music");
+ music.src="music/"+currentMusic+".wav";
+ music.play();
+ }
+
+ currentMusic = properties.musicCombo.value;
+ }
+ if (properties.volume) {
+ var music=document.getElementById("music");
+ music.volume=properties.volume.value/100.0;
+ }
+ }
+};
+
+
+
+
+Vector3.create = function(x, y, z) {
+ return {'x':x, 'y':y, 'z':z};
+};
+Vector3.dot = function (v0, v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
+};
+Vector3.cross = function (v, v0, v1) {
+ v.x = v0.y * v1.z - v0.z * v1.y;
+ v.y = v0.z * v1.x - v0.x * v1.z;
+ v.z = v0.x * v1.y - v0.y * v1.x;
+};
+Vector3.normalize = function (v) {
+ var l = v.x * v.x + v.y * v.y + v.z * v.z;
+ if(l > 0.00001) {
+ l = 1.0 / Math.sqrt(l);
+ v.x *= l;
+ v.y *= l;
+ v.z *= l;
+ }
+};
+Vector3.arrayForm = function(v) {
+ if(v.array) {
+ v.array[0] = v.x;
+ v.array[1] = v.y;
+ v.array[2] = v.z;
+ }
+ else {
+ v.array = new Float32Array([v.x, v.y, v.z]);
+ }
+ return v.array;
+};
+Matrix44.createIdentity = function () {
+ return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
+};
+Matrix44.loadProjection = function (m, aspect, vdeg, near, far) {
+ var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0;
+ var w = h * aspect;
+
+ m[0] = 2.0 * near / w;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+
+ m[4] = 0.0;
+ m[5] = 2.0 * near / h;
+ m[6] = 0.0;
+ m[7] = 0.0;
+
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = -(far + near) / (far - near);
+ m[11] = -1.0;
+
+ m[12] = 0.0;
+ m[13] = 0.0;
+ m[14] = -2.0 * far * near / (far - near);
+ m[15] = 0.0;
+};
+Matrix44.loadLookAt = function (m, vpos, vlook, vup) {
+ var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z);
+ Vector3.normalize(frontv);
+ var sidev = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(sidev, vup, frontv);
+ Vector3.normalize(sidev);
+ var topv = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(topv, frontv, sidev);
+ Vector3.normalize(topv);
+
+ m[0] = sidev.x;
+ m[1] = topv.x;
+ m[2] = frontv.x;
+ m[3] = 0.0;
+
+ m[4] = sidev.y;
+ m[5] = topv.y;
+ m[6] = frontv.y;
+ m[7] = 0.0;
+
+ m[8] = sidev.z;
+ m[9] = topv.z;
+ m[10] = frontv.z;
+ m[11] = 0.0;
+
+ m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]);
+ m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]);
+ m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]);
+ m[15] = 1.0;
+};
+
+//
+var timeInfo = {
+ 'start':0, 'prev':0, // Date
+ 'delta':0, 'elapsed':0 // Number(sec)
+};
+
+//
+var gl;
+var renderSpec = {
+ 'width':0,
+ 'height':0,
+ 'aspect':1,
+ 'array':new Float32Array(3),
+ 'halfWidth':0,
+ 'halfHeight':0,
+ 'halfArray':new Float32Array(3)
+ // and some render targets. see setViewport()
+};
+renderSpec.setSize = function(w, h) {
+ renderSpec.width = w;
+ renderSpec.height = h;
+ renderSpec.aspect = renderSpec.width / renderSpec.height;
+ renderSpec.array[0] = renderSpec.width;
+ renderSpec.array[1] = renderSpec.height;
+ renderSpec.array[2] = renderSpec.aspect;
+
+ renderSpec.halfWidth = Math.floor(w / 2);
+ renderSpec.halfHeight = Math.floor(h / 2);
+ renderSpec.halfArray[0] = renderSpec.halfWidth;
+ renderSpec.halfArray[1] = renderSpec.halfHeight;
+ renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight;
+};
+
+function deleteRenderTarget(rt) {
+ gl.deleteFramebuffer(rt.frameBuffer);
+ gl.deleteRenderbuffer(rt.renderBuffer);
+ gl.deleteTexture(rt.texture);
+}
+
+function createRenderTarget(w, h) {
+ var ret = {
+ 'width':w,
+ 'height':h,
+ 'sizeArray':new Float32Array([w, h, w / h]),
+ 'dtxArray':new Float32Array([1.0 / w, 1.0 / h])
+ };
+ ret.frameBuffer = gl.createFramebuffer();
+ ret.renderBuffer = gl.createRenderbuffer();
+ ret.texture = gl.createTexture();
+
+ gl.bindTexture(gl.TEXTURE_2D, ret.texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer);
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ return ret;
+}
+
+function compileShader(shtype, shsrc) {
+ var retsh = gl.createShader(shtype);
+
+ gl.shaderSource(retsh, shsrc);
+ gl.compileShader(retsh);
+
+ if(!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) {
+ var errlog = gl.getShaderInfoLog(retsh);
+ gl.deleteShader(retsh);
+ console.error(errlog);
+ return null;
+ }
+ return retsh;
+}
+
+function createShader(vtxsrc, frgsrc, uniformlist, attrlist) {
+ var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc);
+ var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc);
+
+ if(vsh == null || fsh == null) {
+ return null;
+ }
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vsh);
+ gl.attachShader(prog, fsh);
+
+ gl.deleteShader(vsh);
+ gl.deleteShader(fsh);
+
+ gl.linkProgram(prog);
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var errlog = gl.getProgramInfoLog(prog);
+ console.error(errlog);
+ return null;
+ }
+
+ if(uniformlist) {
+ prog.uniforms = {};
+ for(var i = 0; i < uniformlist.length; i++) {
+ prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]);
+ }
+ }
+
+ if(attrlist) {
+ prog.attributes = {};
+ for(var i = 0; i < attrlist.length; i++) {
+ var attr = attrlist[i];
+ prog.attributes[attr] = gl.getAttribLocation(prog, attr);
+ }
+ }
+
+ return prog;
+}
+
+function useShader(prog) {
+ gl.useProgram(prog);
+ for(var attr in prog.attributes) {
+ gl.enableVertexAttribArray(prog.attributes[attr]);
+ }
+}
+
+function unuseShader(prog) {
+ for(var attr in prog.attributes) {
+ gl.disableVertexAttribArray(prog.attributes[attr]);;
+ }
+ gl.useProgram(null);
+}
+
+/////
+var projection = {
+ 'angle':60,
+ 'nearfar':new Float32Array([0.1, 100.0]),
+ 'matrix':Matrix44.createIdentity()
+};
+var camera = {
+ 'position':Vector3.create(0, 0, 100),
+ 'lookat':Vector3.create(0, 0, -1),
+ 'up':Vector3.create(0, 1, 0),
+ 'dof':Vector3.create(10.0, 4.0, 8.0),
+ 'matrix':Matrix44.createIdentity()
+};
+
+var pointFlower = {};
+var meshFlower = {};
+var sceneStandBy = false;
+
+var BlossomParticle = function () {
+ this.velocity = new Array(3);
+ this.rotation = new Array(3);
+ this.position = new Array(3);
+ this.euler = new Array(3);
+ this.size = 1.0;
+ this.alpha = 1.0;
+ this.zkey = 0.0;
+};
+
+BlossomParticle.prototype.setVelocity = function (vx, vy, vz) {
+ this.velocity[0] = vx;
+ this.velocity[1] = vy;
+ this.velocity[2] = vz;
+};
+
+BlossomParticle.prototype.setRotation = function (rx, ry, rz) {
+ this.rotation[0] = rx;
+ this.rotation[1] = ry;
+ this.rotation[2] = rz;
+};
+
+BlossomParticle.prototype.setPosition = function (nx, ny, nz) {
+ this.position[0] = nx;
+ this.position[1] = ny;
+ this.position[2] = nz;
+};
+
+BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) {
+ this.euler[0] = rx;
+ this.euler[1] = ry;
+ this.euler[2] = rz;
+};
+
+BlossomParticle.prototype.setSize = function (s) {
+ this.size = s;
+};
+
+BlossomParticle.prototype.update = function (dt, et) {
+ this.position[0] += this.velocity[0] * dt;
+ this.position[1] += this.velocity[1] * dt;
+ this.position[2] += this.velocity[2] * dt;
+
+ this.euler[0] += this.rotation[0] * dt;
+ this.euler[1] += this.rotation[1] * dt;
+ this.euler[2] += this.rotation[2] * dt;
+};
+
+function pwidth(x)
+{
+ var w=Math.floor(x/160.0*192.0+96.0);
+ if (w>191)
+ {
+ return 191;
+ console.log(w);
+ }
+ else if (w<0) return 0;
+ else return w;
+}
+
+function pheight(y)
+{
+ var w=Math.floor(y/90.0*134.0+67.0);
+ if (w>133) return 133;
+ else if (w<0) return 0;
+ else return w;
+}
+
+
+function createPointFlowers() {
+ // get point sizes
+ pointFlower = {}
+ var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
+ renderSpec.pointSize = {'min':prm[0], 'max':prm[1]};
+
+ var vtxsrc = document.getElementById("sakura_point_vsh").textContent;
+ var frgsrc = document.getElementById("sakura_point_fsh").textContent;
+
+ pointFlower.program = createShader(
+ vtxsrc, frgsrc,
+ ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'],
+ ['aPosition', 'aEuler', 'aMisc']
+ );
+
+ useShader(pointFlower.program);
+ pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]);
+ pointFlower.fader = Vector3.create(0.0, 10.0, 0.0);
+
+ // paramerters: velocity[3], rotate[3]
+ pointFlower.numFlowers = flowerNumber;
+ pointFlower.particles = new Array(pointFlower.numFlowers);
+ // vertex attributes {position[3], euler_xyz[3], size[1]}
+ pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2));
+ pointFlower.positionArrayOffset = 0;
+ pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3;
+ pointFlower.miscArrayOffset = pointFlower.numFlowers * 6;
+
+ pointFlower.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ unuseShader(pointFlower.program);
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ pointFlower.particles[i] = new BlossomParticle();
+ }
+}
+
+function initPointFlowers() {
+ //area
+ pointFlower.area = Vector3.create(28.0, 28.0, 40.0);
+ pointFlower.area.x = pointFlower.area.y * renderSpec.aspect;
+
+ pointFlower.fader.x = 10.0; //env fade start
+ pointFlower.fader.y = pointFlower.area.z; //env fade half
+ pointFlower.fader.z = 0.1; //near fade start
+
+ //particles
+ var PI2 = Math.PI * 2.0;
+ var tmpv3 = Vector3.create(0, 0, 0);
+ var tmpv = 0;
+ var symmetryrand = function() {return (Math.random() * 2.0 - 1.0);};
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var tmpprtcl = pointFlower.particles[i];
+
+ //velocity
+ tmpv3.x = symmetryrand() * 0.3 + 0.8;
+ tmpv3.y = symmetryrand() * 0.2 - 1.0;
+ tmpv3.z = symmetryrand() * 0.3 + 0.5;
+ Vector3.normalize(tmpv3);
+ tmpv = 2.0 + Math.random() * 1.0;
+ tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv);
+
+ //rotation
+ tmpprtcl.setRotation(
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5
+ );
+
+ //position
+ tmpprtcl.setPosition(
+ symmetryrand() * pointFlower.area.x,
+ symmetryrand() * pointFlower.area.y,
+ symmetryrand() * pointFlower.area.z -30.0
+ );
+
+ //euler
+ tmpprtcl.setEulerAngles(
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0
+ );
+
+ //size
+ tmpprtcl.setSize(0.9 + Math.random() * 0.1);
+ }
+}
+
+function renderPointFlowers() {
+ //update
+ var PI2 = Math.PI * 2.0;
+ //var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z];
+ var repeatPos = function (prt, cmp, limit1, limit2) {
+ if(prt.position[cmp] + prt.size*0.5 limit2) {
+ //out of area
+ if(prt.position[cmp] - prt.size*0.5 > limit1) {
+ prt.position[cmp] -= (limit2-limit1);
+ }
+ else {
+ prt.position[cmp] += (limit2-limit1);
+ }
+ }
+ };
+ var repeatEuler = function (prt, cmp) {
+ prt.euler[cmp] = prt.euler[cmp] % PI2;
+ if(prt.euler[cmp] < 0.0) {
+ prt.euler[cmp] += PI2;
+ }
+ };
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ prtcl.update(-timeInfo.delta, timeInfo.elapsed);
+ repeatPos(prtcl, 0, -pointFlower.area.x, pointFlower.area.x);
+ repeatPos(prtcl, 1, -pointFlower.area.y, pointFlower.area.y);
+ repeatPos(prtcl, 2, -2*pointFlower.area.z+10.0, 10.0);
+ repeatEuler(prtcl, 0);
+ repeatEuler(prtcl, 1);
+ repeatEuler(prtcl, 2);
+
+ prtcl.alpha = (pointFlower.area.z - prtcl.position[2]) * 0.5;
+
+ prtcl.zkey = (camera.matrix[2] * prtcl.position[0]
+ + camera.matrix[6] * prtcl.position[1]
+ + camera.matrix[10] * prtcl.position[2]
+ + camera.matrix[14]);
+ }
+
+ // sort
+ pointFlower.particles.sort(function(p0, p1){return p0.zkey - p1.zkey;});
+
+ // update data
+ var ipos = pointFlower.positionArrayOffset;
+ var ieuler = pointFlower.eulerArrayOffset;
+ var imisc = pointFlower.miscArrayOffset;
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ pointFlower.dataArray[ipos] = prtcl.position[0];
+ pointFlower.dataArray[ipos + 1] = prtcl.position[1];
+ pointFlower.dataArray[ipos + 2] = prtcl.position[2];
+ ipos += 3;
+ pointFlower.dataArray[ieuler] = prtcl.euler[0];
+ pointFlower.dataArray[ieuler + 1] = prtcl.euler[1];
+ pointFlower.dataArray[ieuler + 2] = prtcl.euler[2];
+ ieuler += 3;
+ pointFlower.dataArray[imisc] = prtcl.size;
+ pointFlower.dataArray[imisc + 1] = prtcl.alpha;
+ imisc += 2;
+ }
+
+ //draw
+ gl.enable(gl.BLEND);
+ //gl.disable(gl.DEPTH_TEST);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ var prog = pointFlower.program;
+ useShader(prog);
+
+ gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix);
+ gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+ gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof));
+ gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader));
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+
+ gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+
+ //main
+ pointFlower.offset[0] = 0.0;
+ pointFlower.offset[1] = 0.0;
+ pointFlower.offset[2] = 0.0;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(prog);
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+}
+
+// effects
+//common util
+function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) {
+ var ret = {};
+ var unifs = ['uResolution', 'uSrc', 'uDelta'];
+ if(exunifs) {
+ unifs = unifs.concat(exunifs);
+ }
+ var attrs = ['aPosition'];
+ if(exattrs) {
+ attrs = attrs.concat(exattrs);
+ }
+
+ ret.program = createShader(vtxsrc, frgsrc, unifs, attrs);
+ useShader(ret.program);
+
+ ret.dataArray = new Float32Array([
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0
+ ]);
+ ret.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(ret.program);
+
+ return ret;
+}
+
+// basic usage
+// useEffect(prog, srctex({'texture':texid, 'dtxArray':(f32)[dtx, dty]})); //basic initialize
+// gl.uniform**(...); //additional uniforms
+// drawEffect()
+// unuseEffect(prog)
+// TEXTURE0 makes src
+function useEffect(fxobj, srctex) {
+ var prog = fxobj.program;
+ useShader(prog);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+
+ if(srctex != null) {
+ gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray);
+ gl.uniform1i(prog.uniforms.uSrc, 0);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, srctex.texture);
+ }
+}
+function drawEffect(fxobj) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer);
+ gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+}
+function unuseEffect(fxobj) {
+ unuseShader(fxobj.program);
+}
+
+var effectLib = {};
+function createEffectLib() {
+
+ var vtxsrc, frgsrc;
+ //common
+ var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent;
+
+ //background
+ frgsrc = document.getElementById("bg_fsh").textContent;
+ effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null);
+
+ // make brightpixels buffer
+ frgsrc = document.getElementById("fx_brightbuf_fsh").textContent;
+ effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null);
+
+ // direction blur
+ frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent;
+ effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null);
+
+ //final composite
+ vtxsrc = document.getElementById("pp_final_vsh").textContent;
+ frgsrc = document.getElementById("pp_final_fsh").textContent;
+ effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null);
+}
+
+// background
+
+function createBackground() {
+
+}
+function initBackground() {
+
+}
+function renderBackground() {
+
+}
+
+// post process
+var postProcess = {};
+function createPostProcess() {
+ //console.log("create post process");
+}
+function initPostProcess() {
+ //console.log("init post process");
+}
+
+function renderPostProcess() {
+ //gl.enable(gl.TEXTURE_2D);
+
+ gl.disable(gl.DEPTH_TEST);
+ var bindRT = function (rt, isclear) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer);
+ gl.viewport(0, 0, rt.width, rt.height);
+ if(isclear) {
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+ };
+
+ //make bright buff
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.mkBrightBuf, renderSpec.mainRT);
+ drawEffect(effectLib.mkBrightBuf);
+ unuseEffect(effectLib.mkBrightBuf);
+
+ // make bloom
+ for(var i = 0; i < 2; i++) {
+ var p = 1.5 + 1 * i;
+ var s = 2.0 + 1 * i;
+ bindRT(renderSpec.wHalfRT1, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT0);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT1);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+ }
+
+ //display
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ useEffect(effectLib.finalComp, renderSpec.mainRT);
+ gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture);
+ drawEffect(effectLib.finalComp);
+ unuseEffect(effectLib.finalComp);
+
+
+ gl.enable(gl.DEPTH_TEST);
+
+
+}
+
+/////
+var SceneEnv = {};
+function createScene() {
+ createEffectLib();
+ createBackground();
+ createPointFlowers();
+ createPostProcess();
+ sceneStandBy = true;
+
+ var vtxsrc = document.getElementById("shader-vs").textContent;
+ var frgsrc = document.getElementById("shader-fs").textContent;
+
+ shaderProgram = createShader(
+ vtxsrc, frgsrc,
+ ['uMVMatrix', 'uPMatrix'],
+ ['aVertexPosition', 'aTextureCoord']
+ );
+}
+
+function initScene() {
+ initBackground();
+ initPointFlowers();
+ initPostProcess();
+ initTextures();
+ initBuffers();
+ camera.position.z = 10.0;//17.320508;
+ //camera.position.z = pointFlower.area.z + projection.nearfar[0];
+ projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0;
+ Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]);
+
+
+
+}
+
+function renderScene() {
+ //draw
+ Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ //gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer);
+ gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height);
+ gl.clearColor(0,0,0,0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ renderBackground();
+ renderPointFlowers();
+ renderMask();
+ renderPostProcess();
+
+
+}
+
+/////
+function onResize(e) {
+ makeCanvasFullScreen(document.getElementById("sakura"));
+ setViewports();
+ if(sceneStandBy) {
+ initScene();
+ }
+}
+
+function setViewports() {
+ renderSpec.setSize(gl.canvas.width, gl.canvas.height);
+
+ gl.clearColor(0,0,0,0);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+
+ var rtfunc = function (rtname, rtw, rth) {
+ var rt = renderSpec[rtname];
+ if(rt) deleteRenderTarget(rt);
+ renderSpec[rtname] = createRenderTarget(rtw, rth);
+ };
+ rtfunc('mainRT', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT0', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT1', renderSpec.width, renderSpec.height);
+ rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight);
+ rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight);
+}
+
+function renderMask(){
+ gl.enable(gl.DEPTH_TEST); // Enable depth testing
+
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); //Enable Alpha Channel
+ gl.enable(gl.BLEND);
+ var prog=shaderProgram;
+ useShader(prog);
+
+ var m=Matrix44.createIdentity();
+
+ perspectiveMatrix = makePerspective(45, 1.0/1.0, 0.1, 100.0);
+
+ //console.log(perspectiveMatrix);
+
+ loadIdentity();
+
+ mvTranslate([-0.0, 0.0, -6.0]);
+
+ mvPushMatrix();
+ mvRotate(maskRotation, [1, 0, 1]);
+ gl.bindBuffer(gl.ARRAY_BUFFER, maskVerticesBuffer);
+ gl.vertexAttribPointer(prog.attributes.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
+
+ // Set the texture coordinates attribute for the vertices.
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, maskVerticesTextureCoordBuffer);
+ gl.vertexAttribPointer(prog.attributes.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
+
+ // Specify the texture to map onto the faces.
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, maskTexture);
+ gl.uniform1i(gl.getUniformLocation(shaderProgram, "uSampler"), 0);
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, maskVerticesIndexBuffer);
+
+ setMatrixUniforms();
+ gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
+
+ mvPopMatrix();
+
+ unuseShader(prog);
+ gl.disable(gl.BLEND);
+
+}
+
+
+function render() {
+ renderScene();
+
+
+}
+
+
+var animating = true;
+function toggleAnimation(elm) {
+ animating ^= true;
+ if(animating) animate();
+ if(elm) {
+ elm.innerHTML = animating? "Stop":"Start";
+ }
+}
+
+function stepAnimation() {
+ if(!animating) animate();
+}
+
+function animate() {
+ var curdate = new Date();
+ timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0;
+ timeInfo.delta = (curdate - timeInfo.prev) / 1000.0;
+ timeInfo.prev = curdate;
+
+ if(animating) requestAnimationFrame(animate);
+ render();
+}
+
+function makeCanvasFullScreen(canvas) {
+ var b = document.body;
+ var d = document.documentElement;
+ fullw = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth);
+ fullh = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight);
+ canvas.width = fullw;
+ canvas.height = fullh;
+}
+
+window.addEventListener('load', function(e) {
+ var canvas = document.getElementById("sakura");
+ try {
+ makeCanvasFullScreen(canvas);
+ gl = canvas.getContext('experimental-webgl');
+ } catch(e) {
+ alert("WebGL not supported." + e);
+ console.error(e);
+ return;
+ }
+
+ window.addEventListener('resize', onResize);
+
+ setViewports();
+ createScene();
+ initScene();
+
+
+
+ timeInfo.start = new Date();
+ timeInfo.prev = timeInfo.start;
+ animate();
+});
+
+//set window.requestAnimationFrame
+(function (w, r) {
+ w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
+})(window, 'equestAnimationFrame');
+
+
+function initTextures() {
+ maskTexture = gl.createTexture();
+ maskImage = new Image();
+ maskImage.onload = function() { handleTextureLoaded(maskImage, maskTexture); }
+ maskImage.src = "images/mask.png";
+}
+
+function handleTextureLoaded(image, texture) {
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,
+ gl.UNSIGNED_BYTE, image);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+}
+
+function initBuffers() {
+ maskVerticesBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, maskVerticesBuffer);
+
+ // Now create an array of vertices for the mask.
+ var canvas = document.getElementById("sakura");
+ var t = canvas.width/canvas.height;
+ var maxD = 10.77;
+ var wz = -20.0;
+ var wwidth = maxD;
+ var wheight = maxD;
+ if( canvas.width/canvas.height > 1.4339059)//1920/1339
+ {//width=1920
+ wwidth = maxD;
+ wheight = maxD / 1.4339059 * t;
+ }
+ else
+ {//height=1339
+ wheight = maxD;
+ wwidth = maxD / t * 1.4339059;
+ }
+
+ var vertices = [
+ // Front face
+ -wwidth, -wheight, wz ,
+ wwidth, -wheight, wz ,
+ wwidth, wheight, wz ,
+ -wwidth, wheight, wz ,
+ ];
+
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
+
+ // Map the texture onto the mask's faces.
+
+ maskVerticesTextureCoordBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, maskVerticesTextureCoordBuffer);
+
+ var textureCoordinates = [
+ // Front
+ 0.0, 0.0,
+ 1.0, 0.0,
+ 1.0, 1.0,
+ 0.0, 1.0,
+ ];
+
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates),
+ gl.STATIC_DRAW);
+ maskVerticesIndexBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, maskVerticesIndexBuffer);
+ var maskVertexIndices = [
+ 0, 1, 2, 0, 2, 3
+ ]
+
+ // Now send the element array to GL
+
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
+ new Uint16Array(maskVertexIndices), gl.STATIC_DRAW);
+}
+
+function loadIdentity() {
+ mvMatrix = Matrix.I(4);
+}
+
+function multMatrix(m) {
+ mvMatrix = mvMatrix.x(m);
+}
+
+function mvTranslate(v) {
+ multMatrix(Matrix.Translation($V([v[0], v[1], v[2]])).ensure4x4());
+}
+
+function setMatrixUniforms() {
+ var pUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
+ gl.uniformMatrix4fv(pUniform, false, new Float32Array(perspectiveMatrix.flatten()));
+
+ var mvUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
+ gl.uniformMatrix4fv(mvUniform, false, new Float32Array(mvMatrix.flatten()));
+}
+
+var mvMatrixStack = [];
+
+function mvPushMatrix(m) {
+ if (m) {
+ mvMatrixStack.push(m.dup());
+ mvMatrix = m.dup();
+ }
+ else {
+ mvMatrixStack.push(mvMatrix.dup());
+ }
+}
+
+function mvPopMatrix() {
+ if (!mvMatrixStack.length) {
+ throw("Can't pop from an empty matrix stack.");
+ }
+
+ mvMatrix = mvMatrixStack.pop();
+ return mvMatrix;
+}
+
+function mvRotate(angle, v) {
+ var inRadians = angle * Math.PI / 180.0;
+ var m = Matrix.Rotation(inRadians, $V([v[0], v[1], v[2]])).ensure4x4();
+ multMatrix(m);
+}
diff --git a/code-nav-home/covers/dynamic/cover-10/js/sylvester.js b/code-nav-home/covers/dynamic/cover-10/js/sylvester.js
new file mode 100644
index 0000000..3e83bee
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-10/js/sylvester.js
@@ -0,0 +1 @@
+eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('9 17={3i:\'0.1.3\',16:1e-6};l v(){}v.23={e:l(i){8(i<1||i>7.4.q)?w:7.4[i-1]},2R:l(){8 7.4.q},1u:l(){8 F.1x(7.2u(7))},24:l(a){9 n=7.4.q;9 V=a.4||a;o(n!=V.q){8 1L}J{o(F.13(7.4[n-1]-V[n-1])>17.16){8 1L}}H(--n);8 2x},1q:l(){8 v.u(7.4)},1b:l(a){9 b=[];7.28(l(x,i){b.19(a(x,i))});8 v.u(b)},28:l(a){9 n=7.4.q,k=n,i;J{i=k-n;a(7.4[i],i+1)}H(--n)},2q:l(){9 r=7.1u();o(r===0){8 7.1q()}8 7.1b(l(x){8 x/r})},1C:l(a){9 V=a.4||a;9 n=7.4.q,k=n,i;o(n!=V.q){8 w}9 b=0,1D=0,1F=0;7.28(l(x,i){b+=x*V[i-1];1D+=x*x;1F+=V[i-1]*V[i-1]});1D=F.1x(1D);1F=F.1x(1F);o(1D*1F===0){8 w}9 c=b/(1D*1F);o(c<-1){c=-1}o(c>1){c=1}8 F.37(c)},1m:l(a){9 b=7.1C(a);8(b===w)?w:(b<=17.16)},34:l(a){9 b=7.1C(a);8(b===w)?w:(F.13(b-F.1A)<=17.16)},2k:l(a){9 b=7.2u(a);8(b===w)?w:(F.13(b)<=17.16)},2j:l(a){9 V=a.4||a;o(7.4.q!=V.q){8 w}8 7.1b(l(x,i){8 x+V[i-1]})},2C:l(a){9 V=a.4||a;o(7.4.q!=V.q){8 w}8 7.1b(l(x,i){8 x-V[i-1]})},22:l(k){8 7.1b(l(x){8 x*k})},x:l(k){8 7.22(k)},2u:l(a){9 V=a.4||a;9 i,2g=0,n=7.4.q;o(n!=V.q){8 w}J{2g+=7.4[n-1]*V[n-1]}H(--n);8 2g},2f:l(a){9 B=a.4||a;o(7.4.q!=3||B.q!=3){8 w}9 A=7.4;8 v.u([(A[1]*B[2])-(A[2]*B[1]),(A[2]*B[0])-(A[0]*B[2]),(A[0]*B[1])-(A[1]*B[0])])},2A:l(){9 m=0,n=7.4.q,k=n,i;J{i=k-n;o(F.13(7.4[i])>F.13(m)){m=7.4[i]}}H(--n);8 m},2Z:l(x){9 a=w,n=7.4.q,k=n,i;J{i=k-n;o(a===w&&7.4[i]==x){a=i+1}}H(--n);8 a},3g:l(){8 S.2X(7.4)},2d:l(){8 7.1b(l(x){8 F.2d(x)})},2V:l(x){8 7.1b(l(y){8(F.13(y-x)<=17.16)?x:y})},1o:l(a){o(a.K){8 a.1o(7)}9 V=a.4||a;o(V.q!=7.4.q){8 w}9 b=0,2b;7.28(l(x,i){2b=x-V[i-1];b+=2b*2b});8 F.1x(b)},3a:l(a){8 a.1h(7)},2T:l(a){8 a.1h(7)},1V:l(t,a){9 V,R,x,y,z;2S(7.4.q){27 2:V=a.4||a;o(V.q!=2){8 w}R=S.1R(t).4;x=7.4[0]-V[0];y=7.4[1]-V[1];8 v.u([V[0]+R[0][0]*x+R[0][1]*y,V[1]+R[1][0]*x+R[1][1]*y]);1I;27 3:o(!a.U){8 w}9 C=a.1r(7).4;R=S.1R(t,a.U).4;x=7.4[0]-C[0];y=7.4[1]-C[1];z=7.4[2]-C[2];8 v.u([C[0]+R[0][0]*x+R[0][1]*y+R[0][2]*z,C[1]+R[1][0]*x+R[1][1]*y+R[1][2]*z,C[2]+R[2][0]*x+R[2][1]*y+R[2][2]*z]);1I;2P:8 w}},1t:l(a){o(a.K){9 P=7.4.2O();9 C=a.1r(P).4;8 v.u([C[0]+(C[0]-P[0]),C[1]+(C[1]-P[1]),C[2]+(C[2]-(P[2]||0))])}1d{9 Q=a.4||a;o(7.4.q!=Q.q){8 w}8 7.1b(l(x,i){8 Q[i-1]+(Q[i-1]-x)})}},1N:l(){9 V=7.1q();2S(V.4.q){27 3:1I;27 2:V.4.19(0);1I;2P:8 w}8 V},2n:l(){8\'[\'+7.4.2K(\', \')+\']\'},26:l(a){7.4=(a.4||a).2O();8 7}};v.u=l(a){9 V=25 v();8 V.26(a)};v.i=v.u([1,0,0]);v.j=v.u([0,1,0]);v.k=v.u([0,0,1]);v.2J=l(n){9 a=[];J{a.19(F.2F())}H(--n);8 v.u(a)};v.1j=l(n){9 a=[];J{a.19(0)}H(--n);8 v.u(a)};l S(){}S.23={e:l(i,j){o(i<1||i>7.4.q||j<1||j>7.4[0].q){8 w}8 7.4[i-1][j-1]},33:l(i){o(i>7.4.q){8 w}8 v.u(7.4[i-1])},2E:l(j){o(j>7.4[0].q){8 w}9 a=[],n=7.4.q,k=n,i;J{i=k-n;a.19(7.4[i][j-1])}H(--n);8 v.u(a)},2R:l(){8{2D:7.4.q,1p:7.4[0].q}},2D:l(){8 7.4.q},1p:l(){8 7.4[0].q},24:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(7.4.q!=M.q||7.4[0].q!=M[0].q){8 1L}9 b=7.4.q,15=b,i,G,10=7.4[0].q,j;J{i=15-b;G=10;J{j=10-G;o(F.13(7.4[i][j]-M[i][j])>17.16){8 1L}}H(--G)}H(--b);8 2x},1q:l(){8 S.u(7.4)},1b:l(a){9 b=[],12=7.4.q,15=12,i,G,10=7.4[0].q,j;J{i=15-12;G=10;b[i]=[];J{j=10-G;b[i][j]=a(7.4[i][j],i+1,j+1)}H(--G)}H(--12);8 S.u(b)},2i:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}8(7.4.q==M.q&&7.4[0].q==M[0].q)},2j:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(!7.2i(M)){8 w}8 7.1b(l(x,i,j){8 x+M[i-1][j-1]})},2C:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(!7.2i(M)){8 w}8 7.1b(l(x,i,j){8 x-M[i-1][j-1]})},2B:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}8(7.4[0].q==M.q)},22:l(a){o(!a.4){8 7.1b(l(x){8 x*a})}9 b=a.1u?2x:1L;9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(!7.2B(M)){8 w}9 d=7.4.q,15=d,i,G,10=M[0].q,j;9 e=7.4[0].q,4=[],21,20,c;J{i=15-d;4[i]=[];G=10;J{j=10-G;21=0;20=e;J{c=e-20;21+=7.4[i][c]*M[c][j]}H(--20);4[i][j]=21}H(--G)}H(--d);9 M=S.u(4);8 b?M.2E(1):M},x:l(a){8 7.22(a)},32:l(a,b,c,d){9 e=[],12=c,i,G,j;9 f=7.4.q,1p=7.4[0].q;J{i=c-12;e[i]=[];G=d;J{j=d-G;e[i][j]=7.4[(a+i-1)%f][(b+j-1)%1p]}H(--G)}H(--12);8 S.u(e)},31:l(){9 a=7.4.q,1p=7.4[0].q;9 b=[],12=1p,i,G,j;J{i=1p-12;b[i]=[];G=a;J{j=a-G;b[i][j]=7.4[j][i]}H(--G)}H(--12);8 S.u(b)},1y:l(){8(7.4.q==7.4[0].q)},2A:l(){9 m=0,12=7.4.q,15=12,i,G,10=7.4[0].q,j;J{i=15-12;G=10;J{j=10-G;o(F.13(7.4[i][j])>F.13(m)){m=7.4[i][j]}}H(--G)}H(--12);8 m},2Z:l(x){9 a=w,12=7.4.q,15=12,i,G,10=7.4[0].q,j;J{i=15-12;G=10;J{j=10-G;o(7.4[i][j]==x){8{i:i+1,j:j+1}}}H(--G)}H(--12);8 w},30:l(){o(!7.1y){8 w}9 a=[],n=7.4.q,k=n,i;J{i=k-n;a.19(7.4[i][i])}H(--n);8 v.u(a)},1K:l(){9 M=7.1q(),1c;9 n=7.4.q,k=n,i,1s,1n=7.4[0].q,p;J{i=k-n;o(M.4[i][i]==0){2e(j=i+1;j17.16){1Y++;1I}}H(--G)}H(--a);8 1Y},3d:l(){8 7.1Y()},2W:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}9 T=7.1q(),1p=T.4[0].q;9 b=T.4.q,15=b,i,G,10=M[0].q,j;o(b!=M.q){8 w}J{i=15-b;G=10;J{j=10-G;T.4[i][1p+j]=M[i][j]}H(--G)}H(--b);8 T},2w:l(){o(!7.1y()||7.2y()){8 w}9 a=7.4.q,15=a,i,j;9 M=7.2W(S.I(a)).1K();9 b,1n=M.4[0].q,p,1c,2v;9 c=[],2c;J{i=a-1;1c=[];b=1n;c[i]=[];2v=M.4[i][i];J{p=1n-b;2c=M.4[i][p]/2v;1c.19(2c);o(p>=15){c[i].19(2c)}}H(--b);M.4[i]=1c;2e(j=0;j3||b.4.q>3){8 w}9 c=b.1u();o(c===0){8 w}7.K=a;7.U=v.u([b.4[0]/c,b.4[1]/c,b.4[2]/c]);8 7}};14.u=l(a,b){9 L=25 14();8 L.1Z(a,b)};14.X=14.u(v.1j(3),v.i);14.Y=14.u(v.1j(3),v.j);14.Z=14.u(v.1j(3),v.k);l 11(){}11.23={24:l(a){8(7.1h(a.K)&&7.1m(a))},1q:l(){8 11.u(7.K,7.W)},2U:l(a){9 V=a.4||a;8 11.u([7.K.4[0]+V[0],7.K.4[1]+V[1],7.K.4[2]+(V[2]||0)],7.W)},1m:l(a){9 b;o(a.W){b=7.W.1C(a.W);8(F.13(b)<=17.16||F.13(F.1A-b)<=17.16)}1d o(a.U){8 7.W.2k(a.U)}8 w},2k:l(a){9 b=7.W.1C(a.W);8(F.13(F.1A/2-b)<=17.16)},1o:l(a){o(7.1v(a)||7.1h(a)){8 0}o(a.K){9 A=7.K.4,B=a.K.4,N=7.W.4;8 F.13((A[0]-B[0])*N[0]+(A[1]-B[1])*N[1]+(A[2]-B[2])*N[2])}1d{9 P=a.4||a;9 A=7.K.4,N=7.W.4;8 F.13((A[0]-P[0])*N[0]+(A[1]-P[1])*N[1]+(A[2]-(P[2]||0))*N[2])}},1h:l(a){o(a.W){8 w}o(a.U){8(7.1h(a.K)&&7.1h(a.K.2j(a.U)))}1d{9 P=a.4||a;9 A=7.K.4,N=7.W.4;9 b=F.13(N[0]*(A[0]-P[0])+N[1]*(A[1]-P[1])+N[2]*(A[2]-(P[2]||0)));8(b<=17.16)}},1v:l(a){o(1g(a.U)==\'1f\'&&1g(a.W)==\'1f\'){8 w}8!7.1m(a)},1U:l(a){o(!7.1v(a)){8 w}o(a.U){9 A=a.K.4,D=a.U.4,P=7.K.4,N=7.W.4;9 b=(N[0]*(P[0]-A[0])+N[1]*(P[1]-A[1])+N[2]*(P[2]-A[2]))/(N[0]*D[0]+N[1]*D[1]+N[2]*D[2]);8 v.u([A[0]+D[0]*b,A[1]+D[1]*b,A[2]+D[2]*b])}1d o(a.W){9 c=7.W.2f(a.W).2q();9 N=7.W.4,A=7.K.4,O=a.W.4,B=a.K.4;9 d=S.1j(2,2),i=0;H(d.2y()){i++;d=S.u([[N[i%3],N[(i+1)%3]],[O[i%3],O[(i+1)%3]]])}9 e=d.2w().4;9 x=N[0]*A[0]+N[1]*A[1]+N[2]*A[2];9 y=O[0]*B[0]+O[1]*B[1]+O[2]*B[2];9 f=[e[0][0]*x+e[0][1]*y,e[1][0]*x+e[1][1]*y];9 g=[];2e(9 j=1;j<=3;j++){g.19((i==j)?0:f[(j+(5-i)%3)%3])}8 14.u(g,c)}},1r:l(a){9 P=a.4||a;9 A=7.K.4,N=7.W.4;9 b=(A[0]-P[0])*N[0]+(A[1]-P[1])*N[1]+(A[2]-(P[2]||0))*N[2];8 v.u([P[0]+N[0]*b,P[1]+N[1]*b,(P[2]||0)+N[2]*b])},1V:l(t,a){9 R=S.1R(t,a.U).4;9 C=a.1r(7.K).4;9 A=7.K.4,N=7.W.4;9 b=C[0],1E=C[1],1J=C[2],1w=A[0],18=A[1],1a=A[2];9 x=1w-b,y=18-1E,z=1a-1J;8 11.u([b+R[0][0]*x+R[0][1]*y+R[0][2]*z,1E+R[1][0]*x+R[1][1]*y+R[1][2]*z,1J+R[2][0]*x+R[2][1]*y+R[2][2]*z],[R[0][0]*N[0]+R[0][1]*N[1]+R[0][2]*N[2],R[1][0]*N[0]+R[1][1]*N[1]+R[1][2]*N[2],R[2][0]*N[0]+R[2][1]*N[1]+R[2][2]*N[2]])},1t:l(a){o(a.W){9 A=7.K.4,N=7.W.4;9 b=A[0],18=A[1],1a=A[2],2M=N[0],2L=N[1],2Q=N[2];9 c=7.K.1t(a).4;9 d=b+2M,2p=18+2L,2m=1a+2Q;9 Q=a.1r([d,2p,2m]).4;9 e=[Q[0]+(Q[0]-d)-c[0],Q[1]+(Q[1]-2p)-c[1],Q[2]+(Q[2]-2m)-c[2]];8 11.u(c,e)}1d o(a.U){8 7.1V(F.1A,a)}1d{9 P=a.4||a;8 11.u(7.K.1t([P[0],P[1],(P[2]||0)]),7.W)}},1Z:l(a,b,c){a=v.u(a);a=a.1N();o(a===w){8 w}b=v.u(b);b=b.1N();o(b===w){8 w}o(1g(c)==\'1f\'){c=w}1d{c=v.u(c);c=c.1N();o(c===w){8 w}}9 d=a.4[0],18=a.4[1],1a=a.4[2];9 e=b.4[0],1W=b.4[1],1X=b.4[2];9 f,1i;o(c!==w){9 g=c.4[0],2l=c.4[1],2t=c.4[2];f=v.u([(1W-18)*(2t-1a)-(1X-1a)*(2l-18),(1X-1a)*(g-d)-(e-d)*(2t-1a),(e-d)*(2l-18)-(1W-18)*(g-d)]);1i=f.1u();o(1i===0){8 w}f=v.u([f.4[0]/1i,f.4[1]/1i,f.4[2]/1i])}1d{1i=F.1x(e*e+1W*1W+1X*1X);o(1i===0){8 w}f=v.u([b.4[0]/1i,b.4[1]/1i,b.4[2]/1i])}7.K=a;7.W=f;8 7}};11.u=l(a,b,c){9 P=25 11();8 P.1Z(a,b,c)};11.2I=11.u(v.1j(3),v.k);11.2H=11.u(v.1j(3),v.i);11.2G=11.u(v.1j(3),v.j);11.36=11.2I;11.35=11.2H;11.3j=11.2G;9 $V=v.u;9 $M=S.u;9 $L=14.u;9 $P=11.u;',62,206,'||||elements|||this|return|var||||||||||||function|||if||length||||create|Vector|null|||||||||Math|nj|while||do|anchor||||||||Matrix||direction||normal||||kj|Plane|ni|abs|Line|ki|precision|Sylvester|A2|push|A3|map|els|else||undefined|typeof|contains|mod|Zero|D3|D2|isParallelTo|kp|distanceFrom|cols|dup|pointClosestTo|np|reflectionIn|modulus|intersects|A1|sqrt|isSquare|X2|PI|X3|angleFrom|mod1|C2|mod2|sin|cos|break|C3|toRightTriangular|false|Y3|to3D|E2|E1|E3|Rotation|Y2|Y1|intersectionWith|rotate|v12|v13|rank|setVectors|nc|sum|multiply|prototype|eql|new|setElements|case|each|PA3|PA2|part|new_element|round|for|cross|product|AD2|isSameSizeAs|add|isPerpendicularTo|v22|AN3|inspect|AD3|AN2|toUnitVector|PsubQ3|PsubQ2|v23|dot|divisor|inverse|true|isSingular|determinant|max|canMultiplyFromLeft|subtract|rows|col|random|ZX|YZ|XY|Random|join|N2|N1|D1|slice|default|N3|dimensions|switch|liesIn|translate|snapTo|augment|Diagonal|trace|indexOf|diagonal|transpose|minor|row|isAntiparallelTo|ZY|YX|acos|RotationZ|RotationY|liesOn|RotationX|inv|rk|tr|det|toDiagonalMatrix|toUpperTriangular|version|XZ'.split('|'),0,{}))
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-10/preview.jpg b/code-nav-home/covers/dynamic/cover-10/preview.jpg
new file mode 100644
index 0000000..2e5e8c3
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-10/preview.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/17c2a4938150c8cd48d3e8fb072494e164286e08.dxs b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/17c2a4938150c8cd48d3e8fb072494e164286e08.dxs
new file mode 100644
index 0000000..ae25c32
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/17c2a4938150c8cd48d3e8fb072494e164286e08.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/4cd8da74ae3b96e190fd87440e015e76c32cb805.dxs b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/4cd8da74ae3b96e190fd87440e015e76c32cb805.dxs
new file mode 100644
index 0000000..e61ec77
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/4cd8da74ae3b96e190fd87440e015e76c32cb805.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/6a5e0fde4a01ee99d94e166f7d38c5d152f2c1e6.dxs b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/6a5e0fde4a01ee99d94e166f7d38c5d152f2c1e6.dxs
new file mode 100644
index 0000000..42caabf
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/6a5e0fde4a01ee99d94e166f7d38c5d152f2c1e6.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/78166c9f658faa0027cb8535eab9195aedb52f98.dxs b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/78166c9f658faa0027cb8535eab9195aedb52f98.dxs
new file mode 100644
index 0000000..3807f0c
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/78166c9f658faa0027cb8535eab9195aedb52f98.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/815f979888d7a7d3cb622eee67d445c0fc94469b.dxs b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/815f979888d7a7d3cb622eee67d445c0fc94469b.dxs
new file mode 100644
index 0000000..7bf30e7
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/815f979888d7a7d3cb622eee67d445c0fc94469b.dxs differ
diff --git a/code-nav-home/covers/dynamic/cover-11/1.jpg b/code-nav-home/covers/dynamic/cover-11/1.jpg
new file mode 100644
index 0000000..a95d69d
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-11/1.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-11/index.html b/code-nav-home/covers/dynamic/cover-11/index.html
new file mode 100644
index 0000000..d3d4c55
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-11/index.html
@@ -0,0 +1,369 @@
+
+
+
+
+
+
+ 编程导航 - 狐女
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-11/js/index.js b/code-nav-home/covers/dynamic/cover-11/js/index.js
new file mode 100644
index 0000000..0fcda8d
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-11/js/index.js
@@ -0,0 +1,802 @@
+// Utilities
+var Vector3 = {};
+var Matrix44 = {};
+Vector3.create = function(x, y, z) {
+ return {'x':x, 'y':y, 'z':z};
+};
+Vector3.dot = function (v0, v1) {
+ return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
+};
+Vector3.cross = function (v, v0, v1) {
+ v.x = v0.y * v1.z - v0.z * v1.y;
+ v.y = v0.z * v1.x - v0.x * v1.z;
+ v.z = v0.x * v1.y - v0.y * v1.x;
+};
+Vector3.normalize = function (v) {
+ var l = v.x * v.x + v.y * v.y + v.z * v.z;
+ if(l > 0.00001) {
+ l = 1.0 / Math.sqrt(l);
+ v.x *= l;
+ v.y *= l;
+ v.z *= l;
+ }
+};
+Vector3.arrayForm = function(v) {
+ if(v.array) {
+ v.array[0] = v.x;
+ v.array[1] = v.y;
+ v.array[2] = v.z;
+ }
+ else {
+ v.array = new Float32Array([v.x, v.y, v.z]);
+ }
+ return v.array;
+};
+Matrix44.createIdentity = function () {
+ return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
+};
+Matrix44.loadProjection = function (m, aspect, vdeg, near, far) {
+ var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0;
+ var w = h * aspect;
+
+ m[0] = 2.0 * near / w;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+
+ m[4] = 0.0;
+ m[5] = 2.0 * near / h;
+ m[6] = 0.0;
+ m[7] = 0.0;
+
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = -(far + near) / (far - near);
+ m[11] = -1.0;
+
+ m[12] = 0.0;
+ m[13] = 0.0;
+ m[14] = -2.0 * far * near / (far - near);
+ m[15] = 0.0;
+};
+Matrix44.loadLookAt = function (m, vpos, vlook, vup) {
+ var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z);
+ Vector3.normalize(frontv);
+ var sidev = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(sidev, vup, frontv);
+ Vector3.normalize(sidev);
+ var topv = Vector3.create(1.0, 0.0, 0.0);
+ Vector3.cross(topv, frontv, sidev);
+ Vector3.normalize(topv);
+
+ m[0] = sidev.x;
+ m[1] = topv.x;
+ m[2] = frontv.x;
+ m[3] = 0.0;
+
+ m[4] = sidev.y;
+ m[5] = topv.y;
+ m[6] = frontv.y;
+ m[7] = 0.0;
+
+ m[8] = sidev.z;
+ m[9] = topv.z;
+ m[10] = frontv.z;
+ m[11] = 0.0;
+
+ m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]);
+ m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]);
+ m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]);
+ m[15] = 1.0;
+};
+
+//
+var timeInfo = {
+ 'start':0, 'prev':0, // Date
+ 'delta':0, 'elapsed':0 // Number(sec)
+};
+
+//
+var gl;
+var renderSpec = {
+ 'width':0,
+ 'height':0,
+ 'aspect':1,
+ 'array':new Float32Array(3),
+ 'halfWidth':0,
+ 'halfHeight':0,
+ 'halfArray':new Float32Array(3)
+ // and some render targets. see setViewport()
+};
+renderSpec.setSize = function(w, h) {
+ renderSpec.width = w;
+ renderSpec.height = h;
+ renderSpec.aspect = renderSpec.width / renderSpec.height;
+ renderSpec.array[0] = renderSpec.width;
+ renderSpec.array[1] = renderSpec.height;
+ renderSpec.array[2] = renderSpec.aspect;
+
+ renderSpec.halfWidth = Math.floor(w / 2);
+ renderSpec.halfHeight = Math.floor(h / 2);
+ renderSpec.halfArray[0] = renderSpec.halfWidth;
+ renderSpec.halfArray[1] = renderSpec.halfHeight;
+ renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight;
+};
+
+function deleteRenderTarget(rt) {
+ gl.deleteFramebuffer(rt.frameBuffer);
+ gl.deleteRenderbuffer(rt.renderBuffer);
+ gl.deleteTexture(rt.texture);
+}
+
+function createRenderTarget(w, h) {
+ var ret = {
+ 'width':w,
+ 'height':h,
+ 'sizeArray':new Float32Array([w, h, w / h]),
+ 'dtxArray':new Float32Array([1.0 / w, 1.0 / h])
+ };
+ ret.frameBuffer = gl.createFramebuffer();
+ ret.renderBuffer = gl.createRenderbuffer();
+ ret.texture = gl.createTexture();
+
+ gl.bindTexture(gl.TEXTURE_2D, ret.texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer);
+
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ return ret;
+}
+
+function compileShader(shtype, shsrc) {
+ var retsh = gl.createShader(shtype);
+
+ gl.shaderSource(retsh, shsrc);
+ gl.compileShader(retsh);
+
+ if(!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) {
+ var errlog = gl.getShaderInfoLog(retsh);
+ gl.deleteShader(retsh);
+ console.error(errlog);
+ return null;
+ }
+ return retsh;
+}
+
+function createShader(vtxsrc, frgsrc, uniformlist, attrlist) {
+ var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc);
+ var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc);
+
+ if(vsh == null || fsh == null) {
+ return null;
+ }
+
+ var prog = gl.createProgram();
+ gl.attachShader(prog, vsh);
+ gl.attachShader(prog, fsh);
+
+ gl.deleteShader(vsh);
+ gl.deleteShader(fsh);
+
+ gl.linkProgram(prog);
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ var errlog = gl.getProgramInfoLog(prog);
+ console.error(errlog);
+ return null;
+ }
+
+ if(uniformlist) {
+ prog.uniforms = {};
+ for(var i = 0; i < uniformlist.length; i++) {
+ prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]);
+ }
+ }
+
+ if(attrlist) {
+ prog.attributes = {};
+ for(var i = 0; i < attrlist.length; i++) {
+ var attr = attrlist[i];
+ prog.attributes[attr] = gl.getAttribLocation(prog, attr);
+ }
+ }
+
+ return prog;
+}
+
+function useShader(prog) {
+ gl.useProgram(prog);
+ for(var attr in prog.attributes) {
+ gl.enableVertexAttribArray(prog.attributes[attr]);;
+ }
+}
+
+function unuseShader(prog) {
+ for(var attr in prog.attributes) {
+ gl.disableVertexAttribArray(prog.attributes[attr]);;
+ }
+ gl.useProgram(null);
+}
+
+/////
+var projection = {
+ 'angle':60,
+ 'nearfar':new Float32Array([0.1, 100.0]),
+ 'matrix':Matrix44.createIdentity()
+};
+var camera = {
+ 'position':Vector3.create(0, 0, 100),
+ 'lookat':Vector3.create(0, 0, 0),
+ 'up':Vector3.create(0, 1, 0),
+ 'dof':Vector3.create(10.0, 4.0, 8.0),
+ 'matrix':Matrix44.createIdentity()
+};
+
+var pointFlower = {};
+var meshFlower = {};
+var sceneStandBy = false;
+
+var BlossomParticle = function () {
+ this.velocity = new Array(3);
+ this.rotation = new Array(3);
+ this.position = new Array(3);
+ this.euler = new Array(3);
+ this.size = 1.0;
+ this.alpha = 1.0;
+ this.zkey = 0.0;
+};
+
+BlossomParticle.prototype.setVelocity = function (vx, vy, vz) {
+ this.velocity[0] = vx;
+ this.velocity[1] = vy;
+ this.velocity[2] = vz;
+};
+
+BlossomParticle.prototype.setRotation = function (rx, ry, rz) {
+ this.rotation[0] = rx;
+ this.rotation[1] = ry;
+ this.rotation[2] = rz;
+};
+
+BlossomParticle.prototype.setPosition = function (nx, ny, nz) {
+ this.position[0] = nx;
+ this.position[1] = ny;
+ this.position[2] = nz;
+};
+
+BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) {
+ this.euler[0] = rx;
+ this.euler[1] = ry;
+ this.euler[2] = rz;
+};
+
+BlossomParticle.prototype.setSize = function (s) {
+ this.size = s;
+};
+
+BlossomParticle.prototype.update = function (dt, et) {
+ this.position[0] += this.velocity[0] * dt;
+ this.position[1] += this.velocity[1] * dt;
+ this.position[2] += this.velocity[2] * dt;
+
+ this.euler[0] += this.rotation[0] * dt;
+ this.euler[1] += this.rotation[1] * dt;
+ this.euler[2] += this.rotation[2] * dt;
+};
+
+function createPointFlowers() {
+ // get point sizes
+ var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
+ renderSpec.pointSize = {'min':prm[0], 'max':prm[1]};
+
+ var vtxsrc = document.getElementById("sakura_point_vsh").textContent;
+ var frgsrc = document.getElementById("sakura_point_fsh").textContent;
+
+ pointFlower.program = createShader(
+ vtxsrc, frgsrc,
+ ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'],
+ ['aPosition', 'aEuler', 'aMisc']
+ );
+
+ useShader(pointFlower.program);
+ pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]);
+ pointFlower.fader = Vector3.create(0.0, 10.0, 0.0);
+
+ // paramerters: velocity[3], rotate[3]
+ pointFlower.numFlowers = 300;
+ pointFlower.particles = new Array(pointFlower.numFlowers);
+ // vertex attributes {position[3], euler_xyz[3], size[1]}
+ pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2));
+ pointFlower.positionArrayOffset = 0;
+ pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3;
+ pointFlower.miscArrayOffset = pointFlower.numFlowers * 6;
+
+ pointFlower.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ unuseShader(pointFlower.program);
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ pointFlower.particles[i] = new BlossomParticle();
+ }
+}
+
+function initPointFlowers() {
+ //area
+ pointFlower.area = Vector3.create(20.0, 20.0, 20.0);
+ pointFlower.area.x = pointFlower.area.y * renderSpec.aspect;
+
+ pointFlower.fader.x = 10.0; //env fade start
+ pointFlower.fader.y = pointFlower.area.z; //env fade half
+ pointFlower.fader.z = 0.1; //near fade start
+
+ //particles
+ var PI2 = Math.PI * 2.0;
+ var tmpv3 = Vector3.create(0, 0, 0);
+ var tmpv = 0;
+ var symmetryrand = function() {return (Math.random() * 2.0 - 1.0);};
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var tmpprtcl = pointFlower.particles[i];
+
+ //velocity
+ tmpv3.x = symmetryrand() * 0.3 - 0.8;
+ tmpv3.y = symmetryrand() * 0.2 - 1.0;
+ tmpv3.z = symmetryrand() * 0.3 - 0.5;
+ Vector3.normalize(tmpv3);
+ tmpv = 2.0 + Math.random() * 1.0;
+ tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv);
+
+ //rotation
+ tmpprtcl.setRotation(
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5,
+ symmetryrand() * PI2 * 0.5
+ );
+
+ //position
+ tmpprtcl.setPosition(
+ symmetryrand() * pointFlower.area.x,
+ symmetryrand() * pointFlower.area.y,
+ symmetryrand() * pointFlower.area.z
+ );
+
+ //euler
+ tmpprtcl.setEulerAngles(
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0,
+ Math.random() * Math.PI * 2.0
+ );
+
+ //size
+ tmpprtcl.setSize(0.9 + Math.random() * 0.1);
+ }
+}
+
+function renderPointFlowers() {
+ //update
+ var PI2 = Math.PI * 2.0;
+ var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z];
+ var repeatPos = function (prt, cmp, limit) {
+ if(Math.abs(prt.position[cmp]) - prt.size * 0.5 > limit) {
+ //out of area
+ if(prt.position[cmp] > 0) {
+ prt.position[cmp] -= limit * 2.0;
+ }
+ else {
+ prt.position[cmp] += limit * 2.0;
+ }
+ }
+ };
+ var repeatEuler = function (prt, cmp) {
+ prt.euler[cmp] = prt.euler[cmp] % PI2;
+ if(prt.euler[cmp] < 0.0) {
+ prt.euler[cmp] += PI2;
+ }
+ };
+
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ prtcl.update(timeInfo.delta, timeInfo.elapsed);
+ repeatPos(prtcl, 0, pointFlower.area.x);
+ repeatPos(prtcl, 1, pointFlower.area.y);
+ repeatPos(prtcl, 2, pointFlower.area.z);
+ repeatEuler(prtcl, 0);
+ repeatEuler(prtcl, 1);
+ repeatEuler(prtcl, 2);
+
+ prtcl.alpha = 1.0;//(pointFlower.area.z - prtcl.position[2]) * 0.5;
+
+ prtcl.zkey = (camera.matrix[2] * prtcl.position[0]
+ + camera.matrix[6] * prtcl.position[1]
+ + camera.matrix[10] * prtcl.position[2]
+ + camera.matrix[14]);
+ }
+
+ // sort
+ pointFlower.particles.sort(function(p0, p1){return p0.zkey - p1.zkey;});
+
+ // update data
+ var ipos = pointFlower.positionArrayOffset;
+ var ieuler = pointFlower.eulerArrayOffset;
+ var imisc = pointFlower.miscArrayOffset;
+ for(var i = 0; i < pointFlower.numFlowers; i++) {
+ var prtcl = pointFlower.particles[i];
+ pointFlower.dataArray[ipos] = prtcl.position[0];
+ pointFlower.dataArray[ipos + 1] = prtcl.position[1];
+ pointFlower.dataArray[ipos + 2] = prtcl.position[2];
+ ipos += 3;
+ pointFlower.dataArray[ieuler] = prtcl.euler[0];
+ pointFlower.dataArray[ieuler + 1] = prtcl.euler[1];
+ pointFlower.dataArray[ieuler + 2] = prtcl.euler[2];
+ ieuler += 3;
+ pointFlower.dataArray[imisc] = prtcl.size;
+ pointFlower.dataArray[imisc + 1] = prtcl.alpha;
+ imisc += 2;
+ }
+
+ //draw
+ gl.enable(gl.BLEND);
+ //gl.disable(gl.DEPTH_TEST);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ var prog = pointFlower.program;
+ useShader(prog);
+
+ gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix);
+ gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+ gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof));
+ gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader));
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW);
+
+ gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+ gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT);
+
+ // doubler
+ for(var i = 1; i < 2; i++) {
+ var zpos = i * -2.0;
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * -1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * -1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ pointFlower.offset[0] = pointFlower.area.x * 1.0;
+ pointFlower.offset[1] = pointFlower.area.y * 1.0;
+ pointFlower.offset[2] = pointFlower.area.z * zpos;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+ }
+
+ //main
+ pointFlower.offset[0] = 0.0;
+ pointFlower.offset[1] = 0.0;
+ pointFlower.offset[2] = 0.0;
+ gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset);
+ gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(prog);
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+}
+
+// effects
+//common util
+function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) {
+ var ret = {};
+ var unifs = ['uResolution', 'uSrc', 'uDelta'];
+ if(exunifs) {
+ unifs = unifs.concat(exunifs);
+ }
+ var attrs = ['aPosition'];
+ if(exattrs) {
+ attrs = attrs.concat(exattrs);
+ }
+
+ ret.program = createShader(vtxsrc, frgsrc, unifs, attrs);
+ useShader(ret.program);
+
+ ret.dataArray = new Float32Array([
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0
+ ]);
+ ret.buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ unuseShader(ret.program);
+
+ return ret;
+}
+
+// basic usage
+// useEffect(prog, srctex({'texture':texid, 'dtxArray':(f32)[dtx, dty]})); //basic initialize
+// gl.uniform**(...); //additional uniforms
+// drawEffect()
+// unuseEffect(prog)
+// TEXTURE0 makes src
+function useEffect(fxobj, srctex) {
+ var prog = fxobj.program;
+ useShader(prog);
+ gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array);
+
+ if(srctex != null) {
+ gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray);
+ gl.uniform1i(prog.uniforms.uSrc, 0);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, srctex.texture);
+ }
+}
+function drawEffect(fxobj) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer);
+ gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+}
+function unuseEffect(fxobj) {
+ unuseShader(fxobj.program);
+}
+
+var effectLib = {};
+function createEffectLib() {
+
+ var vtxsrc, frgsrc;
+ //common
+ var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent;
+
+ //background
+ frgsrc = document.getElementById("bg_fsh").textContent;
+ effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null);
+
+ // make brightpixels buffer
+ frgsrc = document.getElementById("fx_brightbuf_fsh").textContent;
+ effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null);
+
+ // direction blur
+ frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent;
+ effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null);
+
+ //final composite
+ vtxsrc = document.getElementById("pp_final_vsh").textContent;
+ frgsrc = document.getElementById("pp_final_fsh").textContent;
+ effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null);
+}
+
+// background
+function createBackground() {
+ //console.log("create background");
+}
+function initBackground() {
+ //console.log("init background");
+}
+function renderBackground() {
+ gl.disable(gl.DEPTH_TEST);
+
+ useEffect(effectLib.sceneBg, null);
+ gl.uniform2f(effectLib.sceneBg.program.uniforms.uTimes, timeInfo.elapsed, timeInfo.delta);
+ drawEffect(effectLib.sceneBg);
+ unuseEffect(effectLib.sceneBg);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+// post process
+var postProcess = {};
+function createPostProcess() {
+ //console.log("create post process");
+}
+function initPostProcess() {
+ //console.log("init post process");
+}
+
+function renderPostProcess() {
+ gl.enable(gl.TEXTURE_2D);
+ gl.disable(gl.DEPTH_TEST);
+ var bindRT = function (rt, isclear) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer);
+ gl.viewport(0, 0, rt.width, rt.height);
+ if(isclear) {
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ }
+ };
+
+ //make bright buff
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.mkBrightBuf, renderSpec.mainRT);
+ drawEffect(effectLib.mkBrightBuf);
+ unuseEffect(effectLib.mkBrightBuf);
+
+ // make bloom
+ for(var i = 0; i < 2; i++) {
+ var p = 1.5 + 1 * i;
+ var s = 2.0 + 1 * i;
+ bindRT(renderSpec.wHalfRT1, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT0);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+
+ bindRT(renderSpec.wHalfRT0, true);
+ useEffect(effectLib.dirBlur, renderSpec.wHalfRT1);
+ gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s);
+ drawEffect(effectLib.dirBlur);
+ unuseEffect(effectLib.dirBlur);
+ }
+
+ //display
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ useEffect(effectLib.finalComp, renderSpec.mainRT);
+ gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1);
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture);
+ drawEffect(effectLib.finalComp);
+ unuseEffect(effectLib.finalComp);
+
+ gl.enable(gl.DEPTH_TEST);
+}
+
+/////
+var SceneEnv = {};
+function createScene() {
+ createEffectLib();
+ createBackground();
+ createPointFlowers();
+ createPostProcess();
+ sceneStandBy = true;
+}
+
+function initScene() {
+ initBackground();
+ initPointFlowers();
+ initPostProcess();
+
+ //camera.position.z = 17.320508;
+ camera.position.z = pointFlower.area.z + projection.nearfar[0];
+ projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0;
+ Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]);
+}
+
+function renderScene() {
+ //draw
+ Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up);
+
+ gl.enable(gl.DEPTH_TEST);
+
+ //gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer);
+ gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height);
+ gl.clearColor(0.005, 0, 0.05, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ renderBackground();
+ renderPointFlowers();
+ renderPostProcess();
+}
+
+/////
+function onResize(e) {
+ makeCanvasFullScreen(document.getElementById("sakura"));
+ setViewports();
+ if(sceneStandBy) {
+ initScene();
+ }
+}
+
+function setViewports() {
+ renderSpec.setSize(gl.canvas.width, gl.canvas.height);
+
+ gl.clearColor(0.2, 0.2, 0.5, 1.0);
+ gl.viewport(0, 0, renderSpec.width, renderSpec.height);
+
+ var rtfunc = function (rtname, rtw, rth) {
+ var rt = renderSpec[rtname];
+ if(rt) deleteRenderTarget(rt);
+ renderSpec[rtname] = createRenderTarget(rtw, rth);
+ };
+ rtfunc('mainRT', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT0', renderSpec.width, renderSpec.height);
+ rtfunc('wFullRT1', renderSpec.width, renderSpec.height);
+ rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight);
+ rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight);
+}
+
+function render() {
+ renderScene();
+}
+
+var animating = true;
+function toggleAnimation(elm) {
+ animating ^= true;
+ if(animating) animate();
+ if(elm) {
+ elm.innerHTML = animating? "Stop":"Start";
+ }
+}
+
+function stepAnimation() {
+ if(!animating) animate();
+}
+
+function animate() {
+ var curdate = new Date();
+ timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0;
+ timeInfo.delta = (curdate - timeInfo.prev) / 1000.0;
+ timeInfo.prev = curdate;
+
+ if(animating) requestAnimationFrame(animate);
+ render();
+}
+
+function makeCanvasFullScreen(canvas) {
+ var b = document.body;
+ var d = document.documentElement;
+ fullw = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth);
+ fullh = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight);
+ canvas.width = fullw;
+ canvas.height = fullh;
+}
+
+window.addEventListener('load', function(e) {
+ var canvas = document.getElementById("sakura");
+ try {
+ makeCanvasFullScreen(canvas);
+ gl = canvas.getContext('experimental-webgl');
+ } catch(e) {
+ alert("WebGL not supported." + e);
+ console.error(e);
+ return;
+ }
+
+ window.addEventListener('resize', onResize);
+
+ setViewports();
+ createScene();
+ initScene();
+
+ timeInfo.start = new Date();
+ timeInfo.prev = timeInfo.start;
+ animate();
+});
+
+//set window.requestAnimationFrame
+(function (w, r) {
+ w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
+})(window, 'equestAnimationFrame');
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-11/preview.jpg b/code-nav-home/covers/dynamic/cover-11/preview.jpg
new file mode 100644
index 0000000..ab2e712
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-11/preview.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/css/bootstrap.min.css b/code-nav-home/covers/dynamic/cover-12/assets/css/bootstrap.min.css
new file mode 100644
index 0000000..df076d9
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-12/assets/css/bootstrap.min.css
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v4.0.0-alpha.6 (https://getbootstrap.com)
+ * Copyright 2011-2017 The Bootstrap Authors
+ * Copyright 2011-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=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{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}@media print{*,::after,::before,blockquote::first-letter,blockquote::first-line,div::first-letter,div::first-line,li::first-letter,li::first-line,p::first-letter,p::first-line{text-shadow:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}html{-webkit-box-sizing:border-box;box-sizing:border-box}*,::after,::before{-webkit-box-sizing:inherit;box-sizing:inherit}@-ms-viewport{width:device-width}html{-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}body{font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;color:#292b2c;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{cursor:help}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}a{color:#0275d8;text-decoration:none}a:focus,a:hover{color:#014c8c;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle}[role=button]{cursor:pointer}[role=button],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse;background-color:transparent}caption{padding-top:.75rem;padding-bottom:.75rem;color:#636c72;text-align:left;caption-side:bottom}th{text-align:left}label{display:inline-block;margin-bottom:.5rem}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,select,textarea{line-height:inherit}input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:not-allowed}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit}input[type=search]{-webkit-appearance:none}output{display:inline-block}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.1}.display-2{font-size:5.5rem;font-weight:300;line-height:1.1}.display-3{font-size:4.5rem;font-weight:300;line-height:1.1}.display-4{font-size:3.5rem;font-weight:300;line-height:1.1}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:5px}.initialism{font-size:90%;text-transform:uppercase}.blockquote{padding:.5rem 1rem;margin-bottom:1rem;font-size:1.25rem;border-left:.25rem solid #eceeef}.blockquote-footer{display:block;font-size:80%;color:#636c72}.blockquote-footer::before{content:"\2014 \00A0"}.blockquote-reverse{padding-right:1rem;padding-left:0;text-align:right;border-right:.25rem solid #eceeef;border-left:0}.blockquote-reverse .blockquote-footer::before{content:""}.blockquote-reverse .blockquote-footer::after{content:"\00A0 \2014"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #ddd;border-radius:.25rem;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#636c72}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}code{padding:.2rem .4rem;font-size:90%;color:#bd4147;background-color:#f0f0f0;border-radius:.25rem}a>code{padding:0;color:inherit;background-color:inherit}kbd{padding:.2rem .4rem;font-size:90%;color:#fff;background-color:#292b2c;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;margin-top:0;margin-bottom:1rem;font-size:90%;color:#292b2c}pre code{padding:0;font-size:inherit;color:inherit;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{position:relative;margin-left:auto;margin-right:auto;padding-right:15px;padding-left:15px}@media (min-width:576px){.container{padding-right:15px;padding-left:15px}}@media (min-width:768px){.container{padding-right:15px;padding-left:15px}}@media (min-width:992px){.container{padding-right:15px;padding-left:15px}}@media (min-width:1200px){.container{padding-right:15px;padding-left:15px}}@media (min-width:576px){.container{width:540px;max-width:100%}}@media (min-width:768px){.container{width:720px;max-width:100%}}@media (min-width:992px){.container{width:960px;max-width:100%}}@media (min-width:1200px){.container{width:1140px;max-width:100%}}.container-fluid{position:relative;margin-left:auto;margin-right:auto;padding-right:15px;padding-left:15px}@media (min-width:576px){.container-fluid{padding-right:15px;padding-left:15px}}@media (min-width:768px){.container-fluid{padding-right:15px;padding-left:15px}}@media (min-width:992px){.container-fluid{padding-right:15px;padding-left:15px}}@media (min-width:1200px){.container-fluid{padding-right:15px;padding-left:15px}}.row{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}@media (min-width:576px){.row{margin-right:-15px;margin-left:-15px}}@media (min-width:768px){.row{margin-right:-15px;margin-left:-15px}}@media (min-width:992px){.row{margin-right:-15px;margin-left:-15px}}@media (min-width:1200px){.row{margin-right:-15px;margin-left:-15px}}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}@media (min-width:576px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:15px;padding-left:15px}}@media (min-width:768px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:15px;padding-left:15px}}@media (min-width:992px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:15px;padding-left:15px}}@media (min-width:1200px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:15px;padding-left:15px}}.col{-webkit-flex-basis:0;-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-1{-webkit-box-flex:0;-webkit-flex:0 0 8.333333%;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-webkit-box-flex:0;-webkit-flex:0 0 16.666667%;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-webkit-box-flex:0;-webkit-flex:0 0 25%;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-webkit-flex:0 0 33.333333%;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-webkit-box-flex:0;-webkit-flex:0 0 41.666667%;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-webkit-box-flex:0;-webkit-flex:0 0 50%;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-webkit-flex:0 0 58.333333%;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-webkit-box-flex:0;-webkit-flex:0 0 66.666667%;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-webkit-box-flex:0;-webkit-flex:0 0 75%;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-webkit-flex:0 0 83.333333%;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-webkit-box-flex:0;-webkit-flex:0 0 91.666667%;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-0{right:auto}.pull-1{right:8.333333%}.pull-2{right:16.666667%}.pull-3{right:25%}.pull-4{right:33.333333%}.pull-5{right:41.666667%}.pull-6{right:50%}.pull-7{right:58.333333%}.pull-8{right:66.666667%}.pull-9{right:75%}.pull-10{right:83.333333%}.pull-11{right:91.666667%}.pull-12{right:100%}.push-0{left:auto}.push-1{left:8.333333%}.push-2{left:16.666667%}.push-3{left:25%}.push-4{left:33.333333%}.push-5{left:41.666667%}.push-6{left:50%}.push-7{left:58.333333%}.push-8{left:66.666667%}.push-9{left:75%}.push-10{left:83.333333%}.push-11{left:91.666667%}.push-12{left:100%}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-webkit-flex-basis:0;-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-sm-1{-webkit-box-flex:0;-webkit-flex:0 0 8.333333%;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-webkit-box-flex:0;-webkit-flex:0 0 16.666667%;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-webkit-box-flex:0;-webkit-flex:0 0 25%;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-webkit-flex:0 0 33.333333%;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-webkit-box-flex:0;-webkit-flex:0 0 41.666667%;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-webkit-box-flex:0;-webkit-flex:0 0 50%;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-webkit-flex:0 0 58.333333%;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-webkit-box-flex:0;-webkit-flex:0 0 66.666667%;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-webkit-box-flex:0;-webkit-flex:0 0 75%;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-webkit-flex:0 0 83.333333%;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-webkit-box-flex:0;-webkit-flex:0 0 91.666667%;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-sm-0{right:auto}.pull-sm-1{right:8.333333%}.pull-sm-2{right:16.666667%}.pull-sm-3{right:25%}.pull-sm-4{right:33.333333%}.pull-sm-5{right:41.666667%}.pull-sm-6{right:50%}.pull-sm-7{right:58.333333%}.pull-sm-8{right:66.666667%}.pull-sm-9{right:75%}.pull-sm-10{right:83.333333%}.pull-sm-11{right:91.666667%}.pull-sm-12{right:100%}.push-sm-0{left:auto}.push-sm-1{left:8.333333%}.push-sm-2{left:16.666667%}.push-sm-3{left:25%}.push-sm-4{left:33.333333%}.push-sm-5{left:41.666667%}.push-sm-6{left:50%}.push-sm-7{left:58.333333%}.push-sm-8{left:66.666667%}.push-sm-9{left:75%}.push-sm-10{left:83.333333%}.push-sm-11{left:91.666667%}.push-sm-12{left:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-webkit-flex-basis:0;-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-md-1{-webkit-box-flex:0;-webkit-flex:0 0 8.333333%;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-webkit-box-flex:0;-webkit-flex:0 0 16.666667%;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-webkit-box-flex:0;-webkit-flex:0 0 25%;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-webkit-flex:0 0 33.333333%;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-webkit-box-flex:0;-webkit-flex:0 0 41.666667%;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-webkit-box-flex:0;-webkit-flex:0 0 50%;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-webkit-flex:0 0 58.333333%;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-webkit-box-flex:0;-webkit-flex:0 0 66.666667%;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-webkit-box-flex:0;-webkit-flex:0 0 75%;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-webkit-flex:0 0 83.333333%;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-webkit-box-flex:0;-webkit-flex:0 0 91.666667%;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-md-0{right:auto}.pull-md-1{right:8.333333%}.pull-md-2{right:16.666667%}.pull-md-3{right:25%}.pull-md-4{right:33.333333%}.pull-md-5{right:41.666667%}.pull-md-6{right:50%}.pull-md-7{right:58.333333%}.pull-md-8{right:66.666667%}.pull-md-9{right:75%}.pull-md-10{right:83.333333%}.pull-md-11{right:91.666667%}.pull-md-12{right:100%}.push-md-0{left:auto}.push-md-1{left:8.333333%}.push-md-2{left:16.666667%}.push-md-3{left:25%}.push-md-4{left:33.333333%}.push-md-5{left:41.666667%}.push-md-6{left:50%}.push-md-7{left:58.333333%}.push-md-8{left:66.666667%}.push-md-9{left:75%}.push-md-10{left:83.333333%}.push-md-11{left:91.666667%}.push-md-12{left:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-webkit-flex-basis:0;-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-lg-1{-webkit-box-flex:0;-webkit-flex:0 0 8.333333%;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-webkit-box-flex:0;-webkit-flex:0 0 16.666667%;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-webkit-box-flex:0;-webkit-flex:0 0 25%;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-webkit-flex:0 0 33.333333%;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-webkit-box-flex:0;-webkit-flex:0 0 41.666667%;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-webkit-box-flex:0;-webkit-flex:0 0 50%;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-webkit-flex:0 0 58.333333%;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-webkit-box-flex:0;-webkit-flex:0 0 66.666667%;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-webkit-box-flex:0;-webkit-flex:0 0 75%;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-webkit-flex:0 0 83.333333%;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-webkit-box-flex:0;-webkit-flex:0 0 91.666667%;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-lg-0{right:auto}.pull-lg-1{right:8.333333%}.pull-lg-2{right:16.666667%}.pull-lg-3{right:25%}.pull-lg-4{right:33.333333%}.pull-lg-5{right:41.666667%}.pull-lg-6{right:50%}.pull-lg-7{right:58.333333%}.pull-lg-8{right:66.666667%}.pull-lg-9{right:75%}.pull-lg-10{right:83.333333%}.pull-lg-11{right:91.666667%}.pull-lg-12{right:100%}.push-lg-0{left:auto}.push-lg-1{left:8.333333%}.push-lg-2{left:16.666667%}.push-lg-3{left:25%}.push-lg-4{left:33.333333%}.push-lg-5{left:41.666667%}.push-lg-6{left:50%}.push-lg-7{left:58.333333%}.push-lg-8{left:66.666667%}.push-lg-9{left:75%}.push-lg-10{left:83.333333%}.push-lg-11{left:91.666667%}.push-lg-12{left:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-webkit-flex-basis:0;-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-xl-1{-webkit-box-flex:0;-webkit-flex:0 0 8.333333%;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-webkit-box-flex:0;-webkit-flex:0 0 16.666667%;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-webkit-box-flex:0;-webkit-flex:0 0 25%;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-webkit-flex:0 0 33.333333%;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-webkit-box-flex:0;-webkit-flex:0 0 41.666667%;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-webkit-box-flex:0;-webkit-flex:0 0 50%;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-webkit-flex:0 0 58.333333%;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-webkit-box-flex:0;-webkit-flex:0 0 66.666667%;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-webkit-box-flex:0;-webkit-flex:0 0 75%;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-webkit-flex:0 0 83.333333%;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-webkit-box-flex:0;-webkit-flex:0 0 91.666667%;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-xl-0{right:auto}.pull-xl-1{right:8.333333%}.pull-xl-2{right:16.666667%}.pull-xl-3{right:25%}.pull-xl-4{right:33.333333%}.pull-xl-5{right:41.666667%}.pull-xl-6{right:50%}.pull-xl-7{right:58.333333%}.pull-xl-8{right:66.666667%}.pull-xl-9{right:75%}.pull-xl-10{right:83.333333%}.pull-xl-11{right:91.666667%}.pull-xl-12{right:100%}.push-xl-0{left:auto}.push-xl-1{left:8.333333%}.push-xl-2{left:16.666667%}.push-xl-3{left:25%}.push-xl-4{left:33.333333%}.push-xl-5{left:41.666667%}.push-xl-6{left:50%}.push-xl-7{left:58.333333%}.push-xl-8{left:66.666667%}.push-xl-9{left:75%}.push-xl-10{left:83.333333%}.push-xl-11{left:91.666667%}.push-xl-12{left:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #eceeef}.table thead th{vertical-align:bottom;border-bottom:2px solid #eceeef}.table tbody+tbody{border-top:2px solid #eceeef}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #eceeef}.table-bordered td,.table-bordered th{border:1px solid #eceeef}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table-success,.table-success>td,.table-success>th{background-color:#dff0d8}.table-hover .table-success:hover{background-color:#d0e9c6}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#d0e9c6}.table-info,.table-info>td,.table-info>th{background-color:#d9edf7}.table-hover .table-info:hover{background-color:#c4e3f3}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#c4e3f3}.table-warning,.table-warning>td,.table-warning>th{background-color:#fcf8e3}.table-hover .table-warning:hover{background-color:#faf2cc}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#faf2cc}.table-danger,.table-danger>td,.table-danger>th{background-color:#f2dede}.table-hover .table-danger:hover{background-color:#ebcccc}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#ebcccc}.thead-inverse th{color:#fff;background-color:#292b2c}.thead-default th{color:#464a4c;background-color:#eceeef}.table-inverse{color:#fff;background-color:#292b2c}.table-inverse td,.table-inverse th,.table-inverse thead th{border-color:#fff}.table-inverse.table-bordered{border:0}.table-responsive{display:block;width:100%;overflow-x:auto;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive.table-bordered{border:0}.form-control{display:block;width:100%;padding:.5rem .75rem;font-size:1rem;line-height:1.25;color:#464a4c;background-color:#fff;background-image:none;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s,-webkit-box-shadow ease-in-out .15s}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#464a4c;background-color:#fff;border-color:#5cb3fd;outline:0}.form-control::-webkit-input-placeholder{color:#636c72;opacity:1}.form-control::-moz-placeholder{color:#636c72;opacity:1}.form-control:-ms-input-placeholder{color:#636c72;opacity:1}.form-control::placeholder{color:#636c72;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#eceeef;opacity:1}.form-control:disabled{cursor:not-allowed}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#464a4c;background-color:#fff}.form-control-file,.form-control-range{display:block}.col-form-label{padding-top:calc(.5rem - 1px * 2);padding-bottom:calc(.5rem - 1px * 2);margin-bottom:0}.col-form-label-lg{padding-top:calc(.75rem - 1px * 2);padding-bottom:calc(.75rem - 1px * 2);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem - 1px * 2);padding-bottom:calc(.25rem - 1px * 2);font-size:.875rem}.col-form-legend{padding-top:.5rem;padding-bottom:.5rem;margin-bottom:0;font-size:1rem}.form-control-static{padding-top:.5rem;padding-bottom:.5rem;margin-bottom:0;line-height:1.25;border:solid transparent;border-width:1px 0}.form-control-static.form-control-lg,.form-control-static.form-control-sm,.input-group-lg>.form-control-static.form-control,.input-group-lg>.form-control-static.input-group-addon,.input-group-lg>.input-group-btn>.form-control-static.btn,.input-group-sm>.form-control-static.form-control,.input-group-sm>.form-control-static.input-group-addon,.input-group-sm>.input-group-btn>.form-control-static.btn{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-sm>.input-group-btn>select.btn:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),.input-group-sm>select.input-group-addon:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:1.8125rem}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{padding:.75rem 1.5rem;font-size:1.25rem;border-radius:.3rem}.input-group-lg>.input-group-btn>select.btn:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),.input-group-lg>select.input-group-addon:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:3.166667rem}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-check{position:relative;display:block;margin-bottom:.5rem}.form-check.disabled .form-check-label{color:#636c72;cursor:not-allowed}.form-check-label{padding-left:1.25rem;margin-bottom:0;cursor:pointer}.form-check-input{position:absolute;margin-top:.25rem;margin-left:-1.25rem}.form-check-input:only-child{position:static}.form-check-inline{display:inline-block}.form-check-inline .form-check-label{vertical-align:middle}.form-check-inline+.form-check-inline{margin-left:.75rem}.form-control-feedback{margin-top:.25rem}.form-control-danger,.form-control-success,.form-control-warning{padding-right:2.25rem;background-repeat:no-repeat;background-position:center right .5625rem;-webkit-background-size:1.125rem 1.125rem;background-size:1.125rem 1.125rem}.has-success .col-form-label,.has-success .custom-control,.has-success .form-check-label,.has-success .form-control-feedback,.has-success .form-control-label{color:#5cb85c}.has-success .form-control{border-color:#5cb85c}.has-success .input-group-addon{color:#5cb85c;border-color:#5cb85c;background-color:#eaf6ea}.has-success .form-control-success{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%235cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E")}.has-warning .col-form-label,.has-warning .custom-control,.has-warning .form-check-label,.has-warning .form-control-feedback,.has-warning .form-control-label{color:#f0ad4e}.has-warning .form-control{border-color:#f0ad4e}.has-warning .input-group-addon{color:#f0ad4e;border-color:#f0ad4e;background-color:#fff}.has-warning .form-control-warning{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23f0ad4e' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E")}.has-danger .col-form-label,.has-danger .custom-control,.has-danger .form-check-label,.has-danger .form-control-feedback,.has-danger .form-control-label{color:#d9534f}.has-danger .form-control{border-color:#d9534f}.has-danger .input-group-addon{color:#d9534f;border-color:#d9534f;background-color:#fdf7f7}.has-danger .form-control-danger{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23d9534f' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E")}.form-inline{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{width:auto}.form-inline .form-control-label{margin-bottom:0;vertical-align:middle}.form-inline .form-check{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;width:auto;margin-top:0;margin-bottom:0}.form-inline .form-check-label{padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:0}.form-inline .custom-control-indicator{position:static;display:inline-block;margin-right:.25rem;vertical-align:text-bottom}.form-inline .has-feedback .form-control-feedback{top:0}}.btn{display:inline-block;font-weight:400;line-height:1.25;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.5rem 1rem;font-size:1rem;border-radius:.25rem;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;-webkit-box-shadow:0 0 0 2px rgba(2,117,216,.25);box-shadow:0 0 0 2px rgba(2,117,216,.25)}.btn.disabled,.btn:disabled{cursor:not-allowed;opacity:.65}.btn.active,.btn:active{background-image:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#0275d8;border-color:#0275d8}.btn-primary:hover{color:#fff;background-color:#025aa5;border-color:#01549b}.btn-primary.focus,.btn-primary:focus{-webkit-box-shadow:0 0 0 2px rgba(2,117,216,.5);box-shadow:0 0 0 2px rgba(2,117,216,.5)}.btn-primary.disabled,.btn-primary:disabled{background-color:#0275d8;border-color:#0275d8}.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#025aa5;background-image:none;border-color:#01549b}.btn-secondary{color:#292b2c;background-color:#fff;border-color:#ccc}.btn-secondary:hover{color:#292b2c;background-color:#e6e6e6;border-color:#adadad}.btn-secondary.focus,.btn-secondary:focus{-webkit-box-shadow:0 0 0 2px rgba(204,204,204,.5);box-shadow:0 0 0 2px rgba(204,204,204,.5)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:#fff;border-color:#ccc}.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{color:#292b2c;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-info{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#2aabd2}.btn-info.focus,.btn-info:focus{-webkit-box-shadow:0 0 0 2px rgba(91,192,222,.5);box-shadow:0 0 0 2px rgba(91,192,222,.5)}.btn-info.disabled,.btn-info:disabled{background-color:#5bc0de;border-color:#5bc0de}.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#31b0d5;background-image:none;border-color:#2aabd2}.btn-success{color:#fff;background-color:#5cb85c;border-color:#5cb85c}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#419641}.btn-success.focus,.btn-success:focus{-webkit-box-shadow:0 0 0 2px rgba(92,184,92,.5);box-shadow:0 0 0 2px rgba(92,184,92,.5)}.btn-success.disabled,.btn-success:disabled{background-color:#5cb85c;border-color:#5cb85c}.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#449d44;background-image:none;border-color:#419641}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#f0ad4e}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#eb9316}.btn-warning.focus,.btn-warning:focus{-webkit-box-shadow:0 0 0 2px rgba(240,173,78,.5);box-shadow:0 0 0 2px rgba(240,173,78,.5)}.btn-warning.disabled,.btn-warning:disabled{background-color:#f0ad4e;border-color:#f0ad4e}.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#ec971f;background-image:none;border-color:#eb9316}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d9534f}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#c12e2a}.btn-danger.focus,.btn-danger:focus{-webkit-box-shadow:0 0 0 2px rgba(217,83,79,.5);box-shadow:0 0 0 2px rgba(217,83,79,.5)}.btn-danger.disabled,.btn-danger:disabled{background-color:#d9534f;border-color:#d9534f}.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#c9302c;background-image:none;border-color:#c12e2a}.btn-outline-primary{color:#0275d8;background-image:none;background-color:transparent;border-color:#0275d8}.btn-outline-primary:hover{color:#fff;background-color:#0275d8;border-color:#0275d8}.btn-outline-primary.focus,.btn-outline-primary:focus{-webkit-box-shadow:0 0 0 2px rgba(2,117,216,.5);box-shadow:0 0 0 2px rgba(2,117,216,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#0275d8;background-color:transparent}.btn-outline-primary.active,.btn-outline-primary:active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#0275d8;border-color:#0275d8}.btn-outline-secondary{color:#ccc;background-image:none;background-color:transparent;border-color:#ccc}.btn-outline-secondary:hover{color:#fff;background-color:#ccc;border-color:#ccc}.btn-outline-secondary.focus,.btn-outline-secondary:focus{-webkit-box-shadow:0 0 0 2px rgba(204,204,204,.5);box-shadow:0 0 0 2px rgba(204,204,204,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#ccc;background-color:transparent}.btn-outline-secondary.active,.btn-outline-secondary:active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#ccc;border-color:#ccc}.btn-outline-info{color:#5bc0de;background-image:none;background-color:transparent;border-color:#5bc0de}.btn-outline-info:hover{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-outline-info.focus,.btn-outline-info:focus{-webkit-box-shadow:0 0 0 2px rgba(91,192,222,.5);box-shadow:0 0 0 2px rgba(91,192,222,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#5bc0de;background-color:transparent}.btn-outline-info.active,.btn-outline-info:active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-outline-success{color:#5cb85c;background-image:none;background-color:transparent;border-color:#5cb85c}.btn-outline-success:hover{color:#fff;background-color:#5cb85c;border-color:#5cb85c}.btn-outline-success.focus,.btn-outline-success:focus{-webkit-box-shadow:0 0 0 2px rgba(92,184,92,.5);box-shadow:0 0 0 2px rgba(92,184,92,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#5cb85c;background-color:transparent}.btn-outline-success.active,.btn-outline-success:active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#5cb85c;border-color:#5cb85c}.btn-outline-warning{color:#f0ad4e;background-image:none;background-color:transparent;border-color:#f0ad4e}.btn-outline-warning:hover{color:#fff;background-color:#f0ad4e;border-color:#f0ad4e}.btn-outline-warning.focus,.btn-outline-warning:focus{-webkit-box-shadow:0 0 0 2px rgba(240,173,78,.5);box-shadow:0 0 0 2px rgba(240,173,78,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#f0ad4e;background-color:transparent}.btn-outline-warning.active,.btn-outline-warning:active,.show>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#f0ad4e;border-color:#f0ad4e}.btn-outline-danger{color:#d9534f;background-image:none;background-color:transparent;border-color:#d9534f}.btn-outline-danger:hover{color:#fff;background-color:#d9534f;border-color:#d9534f}.btn-outline-danger.focus,.btn-outline-danger:focus{-webkit-box-shadow:0 0 0 2px rgba(217,83,79,.5);box-shadow:0 0 0 2px rgba(217,83,79,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#d9534f;background-color:transparent}.btn-outline-danger.active,.btn-outline-danger:active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#d9534f;border-color:#d9534f}.btn-link{font-weight:400;color:#0275d8;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link:disabled{background-color:transparent}.btn-link,.btn-link:active,.btn-link:focus{border-color:transparent}.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#014c8c;text-decoration:underline;background-color:transparent}.btn-link:disabled{color:#636c72}.btn-link:disabled:focus,.btn-link:disabled:hover{text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:.75rem 1.5rem;font-size:1.25rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.show{opacity:1}.collapse{display:none}.collapse.show{display:block}tr.collapse.show{display:table-row}tbody.collapse.show{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.dropdown,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.3em;vertical-align:middle;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-left:.3em solid transparent}.dropdown-toggle:focus{outline:0}.dropup .dropdown-toggle::after{border-top:0;border-bottom:.3em solid}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#292b2c;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-divider{height:1px;margin:.5rem 0;overflow:hidden;background-color:#eceeef}.dropdown-item{display:block;width:100%;padding:3px 1.5rem;clear:both;font-weight:400;color:#292b2c;text-align:inherit;white-space:nowrap;background:0 0;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#1d1e1f;text-decoration:none;background-color:#f7f7f9}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#0275d8}.dropdown-item.disabled,.dropdown-item:disabled{color:#636c72;cursor:not-allowed;background-color:transparent}.show>.dropdown-menu{display:block}.show>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#636c72;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.dropup .dropdown-menu{top:auto;bottom:100%;margin-bottom:.125rem}.btn-group,.btn-group-vertical{position:relative;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:2}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn+.dropdown-toggle-split::after{margin-left:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:1.125rem;padding-left:1.125rem}.btn-group-vertical{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%}.input-group .form-control{position:relative;z-index:2;-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group .form-control:active,.input-group .form-control:focus,.input-group .form-control:hover{z-index:3}.input-group .form-control,.input-group-addon,.input-group-btn{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{white-space:nowrap;vertical-align:middle}.input-group-addon{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.25;color:#464a4c;text-align:center;background-color:#eceeef;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.input-group-addon.form-control-sm,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.input-group-addon.btn{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-addon.form-control-lg,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.input-group-addon.btn{padding:.75rem 1.5rem;font-size:1.25rem;border-radius:.3rem}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:not(:last-child),.input-group-addon:not(:last-child),.input-group-btn:not(:first-child)>.btn-group:not(:last-child)>.btn,.input-group-btn:not(:first-child)>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:not(:last-child)>.btn,.input-group-btn:not(:last-child)>.btn-group>.btn,.input-group-btn:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:not(:last-child){border-right:0}.input-group .form-control:not(:first-child),.input-group-addon:not(:first-child),.input-group-btn:not(:first-child)>.btn,.input-group-btn:not(:first-child)>.btn-group>.btn,.input-group-btn:not(:first-child)>.dropdown-toggle,.input-group-btn:not(:last-child)>.btn-group:not(:first-child)>.btn,.input-group-btn:not(:last-child)>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.form-control+.input-group-addon:not(:first-child){border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative;-webkit-box-flex:1;-webkit-flex:1 1 0%;-ms-flex:1 1 0%;flex:1 1 0%}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:3}.input-group-btn:not(:last-child)>.btn,.input-group-btn:not(:last-child)>.btn-group{margin-right:-1px}.input-group-btn:not(:first-child)>.btn,.input-group-btn:not(:first-child)>.btn-group{z-index:2;margin-left:-1px}.input-group-btn:not(:first-child)>.btn-group:active,.input-group-btn:not(:first-child)>.btn-group:focus,.input-group-btn:not(:first-child)>.btn-group:hover,.input-group-btn:not(:first-child)>.btn:active,.input-group-btn:not(:first-child)>.btn:focus,.input-group-btn:not(:first-child)>.btn:hover{z-index:3}.custom-control{position:relative;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;min-height:1.5rem;padding-left:1.5rem;margin-right:1rem;cursor:pointer}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-indicator{color:#fff;background-color:#0275d8}.custom-control-input:focus~.custom-control-indicator{-webkit-box-shadow:0 0 0 1px #fff,0 0 0 3px #0275d8;box-shadow:0 0 0 1px #fff,0 0 0 3px #0275d8}.custom-control-input:active~.custom-control-indicator{color:#fff;background-color:#8fcafe}.custom-control-input:disabled~.custom-control-indicator{cursor:not-allowed;background-color:#eceeef}.custom-control-input:disabled~.custom-control-description{color:#636c72;cursor:not-allowed}.custom-control-indicator{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#ddd;background-repeat:no-repeat;background-position:center center;-webkit-background-size:50% 50%;background-size:50% 50%}.custom-checkbox .custom-control-indicator{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-indicator{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-indicator{background-color:#0275d8;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-radio .custom-control-indicator{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-indicator{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-controls-stacked{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.custom-controls-stacked .custom-control{margin-bottom:.25rem}.custom-controls-stacked .custom-control+.custom-control{margin-left:0}.custom-select{display:inline-block;max-width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.25;color:#464a4c;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;-webkit-background-size:8px 10px;background-size:8px 10px;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;-moz-appearance:none;-webkit-appearance:none}.custom-select:focus{border-color:#5cb3fd;outline:0}.custom-select:focus::-ms-value{color:#464a4c;background-color:#fff}.custom-select:disabled{color:#636c72;cursor:not-allowed;background-color:#eceeef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-file{position:relative;display:inline-block;max-width:100%;height:2.5rem;margin-bottom:0;cursor:pointer}.custom-file-input{min-width:14rem;max-width:100%;height:2.5rem;margin:0;filter:alpha(opacity=0);opacity:0}.custom-file-control{position:absolute;top:0;right:0;left:0;z-index:5;height:2.5rem;padding:.5rem 1rem;line-height:1.5;color:#464a4c;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.custom-file-control:lang(en)::after{content:"Choose file..."}.custom-file-control::before{position:absolute;top:-1px;right:-1px;bottom:-1px;z-index:6;display:block;height:2.5rem;padding:.5rem 1rem;line-height:1.5;color:#464a4c;background-color:#eceeef;border:1px solid rgba(0,0,0,.15);border-radius:0 .25rem .25rem 0}.custom-file-control:lang(en)::before{content:"Browse"}.nav{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5em 1em}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#636c72;cursor:not-allowed}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-right-radius:.25rem;border-top-left-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#eceeef #eceeef #ddd}.nav-tabs .nav-link.disabled{color:#636c72;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#464a4c;background-color:#fff;border-color:#ddd #ddd #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-item.show .nav-link,.nav-pills .nav-link.active{color:#fff;cursor:default;background-color:#0275d8}.nav-fill .nav-item{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-webkit-box-flex:1;-webkit-flex:1 1 100%;-ms-flex:1 1 100%;flex:1 1 100%;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:.5rem 1rem}.navbar-brand{display:inline-block;padding-top:.25rem;padding-bottom:.25rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-text{display:inline-block;padding-top:.425rem;padding-bottom:.425rem}.navbar-toggler{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start;padding:.25rem .75rem;font-size:1.25rem;line-height:1;background:0 0;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;-webkit-background-size:100% 100%;background-size:100% 100%}.navbar-toggler-left{position:absolute;left:1rem}.navbar-toggler-right{position:absolute;right:1rem}@media (max-width:575px){.navbar-toggleable .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable>.container{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-toggleable{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable>.container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable .navbar-collapse{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable .navbar-toggler{display:none}}@media (max-width:767px){.navbar-toggleable-sm .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable-sm>.container{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-toggleable-sm{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-sm .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable-sm>.container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-sm .navbar-collapse{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable-sm .navbar-toggler{display:none}}@media (max-width:991px){.navbar-toggleable-md .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable-md>.container{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-toggleable-md{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-md .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable-md>.container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-md .navbar-collapse{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable-md .navbar-toggler{display:none}}@media (max-width:1199px){.navbar-toggleable-lg .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable-lg>.container{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-toggleable-lg{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-lg .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable-lg>.container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-lg .navbar-collapse{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable-lg .navbar-toggler{display:none}}.navbar-toggleable-xl{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-xl .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable-xl>.container{padding-right:0;padding-left:0}.navbar-toggleable-xl .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable-xl>.container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-xl .navbar-collapse{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable-xl .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-toggler{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover,.navbar-light .navbar-toggler:focus,.navbar-light .navbar-toggler:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.open,.navbar-light .navbar-nav .open>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-toggler{color:#fff}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-toggler:focus,.navbar-inverse .navbar-toggler:hover{color:#fff}.navbar-inverse .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-inverse .navbar-nav .nav-link:focus,.navbar-inverse .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-inverse .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-inverse .navbar-nav .active>.nav-link,.navbar-inverse .navbar-nav .nav-link.active,.navbar-inverse .navbar-nav .nav-link.open,.navbar-inverse .navbar-nav .open>.nav-link{color:#fff}.navbar-inverse .navbar-toggler{border-color:rgba(255,255,255,.1)}.navbar-inverse .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E")}.navbar-inverse .navbar-text{color:rgba(255,255,255,.5)}.card{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;background-color:#fff;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card-block{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card>.list-group:first-child .list-group-item:first-child{border-top-right-radius:.25rem;border-top-left-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:#f7f7f9;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:#f7f7f9;border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-primary{background-color:#0275d8;border-color:#0275d8}.card-primary .card-footer,.card-primary .card-header{background-color:transparent}.card-success{background-color:#5cb85c;border-color:#5cb85c}.card-success .card-footer,.card-success .card-header{background-color:transparent}.card-info{background-color:#5bc0de;border-color:#5bc0de}.card-info .card-footer,.card-info .card-header{background-color:transparent}.card-warning{background-color:#f0ad4e;border-color:#f0ad4e}.card-warning .card-footer,.card-warning .card-header{background-color:transparent}.card-danger{background-color:#d9534f;border-color:#d9534f}.card-danger .card-footer,.card-danger .card-header{background-color:transparent}.card-outline-primary{background-color:transparent;border-color:#0275d8}.card-outline-secondary{background-color:transparent;border-color:#ccc}.card-outline-info{background-color:transparent;border-color:#5bc0de}.card-outline-success{background-color:transparent;border-color:#5cb85c}.card-outline-warning{background-color:transparent;border-color:#f0ad4e}.card-outline-danger{background-color:transparent;border-color:#d9534f}.card-inverse{color:rgba(255,255,255,.65)}.card-inverse .card-footer,.card-inverse .card-header{background-color:transparent;border-color:rgba(255,255,255,.2)}.card-inverse .card-blockquote,.card-inverse .card-footer,.card-inverse .card-header,.card-inverse .card-title{color:#fff}.card-inverse .card-blockquote .blockquote-footer,.card-inverse .card-link,.card-inverse .card-subtitle,.card-inverse .card-text{color:rgba(255,255,255,.65)}.card-inverse .card-link:focus,.card-inverse .card-link:hover{color:#fff}.card-blockquote{padding:0;margin-bottom:0;border-left:0}.card-img{border-radius:calc(.25rem - 1px)}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img-top{border-top-right-radius:calc(.25rem - 1px);border-top-left-radius:calc(.25rem - 1px)}.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}@media (min-width:576px){.card-deck{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-deck .card{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex:1 0 0%;-ms-flex:1 0 0%;flex:1 0 0%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.card-deck .card:not(:first-child){margin-left:15px}.card-deck .card:not(:last-child){margin-right:15px}}@media (min-width:576px){.card-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group .card{-webkit-box-flex:1;-webkit-flex:1 0 0%;-ms-flex:1 0 0%;flex:1 0 0%}.card-group .card+.card{margin-left:0;border-left:0}.card-group .card:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.card-group .card:first-child .card-img-top{border-top-right-radius:0}.card-group .card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group .card:last-child{border-bottom-left-radius:0;border-top-left-radius:0}.card-group .card:last-child .card-img-top{border-top-left-radius:0}.card-group .card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group .card:not(:first-child):not(:last-child){border-radius:0}.card-group .card:not(:first-child):not(:last-child) .card-img-bottom,.card-group .card:not(:first-child):not(:last-child) .card-img-top{border-radius:0}}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%;margin-bottom:.75rem}}.breadcrumb{padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#eceeef;border-radius:.25rem}.breadcrumb::after{display:block;content:"";clear:both}.breadcrumb-item{float:left}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;padding-left:.5rem;color:#636c72;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#636c72}.pagination{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-item:first-child .page-link{margin-left:0;border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.page-item:last-child .page-link{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.page-item.active .page-link{z-index:2;color:#fff;background-color:#0275d8;border-color:#0275d8}.page-item.disabled .page-link{color:#636c72;pointer-events:none;cursor:not-allowed;background-color:#fff;border-color:#ddd}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#0275d8;background-color:#fff;border:1px solid #ddd}.page-link:focus,.page-link:hover{color:#014c8c;text-decoration:none;background-color:#eceeef;border-color:#ddd}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-bottom-left-radius:.3rem;border-top-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-bottom-right-radius:.3rem;border-top-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-bottom-left-radius:.2rem;border-top-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-bottom-right-radius:.2rem;border-top-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-default{background-color:#636c72}.badge-default[href]:focus,.badge-default[href]:hover{background-color:#4b5257}.badge-primary{background-color:#0275d8}.badge-primary[href]:focus,.badge-primary[href]:hover{background-color:#025aa5}.badge-success{background-color:#5cb85c}.badge-success[href]:focus,.badge-success[href]:hover{background-color:#449d44}.badge-info{background-color:#5bc0de}.badge-info[href]:focus,.badge-info[href]:hover{background-color:#31b0d5}.badge-warning{background-color:#f0ad4e}.badge-warning[href]:focus,.badge-warning[href]:hover{background-color:#ec971f}.badge-danger{background-color:#d9534f}.badge-danger[href]:focus,.badge-danger[href]:hover{background-color:#c9302c}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#eceeef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-hr{border-top-color:#d0d5d8}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible .close{position:relative;top:-.75rem;right:-1.25rem;padding:.75rem 1.25rem;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d0e9c6;color:#3c763d}.alert-success hr{border-top-color:#c1e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bcdff1;color:#31708f}.alert-info hr{border-top-color:#a6d5ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faf2cc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7ecb5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebcccc;color:#a94442}.alert-danger hr{border-top-color:#e4b9b9}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;overflow:hidden;font-size:.75rem;line-height:1rem;text-align:center;background-color:#eceeef;border-radius:.25rem}.progress-bar{height:1rem;color:#fff;background-color:#0275d8}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:1rem 1rem;background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;-o-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start}.media-body{-webkit-box-flex:1;-webkit-flex:1 1 0%;-ms-flex:1 1 0%;flex:1 1 0%}.list-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#464a4c;text-align:inherit}.list-group-item-action .list-group-item-heading{color:#292b2c}.list-group-item-action:focus,.list-group-item-action:hover{color:#464a4c;text-decoration:none;background-color:#f7f7f9}.list-group-item-action:active{color:#292b2c;background-color:#eceeef}.list-group-item{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-right-radius:.25rem;border-top-left-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#636c72;cursor:not-allowed;background-color:#fff}.list-group-item.disabled .list-group-item-heading,.list-group-item:disabled .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item:disabled .list-group-item-text{color:#636c72}.list-group-item.active{z-index:2;color:#fff;background-color:#0275d8;border-color:#0275d8}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text{color:#daeeff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active{color:#fff;background-color:#a94442;border-color:#a94442}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.75}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out,-o-transform .3s ease-out;-webkit-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.show .modal-dialog{-webkit-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:15px;border-bottom:1px solid #eceeef}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;padding:15px}.modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end;padding:15px;border-top:1px solid #eceeef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:30px auto}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip.bs-tether-element-attached-bottom,.tooltip.tooltip-top{padding:5px 0;margin-top:-3px}.tooltip.bs-tether-element-attached-bottom .tooltip-inner::before,.tooltip.tooltip-top .tooltip-inner::before{bottom:0;left:50%;margin-left:-5px;content:"";border-width:5px 5px 0;border-top-color:#000}.tooltip.bs-tether-element-attached-left,.tooltip.tooltip-right{padding:0 5px;margin-left:3px}.tooltip.bs-tether-element-attached-left .tooltip-inner::before,.tooltip.tooltip-right .tooltip-inner::before{top:50%;left:0;margin-top:-5px;content:"";border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.bs-tether-element-attached-top,.tooltip.tooltip-bottom{padding:5px 0;margin-top:3px}.tooltip.bs-tether-element-attached-top .tooltip-inner::before,.tooltip.tooltip-bottom .tooltip-inner::before{top:0;left:50%;margin-left:-5px;content:"";border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bs-tether-element-attached-right,.tooltip.tooltip-left{padding:0 5px;margin-left:-3px}.tooltip.bs-tether-element-attached-right .tooltip-inner::before,.tooltip.tooltip-left .tooltip-inner::before{top:50%;right:0;margin-top:-5px;content:"";border-width:5px 0 5px 5px;border-left-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.tooltip-inner::before{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;padding:1px;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;font-size:.875rem;word-wrap:break-word;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover.bs-tether-element-attached-bottom,.popover.popover-top{margin-top:-10px}.popover.bs-tether-element-attached-bottom::after,.popover.bs-tether-element-attached-bottom::before,.popover.popover-top::after,.popover.popover-top::before{left:50%;border-bottom-width:0}.popover.bs-tether-element-attached-bottom::before,.popover.popover-top::before{bottom:-11px;margin-left:-11px;border-top-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-bottom::after,.popover.popover-top::after{bottom:-10px;margin-left:-10px;border-top-color:#fff}.popover.bs-tether-element-attached-left,.popover.popover-right{margin-left:10px}.popover.bs-tether-element-attached-left::after,.popover.bs-tether-element-attached-left::before,.popover.popover-right::after,.popover.popover-right::before{top:50%;border-left-width:0}.popover.bs-tether-element-attached-left::before,.popover.popover-right::before{left:-11px;margin-top:-11px;border-right-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-left::after,.popover.popover-right::after{left:-10px;margin-top:-10px;border-right-color:#fff}.popover.bs-tether-element-attached-top,.popover.popover-bottom{margin-top:10px}.popover.bs-tether-element-attached-top::after,.popover.bs-tether-element-attached-top::before,.popover.popover-bottom::after,.popover.popover-bottom::before{left:50%;border-top-width:0}.popover.bs-tether-element-attached-top::before,.popover.popover-bottom::before{top:-11px;margin-left:-11px;border-bottom-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-top::after,.popover.popover-bottom::after{top:-10px;margin-left:-10px;border-bottom-color:#f7f7f7}.popover.bs-tether-element-attached-top .popover-title::before,.popover.popover-bottom .popover-title::before{position:absolute;top:0;left:50%;display:block;width:20px;margin-left:-10px;content:"";border-bottom:1px solid #f7f7f7}.popover.bs-tether-element-attached-right,.popover.popover-left{margin-left:-10px}.popover.bs-tether-element-attached-right::after,.popover.bs-tether-element-attached-right::before,.popover.popover-left::after,.popover.popover-left::before{top:50%;border-right-width:0}.popover.bs-tether-element-attached-right::before,.popover.popover-left::before{right:-11px;margin-top:-11px;border-left-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-right::after,.popover.popover-left::after{right:-10px;margin-top:-10px;border-left-color:#fff}.popover-title{padding:8px 14px;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-right-radius:calc(.3rem - 1px);border-top-left-radius:calc(.3rem - 1px)}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover::after,.popover::before{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover::before{content:"";border-width:11px}.popover::after{content:"";border-width:10px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;width:100%}@media (-webkit-transform-3d){.carousel-item{-webkit-transition:-webkit-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out,-o-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}}@supports ((-webkit-transform:translate3d(0,0,0)) or (transform:translate3d(0,0,0))){.carousel-item{-webkit-transition:-webkit-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out,-o-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}@media (-webkit-transform-3d){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@supports ((-webkit-transform:translate3d(0,0,0)) or (transform:translate3d(0,0,0))){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;-webkit-background-size:100% 100%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M4 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M1.5 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;max-width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-faded{background-color:#f7f7f7}.bg-primary{background-color:#0275d8!important}a.bg-primary:focus,a.bg-primary:hover{background-color:#025aa5!important}.bg-success{background-color:#5cb85c!important}a.bg-success:focus,a.bg-success:hover{background-color:#449d44!important}.bg-info{background-color:#5bc0de!important}a.bg-info:focus,a.bg-info:hover{background-color:#31b0d5!important}.bg-warning{background-color:#f0ad4e!important}a.bg-warning:focus,a.bg-warning:hover{background-color:#ec971f!important}.bg-danger{background-color:#d9534f!important}a.bg-danger:focus,a.bg-danger:hover{background-color:#c9302c!important}.bg-inverse{background-color:#292b2c!important}a.bg-inverse:focus,a.bg-inverse:hover{background-color:#101112!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.rounded{border-radius:.25rem}.rounded-top{border-top-right-radius:.25rem;border-top-left-radius:.25rem}.rounded-right{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.rounded-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-left{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.rounded-circle{border-radius:50%}.rounded-0{border-radius:0}.clearfix::after{display:block;content:"";clear:both}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-cell{display:table-cell!important}.d-flex{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-webkit-inline-box!important;display:-webkit-inline-flex!important;display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-webkit-inline-box!important;display:-webkit-inline-flex!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-webkit-inline-box!important;display:-webkit-inline-flex!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-webkit-inline-box!important;display:-webkit-inline-flex!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-webkit-box!important;display:-webkit-flex!important;display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-webkit-inline-box!important;display:-webkit-inline-flex!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}.flex-first{-webkit-box-ordinal-group:0;-webkit-order:-1;-ms-flex-order:-1;order:-1}.flex-last{-webkit-box-ordinal-group:2;-webkit-order:1;-ms-flex-order:1;order:1}.flex-unordered{-webkit-box-ordinal-group:1;-webkit-order:0;-ms-flex-order:0;order:0}.flex-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-webkit-flex-direction:row!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-webkit-flex-direction:column!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:row-reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:column-reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-webkit-flex-wrap:wrap!important;-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-webkit-flex-wrap:nowrap!important;-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-webkit-flex-wrap:wrap-reverse!important;-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-start{-webkit-box-pack:start!important;-webkit-justify-content:flex-start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-webkit-box-pack:end!important;-webkit-justify-content:flex-end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-webkit-box-pack:center!important;-webkit-justify-content:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-webkit-justify-content:space-around!important;-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-webkit-box-align:start!important;-webkit-align-items:flex-start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-webkit-box-align:end!important;-webkit-align-items:flex-end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-webkit-box-align:center!important;-webkit-align-items:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-webkit-box-align:baseline!important;-webkit-align-items:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-webkit-box-align:stretch!important;-webkit-align-items:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-webkit-align-content:flex-start!important;-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-webkit-align-content:flex-end!important;-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-webkit-align-content:center!important;-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-webkit-align-content:space-between!important;-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-webkit-align-content:space-around!important;-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-webkit-align-content:stretch!important;-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-first{-webkit-box-ordinal-group:0;-webkit-order:-1;-ms-flex-order:-1;order:-1}.flex-sm-last{-webkit-box-ordinal-group:2;-webkit-order:1;-ms-flex-order:1;order:1}.flex-sm-unordered{-webkit-box-ordinal-group:1;-webkit-order:0;-ms-flex-order:0;order:0}.flex-sm-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-webkit-flex-direction:row!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-webkit-flex-direction:column!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:row-reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:column-reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-webkit-flex-wrap:wrap!important;-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-webkit-flex-wrap:nowrap!important;-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-webkit-flex-wrap:wrap-reverse!important;-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-sm-start{-webkit-box-pack:start!important;-webkit-justify-content:flex-start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-webkit-box-pack:end!important;-webkit-justify-content:flex-end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-webkit-box-pack:center!important;-webkit-justify-content:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-webkit-justify-content:space-around!important;-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-webkit-box-align:start!important;-webkit-align-items:flex-start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-webkit-box-align:end!important;-webkit-align-items:flex-end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-webkit-box-align:center!important;-webkit-align-items:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-webkit-box-align:baseline!important;-webkit-align-items:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-webkit-box-align:stretch!important;-webkit-align-items:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-webkit-align-content:flex-start!important;-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-webkit-align-content:flex-end!important;-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-webkit-align-content:center!important;-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-webkit-align-content:space-between!important;-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-webkit-align-content:space-around!important;-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-webkit-align-content:stretch!important;-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-sm-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-sm-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-first{-webkit-box-ordinal-group:0;-webkit-order:-1;-ms-flex-order:-1;order:-1}.flex-md-last{-webkit-box-ordinal-group:2;-webkit-order:1;-ms-flex-order:1;order:1}.flex-md-unordered{-webkit-box-ordinal-group:1;-webkit-order:0;-ms-flex-order:0;order:0}.flex-md-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-webkit-flex-direction:row!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-webkit-flex-direction:column!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:row-reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:column-reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-webkit-flex-wrap:wrap!important;-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-webkit-flex-wrap:nowrap!important;-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-webkit-flex-wrap:wrap-reverse!important;-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-md-start{-webkit-box-pack:start!important;-webkit-justify-content:flex-start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-webkit-box-pack:end!important;-webkit-justify-content:flex-end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-webkit-box-pack:center!important;-webkit-justify-content:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-webkit-justify-content:space-around!important;-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-webkit-box-align:start!important;-webkit-align-items:flex-start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-webkit-box-align:end!important;-webkit-align-items:flex-end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-webkit-box-align:center!important;-webkit-align-items:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-webkit-box-align:baseline!important;-webkit-align-items:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-webkit-box-align:stretch!important;-webkit-align-items:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-webkit-align-content:flex-start!important;-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-webkit-align-content:flex-end!important;-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-webkit-align-content:center!important;-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-webkit-align-content:space-between!important;-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-webkit-align-content:space-around!important;-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-webkit-align-content:stretch!important;-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-md-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-md-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-first{-webkit-box-ordinal-group:0;-webkit-order:-1;-ms-flex-order:-1;order:-1}.flex-lg-last{-webkit-box-ordinal-group:2;-webkit-order:1;-ms-flex-order:1;order:1}.flex-lg-unordered{-webkit-box-ordinal-group:1;-webkit-order:0;-ms-flex-order:0;order:0}.flex-lg-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-webkit-flex-direction:row!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-webkit-flex-direction:column!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:row-reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:column-reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-webkit-flex-wrap:wrap!important;-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-webkit-flex-wrap:nowrap!important;-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-webkit-flex-wrap:wrap-reverse!important;-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-lg-start{-webkit-box-pack:start!important;-webkit-justify-content:flex-start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-webkit-box-pack:end!important;-webkit-justify-content:flex-end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-webkit-box-pack:center!important;-webkit-justify-content:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-webkit-justify-content:space-around!important;-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-webkit-box-align:start!important;-webkit-align-items:flex-start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-webkit-box-align:end!important;-webkit-align-items:flex-end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-webkit-box-align:center!important;-webkit-align-items:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-webkit-box-align:baseline!important;-webkit-align-items:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-webkit-box-align:stretch!important;-webkit-align-items:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-webkit-align-content:flex-start!important;-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-webkit-align-content:flex-end!important;-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-webkit-align-content:center!important;-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-webkit-align-content:space-between!important;-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-webkit-align-content:space-around!important;-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-webkit-align-content:stretch!important;-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-lg-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-lg-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-first{-webkit-box-ordinal-group:0;-webkit-order:-1;-ms-flex-order:-1;order:-1}.flex-xl-last{-webkit-box-ordinal-group:2;-webkit-order:1;-ms-flex-order:1;order:1}.flex-xl-unordered{-webkit-box-ordinal-group:1;-webkit-order:0;-ms-flex-order:0;order:0}.flex-xl-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-webkit-flex-direction:row!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-webkit-flex-direction:column!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:row-reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-webkit-flex-direction:column-reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-webkit-flex-wrap:wrap!important;-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-webkit-flex-wrap:nowrap!important;-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-webkit-flex-wrap:wrap-reverse!important;-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-xl-start{-webkit-box-pack:start!important;-webkit-justify-content:flex-start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-webkit-box-pack:end!important;-webkit-justify-content:flex-end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-webkit-box-pack:center!important;-webkit-justify-content:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-webkit-justify-content:space-around!important;-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-webkit-box-align:start!important;-webkit-align-items:flex-start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-webkit-box-align:end!important;-webkit-align-items:flex-end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-webkit-box-align:center!important;-webkit-align-items:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-webkit-box-align:baseline!important;-webkit-align-items:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-webkit-box-align:stretch!important;-webkit-align-items:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-webkit-align-content:flex-start!important;-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-webkit-align-content:flex-end!important;-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-webkit-align-content:center!important;-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-webkit-align-content:space-between!important;-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-webkit-align-content:space-around!important;-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-webkit-align-content:stretch!important;-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-xl-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-xl-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1030}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0 0!important}.mt-0{margin-top:0!important}.mr-0{margin-right:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mx-0{margin-right:0!important;margin-left:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.m-1{margin:.25rem .25rem!important}.mt-1{margin-top:.25rem!important}.mr-1{margin-right:.25rem!important}.mb-1{margin-bottom:.25rem!important}.ml-1{margin-left:.25rem!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-2{margin:.5rem .5rem!important}.mt-2{margin-top:.5rem!important}.mr-2{margin-right:.5rem!important}.mb-2{margin-bottom:.5rem!important}.ml-2{margin-left:.5rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-3{margin:1rem 1rem!important}.mt-3{margin-top:1rem!important}.mr-3{margin-right:1rem!important}.mb-3{margin-bottom:1rem!important}.ml-3{margin-left:1rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-4{margin:1.5rem 1.5rem!important}.mt-4{margin-top:1.5rem!important}.mr-4{margin-right:1.5rem!important}.mb-4{margin-bottom:1.5rem!important}.ml-4{margin-left:1.5rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-5{margin:3rem 3rem!important}.mt-5{margin-top:3rem!important}.mr-5{margin-right:3rem!important}.mb-5{margin-bottom:3rem!important}.ml-5{margin-left:3rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-0{padding:0 0!important}.pt-0{padding-top:0!important}.pr-0{padding-right:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.px-0{padding-right:0!important;padding-left:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.p-1{padding:.25rem .25rem!important}.pt-1{padding-top:.25rem!important}.pr-1{padding-right:.25rem!important}.pb-1{padding-bottom:.25rem!important}.pl-1{padding-left:.25rem!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-2{padding:.5rem .5rem!important}.pt-2{padding-top:.5rem!important}.pr-2{padding-right:.5rem!important}.pb-2{padding-bottom:.5rem!important}.pl-2{padding-left:.5rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-3{padding:1rem 1rem!important}.pt-3{padding-top:1rem!important}.pr-3{padding-right:1rem!important}.pb-3{padding-bottom:1rem!important}.pl-3{padding-left:1rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-4{padding:1.5rem 1.5rem!important}.pt-4{padding-top:1.5rem!important}.pr-4{padding-right:1.5rem!important}.pb-4{padding-bottom:1.5rem!important}.pl-4{padding-left:1.5rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-5{padding:3rem 3rem!important}.pt-5{padding-top:3rem!important}.pr-5{padding-right:3rem!important}.pb-5{padding-bottom:3rem!important}.pl-5{padding-left:3rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-auto{margin:auto!important}.mt-auto{margin-top:auto!important}.mr-auto{margin-right:auto!important}.mb-auto{margin-bottom:auto!important}.ml-auto{margin-left:auto!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}@media (min-width:576px){.m-sm-0{margin:0 0!important}.mt-sm-0{margin-top:0!important}.mr-sm-0{margin-right:0!important}.mb-sm-0{margin-bottom:0!important}.ml-sm-0{margin-left:0!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.m-sm-1{margin:.25rem .25rem!important}.mt-sm-1{margin-top:.25rem!important}.mr-sm-1{margin-right:.25rem!important}.mb-sm-1{margin-bottom:.25rem!important}.ml-sm-1{margin-left:.25rem!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-sm-2{margin:.5rem .5rem!important}.mt-sm-2{margin-top:.5rem!important}.mr-sm-2{margin-right:.5rem!important}.mb-sm-2{margin-bottom:.5rem!important}.ml-sm-2{margin-left:.5rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-sm-3{margin:1rem 1rem!important}.mt-sm-3{margin-top:1rem!important}.mr-sm-3{margin-right:1rem!important}.mb-sm-3{margin-bottom:1rem!important}.ml-sm-3{margin-left:1rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-sm-4{margin:1.5rem 1.5rem!important}.mt-sm-4{margin-top:1.5rem!important}.mr-sm-4{margin-right:1.5rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.ml-sm-4{margin-left:1.5rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-sm-5{margin:3rem 3rem!important}.mt-sm-5{margin-top:3rem!important}.mr-sm-5{margin-right:3rem!important}.mb-sm-5{margin-bottom:3rem!important}.ml-sm-5{margin-left:3rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-sm-0{padding:0 0!important}.pt-sm-0{padding-top:0!important}.pr-sm-0{padding-right:0!important}.pb-sm-0{padding-bottom:0!important}.pl-sm-0{padding-left:0!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.p-sm-1{padding:.25rem .25rem!important}.pt-sm-1{padding-top:.25rem!important}.pr-sm-1{padding-right:.25rem!important}.pb-sm-1{padding-bottom:.25rem!important}.pl-sm-1{padding-left:.25rem!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-sm-2{padding:.5rem .5rem!important}.pt-sm-2{padding-top:.5rem!important}.pr-sm-2{padding-right:.5rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pl-sm-2{padding-left:.5rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-sm-3{padding:1rem 1rem!important}.pt-sm-3{padding-top:1rem!important}.pr-sm-3{padding-right:1rem!important}.pb-sm-3{padding-bottom:1rem!important}.pl-sm-3{padding-left:1rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-sm-4{padding:1.5rem 1.5rem!important}.pt-sm-4{padding-top:1.5rem!important}.pr-sm-4{padding-right:1.5rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pl-sm-4{padding-left:1.5rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-sm-5{padding:3rem 3rem!important}.pt-sm-5{padding-top:3rem!important}.pr-sm-5{padding-right:3rem!important}.pb-sm-5{padding-bottom:3rem!important}.pl-sm-5{padding-left:3rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto{margin-top:auto!important}.mr-sm-auto{margin-right:auto!important}.mb-sm-auto{margin-bottom:auto!important}.ml-sm-auto{margin-left:auto!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}}@media (min-width:768px){.m-md-0{margin:0 0!important}.mt-md-0{margin-top:0!important}.mr-md-0{margin-right:0!important}.mb-md-0{margin-bottom:0!important}.ml-md-0{margin-left:0!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.m-md-1{margin:.25rem .25rem!important}.mt-md-1{margin-top:.25rem!important}.mr-md-1{margin-right:.25rem!important}.mb-md-1{margin-bottom:.25rem!important}.ml-md-1{margin-left:.25rem!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-md-2{margin:.5rem .5rem!important}.mt-md-2{margin-top:.5rem!important}.mr-md-2{margin-right:.5rem!important}.mb-md-2{margin-bottom:.5rem!important}.ml-md-2{margin-left:.5rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-md-3{margin:1rem 1rem!important}.mt-md-3{margin-top:1rem!important}.mr-md-3{margin-right:1rem!important}.mb-md-3{margin-bottom:1rem!important}.ml-md-3{margin-left:1rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-md-4{margin:1.5rem 1.5rem!important}.mt-md-4{margin-top:1.5rem!important}.mr-md-4{margin-right:1.5rem!important}.mb-md-4{margin-bottom:1.5rem!important}.ml-md-4{margin-left:1.5rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-md-5{margin:3rem 3rem!important}.mt-md-5{margin-top:3rem!important}.mr-md-5{margin-right:3rem!important}.mb-md-5{margin-bottom:3rem!important}.ml-md-5{margin-left:3rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-md-0{padding:0 0!important}.pt-md-0{padding-top:0!important}.pr-md-0{padding-right:0!important}.pb-md-0{padding-bottom:0!important}.pl-md-0{padding-left:0!important}.px-md-0{padding-right:0!important;padding-left:0!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.p-md-1{padding:.25rem .25rem!important}.pt-md-1{padding-top:.25rem!important}.pr-md-1{padding-right:.25rem!important}.pb-md-1{padding-bottom:.25rem!important}.pl-md-1{padding-left:.25rem!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-md-2{padding:.5rem .5rem!important}.pt-md-2{padding-top:.5rem!important}.pr-md-2{padding-right:.5rem!important}.pb-md-2{padding-bottom:.5rem!important}.pl-md-2{padding-left:.5rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-md-3{padding:1rem 1rem!important}.pt-md-3{padding-top:1rem!important}.pr-md-3{padding-right:1rem!important}.pb-md-3{padding-bottom:1rem!important}.pl-md-3{padding-left:1rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-md-4{padding:1.5rem 1.5rem!important}.pt-md-4{padding-top:1.5rem!important}.pr-md-4{padding-right:1.5rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pl-md-4{padding-left:1.5rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-md-5{padding:3rem 3rem!important}.pt-md-5{padding-top:3rem!important}.pr-md-5{padding-right:3rem!important}.pb-md-5{padding-bottom:3rem!important}.pl-md-5{padding-left:3rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto{margin-top:auto!important}.mr-md-auto{margin-right:auto!important}.mb-md-auto{margin-bottom:auto!important}.ml-md-auto{margin-left:auto!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}}@media (min-width:992px){.m-lg-0{margin:0 0!important}.mt-lg-0{margin-top:0!important}.mr-lg-0{margin-right:0!important}.mb-lg-0{margin-bottom:0!important}.ml-lg-0{margin-left:0!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.m-lg-1{margin:.25rem .25rem!important}.mt-lg-1{margin-top:.25rem!important}.mr-lg-1{margin-right:.25rem!important}.mb-lg-1{margin-bottom:.25rem!important}.ml-lg-1{margin-left:.25rem!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-lg-2{margin:.5rem .5rem!important}.mt-lg-2{margin-top:.5rem!important}.mr-lg-2{margin-right:.5rem!important}.mb-lg-2{margin-bottom:.5rem!important}.ml-lg-2{margin-left:.5rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-lg-3{margin:1rem 1rem!important}.mt-lg-3{margin-top:1rem!important}.mr-lg-3{margin-right:1rem!important}.mb-lg-3{margin-bottom:1rem!important}.ml-lg-3{margin-left:1rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-lg-4{margin:1.5rem 1.5rem!important}.mt-lg-4{margin-top:1.5rem!important}.mr-lg-4{margin-right:1.5rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.ml-lg-4{margin-left:1.5rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-lg-5{margin:3rem 3rem!important}.mt-lg-5{margin-top:3rem!important}.mr-lg-5{margin-right:3rem!important}.mb-lg-5{margin-bottom:3rem!important}.ml-lg-5{margin-left:3rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-lg-0{padding:0 0!important}.pt-lg-0{padding-top:0!important}.pr-lg-0{padding-right:0!important}.pb-lg-0{padding-bottom:0!important}.pl-lg-0{padding-left:0!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.p-lg-1{padding:.25rem .25rem!important}.pt-lg-1{padding-top:.25rem!important}.pr-lg-1{padding-right:.25rem!important}.pb-lg-1{padding-bottom:.25rem!important}.pl-lg-1{padding-left:.25rem!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-lg-2{padding:.5rem .5rem!important}.pt-lg-2{padding-top:.5rem!important}.pr-lg-2{padding-right:.5rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pl-lg-2{padding-left:.5rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-lg-3{padding:1rem 1rem!important}.pt-lg-3{padding-top:1rem!important}.pr-lg-3{padding-right:1rem!important}.pb-lg-3{padding-bottom:1rem!important}.pl-lg-3{padding-left:1rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-lg-4{padding:1.5rem 1.5rem!important}.pt-lg-4{padding-top:1.5rem!important}.pr-lg-4{padding-right:1.5rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pl-lg-4{padding-left:1.5rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-lg-5{padding:3rem 3rem!important}.pt-lg-5{padding-top:3rem!important}.pr-lg-5{padding-right:3rem!important}.pb-lg-5{padding-bottom:3rem!important}.pl-lg-5{padding-left:3rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto{margin-top:auto!important}.mr-lg-auto{margin-right:auto!important}.mb-lg-auto{margin-bottom:auto!important}.ml-lg-auto{margin-left:auto!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0 0!important}.mt-xl-0{margin-top:0!important}.mr-xl-0{margin-right:0!important}.mb-xl-0{margin-bottom:0!important}.ml-xl-0{margin-left:0!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.m-xl-1{margin:.25rem .25rem!important}.mt-xl-1{margin-top:.25rem!important}.mr-xl-1{margin-right:.25rem!important}.mb-xl-1{margin-bottom:.25rem!important}.ml-xl-1{margin-left:.25rem!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-xl-2{margin:.5rem .5rem!important}.mt-xl-2{margin-top:.5rem!important}.mr-xl-2{margin-right:.5rem!important}.mb-xl-2{margin-bottom:.5rem!important}.ml-xl-2{margin-left:.5rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-xl-3{margin:1rem 1rem!important}.mt-xl-3{margin-top:1rem!important}.mr-xl-3{margin-right:1rem!important}.mb-xl-3{margin-bottom:1rem!important}.ml-xl-3{margin-left:1rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-xl-4{margin:1.5rem 1.5rem!important}.mt-xl-4{margin-top:1.5rem!important}.mr-xl-4{margin-right:1.5rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.ml-xl-4{margin-left:1.5rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-xl-5{margin:3rem 3rem!important}.mt-xl-5{margin-top:3rem!important}.mr-xl-5{margin-right:3rem!important}.mb-xl-5{margin-bottom:3rem!important}.ml-xl-5{margin-left:3rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-xl-0{padding:0 0!important}.pt-xl-0{padding-top:0!important}.pr-xl-0{padding-right:0!important}.pb-xl-0{padding-bottom:0!important}.pl-xl-0{padding-left:0!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.p-xl-1{padding:.25rem .25rem!important}.pt-xl-1{padding-top:.25rem!important}.pr-xl-1{padding-right:.25rem!important}.pb-xl-1{padding-bottom:.25rem!important}.pl-xl-1{padding-left:.25rem!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-xl-2{padding:.5rem .5rem!important}.pt-xl-2{padding-top:.5rem!important}.pr-xl-2{padding-right:.5rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pl-xl-2{padding-left:.5rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-xl-3{padding:1rem 1rem!important}.pt-xl-3{padding-top:1rem!important}.pr-xl-3{padding-right:1rem!important}.pb-xl-3{padding-bottom:1rem!important}.pl-xl-3{padding-left:1rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-xl-4{padding:1.5rem 1.5rem!important}.pt-xl-4{padding-top:1.5rem!important}.pr-xl-4{padding-right:1.5rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pl-xl-4{padding-left:1.5rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-xl-5{padding:3rem 3rem!important}.pt-xl-5{padding-top:3rem!important}.pr-xl-5{padding-right:3rem!important}.pb-xl-5{padding-bottom:3rem!important}.pl-xl-5{padding-left:3rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto{margin-top:auto!important}.mr-xl-auto{margin-right:auto!important}.mb-xl-auto{margin-bottom:auto!important}.ml-xl-auto{margin-left:auto!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-normal{font-weight:400}.font-weight-bold{font-weight:700}.font-italic{font-style:italic}.text-white{color:#fff!important}.text-muted{color:#636c72!important}a.text-muted:focus,a.text-muted:hover{color:#4b5257!important}.text-primary{color:#0275d8!important}a.text-primary:focus,a.text-primary:hover{color:#025aa5!important}.text-success{color:#5cb85c!important}a.text-success:focus,a.text-success:hover{color:#449d44!important}.text-info{color:#5bc0de!important}a.text-info:focus,a.text-info:hover{color:#31b0d5!important}.text-warning{color:#f0ad4e!important}a.text-warning:focus,a.text-warning:hover{color:#ec971f!important}.text-danger{color:#d9534f!important}a.text-danger:focus,a.text-danger:hover{color:#c9302c!important}.text-gray-dark{color:#292b2c!important}a.text-gray-dark:focus,a.text-gray-dark:hover{color:#101112!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.invisible{visibility:hidden!important}.hidden-xs-up{display:none!important}@media (max-width:575px){.hidden-xs-down{display:none!important}}@media (min-width:576px){.hidden-sm-up{display:none!important}}@media (max-width:767px){.hidden-sm-down{display:none!important}}@media (min-width:768px){.hidden-md-up{display:none!important}}@media (max-width:991px){.hidden-md-down{display:none!important}}@media (min-width:992px){.hidden-lg-up{display:none!important}}@media (max-width:1199px){.hidden-lg-down{display:none!important}}@media (min-width:1200px){.hidden-xl-up{display:none!important}}.hidden-xl-down{display:none!important}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}/*# sourceMappingURL=bootstrap.min.css.map */
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/css/stylesheet.css b/code-nav-home/covers/dynamic/cover-12/assets/css/stylesheet.css
new file mode 100644
index 0000000..930ffdc
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-12/assets/css/stylesheet.css
@@ -0,0 +1,46 @@
+@font-face { font-family: "Digital"; src: url('../fonts/Adequate-ExtraLight.ttf'); }
+@font-face { font-family: "Micro"; src: url('../fonts/MicroExtendFLF.ttf'); }
+body {
+ background-image: url(../img/bg.jpg);
+ background-size: cover;
+ background-position: top center;
+ background-color:#FFF;
+}
+
+.content {
+ display: absolute;
+ width: 100%;
+ top: 0;
+ left: 0;
+ display: table;
+ vertical-align: middle;
+ height: 100vh;
+}
+
+.content .inner {
+ display:table-cell;
+ vertical-align: middle;
+ font-family: "Muli-Light";
+}
+.time, .date, .seconds {
+ font-family: "Micro";
+ color:#FFF;
+}
+.timeblock {
+ margin: 0 auto;
+ border: solid 1px rgba(255,255,255,0.5);
+ line-height: 100px;
+ border-radius: 300px;
+ padding-top: 110px;
+ width: 300px;
+ height: 300px;
+ box-shadow: inset 0 0 30px rgba(255,255,255,0.5);
+
+}
+#particles-js{
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/fonts/Adequate-ExtraLight.ttf b/code-nav-home/covers/dynamic/cover-12/assets/fonts/Adequate-ExtraLight.ttf
new file mode 100644
index 0000000..09a2f6d
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-12/assets/fonts/Adequate-ExtraLight.ttf differ
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Bold.ttf b/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Bold.ttf
new file mode 100644
index 0000000..2852aac
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Bold.ttf differ
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-BoldItalic.ttf b/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-BoldItalic.ttf
new file mode 100644
index 0000000..9107823
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-BoldItalic.ttf differ
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Italic.ttf b/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Italic.ttf
new file mode 100644
index 0000000..d7e7f02
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Italic.ttf differ
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF.ttf b/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF.ttf
new file mode 100644
index 0000000..8307d30
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF.ttf differ
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/img/bg.jpg b/code-nav-home/covers/dynamic/cover-12/assets/img/bg.jpg
new file mode 100644
index 0000000..7629967
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-12/assets/img/bg.jpg differ
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/js/app.js b/code-nav-home/covers/dynamic/cover-12/assets/js/app.js
new file mode 100644
index 0000000..252f7f9
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-12/assets/js/app.js
@@ -0,0 +1,130 @@
+$(function() {
+ particlesJS("particles-js", {
+ "particles": {
+ "number": {
+ "value": 100,
+ "density": {
+ "enable": true,
+ "value_area": 800
+ }
+ },
+ "color": {
+ "value": "#ffffff"
+ },
+ "shape": {
+ "type": "circle",
+ "stroke": {
+ "width": 0,
+ "color": "#000000"
+ },
+ "polygon": {
+ "nb_sides": 5
+ },
+ "image": {
+ "src": "img/github.svg",
+ "width": 100,
+ "height": 100
+ }
+ },
+ "opacity": {
+ "value": 0.5,
+ "random": false,
+ "anim": {
+ "enable": false,
+ "speed": 1,
+ "opacity_min": 0.1,
+ "sync": false
+ }
+ },
+ "size": {
+ "value": 3,
+ "random": true,
+ "anim": {
+ "enable": false,
+ "speed": 40,
+ "size_min": 0.1,
+ "sync": false
+ }
+ },
+ "line_linked": {
+ "enable": 0,
+ "distance": 150,
+ "color": "#ffffff",
+ "opacity": 0.4,
+ "width": 1
+ },
+ "move": {
+ "enable": true,
+ "speed": 3,
+ "direction": "bottom",
+ "random": false,
+ "straight": false,
+ "out_mode": "out",
+ "bounce": false,
+ "attract": {
+ "enable": false,
+ "rotateX": 600,
+ "rotateY": 1200
+ }
+ }
+ },
+ "interactivity": {
+ "detect_on": "canvas",
+ "events": {
+ "onhover": {
+ "enable": true,
+ "mode": "grab"
+ },
+ "onclick": {
+ "enable": false,
+ "mode": "repulse"
+ },
+ "resize": true
+ },
+ "modes": {
+ "grab": {
+ "distance": 100,
+ "line_linked": {
+ "opacity": 1
+ }
+ },
+ "bubble": {
+ "distance": 400,
+ "size": 40,
+ "duration": 2,
+ "opacity": 8,
+ "speed": 3
+ },
+ "repulse": {
+ "distance": 200,
+ "duration": 0.4
+ },
+ "push": {
+ "particles_nb": 4
+ },
+ "remove": {
+ "particles_nb": 2
+ }
+ }
+ },
+ "retina_detect": true
+ });
+
+ setInterval(function() {
+ var months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
+ var dt = new Date();
+ var time = dt.getHours() + ":" + dt.getMinutes() + "";
+
+ $('.date').html(""+months[dt.getMonth()]+" "+dt.getDate()+", "+dt.getFullYear()+"");
+
+ var hours = dt.getHours() < 12 ? dt.getHours() : dt.getHours() - 12;
+ var am = dt.getHours() < 12 ? "AM" : "PM";
+
+ var minutes = ""+dt.getMinutes()+"";
+ if (minutes < 10) {
+ minutes = "0"+minutes+"";
+ }
+ $('.time').html(""+hours+":"+minutes+" "+am+"");
+ $('.seconds').html(""+dt.getSeconds()+"s")
+ }, 1000);
+});
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/js/bootstrap.min.js b/code-nav-home/covers/dynamic/cover-12/assets/js/bootstrap.min.js
new file mode 100644
index 0000000..d9c72df
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-12/assets/js/bootstrap.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v4.0.0-alpha.6 (https://getbootstrap.com)
+ * Copyright 2011-2017 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");+function(t){var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1||e[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}(jQuery),+function(){function t(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function e(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},o=function(){function t(t,e){for(var n=0;nthis._items.length-1||e<0)){if(this._isSliding)return void t(this._element).one(m.SLID,function(){return n.to(e)});if(i===e)return this.pause(),void this.cycle();var o=e>i?p.NEXT:p.PREVIOUS;this._slide(o,this._items[e])}},h.prototype.dispose=function(){t(this._element).off(l),t.removeData(this._element,a),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},h.prototype._getConfig=function(n){return n=t.extend({},_,n),r.typeCheckConfig(e,n,g),n},h.prototype._addEventListeners=function(){var e=this;this._config.keyboard&&t(this._element).on(m.KEYDOWN,function(t){return e._keydown(t)}),"hover"!==this._config.pause||"ontouchstart"in document.documentElement||t(this._element).on(m.MOUSEENTER,function(t){return e.pause(t)}).on(m.MOUSELEAVE,function(t){return e.cycle(t)})},h.prototype._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case d:t.preventDefault(),this.prev();break;case f:t.preventDefault(),this.next();break;default:return}},h.prototype._getItemIndex=function(e){return this._items=t.makeArray(t(e).parent().find(v.ITEM)),this._items.indexOf(e)},h.prototype._getItemByDirection=function(t,e){var n=t===p.NEXT,i=t===p.PREVIOUS,o=this._getItemIndex(e),r=this._items.length-1,s=i&&0===o||n&&o===r;if(s&&!this._config.wrap)return e;var a=t===p.PREVIOUS?-1:1,l=(o+a)%this._items.length;return l===-1?this._items[this._items.length-1]:this._items[l]},h.prototype._triggerSlideEvent=function(e,n){var i=t.Event(m.SLIDE,{relatedTarget:e,direction:n});return t(this._element).trigger(i),i},h.prototype._setActiveIndicatorElement=function(e){if(this._indicatorsElement){t(this._indicatorsElement).find(v.ACTIVE).removeClass(E.ACTIVE);var n=this._indicatorsElement.children[this._getItemIndex(e)];n&&t(n).addClass(E.ACTIVE)}},h.prototype._slide=function(e,n){var i=this,o=t(this._element).find(v.ACTIVE_ITEM)[0],s=n||o&&this._getItemByDirection(e,o),a=Boolean(this._interval),l=void 0,h=void 0,c=void 0;if(e===p.NEXT?(l=E.LEFT,h=E.NEXT,c=p.LEFT):(l=E.RIGHT,h=E.PREV,c=p.RIGHT),s&&t(s).hasClass(E.ACTIVE))return void(this._isSliding=!1);var d=this._triggerSlideEvent(s,c);if(!d.isDefaultPrevented()&&o&&s){this._isSliding=!0,a&&this.pause(),this._setActiveIndicatorElement(s);var f=t.Event(m.SLID,{relatedTarget:s,direction:c});r.supportsTransitionEnd()&&t(this._element).hasClass(E.SLIDE)?(t(s).addClass(h),r.reflow(s),t(o).addClass(l),t(s).addClass(l),t(o).one(r.TRANSITION_END,function(){t(s).removeClass(l+" "+h).addClass(E.ACTIVE),t(o).removeClass(E.ACTIVE+" "+h+" "+l),i._isSliding=!1,setTimeout(function(){return t(i._element).trigger(f)},0)}).emulateTransitionEnd(u)):(t(o).removeClass(E.ACTIVE),t(s).addClass(E.ACTIVE),this._isSliding=!1,t(this._element).trigger(f)),a&&this.cycle()}},h._jQueryInterface=function(e){return this.each(function(){var n=t(this).data(a),o=t.extend({},_,t(this).data());"object"===("undefined"==typeof e?"undefined":i(e))&&t.extend(o,e);var r="string"==typeof e?e:o.slide;if(n||(n=new h(this,o),t(this).data(a,n)),"number"==typeof e)n.to(e);else if("string"==typeof r){if(void 0===n[r])throw new Error('No method named "'+r+'"');n[r]()}else o.interval&&(n.pause(),n.cycle())})},h._dataApiClickHandler=function(e){var n=r.getSelectorFromElement(this);if(n){var i=t(n)[0];if(i&&t(i).hasClass(E.CAROUSEL)){var o=t.extend({},t(i).data(),t(this).data()),s=this.getAttribute("data-slide-to");s&&(o.interval=!1),h._jQueryInterface.call(t(i),o),s&&t(i).data(a).to(s),e.preventDefault()}}},o(h,null,[{key:"VERSION",get:function(){return s}},{key:"Default",get:function(){return _}}]),h}();return t(document).on(m.CLICK_DATA_API,v.DATA_SLIDE,T._dataApiClickHandler),t(window).on(m.LOAD_DATA_API,function(){t(v.DATA_RIDE).each(function(){var e=t(this);T._jQueryInterface.call(e,e.data())})}),t.fn[e]=T._jQueryInterface,t.fn[e].Constructor=T,t.fn[e].noConflict=function(){return t.fn[e]=c,T._jQueryInterface},T}(jQuery),function(t){var e="collapse",s="4.0.0-alpha.6",a="bs.collapse",l="."+a,h=".data-api",c=t.fn[e],u=600,d={toggle:!0,parent:""},f={toggle:"boolean",parent:"string"},_={SHOW:"show"+l,SHOWN:"shown"+l,HIDE:"hide"+l,HIDDEN:"hidden"+l,CLICK_DATA_API:"click"+l+h},g={SHOW:"show",COLLAPSE:"collapse",COLLAPSING:"collapsing",COLLAPSED:"collapsed"},p={WIDTH:"width",HEIGHT:"height"},m={ACTIVES:".card > .show, .card > .collapsing",DATA_TOGGLE:'[data-toggle="collapse"]'},E=function(){function l(e,i){n(this,l),this._isTransitioning=!1,this._element=e,this._config=this._getConfig(i),this._triggerArray=t.makeArray(t('[data-toggle="collapse"][href="#'+e.id+'"],'+('[data-toggle="collapse"][data-target="#'+e.id+'"]'))),this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}return l.prototype.toggle=function(){t(this._element).hasClass(g.SHOW)?this.hide():this.show()},l.prototype.show=function(){var e=this;if(this._isTransitioning)throw new Error("Collapse is transitioning");if(!t(this._element).hasClass(g.SHOW)){var n=void 0,i=void 0;if(this._parent&&(n=t.makeArray(t(this._parent).find(m.ACTIVES)),n.length||(n=null)),!(n&&(i=t(n).data(a),i&&i._isTransitioning))){var o=t.Event(_.SHOW);if(t(this._element).trigger(o),!o.isDefaultPrevented()){n&&(l._jQueryInterface.call(t(n),"hide"),i||t(n).data(a,null));var s=this._getDimension();t(this._element).removeClass(g.COLLAPSE).addClass(g.COLLAPSING),this._element.style[s]=0,this._element.setAttribute("aria-expanded",!0),this._triggerArray.length&&t(this._triggerArray).removeClass(g.COLLAPSED).attr("aria-expanded",!0),this.setTransitioning(!0);var h=function(){t(e._element).removeClass(g.COLLAPSING).addClass(g.COLLAPSE).addClass(g.SHOW),e._element.style[s]="",e.setTransitioning(!1),t(e._element).trigger(_.SHOWN)};if(!r.supportsTransitionEnd())return void h();var c=s[0].toUpperCase()+s.slice(1),d="scroll"+c;t(this._element).one(r.TRANSITION_END,h).emulateTransitionEnd(u),this._element.style[s]=this._element[d]+"px"}}}},l.prototype.hide=function(){var e=this;if(this._isTransitioning)throw new Error("Collapse is transitioning");if(t(this._element).hasClass(g.SHOW)){var n=t.Event(_.HIDE);if(t(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension(),o=i===p.WIDTH?"offsetWidth":"offsetHeight";this._element.style[i]=this._element[o]+"px",r.reflow(this._element),t(this._element).addClass(g.COLLAPSING).removeClass(g.COLLAPSE).removeClass(g.SHOW),this._element.setAttribute("aria-expanded",!1),this._triggerArray.length&&t(this._triggerArray).addClass(g.COLLAPSED).attr("aria-expanded",!1),this.setTransitioning(!0);var s=function(){e.setTransitioning(!1),t(e._element).removeClass(g.COLLAPSING).addClass(g.COLLAPSE).trigger(_.HIDDEN)};return this._element.style[i]="",r.supportsTransitionEnd()?void t(this._element).one(r.TRANSITION_END,s).emulateTransitionEnd(u):void s()}}},l.prototype.setTransitioning=function(t){this._isTransitioning=t},l.prototype.dispose=function(){t.removeData(this._element,a),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},l.prototype._getConfig=function(n){return n=t.extend({},d,n),n.toggle=Boolean(n.toggle),r.typeCheckConfig(e,n,f),n},l.prototype._getDimension=function(){var e=t(this._element).hasClass(p.WIDTH);return e?p.WIDTH:p.HEIGHT},l.prototype._getParent=function(){var e=this,n=t(this._config.parent)[0],i='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]';return t(n).find(i).each(function(t,n){e._addAriaAndCollapsedClass(l._getTargetFromElement(n),[n])}),n},l.prototype._addAriaAndCollapsedClass=function(e,n){if(e){var i=t(e).hasClass(g.SHOW);e.setAttribute("aria-expanded",i),n.length&&t(n).toggleClass(g.COLLAPSED,!i).attr("aria-expanded",i)}},l._getTargetFromElement=function(e){var n=r.getSelectorFromElement(e);return n?t(n)[0]:null},l._jQueryInterface=function(e){return this.each(function(){var n=t(this),o=n.data(a),r=t.extend({},d,n.data(),"object"===("undefined"==typeof e?"undefined":i(e))&&e);if(!o&&r.toggle&&/show|hide/.test(e)&&(r.toggle=!1),o||(o=new l(this,r),n.data(a,o)),"string"==typeof e){if(void 0===o[e])throw new Error('No method named "'+e+'"');o[e]()}})},o(l,null,[{key:"VERSION",get:function(){return s}},{key:"Default",get:function(){return d}}]),l}();return t(document).on(_.CLICK_DATA_API,m.DATA_TOGGLE,function(e){e.preventDefault();var n=E._getTargetFromElement(this),i=t(n).data(a),o=i?"toggle":t(this).data();E._jQueryInterface.call(t(n),o)}),t.fn[e]=E._jQueryInterface,t.fn[e].Constructor=E,t.fn[e].noConflict=function(){return t.fn[e]=c,E._jQueryInterface},E}(jQuery),function(t){var e="dropdown",i="4.0.0-alpha.6",s="bs.dropdown",a="."+s,l=".data-api",h=t.fn[e],c=27,u=38,d=40,f=3,_={HIDE:"hide"+a,HIDDEN:"hidden"+a,SHOW:"show"+a,SHOWN:"shown"+a,CLICK:"click"+a,CLICK_DATA_API:"click"+a+l,FOCUSIN_DATA_API:"focusin"+a+l,KEYDOWN_DATA_API:"keydown"+a+l},g={BACKDROP:"dropdown-backdrop",DISABLED:"disabled",SHOW:"show"},p={BACKDROP:".dropdown-backdrop",DATA_TOGGLE:'[data-toggle="dropdown"]',FORM_CHILD:".dropdown form",ROLE_MENU:'[role="menu"]',ROLE_LISTBOX:'[role="listbox"]',NAVBAR_NAV:".navbar-nav",VISIBLE_ITEMS:'[role="menu"] li:not(.disabled) a, [role="listbox"] li:not(.disabled) a'},m=function(){function e(t){n(this,e),this._element=t,this._addEventListeners()}return e.prototype.toggle=function(){if(this.disabled||t(this).hasClass(g.DISABLED))return!1;var n=e._getParentFromElement(this),i=t(n).hasClass(g.SHOW);if(e._clearMenus(),i)return!1;if("ontouchstart"in document.documentElement&&!t(n).closest(p.NAVBAR_NAV).length){var o=document.createElement("div");o.className=g.BACKDROP,t(o).insertBefore(this),t(o).on("click",e._clearMenus)}var r={relatedTarget:this},s=t.Event(_.SHOW,r);return t(n).trigger(s),!s.isDefaultPrevented()&&(this.focus(),this.setAttribute("aria-expanded",!0),t(n).toggleClass(g.SHOW),t(n).trigger(t.Event(_.SHOWN,r)),!1)},e.prototype.dispose=function(){t.removeData(this._element,s),t(this._element).off(a),this._element=null},e.prototype._addEventListeners=function(){t(this._element).on(_.CLICK,this.toggle)},e._jQueryInterface=function(n){return this.each(function(){var i=t(this).data(s);if(i||(i=new e(this),t(this).data(s,i)),"string"==typeof n){if(void 0===i[n])throw new Error('No method named "'+n+'"');i[n].call(this)}})},e._clearMenus=function(n){if(!n||n.which!==f){var i=t(p.BACKDROP)[0];i&&i.parentNode.removeChild(i);for(var o=t.makeArray(t(p.DATA_TOGGLE)),r=0;r0&&a--,n.which===d&&adocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},h.prototype._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},h.prototype._checkScrollbar=function(){this._isBodyOverflowing=document.body.clientWidth=n){var i=this._targets[this._targets.length-1];return void(this._activeTarget!==i&&this._activate(i))}if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){var r=this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&(void 0===this._offsets[o+1]||t "+g.NAV_LINKS).addClass(_.ACTIVE),t(this._scrollElement).trigger(f.ACTIVATE,{relatedTarget:e})},h.prototype._clear=function(){t(this._selector).filter(g.ACTIVE).removeClass(_.ACTIVE)},h._jQueryInterface=function(e){return this.each(function(){var n=t(this).data(a),o="object"===("undefined"==typeof e?"undefined":i(e))&&e;
+if(n||(n=new h(this,o),t(this).data(a,n)),"string"==typeof e){if(void 0===n[e])throw new Error('No method named "'+e+'"');n[e]()}})},o(h,null,[{key:"VERSION",get:function(){return s}},{key:"Default",get:function(){return u}}]),h}();return t(window).on(f.LOAD_DATA_API,function(){for(var e=t.makeArray(t(g.DATA_SPY)),n=e.length;n--;){var i=t(e[n]);m._jQueryInterface.call(i,i.data())}}),t.fn[e]=m._jQueryInterface,t.fn[e].Constructor=m,t.fn[e].noConflict=function(){return t.fn[e]=c,m._jQueryInterface},m}(jQuery),function(t){var e="tab",i="4.0.0-alpha.6",s="bs.tab",a="."+s,l=".data-api",h=t.fn[e],c=150,u={HIDE:"hide"+a,HIDDEN:"hidden"+a,SHOW:"show"+a,SHOWN:"shown"+a,CLICK_DATA_API:"click"+a+l},d={DROPDOWN_MENU:"dropdown-menu",ACTIVE:"active",DISABLED:"disabled",FADE:"fade",SHOW:"show"},f={A:"a",LI:"li",DROPDOWN:".dropdown",LIST:"ul:not(.dropdown-menu), ol:not(.dropdown-menu), nav:not(.dropdown-menu)",FADE_CHILD:"> .nav-item .fade, > .fade",ACTIVE:".active",ACTIVE_CHILD:"> .nav-item > .active, > .active",DATA_TOGGLE:'[data-toggle="tab"], [data-toggle="pill"]',DROPDOWN_TOGGLE:".dropdown-toggle",DROPDOWN_ACTIVE_CHILD:"> .dropdown-menu .active"},_=function(){function e(t){n(this,e),this._element=t}return e.prototype.show=function(){var e=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&t(this._element).hasClass(d.ACTIVE)||t(this._element).hasClass(d.DISABLED))){var n=void 0,i=void 0,o=t(this._element).closest(f.LIST)[0],s=r.getSelectorFromElement(this._element);o&&(i=t.makeArray(t(o).find(f.ACTIVE)),i=i[i.length-1]);var a=t.Event(u.HIDE,{relatedTarget:this._element}),l=t.Event(u.SHOW,{relatedTarget:i});if(i&&t(i).trigger(a),t(this._element).trigger(l),!l.isDefaultPrevented()&&!a.isDefaultPrevented()){s&&(n=t(s)[0]),this._activate(this._element,o);var h=function(){var n=t.Event(u.HIDDEN,{relatedTarget:e._element}),o=t.Event(u.SHOWN,{relatedTarget:i});t(i).trigger(n),t(e._element).trigger(o)};n?this._activate(n,n.parentNode,h):h()}}},e.prototype.dispose=function(){t.removeClass(this._element,s),this._element=null},e.prototype._activate=function(e,n,i){var o=this,s=t(n).find(f.ACTIVE_CHILD)[0],a=i&&r.supportsTransitionEnd()&&(s&&t(s).hasClass(d.FADE)||Boolean(t(n).find(f.FADE_CHILD)[0])),l=function(){return o._transitionComplete(e,s,a,i)};s&&a?t(s).one(r.TRANSITION_END,l).emulateTransitionEnd(c):l(),s&&t(s).removeClass(d.SHOW)},e.prototype._transitionComplete=function(e,n,i,o){if(n){t(n).removeClass(d.ACTIVE);var s=t(n.parentNode).find(f.DROPDOWN_ACTIVE_CHILD)[0];s&&t(s).removeClass(d.ACTIVE),n.setAttribute("aria-expanded",!1)}if(t(e).addClass(d.ACTIVE),e.setAttribute("aria-expanded",!0),i?(r.reflow(e),t(e).addClass(d.SHOW)):t(e).removeClass(d.FADE),e.parentNode&&t(e.parentNode).hasClass(d.DROPDOWN_MENU)){var a=t(e).closest(f.DROPDOWN)[0];a&&t(a).find(f.DROPDOWN_TOGGLE).addClass(d.ACTIVE),e.setAttribute("aria-expanded",!0)}o&&o()},e._jQueryInterface=function(n){return this.each(function(){var i=t(this),o=i.data(s);if(o||(o=new e(this),i.data(s,o)),"string"==typeof n){if(void 0===o[n])throw new Error('No method named "'+n+'"');o[n]()}})},o(e,null,[{key:"VERSION",get:function(){return i}}]),e}();return t(document).on(u.CLICK_DATA_API,f.DATA_TOGGLE,function(e){e.preventDefault(),_._jQueryInterface.call(t(this),"show")}),t.fn[e]=_._jQueryInterface,t.fn[e].Constructor=_,t.fn[e].noConflict=function(){return t.fn[e]=h,_._jQueryInterface},_}(jQuery),function(t){if("undefined"==typeof Tether)throw new Error("Bootstrap tooltips require Tether (http://tether.io/)");var e="tooltip",s="4.0.0-alpha.6",a="bs.tooltip",l="."+a,h=t.fn[e],c=150,u="bs-tether",d={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:"0 0",constraints:[],container:!1},f={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"string",constraints:"array",container:"(string|element|boolean)"},_={TOP:"bottom center",RIGHT:"middle left",BOTTOM:"top center",LEFT:"middle right"},g={SHOW:"show",OUT:"out"},p={HIDE:"hide"+l,HIDDEN:"hidden"+l,SHOW:"show"+l,SHOWN:"shown"+l,INSERTED:"inserted"+l,CLICK:"click"+l,FOCUSIN:"focusin"+l,FOCUSOUT:"focusout"+l,MOUSEENTER:"mouseenter"+l,MOUSELEAVE:"mouseleave"+l},m={FADE:"fade",SHOW:"show"},E={TOOLTIP:".tooltip",TOOLTIP_INNER:".tooltip-inner"},v={element:!1,enabled:!1},T={HOVER:"hover",FOCUS:"focus",CLICK:"click",MANUAL:"manual"},I=function(){function h(t,e){n(this,h),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._isTransitioning=!1,this._tether=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}return h.prototype.enable=function(){this._isEnabled=!0},h.prototype.disable=function(){this._isEnabled=!1},h.prototype.toggleEnabled=function(){this._isEnabled=!this._isEnabled},h.prototype.toggle=function(e){if(e){var n=this.constructor.DATA_KEY,i=t(e.currentTarget).data(n);i||(i=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(t(this.getTipElement()).hasClass(m.SHOW))return void this._leave(null,this);this._enter(null,this)}},h.prototype.dispose=function(){clearTimeout(this._timeout),this.cleanupTether(),t.removeData(this.element,this.constructor.DATA_KEY),t(this.element).off(this.constructor.EVENT_KEY),t(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&t(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._tether=null,this.element=null,this.config=null,this.tip=null},h.prototype.show=function(){var e=this;if("none"===t(this.element).css("display"))throw new Error("Please use show on visible elements");var n=t.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){if(this._isTransitioning)throw new Error("Tooltip is transitioning");t(this.element).trigger(n);var i=t.contains(this.element.ownerDocument.documentElement,this.element);if(n.isDefaultPrevented()||!i)return;var o=this.getTipElement(),s=r.getUID(this.constructor.NAME);o.setAttribute("id",s),this.element.setAttribute("aria-describedby",s),this.setContent(),this.config.animation&&t(o).addClass(m.FADE);var a="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,l=this._getAttachment(a),c=this.config.container===!1?document.body:t(this.config.container);t(o).data(this.constructor.DATA_KEY,this).appendTo(c),t(this.element).trigger(this.constructor.Event.INSERTED),this._tether=new Tether({attachment:l,element:o,target:this.element,classes:v,classPrefix:u,offset:this.config.offset,constraints:this.config.constraints,addTargetClasses:!1}),r.reflow(o),this._tether.position(),t(o).addClass(m.SHOW);var d=function(){var n=e._hoverState;e._hoverState=null,e._isTransitioning=!1,t(e.element).trigger(e.constructor.Event.SHOWN),n===g.OUT&&e._leave(null,e)};if(r.supportsTransitionEnd()&&t(this.tip).hasClass(m.FADE))return this._isTransitioning=!0,void t(this.tip).one(r.TRANSITION_END,d).emulateTransitionEnd(h._TRANSITION_DURATION);d()}},h.prototype.hide=function(e){var n=this,i=this.getTipElement(),o=t.Event(this.constructor.Event.HIDE);if(this._isTransitioning)throw new Error("Tooltip is transitioning");var s=function(){n._hoverState!==g.SHOW&&i.parentNode&&i.parentNode.removeChild(i),n.element.removeAttribute("aria-describedby"),t(n.element).trigger(n.constructor.Event.HIDDEN),n._isTransitioning=!1,n.cleanupTether(),e&&e()};t(this.element).trigger(o),o.isDefaultPrevented()||(t(i).removeClass(m.SHOW),this._activeTrigger[T.CLICK]=!1,this._activeTrigger[T.FOCUS]=!1,this._activeTrigger[T.HOVER]=!1,r.supportsTransitionEnd()&&t(this.tip).hasClass(m.FADE)?(this._isTransitioning=!0,t(i).one(r.TRANSITION_END,s).emulateTransitionEnd(c)):s(),this._hoverState="")},h.prototype.isWithContent=function(){return Boolean(this.getTitle())},h.prototype.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0]},h.prototype.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(E.TOOLTIP_INNER),this.getTitle()),e.removeClass(m.FADE+" "+m.SHOW),this.cleanupTether()},h.prototype.setElementContent=function(e,n){var o=this.config.html;"object"===("undefined"==typeof n?"undefined":i(n))&&(n.nodeType||n.jquery)?o?t(n).parent().is(e)||e.empty().append(n):e.text(t(n).text()):e[o?"html":"text"](n)},h.prototype.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},h.prototype.cleanupTether=function(){this._tether&&this._tether.destroy()},h.prototype._getAttachment=function(t){return _[t.toUpperCase()]},h.prototype._setListeners=function(){var e=this,n=this.config.trigger.split(" ");n.forEach(function(n){if("click"===n)t(e.element).on(e.constructor.Event.CLICK,e.config.selector,function(t){return e.toggle(t)});else if(n!==T.MANUAL){var i=n===T.HOVER?e.constructor.Event.MOUSEENTER:e.constructor.Event.FOCUSIN,o=n===T.HOVER?e.constructor.Event.MOUSELEAVE:e.constructor.Event.FOCUSOUT;t(e.element).on(i,e.config.selector,function(t){return e._enter(t)}).on(o,e.config.selector,function(t){return e._leave(t)})}t(e.element).closest(".modal").on("hide.bs.modal",function(){return e.hide()})}),this.config.selector?this.config=t.extend({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},h.prototype._fixTitle=function(){var t=i(this.element.getAttribute("data-original-title"));(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},h.prototype._enter=function(e,n){var i=this.constructor.DATA_KEY;return n=n||t(e.currentTarget).data(i),n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusin"===e.type?T.FOCUS:T.HOVER]=!0),t(n.getTipElement()).hasClass(m.SHOW)||n._hoverState===g.SHOW?void(n._hoverState=g.SHOW):(clearTimeout(n._timeout),n._hoverState=g.SHOW,n.config.delay&&n.config.delay.show?void(n._timeout=setTimeout(function(){n._hoverState===g.SHOW&&n.show()},n.config.delay.show)):void n.show())},h.prototype._leave=function(e,n){var i=this.constructor.DATA_KEY;if(n=n||t(e.currentTarget).data(i),n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusout"===e.type?T.FOCUS:T.HOVER]=!1),!n._isWithActiveTrigger())return clearTimeout(n._timeout),n._hoverState=g.OUT,n.config.delay&&n.config.delay.hide?void(n._timeout=setTimeout(function(){n._hoverState===g.OUT&&n.hide()},n.config.delay.hide)):void n.hide()},h.prototype._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},h.prototype._getConfig=function(n){return n=t.extend({},this.constructor.Default,t(this.element).data(),n),n.delay&&"number"==typeof n.delay&&(n.delay={show:n.delay,hide:n.delay}),r.typeCheckConfig(e,n,this.constructor.DefaultType),n},h.prototype._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},h._jQueryInterface=function(e){return this.each(function(){var n=t(this).data(a),o="object"===("undefined"==typeof e?"undefined":i(e))&&e;if((n||!/dispose|hide/.test(e))&&(n||(n=new h(this,o),t(this).data(a,n)),"string"==typeof e)){if(void 0===n[e])throw new Error('No method named "'+e+'"');n[e]()}})},o(h,null,[{key:"VERSION",get:function(){return s}},{key:"Default",get:function(){return d}},{key:"NAME",get:function(){return e}},{key:"DATA_KEY",get:function(){return a}},{key:"Event",get:function(){return p}},{key:"EVENT_KEY",get:function(){return l}},{key:"DefaultType",get:function(){return f}}]),h}();return t.fn[e]=I._jQueryInterface,t.fn[e].Constructor=I,t.fn[e].noConflict=function(){return t.fn[e]=h,I._jQueryInterface},I}(jQuery));(function(r){var a="popover",l="4.0.0-alpha.6",h="bs.popover",c="."+h,u=r.fn[a],d=r.extend({},s.Default,{placement:"right",trigger:"click",content:"",template:''}),f=r.extend({},s.DefaultType,{content:"(string|element|function)"}),_={FADE:"fade",SHOW:"show"},g={TITLE:".popover-title",CONTENT:".popover-content"},p={HIDE:"hide"+c,HIDDEN:"hidden"+c,SHOW:"show"+c,SHOWN:"shown"+c,INSERTED:"inserted"+c,CLICK:"click"+c,FOCUSIN:"focusin"+c,FOCUSOUT:"focusout"+c,MOUSEENTER:"mouseenter"+c,MOUSELEAVE:"mouseleave"+c},m=function(s){function u(){return n(this,u),t(this,s.apply(this,arguments))}return e(u,s),u.prototype.isWithContent=function(){return this.getTitle()||this._getContent()},u.prototype.getTipElement=function(){return this.tip=this.tip||r(this.config.template)[0]},u.prototype.setContent=function(){var t=r(this.getTipElement());this.setElementContent(t.find(g.TITLE),this.getTitle()),this.setElementContent(t.find(g.CONTENT),this._getContent()),t.removeClass(_.FADE+" "+_.SHOW),this.cleanupTether()},u.prototype._getContent=function(){return this.element.getAttribute("data-content")||("function"==typeof this.config.content?this.config.content.call(this.element):this.config.content)},u._jQueryInterface=function(t){return this.each(function(){var e=r(this).data(h),n="object"===("undefined"==typeof t?"undefined":i(t))?t:null;if((e||!/destroy|hide/.test(t))&&(e||(e=new u(this,n),r(this).data(h,e)),"string"==typeof t)){if(void 0===e[t])throw new Error('No method named "'+t+'"');e[t]()}})},o(u,null,[{key:"VERSION",get:function(){return l}},{key:"Default",get:function(){return d}},{key:"NAME",get:function(){return a}},{key:"DATA_KEY",get:function(){return h}},{key:"Event",get:function(){return p}},{key:"EVENT_KEY",get:function(){return c}},{key:"DefaultType",get:function(){return f}}]),u}(s);return r.fn[a]=m._jQueryInterface,r.fn[a].Constructor=m,r.fn[a].noConflict=function(){return r.fn[a]=u,m._jQueryInterface},m})(jQuery)}();
\ No newline at end of file
diff --git a/code-nav-home/covers/dynamic/cover-12/assets/js/jquery-3.1.1.min.js b/code-nav-home/covers/dynamic/cover-12/assets/js/jquery-3.1.1.min.js
new file mode 100644
index 0000000..4c5be4c
--- /dev/null
+++ b/code-nav-home/covers/dynamic/cover-12/assets/js/jquery-3.1.1.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */
+!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):C.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/[^\x20\t\r\n\f]+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),
+a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,ka=/^$|\/(?:java|ecma)script/i,la={option:[1,""],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};la.optgroup=la.option,la.tbody=la.tfoot=la.colgroup=la.caption=la.thead,la.th=la.td;function ma(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function na(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=ma(l.appendChild(f),"script"),j&&na(g),c){k=0;while(f=g[k++])ka.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var qa=d.documentElement,ra=/^key/,sa=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ta=/^([^.]*)(?:\.(.+)|)/;function ua(){return!0}function va(){return!1}function wa(){try{return d.activeElement}catch(a){}}function xa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)xa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=va;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(qa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,za=/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code-nav-home/covers/dynamic/cover-12/preview.jpg b/code-nav-home/covers/dynamic/cover-12/preview.jpg
new file mode 100644
index 0000000..7e909c4
Binary files /dev/null and b/code-nav-home/covers/dynamic/cover-12/preview.jpg differ
diff --git a/code-nav-home/covers/dynamic/fireBlackHole/img/24ac8094-7dc0-40c4-9956-f69c5fb45896.jpg b/code-nav-home/covers/dynamic/fireBlackHole/img/24ac8094-7dc0-40c4-9956-f69c5fb45896.jpg
new file mode 100644
index 0000000..e4490ee
Binary files /dev/null and b/code-nav-home/covers/dynamic/fireBlackHole/img/24ac8094-7dc0-40c4-9956-f69c5fb45896.jpg differ
diff --git a/code-nav-home/covers/dynamic/fireBlackHole/index.html b/code-nav-home/covers/dynamic/fireBlackHole/index.html
new file mode 100644
index 0000000..90cdce5
--- /dev/null
+++ b/code-nav-home/covers/dynamic/fireBlackHole/index.html
@@ -0,0 +1,229 @@
+
+
+