From 19d3ab7affa2d964baba0443fbecc369cf34d583 Mon Sep 17 00:00:00 2001
From: James Feng Cao
Date: Wed, 29 Apr 2020 16:37:43 +0800
Subject: [PATCH] blog update
---
adblock/index.html | 176 +
adblock_css/index.html | 171 +
adblock_hosts/index.html | 178 +
archives/2019/06/index.html | 516 +++
archives/2019/11/index.html | 516 +++
archives/2019/index.html | 516 +++
archives/2020/01/index.html | 516 +++
archives/2020/03/index.html | 516 +++
archives/2020/04/index.html | 516 +++
archives/2020/index.html | 516 +++
archives/index.html | 516 +++
bc/index.html | 166 +
bookmarklet/index.html | 167 +
cmd/index.html | 181 +
css/aircloud.css | 1146 +++++
css/aircloud.less | 19 +
css/gitment.css | 1146 +++++
filecap/index.html | 196 +
filenames/index.html | 161 +
globalcss/index.html | 162 +
gnuplot/index.html | 185 +
hosts/index.html | 175 +
index.html | 490 +++
js/gitment.js | 3757 +++++++++++++++++
js/index.js | 348 ++
links/index.html | 161 +
loadbt/index.html | 204 +
logcat/index.html | 169 +
multiaccount/index.html | 164 +
offlinecache/index.html | 176 +
pccopy/index.html | 193 +
pcdown/index.html | 183 +
redirect/index.html | 188 +
rjs/index.html | 176 +
searchcat/index.html | 171 +
searchurl/alipay.png | Bin 0 -> 5538 bytes
searchurl/backup.html | 34 +
searchurl/bml/content/comparecells.js | 197 +
searchurl/bml/content/designmode.js | 1 +
searchurl/bml/content/freeviddy.js | 54 +
searchurl/bml/content/fullimg.js | 497 +++
searchurl/bml/content/read.js | 1447 +++++++
searchurl/bml/content/rmi.js | 79 +
searchurl/bml/content/rmo.js | 94 +
searchurl/bml/content/vidspeed.js | 1 +
searchurl/cmds.html | 14 +
searchurl/default.hosts.tar.gz | Bin 0 -> 358 bytes
searchurl/donate.html | 7 +
searchurl/func.html | 50 +
searchurl/input.html | 473 +++
searchurl/quickstart.html | 23 +
searchurl/res.html | 10 +
searchurl/script/axel.sh | 7 +
searchurl/script/baidupcs.sh | 13 +
searchurl/script/bc.sh | 5 +
searchurl/script/disable_sh.sh | 1 +
searchurl/script/filecap_app.sh | 14 +
searchurl/script/filecap_microsoft.sh | 14 +
searchurl/script/filecap_search.sh | 4 +
searchurl/script/filecap_sh.sh | 1 +
searchurl/script/filecap_tar.sh | 8 +
searchurl/script/filecap_ziprar.sh | 7 +
searchurl/script/gnuplot.sh | 7 +
searchurl/script/histuniq.sh | 4 +
searchurl/script/hosts_ad.sh | 29 +
searchurl/script/js_caiyun.sh | 2 +
searchurl/script/plugins.html | 170 +
searchurl/script/xzdic.sh | 4 +
searchurl/script/xzgrep.sh | 4 +
.../sdcard/uweb/bookmark/movie_zh.search | 153 +
.../sdcard/uweb/bookmark/novel_zh.search | 135 +
searchurl/sdcard/uweb/default.hosts | 31 +
searchurl/search.html | 157 +
searchurl/searchcat.html | 28 +
searchurl/searchcat.tar.gz | Bin 0 -> 6349 bytes
searchurl/template/backup.html | 10 +
searchurl/txt/cmds.txt | 3 +
searchurl/txt/magnet.search | 22 +
searchurl/txt/margintop.css | 1 +
searchurl/txt/night.css | 1 +
searchurl/txt/rjs.txt | 4 +
searchurl/uas.html | 28 +
searchurl/urls.html | 51 +
searchurl/v541.search | 541 +++
searchurl/v678.search | 678 +++
searchurl/weixin.png | Bin 0 -> 42605 bytes
sitejs/index.html | 185 +
tags/PC/index.html | 516 +++
tags/Windows/index.html | 516 +++
tags/css/index.html | 516 +++
tags/curl/index.html | 516 +++
tags/index.html | 792 ++++
tags/javascript/index.html | 516 +++
tags/ssh/index.html | 516 +++
tags/termux/index.html | 516 +++
tags/下载/index.html | 516 +++
tags/剪贴板/index.html | 516 +++
tags/国外网址/index.html | 516 +++
tags/广告屏蔽/index.html | 516 +++
tags/搜索/index.html | 516 +++
tags/电视/index.html | 516 +++
tags/离线/index.html | 516 +++
tags/网盘/index.html | 516 +++
tags/资源/index.html | 516 +++
tags/重定向/index.html | 516 +++
tvlive/index.html | 166 +
video/index.html | 197 +
107 files changed, 29967 insertions(+)
diff --git a/adblock/index.html b/adblock/index.html
index e69de29..004e8c8 100644
--- a/adblock/index.html
+++ b/adblock/index.html
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 广告屏蔽技术总览
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 广告屏蔽技术总览
+
+
+
+
Post:2019-11-12 15:17:08
+
+
Tags:/
+
+ 广告屏蔽
+ /
+
+
+
+
+
+
+
+
超微浏览器提供了形形色色的广告屏蔽技术,善于使用的话根本无需求助于复杂的屏蔽规则。
+
+- 如果网站并非视频类小网站,长按底部工具栏[☰]按钮,选取”禁用iframe”,此法可屏蔽大多数广告。更多可参看自定义样式屏蔽广告。
+- 对非复杂交互非国内广告大厂网页而言(譬如云盘管理属复杂交互),特别是小说网站,可以长按设置,选取”屏蔽外链脚本”。(内在逻辑:小网站一般无力开发完整的广告系统,它们经常使用大厂的广告脚本。)
+- 利用视频全屏播放屏蔽一切广告。
+- 长按[☰]按钮可屏蔽浮动广告。
+- 双正则表达式hosts文件绝杀广告。
+- 针对特定网站的脚本样式屏蔽广告。
+- 对非图片为主的网站可直接关闭图像。
+- 对非交互性网站,可关闭[JS]脚本。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/adblock_css/index.html b/adblock_css/index.html
index e69de29..01edd16 100644
--- a/adblock_css/index.html
+++ b/adblock_css/index.html
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用用户自定义样式屏蔽广告
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用用户自定义样式屏蔽广告
+
+
+
+
Post:2019-06-05 17:55:34
+
+
Tags:/
+
+ 广告屏蔽
+ /
+
+ css
+ /
+
+
+
+
+
+
+
+
超微浏览器支持超级hosts文件,这一技术可以完全绝杀手机广告小厂。但少部分广告大厂本身也提供高质量的内容服务,它们可以将广告伪装成正常的内容从而逃脱hosts文件绝杀。
对这一部分广告而言,我们可以利用超微浏览器的自定义样式功能加以屏蔽。
+
下载下面文件(可改名成“广告屏蔽.css”),将其放到/scard/uweb/css目录下:
广告屏蔽css文件
+
重启浏览器,长按底部工具条[☰]按钮弹出对话框后勾选上述文件名即可屏蔽广告。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/adblock_hosts/index.html b/adblock_hosts/index.html
index e69de29..fb148d3 100644
--- a/adblock_hosts/index.html
+++ b/adblock_hosts/index.html
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用超级hosts绝杀广告
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用超级hosts绝杀广告
+
+
+
+
Post:2019-06-05 17:55:34
+
+
Tags:/
+
+ 广告屏蔽
+ /
+
+
+
+
+
+
+
+
超级hosts文件可屏蔽文件中域名的一切子域名、孙域名、……,可彻底绝杀一切广告。所以用户屏蔽根域名时无需选择提示中出现的整个域名,只需选取最后两段或三段(少数很短的域名可取四段)。
+
+- 长按广告链接,点击“图片:屏蔽根域名”,修改弹出域名,一般取最后两段,点击”确定”屏蔽当前图片网址。
+- 部分广告没有链接可长按,或虽有链接但长按时不出现图片相关菜单。此时可长按[JS]点击”背景图片”或”看图模式”,再长按广告链接点击“图片:屏蔽根域名”,屏蔽图片网址。
+- 可长按设置开启”资源嗅探”,推荐设置文件”/sdcard/uweb/types.sniff”内容为js,刷新网页后关闭”资源嗅探”选项。在弹出的资源网页上长按链接,屏蔽根域名。
+(可选) 长按广告链接,点击“屏蔽根域名”,屏蔽链接网址。
+
+(可选) 某些广告靠javascript激发,链接中不出现域名,可点击激发至新网址后将新网址根域名屏蔽。
+
+超级hosts文件支持域名及整个网址正则表达式
default.hosts文件格式每行如下:
根域名[空格]域名前缀正则表达式[空格]网址路径正则表达式
空格及后面两个正则表达式为可选择项。
+
+
+
部分国内大厂广告 (将下列内容放入/sdcard/uweb/default.hosts,点击本链接自动用以下内容覆盖default.hosts):
lianmeng.360.cn
appjiagu.com
adm-cnzz.net
alimama.com
ipinyou.com
mct01.com
tanx.com
wrating.com
cpro.baidu.com
pos.baidu.com
share.baidu.com
e.qq.com
gdt.qq.com
l.qq.com
push.qq.com
beacon.sina.com.cn
mix.sina.com.cn
go.sohu.com
inte.sogou.com
epro.sogou.com
golden1.sogou.com
uranus.sogou.com
inte.sogoucdn.com
lu.sogoucdn.com
theta.sogoucdn.com
ad.xiaomi.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/archives/2019/06/index.html b/archives/2019/06/index.html
index e69de29..729e05d 100644
--- a/archives/2019/06/index.html
+++ b/archives/2019/06/index.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/archives/2019/11/index.html b/archives/2019/11/index.html
index e69de29..729e05d 100644
--- a/archives/2019/11/index.html
+++ b/archives/2019/11/index.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/archives/2019/index.html b/archives/2019/index.html
index e69de29..729e05d 100644
--- a/archives/2019/index.html
+++ b/archives/2019/index.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/archives/2020/01/index.html b/archives/2020/01/index.html
index e69de29..729e05d 100644
--- a/archives/2020/01/index.html
+++ b/archives/2020/01/index.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/archives/2020/03/index.html b/archives/2020/03/index.html
index e69de29..729e05d 100644
--- a/archives/2020/03/index.html
+++ b/archives/2020/03/index.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/archives/2020/04/index.html b/archives/2020/04/index.html
index e69de29..729e05d 100644
--- a/archives/2020/04/index.html
+++ b/archives/2020/04/index.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/archives/2020/index.html b/archives/2020/index.html
index e69de29..729e05d 100644
--- a/archives/2020/index.html
+++ b/archives/2020/index.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/archives/index.html b/archives/index.html
index e69de29..729e05d 100644
--- a/archives/index.html
+++ b/archives/index.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bc/index.html b/bc/index.html
index e69de29..01d7a3d 100644
--- a/bc/index.html
+++ b/bc/index.html
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 配置浏览器地址栏作为超级计算器(bc)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bookmarklet/index.html b/bookmarklet/index.html
index e69de29..610a106 100644
--- a/bookmarklet/index.html
+++ b/bookmarklet/index.html
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 小书签
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cmd/index.html b/cmd/index.html
index e69de29..ba00ce1 100644
--- a/cmd/index.html
+++ b/cmd/index.html
@@ -0,0 +1,181 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 一键执行任意预定义命令(附手机PC剪贴板互通)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 一键执行任意预定义命令(附手机PC剪贴板互通)
+
+
+
+
Post:2019-06-05 17:55:34
+
+
Tags:/
+
+ termux
+ /
+
+ ssh
+ /
+
+ 剪贴板
+ /
+
+
+
+
+
+
+
+
技巧等级:中级 PC剪贴板(高级)
+
uweb浏览器支持一键执行任意预定义命令,这些命令可以与剪贴板交互,可以将结果(文本、图像、音视频)输出到浏览器窗口。
+
手机推荐安装uweb定制Termux,否则能够执行的命令极其有限。
+
预定义命令保存在文件”/sdcard/uweb/default.cmds”中。重启浏览器,长按历史按钮,超微将弹出菜单供用户点击执行。
+
资深用户可能注意到文件名与default.acmd类似。default.acmd中的命令适合以不同的参数反复执行;而default.cmds一般以单次执行为多。default.acmd结果会显示在浏览器当前窗口;而default.cmds中命令执行结果会显示在新窗口之中。这两个文件格式也完全相同,每行格式如下:
[命令名称]:[mimetype]:[命令代码]
+
命令代码可以是任意命令,其中可以包含%c(当前网址cookie)、%s (地址栏输入)、 %t (当前窗口标题)、 %u (当前窗口url或文件路径)。执行时这些特殊标识将会被相应内容自动替换。
+
mimetype用来表示命令的输出类型。除了标准的mimetype之外,超微对此还作了扩充,便利与剪贴板交互。下面是扩充版的mimetype:
“clip/clip” : 以剪贴板作为命令输入,输出结果复制到剪贴板。
“/clip” : 输出结果复制到剪贴板。
“clip/text/html” : 以剪贴板作为命令输入,输出结果mimetype类型为“text/html”。
“termux/*”: 在termux中执行命令。
+
下面是笔者使用的default.cmds配置(命令具体解释):
+
复制手机剪贴板至PC剪贴板:clip:ssh [user:password]@192.168.2.102 "DISPLAY=:0 xsel -i"
+PC剪贴板至手机剪贴板:/clip:ssh [user:password]@192.168.2.102 "DISPLAY=:0 xsel -o"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/css/aircloud.css b/css/aircloud.css
index e69de29..2e177cf 100644
--- a/css/aircloud.css
+++ b/css/aircloud.css
@@ -0,0 +1,1146 @@
+/*varibles*/
+* {
+ font-family: "italic", Helvetica, Arial, "Heiti SC", "Microsoft YaHei";
+}
+body,
+html {
+ margin: 0;
+ padding: 0;
+}
+body {
+ margin-left: calc(100vw - 100%) !important;
+}
+.red {
+ color: red;
+}
+.hide {
+ display: none !important;
+}
+.show-block {
+ display: block !important;
+}
+.show-block {
+ animation: showBlock 0.4s forwards;
+ display: block !important;
+}
+@keyframes showBlock {
+ from {
+ opacity: 0;
+ transform: translateY(-100%);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+.hide-block {
+ display: block !important;
+ animation: hideBlock 0.4s forwards;
+ opacity: 1;
+ transform: translateY(0);
+}
+@keyframes hideBlock {
+ from {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ to {
+ opacity: 0;
+ transform: translateY(-100%);
+ display: none;
+ }
+}
+.show-flex-fade {
+ animation: showFade 0.4s forwards;
+ display: flex !important;
+}
+.hide-flex-fade {
+ animation: hideFade 0.4s forwards;
+}
+@keyframes showFade {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+@keyframes hideFade {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ display: none !important;
+ }
+}
+.no-indent {
+ text-indent: 0 !important;
+}
+.no-indent p,
+.no-indent h1,
+.no-indent h2,
+.no-indent h3,
+.no-indent h4,
+.no-indent h5,
+.no-indent h6,
+.no-indent ul,
+.no-indent ol {
+ text-indent: 0 !important;
+}
+.nav {
+ position: relative;
+ padding-top: 50px;
+ color: #333333;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+.nav .avatar-name {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ border-bottom: 1px solid #979797;
+}
+.nav .avatar-name .avatar {
+ width: 120px;
+ height: 120px;
+ padding: 10px;
+ box-sizing: border-box;
+}
+.nav .avatar-name .avatar img {
+ width: 100px;
+ height: 100px;
+}
+.nav .avatar-name .name {
+ margin-top: 10px;
+ margin-bottom: 20px;
+}
+.nav .avatar-name .name i {
+ font-size: 16px;
+ font-family: "italic" !important;
+ font-weight: 300;
+ color: #666666;
+}
+.nav .contents ul {
+ width: 100%;
+ padding-left: 0;
+ margin-top: 25px;
+ margin-bottom: 25px;
+}
+.nav .contents ul li,
+.nav .contents ul li a {
+ text-decoration: none;
+ font-size: 15px;
+ margin: 20px auto;
+ padding-left: 0;
+ list-style: none;
+}
+.nav .contents ul li i,
+.nav .contents ul li a i {
+ cursor: pointer;
+ color: #999999;
+ margin-right: 5px;
+}
+.nav .contents ul li span,
+.nav .contents ul li a span {
+ cursor: pointer;
+ color: #999999;
+}
+.nav .contents ul li.active span,
+.nav .contents ul li.active i {
+ color: #4a4a4a;
+}
+.nav .contents ul li:hover span,
+.nav .contents ul li:hover i {
+ color: #4a4a4a;
+}
+.site-nav-toggle {
+ display: none;
+}
+.site-nav-toggle button {
+ outline: none;
+ margin-top: 2px;
+ padding: 9px 10px;
+ background: transparent;
+ border: none;
+ user-select: none;
+}
+.site-nav-toggle button .btn-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ background: #666666;
+ border-radius: 1px;
+}
+.site-nav-toggle button .btn-bar + .btn-bar {
+ margin-top: 4px;
+}
+.search-field {
+ overflow: hidden;
+ display: none;
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ z-index: 3;
+ left: 0;
+ right: 0;
+ width: 100vw;
+ height: 100vh;
+ background-color: rgba(0, 0, 0, 0.3);
+ align-items: center;
+ flex-direction: column;
+}
+.search-field .search-container {
+ width: 40vw;
+ min-width: 500px;
+ height: 70vh;
+ margin-top: 15vh;
+}
+.search-field .search-container .search-input {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ padding-top: 10px;
+}
+.search-field .search-container .search-input span {
+ width: 60px;
+ color: #999999;
+ line-height: 30px;
+ text-align: center;
+}
+.search-field .search-container .search-input span:nth-child(1) {
+ width: 40px;
+}
+.search-field .search-container .search-input #begin-search {
+ cursor: pointer;
+}
+.search-field .search-container .search-input #begin-search:hover {
+ color: #4a4a4a;
+}
+.search-field .search-container .search-input input {
+ flex: 1;
+ background-color: #f3f4f7;
+ border: 1px solid #cccccc;
+ height: 30px;
+ font-size: 18px;
+ color: #4a4a4a;
+ box-sizing: border-box;
+ font-weight: 300;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+.search-field .search-result-container {
+ height: calc(70vh - 50px);
+ overflow-y: scroll;
+ overflow-x: hidden;
+}
+.search-field .search-result-container::-webkit-scrollbar {
+ width: 4px;
+}
+.search-field .search-result-container .no-search-result {
+ width: 100%;
+ height: 200px;
+ text-align: center;
+ padding-top: 100px;
+ color: #999999;
+ font-size: 16px;
+}
+.search-field .search-result-container::-webkit-scrollbar-thumb {
+ background-color: #c3c4c7;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+}
+.search-field .search-result-container ul {
+ margin-top: 10px;
+ width: calc(100% - 25px);
+ padding-left: 10px;
+}
+.search-field .search-result-container ul li {
+ margin-bottom: 15px;
+ list-style: none;
+}
+.search-field .search-result-container ul li a {
+ text-decoration: none;
+ cursor: pointer;
+ font-size: 16px;
+ color: #4a4a4a;
+ font-weight: 300;
+ padding-bottom: 5px;
+}
+.search-field .search-result-container ul li ul {
+ padding-left: 10px;
+}
+.search-field .search-result-container ul li ul li {
+ list-style: none;
+ color: #666666;
+ font-weight: 300;
+ font-size: 13px;
+}
+@media screen and (max-width: 680px) {
+ .search-field .search-container {
+ min-width: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ }
+ .search-field .search-result-container {
+ height: calc(100vh - 50px);
+ }
+ .nav {
+ margin-top: 50px;
+ position: relative;
+ top: 0;
+ width: 100%;
+ }
+ .nav .avatar-name {
+ border-bottom: none;
+ }
+ .nav .contents {
+ display: none;
+ position: fixed;
+ left: 0;
+ top: 40px;
+ width: 100%;
+ border-bottom: 1px solid #CCCCCC;
+ border-top: 1px solid #CCCCCC;
+ }
+ .nav .contents ul {
+ padding-left: 30px;
+ }
+ .site-nav-toggle {
+ height: 40px;
+ box-sizing: border-box;
+ display: block;
+ position: fixed;
+ width: 100%;
+ padding-top: 2px;
+ padding-left: 20px;
+ z-index: 2;
+ }
+}
+.post-preview {
+ width: 100%;
+ height: max-content;
+ margin-bottom: 10px;
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: row;
+}
+.post-preview .post-time {
+ font-size: 17px;
+ color: #999999;
+ width: 125px;
+ font-weight: 300;
+ line-height: 24px;
+}
+.post-preview .post-info {
+ flex: 1;
+}
+.post-preview .post-info a {
+ cursor: pointer;
+ text-decoration: none;
+}
+.post-preview .post-info a h3 {
+ line-height: 24px;
+ cursor: pointer;
+ margin-top: 0;
+ margin-bottom: 5px;
+ color: #101010;
+ font-size: 18px;
+ font-weight: 300;
+ transition: color 0.4s;
+}
+.post-preview .post-info a h3:hover {
+ color: #4990E2;
+}
+.post-preview .post-info p {
+ margin-top: 0;
+}
+.post-preview .post-info p span,
+.post-preview .post-info p a {
+ font-weight: 300;
+ color: #999999;
+ font-size: 14px;
+ text-decoration: none;
+}
+.post-preview-container {
+ min-height: 420px;
+}
+.pager {
+ width: 100%;
+ height: 40px;
+ padding-left: 0;
+ display: flex;
+}
+.pager .previous {
+ flex: 1;
+ display: flex;
+ flex-direction: row;
+ cursor: pointer;
+}
+.pager .next {
+ flex: 1;
+ display: flex;
+ flex-direction: row-reverse;
+ cursor: pointer;
+}
+.pager .previous a,
+.pager .next a {
+ box-sizing: border-box;
+ cursor: pointer;
+ transition: color 0.4s, background-color 0.4s;
+ border: 1px solid #999999;
+ line-height: 40px;
+ width: 150px;
+ height: 40px;
+ font-size: 18px;
+ color: #999999;
+ text-align: center;
+ text-decoration: none;
+}
+.pager .previous a:hover,
+.pager .next a:hover {
+ color: white;
+ cursor: pointer;
+ background-color: #666666;
+}
+@media screen and (max-width: 680px) {
+ .post-preview-container {
+ min-height: 0 !important;
+ }
+ .post-preview {
+ width: 100%;
+ height: max-content;
+ margin-bottom: 10px;
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ padding-left: 10px;
+ padding-right: 10px;
+ border-bottom: 1px solid #EEEEEE;
+ }
+ .post-preview .post-time {
+ font-size: 11px;
+ color: #999999;
+ width: 125px;
+ font-weight: 300;
+ line-height: 20px;
+ font-style: oblique;
+ }
+ .post-preview .post-info {
+ flex: 1;
+ }
+ .post-preview .post-info a {
+ cursor: pointer;
+ text-decoration: none;
+ }
+ .post-preview .post-info a h3 {
+ line-height: 20px;
+ cursor: pointer;
+ margin-top: 0;
+ margin-bottom: 5px;
+ color: #101010;
+ font-size: 15px;
+ font-weight: 300;
+ }
+ .post-preview .post-info p {
+ margin-top: 0;
+ }
+ .post-preview .post-info p span,
+ .post-preview .post-info p a {
+ font-weight: 300;
+ color: #999999;
+ font-size: 12px;
+ text-decoration: none;
+ }
+ .pager {
+ width: 100%;
+ height: 40px;
+ padding-left: 10px;
+ padding-right: 10px;
+ display: flex;
+ }
+ .pager .previous {
+ flex: 1;
+ display: flex;
+ flex-direction: row;
+ cursor: pointer;
+ }
+ .pager .next {
+ flex: 1;
+ display: flex;
+ flex-direction: row-reverse;
+ cursor: pointer;
+ }
+ .pager .previous a,
+ .pager .next a {
+ box-sizing: border-box;
+ cursor: pointer;
+ transition: color 0.4s, background-color 0.4s;
+ border: 1px solid #999999;
+ line-height: 30px;
+ width: 120px;
+ height: 30px;
+ font-size: 14px;
+ color: #999999;
+ text-align: center;
+ text-decoration: none;
+ }
+ .pager .previous a:hover,
+ .pager .next a:hover {
+ color: white;
+ cursor: pointer;
+ background-color: #666666;
+ }
+}
+.tags {
+ line-height: 30px;
+ margin-bottom: 25px;
+}
+.tags a {
+ text-decoration: none;
+ color: #999999;
+ margin-right: 15px;
+}
+.tags a:hover {
+ color: #4a4a4a;
+}
+.tags a::before {
+ content: "#";
+}
+.one-tag-list {
+ margin-bottom: 25px;
+}
+.one-tag-list .fa-tag {
+ margin-bottom: 15px;
+ display: block;
+ color: #999999;
+}
+.one-tag-list .post-preview {
+ padding-left: 2em;
+}
+.one-tag-list .post-preview a {
+ cursor: pointer;
+ text-decoration: none;
+}
+.one-tag-list .post-preview a .post-title {
+ margin-bottom: 5px;
+ line-height: 20px;
+ cursor: pointer;
+ margin-top: 0;
+ color: #101010;
+ font-size: 18px;
+ font-weight: 300;
+ transition: color 0.4s;
+}
+.one-tag-list .post-preview a .post-title:hover {
+ color: #4990E2;
+}
+@media screen and (max-width: 680px) {
+ .one-tag-list {
+ margin-bottom: 25px;
+ }
+ .one-tag-list .fa-tag {
+ margin-bottom: 15px;
+ display: block;
+ color: #999999;
+ }
+ .one-tag-list .post-preview {
+ padding-left: 2em;
+ }
+ .one-tag-list .post-preview a {
+ cursor: pointer;
+ text-decoration: none;
+ }
+ .one-tag-list .post-preview a .post-title {
+ font-size: 14px;
+ font-weight: 300;
+ text-decoration: none;
+ line-height: 20px;
+ color: #4a4a4a;
+ margin-bottom: 5px;
+ cursor: pointer;
+ margin-top: 0;
+ transition: color 0.4s;
+ }
+ .one-tag-list .post-preview a .post-title:hover {
+ color: #4990E2;
+ }
+}
+.post-container {
+ width: 100%;
+ height: max-content;
+ display: flex;
+ flex-direction: column;
+}
+.post-container .post-title {
+ width: 100%;
+ text-align: center;
+ line-height: 24px;
+ margin-top: 0;
+ margin-bottom: 5px;
+ color: #101010;
+ font-size: 20px;
+ font-weight: 300;
+}
+.post-container .post-meta {
+ text-align: center;
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+.post-container .post-meta span,
+.post-container .post-meta a {
+ font-weight: 300;
+ color: #999999;
+ font-size: 13px;
+ text-decoration: none;
+}
+.post-container .post-meta .attr {
+ margin-right: 5px;
+ margin-left: 5px;
+}
+.post-content {
+ line-height: 20px;
+ font-size: 15px;
+ text-indent: 0;
+ color: #333333;
+ font-weight: 300;
+}
+.post-content blockquote {
+ border-top: 1px solid #cccccc;
+ border-bottom: 1px solid #cccccc;
+ margin-left: 2em;
+ margin-right: 2em;
+ padding-left: 0;
+ padding-right: 0;
+}
+.post-content blockquote p {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ color: #666666;
+}
+.post-content a {
+ text-decoration: none;
+ color: #4990E2;
+}
+.post-content p {
+ color: #404040;
+ font-size: 14px;
+ line-height: 30px;
+ text-indent: 0;
+ letter-spacing: 1px;
+}
+.post-content p img {
+ width: 80%;
+}
+.post-content ul,
+.post-content ol {
+ padding-left: 2em;
+}
+.post-content ul li,
+.post-content ol li {
+ list-style: none;
+ color: #404040;
+ font-size: 14px;
+ line-height: 30px;
+ text-indent: 0;
+ letter-spacing: 1px;
+ margin-bottom: 5px;
+ margin-top: 5px;
+}
+.post-content ul li:before,
+.post-content ol li:before {
+ content: '• ';
+}
+.post-content pre {
+ text-indent: 0;
+ padding: 10px;
+}
+.post-content pre code {
+ line-height: 175%;
+}
+.post-content h1 {
+ color: #333333;
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+.post-content h2 {
+ color: #333333;
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+.post-content h3 {
+ color: #333333;
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+.post-content h4 {
+ color: #333333;
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+.post-content h5 {
+ color: #333333;
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+.post-content h6 {
+ color: #333333;
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+#comment-container {
+ text-indent: 0;
+}
+#lv-container {
+ text-indent: 0;
+}
+.post-content li p {
+ display: inline;
+}
+.index-about {
+ text-align: center;
+ width: 100%;
+ margin-top: 45px;
+ margin-bottom: 40px;
+ opacity: 0;
+ animation: showBlock 1.6s forwards;
+}
+.index-about i {
+ font-size: 15px;
+ font-family: "italic" !important;
+ font-weight: 300;
+ color: #444444;
+}
+.index-about-mobile {
+ display: none;
+}
+.index-container {
+ justify-content: center;
+ height: max-content;
+ position: relative;
+ width: 1024px;
+ margin: auto;
+ display: flex;
+ flex-direction: row;
+}
+.index-container .index-left {
+ width: 240px;
+}
+.index-container .index-middle {
+ max-width: 784px;
+ flex: 1;
+}
+@media screen and (max-width: 1180px) {
+ .index-container {
+ left: 0;
+ width: 100%;
+ box-sizing: border-box;
+ margin: auto;
+ padding: 0 40px 0 10px;
+ display: flex;
+ flex-direction: row;
+ }
+ .index-container .index-left {
+ width: 180px;
+ }
+ .index-container .index-middle {
+ flex: 1;
+ max-width: calc(100% - 180px);
+ }
+}
+@media screen and (max-width: 680px) {
+ .index-container {
+ width: 100%;
+ box-sizing: border-box;
+ margin: auto;
+ display: flex;
+ flex-direction: column;
+ padding: 0 25px 0 25px;
+ min-height: 0;
+ }
+ .index-container .index-left {
+ width: 100%;
+ }
+ .index-container .index-middle {
+ max-width: 100%;
+ flex: 1;
+ }
+ .index-about {
+ display: none;
+ }
+ .index-about-mobile {
+ display: block;
+ text-align: center;
+ width: 100%;
+ margin-top: 0;
+ margin-bottom: 40px;
+ }
+ .index-about-mobile i {
+ font-size: 15px;
+ font-family: "italic" !important;
+ font-weight: 300;
+ color: #444444;
+ }
+}
+.archives-container .one-tag-list .listing-seperator {
+ font-size: 18px;
+ color: #999999;
+}
+.archives-container .one-tag-list ul {
+ list-style: none;
+}
+.archives-container .one-tag-list ul li {
+ display: flex;
+ align-items: center;
+ flex-direction: row;
+ margin-bottom: 10px;
+}
+.archives-container .one-tag-list ul li span {
+ color: #999999;
+ margin-right: 15px;
+ min-width: 45px;
+}
+.archives-container .one-tag-list ul li a {
+ text-decoration: none;
+ line-height: 20px;
+ color: #4a4a4a;
+}
+.archives-container .one-tag-list ul li a span {
+ color: #4a4a4a;
+ transition: color 0.4s;
+}
+.archives-container .one-tag-list ul li a span:hover {
+ color: #4990E2;
+}
+@media screen and (max-width: 680px) {
+ .archives-container .one-tag-list .listing-seperator {
+ font-size: 18px;
+ color: #999999;
+ }
+ .archives-container .one-tag-list ul {
+ list-style: none;
+ padding-left: 1em;
+ }
+ .archives-container .one-tag-list ul li {
+ display: flex;
+ align-items: center;
+ flex-direction: row;
+ margin-bottom: 10px;
+ }
+ .archives-container .one-tag-list ul li span {
+ color: #999999;
+ margin-right: 15px;
+ min-width: 45px;
+ font-size: 14px;
+ }
+ .archives-container .one-tag-list ul li i {
+ font-size: 12px;
+ }
+ .archives-container .one-tag-list ul li a {
+ font-size: 14px;
+ font-weight: 300;
+ text-decoration: none;
+ line-height: 20px;
+ color: #4a4a4a;
+ }
+ .archives-container .one-tag-list ul li a span {
+ color: #4a4a4a;
+ }
+}
+pre,
+.highlight {
+ overflow: auto;
+ margin: 20px 0;
+ padding: 0;
+ font-size: 13px;
+ color: #4d4d4c;
+ background: #f7f7f7;
+ line-height: 1.6;
+}
+pre,
+code {
+ font-family: consolas, Menlo, "PingFang SC", "Microsoft YaHei", monospace;
+}
+code {
+ padding: 2px 4px;
+ word-wrap: break-word;
+ color: #555;
+ background: #eee;
+ border-radius: 3px;
+ font-size: 13px;
+}
+pre {
+ padding: 10px;
+}
+pre code {
+ padding: 0;
+ color: #4d4d4c;
+ background: none;
+ text-shadow: none;
+}
+.highlight {
+ border-radius: 1px;
+}
+.highlight pre {
+ border: none;
+ margin: 0;
+ padding: 10px 0;
+}
+.highlight table {
+ margin: 0;
+ width: auto;
+ border: none;
+}
+.highlight td {
+ border: none;
+ padding: 0;
+}
+.highlight figcaption {
+ font-size: 1em;
+ color: #4d4d4c;
+ line-height: 1em;
+ margin-bottom: 1em;
+}
+.highlight figcaption a {
+ float: right;
+ color: #4d4d4c;
+}
+.highlight figcaption a:hover {
+ border-bottom-color: #4d4d4c;
+}
+.highlight .gutter pre {
+ padding-left: 10px;
+ padding-right: 10px;
+ color: #869194;
+ text-align: right;
+ background-color: #eff2f3;
+}
+.highlight .code pre {
+ width: 100%;
+ padding-left: 10px;
+ padding-right: 10px;
+ background-color: #f7f7f7;
+}
+.highlight .line {
+ height: 20px;
+}
+.gutter {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.gist table {
+ width: auto;
+}
+.gist table td {
+ border: none;
+}
+pre .deletion {
+ background: #fdd;
+}
+pre .addition {
+ background: #dfd;
+}
+pre .meta {
+ color: #8959a8;
+}
+pre .comment {
+ color: #8e908c;
+}
+pre .variable,
+pre .attribute,
+pre .tag,
+pre .regexp,
+pre .ruby .constant,
+pre .xml .tag .title,
+pre .xml .pi,
+pre .xml .doctype,
+pre .html .doctype,
+pre .css .id,
+pre .css .class,
+pre .css .pseudo {
+ color: #c82829;
+}
+pre .number,
+pre .preprocessor,
+pre .built_in,
+pre .literal,
+pre .params,
+pre .constant,
+pre .command {
+ color: #f5871f;
+}
+pre .ruby .class .title,
+pre .css .rules .attribute,
+pre .string,
+pre .value,
+pre .inheritance,
+pre .header,
+pre .ruby .symbol,
+pre .xml .cdata,
+pre .special,
+pre .number,
+pre .formula {
+ color: #718c00;
+}
+pre .title,
+pre .css .hexcolor {
+ color: #3e999f;
+}
+pre .function,
+pre .python .decorator,
+pre .python .title,
+pre .ruby .function .title,
+pre .ruby .title .keyword,
+pre .perl .sub,
+pre .javascript .title,
+pre .coffeescript .title {
+ color: #4271ae;
+}
+pre .keyword,
+pre .javascript .function {
+ color: #8959a8;
+}
+.footer {
+ width: 100%;
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ color: #979797;
+ margin-bottom: 10px;
+}
+.footer p {
+ font-family: "Montserrat", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, sans-serif;
+ font-size: 14px;
+ margin-top: 5px;
+ margin-bottom: 0;
+ font-weight: 300;
+}
+.footer p a {
+ font-weight: 300;
+ font-family: "Montserrat", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, sans-serif;
+ cursor: pointer;
+ color: #333333;
+}
+.footer p span a {
+ font-weight: 300;
+ font-family: "Montserrat", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, sans-serif;
+ cursor: pointer;
+ color: #979797;
+ text-decoration: none;
+}
+.footer p span a:hover {
+ color: #333333;
+}
+.list-inline.text-center {
+ color: #444444;
+ font-size: 20px;
+ padding-left: 0;
+ margin-bottom: 0;
+}
+.list-inline.text-center li {
+ display: inline-block;
+ margin: 0 2px;
+ background-color: #979797;
+ height: 24px;
+ width: 24px;
+ border-radius: 12px;
+ text-align: center;
+}
+.list-inline.text-center li a {
+ text-decoration: none;
+}
+.list-inline.text-center li a span i {
+ line-height: 20px;
+ color: white;
+}
+.list-inline.text-center li:hover {
+ background-color: #333333;
+}
+@media screen and (max-width: 680px) {
+ .footer {
+ box-sizing: border-box;
+ padding-left: 20px;
+ padding-right: 20px;
+ }
+ .footer p {
+ font-family: "Montserrat", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, sans-serif;
+ font-size: 11px;
+ margin-top: 5px;
+ margin-bottom: 0;
+ font-weight: 300;
+ }
+ .footer p span a {
+ font-size: 11px;
+ font-weight: 300;
+ font-family: "Montserrat", "Helvetica Neue", "Hiragino Sans GB", "LiHei Pro", Arial, sans-serif;
+ cursor: pointer;
+ color: #979797;
+ text-decoration: none;
+ }
+ .footer p span a:hover {
+ color: #333333;
+ }
+}
+.toc-article {
+ width: 240px;
+}
+.toc-article ol {
+ padding-left: 10px;
+ cursor: pointer;
+ font-size: 0;
+}
+.toc-article li {
+ font-size: 0;
+ box-sizing: border-box;
+ border-left: 2px solid #cccccc;
+ list-style: none;
+ padding-left: 10px;
+}
+.toc-article li a {
+ display: block;
+ line-height: 20px;
+ margin-bottom: 10px;
+ text-decoration: none;
+ color: #999999;
+ font-size: 14px;
+}
+.toc-article li a span {
+ word-break: break-all;
+}
+.toc-article li.active {
+ border-left: 2px solid #4990E2;
+}
+.toc-article li.active > a {
+ color: #4990E2;
+}
+.toc-article li:hover {
+ border-left: 2px solid #4990E2;
+}
+.toc-article li:hover > a {
+ color: #4990E2;
+}
+.toc-article > ol > li {
+ border-left: none !important;
+}
+.toc-fixed {
+ position: fixed;
+ top: 10px;
+ width: 240px;
+}
+.toc-fixed::-webkit-scrollbar {
+ width: 0;
+}
+.toc-fixed::-webkit-scrollbar-thumb {
+ -webkit-border-radius: 4px;
+ border-radius: 2px;
+}
+@media screen and (max-width: 1180px) {
+ .toc-article {
+ display: none;
+ }
+}
diff --git a/css/aircloud.less b/css/aircloud.less
index e69de29..58208cd 100644
--- a/css/aircloud.less
+++ b/css/aircloud.less
@@ -0,0 +1,19 @@
+@import "../_less/variables";
+@import "../_less/common";
+@import "../_less/nav";
+@import "../_less/about";
+@import "../_less/index";
+@import "../_less/tag";
+@import "../_less/post";
+@import "../_less/page";
+@import "../_less/layout";
+
+
+@import "../_less/archive";
+
+@import "../_less/hightlight";
+// _partial:
+@import "../_less/_partial/footer";
+
+@import "../_less/toc";
+
diff --git a/css/gitment.css b/css/gitment.css
index e69de29..5414f78 100644
--- a/css/gitment.css
+++ b/css/gitment.css
@@ -0,0 +1,1146 @@
+.gitment-container {
+ font-family: sans-serif;
+ font-size: 14px;
+ line-height: 1.5;
+ color: #333;
+ word-wrap: break-word;
+}
+
+.gitment-container * {
+ box-sizing: border-box;
+}
+
+.gitment-container *:disabled {
+ cursor: not-allowed;
+}
+
+.gitment-container a,
+.gitment-container a:visited {
+ cursor: pointer;
+ text-decoration: none;
+}
+
+.gitment-container a:hover {
+ text-decoration: underline;
+}
+
+.gitment-container .gitment-hidden {
+ display: none;
+}
+
+.gitment-container .gitment-spinner-icon {
+ fill: #333;
+
+ -webkit-animation: gitment-spin 1s steps(12) infinite;
+ animation: gitment-spin 1s steps(12) infinite;
+}
+
+@-webkit-keyframes gitment-spin {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg)
+ }
+}
+
+@keyframes gitment-spin {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg)
+ }
+}
+
+.gitment-root-container {
+ margin: 19px 0;
+}
+
+.gitment-header-container {
+ margin: 19px 0;
+}
+
+.gitment-header-like-btn,
+.gitment-comment-like-btn {
+ cursor: pointer;
+}
+
+.gitment-comment-like-btn {
+ float: right;
+}
+
+.gitment-comment-like-btn.liked {
+ color: #F44336;
+}
+
+.gitment-header-like-btn svg {
+ vertical-align: middle;
+ height: 30px;
+}
+
+.gitment-comment-like-btn svg {
+ vertical-align: middle;
+ height: 20px;
+}
+
+.gitment-header-like-btn.liked svg,
+.gitment-comment-like-btn.liked svg {
+ fill: #F44336;
+}
+
+a.gitment-header-issue-link,
+a.gitment-header-issue-link:visited {
+ float: right;
+ line-height: 30px;
+ color: #666;
+}
+
+a.gitment-header-issue-link:hover {
+ color: #666;
+}
+
+.gitment-comments-loading,
+.gitment-comments-error,
+.gitment-comments-empty {
+ text-align: center;
+ margin: 50px 0;
+}
+
+.gitment-comments-list {
+ list-style: none;
+ padding-left: 0;
+ margin: 0 0 38px;
+}
+
+.gitment-comment,
+.gitment-editor-container {
+ position: relative;
+ min-height: 60px;
+ padding-left: 60px;
+ margin: 19px 0;
+}
+
+.gitment-comment-avatar,
+.gitment-editor-avatar {
+ float: left;
+ margin-left: -60px;
+}
+
+.gitment-comment-avatar,
+.gitment-comment-avatar-img,
+.gitment-comment-avatar,
+.gitment-editor-avatar-img,
+.gitment-editor-avatar svg {
+ width: 44px;
+ height: 44px;
+ border-radius: 3px;
+}
+
+.gitment-editor-avatar .gitment-github-icon {
+ fill: #fff;
+ background-color: #333;
+}
+
+.gitment-comment-main,
+.gitment-editor-main {
+ position: relative;
+ border: 1px solid #CFD8DC;
+ border-radius: 0;
+}
+
+.gitment-editor-main::before,
+.gitment-editor-main::after,
+.gitment-comment-main::before,
+.gitment-comment-main::after {
+ position: absolute;
+ top: 11px;
+ left: -16px;
+ display: block;
+ width: 0;
+ height: 0;
+ pointer-events: none;
+ content: "";
+ border-color: transparent;
+ border-style: solid solid outset;
+}
+
+.gitment-editor-main::before,
+.gitment-comment-main::before {
+ border-width: 8px;
+ border-right-color: #CFD8DC;
+}
+
+.gitment-editor-main::after,
+.gitment-comment-main::after {
+ margin-top: 1px;
+ margin-left: 2px;
+ border-width: 7px;
+ border-right-color: #fff;
+}
+
+.gitment-comment-header {
+ margin: 12px 15px;
+ color: #666;
+ background-color: #fff;
+ border-radius: 3px;
+}
+
+.gitment-editor-header {
+ padding: 0;
+ margin: 0;
+ border-bottom: 1px solid #CFD8DC;
+}
+
+a.gitment-comment-name,
+a.gitment-comment-name:visited {
+ font-weight: 600;
+ color: #666;
+}
+
+.gitment-editor-tabs {
+ margin-bottom: -1px;
+ margin-left: -1px;
+}
+
+.gitment-editor-tab {
+ display: inline-block;
+ padding: 11px 12px;
+ font-size: 14px;
+ line-height: 20px;
+ color: #666;
+ text-decoration: none;
+ background-color: transparent;
+ border-width: 0 1px;
+ border-style: solid;
+ border-color: transparent;
+ border-radius: 0;
+
+ white-space: nowrap;
+ cursor: pointer;
+ user-select: none;
+
+ outline: none;
+}
+
+.gitment-editor-tab.gitment-selected {
+ color: #333;
+ background-color: #fff;
+ border-color: #CFD8DC;
+}
+
+.gitment-editor-login {
+ float: right;
+ margin-top: -30px;
+ margin-right: 15px;
+}
+
+a.gitment-footer-project-link,
+a.gitment-footer-project-link:visited,
+a.gitment-editor-login-link,
+a.gitment-editor-login-link:visited {
+ color: #2196F3;
+}
+
+a.gitment-editor-logout-link,
+a.gitment-editor-logout-link:visited {
+ color: #666;
+}
+
+a.gitment-editor-logout-link:hover {
+ color: #2196F3;
+ text-decoration: none;
+}
+
+.gitment-comment-body {
+ position: relative;
+ margin: 12px 15px;
+ overflow: hidden;
+ border-radius: 3px;
+}
+
+.gitment-comment-body-folded {
+ cursor: pointer;
+}
+
+.gitment-comment-body-folded::before {
+ display: block !important;
+ content: "";
+ position: absolute;
+ width: 100%;
+ left: 0;
+ top: 0;
+ bottom: 50px;
+ pointer-events: none;
+ background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0), rgba(255, 255, 255, .9));
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, .9));
+}
+
+.gitment-comment-body-folded::after {
+ display: block !important;
+ content: "Click to Expand" !important;
+ text-align: center;
+ color: #666;
+ position: absolute;
+ width: 100%;
+ height: 50px;
+ line-height: 50px;
+ left: 0;
+ bottom: 0;
+ pointer-events: none;
+ background: rgba(255, 255, 255, .9);
+}
+
+.gitment-editor-body {
+ margin: 0;
+}
+
+.gitment-comment-body > *:first-child,
+.gitment-editor-preview > *:first-child {
+ margin-top: 0 !important;
+}
+
+.gitment-comment-body > *:last-child,
+.gitment-editor-preview > *:last-child {
+ margin-bottom: 0 !important;
+}
+
+.gitment-editor-body textarea {
+ display: block;
+ width: 100%;
+ min-height: 150px;
+ max-height: 500px;
+ padding: 16px;
+ resize: vertical;
+
+ max-width: 100%;
+ margin: 0;
+ font-size: 14px;
+ line-height: 1.6;
+
+ background-color: #fff;
+
+ color: #333;
+ vertical-align: middle;
+ border: none;
+ border-radius: 0;
+ outline: none;
+ box-shadow: none;
+
+ overflow: visible;
+}
+
+.gitment-editor-body textarea:focus {
+ background-color: #fff;
+}
+
+.gitment-editor-preview {
+ min-height: 150px;
+
+ padding: 16px;
+ background-color: transparent;
+
+ width: 100%;
+ font-size: 14px;
+
+ line-height: 1.5;
+ word-wrap: break-word;
+}
+
+.gitment-editor-footer {
+ padding: 0;
+ margin-top: 10px;
+}
+
+.gitment-editor-footer::after {
+ display: table;
+ clear: both;
+ content: "";
+}
+
+a.gitment-editor-footer-tip {
+ display: inline-block;
+ padding-top: 10px;
+ font-size: 12px;
+ color: #666;
+}
+
+a.gitment-editor-footer-tip:hover {
+ color: #2196F3;
+ text-decoration: none;
+}
+
+.gitment-comments-pagination {
+ list-style: none;
+ text-align: right;
+ border-radius: 0;
+ margin: -19px 0 19px 0;
+}
+
+.gitment-comments-page-item {
+ display: inline-block;
+ cursor: pointer;
+ border: 1px solid #CFD8DC;
+ margin-left: -1px;
+ padding: .25rem .5rem;
+}
+
+.gitment-comments-page-item:hover {
+ background-color: #f5f5f5;
+}
+
+.gitment-comments-page-item.gitment-selected {
+ background-color: #f5f5f5;
+}
+
+.gitment-editor-submit,
+.gitment-comments-init-btn {
+ color: #fff;
+ background-color: #00BCD4;
+
+ position: relative;
+ display: inline-block;
+ padding: 7px 13px;
+ font-size: 14px;
+ font-weight: 600;
+ line-height: 20px;
+ white-space: nowrap;
+ vertical-align: middle;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-size: 110% 110%;
+ border: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+
+.gitment-editor-submit:hover,
+.gitment-comments-init-btn:hover {
+ background-color: #00ACC1;
+}
+
+.gitment-comments-init-btn:disabled,
+.gitment-editor-submit:disabled {
+ color: rgba(255,255,255,0.75);
+ background-color: #4DD0E1;
+ box-shadow: none;
+}
+
+.gitment-editor-submit {
+ float: right;
+}
+
+.gitment-footer-container {
+ margin-top: 30px;
+ margin-bottom: 20px;
+ text-align: right;
+ font-size: 12px;
+}
+
+/*
+ * Markdown CSS
+ * Copied from https://github.com/sindresorhus/github-markdown-css
+ */
+.gitment-markdown {
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%;
+ line-height: 1.5;
+ color: #333;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+ font-size: 16px;
+ line-height: 1.5;
+ word-wrap: break-word;
+}
+
+.gitment-markdown .pl-c {
+ color: #969896;
+}
+
+.gitment-markdown .pl-c1,
+.gitment-markdown .pl-s .pl-v {
+ color: #0086b3;
+}
+
+.gitment-markdown .pl-e,
+.gitment-markdown .pl-en {
+ color: #795da3;
+}
+
+.gitment-markdown .pl-smi,
+.gitment-markdown .pl-s .pl-s1 {
+ color: #333;
+}
+
+.gitment-markdown .pl-ent {
+ color: #63a35c;
+}
+
+.gitment-markdown .pl-k {
+ color: #a71d5d;
+}
+
+.gitment-markdown .pl-s,
+.gitment-markdown .pl-pds,
+.gitment-markdown .pl-s .pl-pse .pl-s1,
+.gitment-markdown .pl-sr,
+.gitment-markdown .pl-sr .pl-cce,
+.gitment-markdown .pl-sr .pl-sre,
+.gitment-markdown .pl-sr .pl-sra {
+ color: #183691;
+}
+
+.gitment-markdown .pl-v,
+.gitment-markdown .pl-smw {
+ color: #ed6a43;
+}
+
+.gitment-markdown .pl-bu {
+ color: #b52a1d;
+}
+
+.gitment-markdown .pl-ii {
+ color: #f8f8f8;
+ background-color: #b52a1d;
+}
+
+.gitment-markdown .pl-c2 {
+ color: #f8f8f8;
+ background-color: #b52a1d;
+}
+
+.gitment-markdown .pl-c2::before {
+ content: "^M";
+}
+
+.gitment-markdown .pl-sr .pl-cce {
+ font-weight: bold;
+ color: #63a35c;
+}
+
+.gitment-markdown .pl-ml {
+ color: #693a17;
+}
+
+.gitment-markdown .pl-mh,
+.gitment-markdown .pl-mh .pl-en,
+.gitment-markdown .pl-ms {
+ font-weight: bold;
+ color: #1d3e81;
+}
+
+.gitment-markdown .pl-mq {
+ color: #008080;
+}
+
+.gitment-markdown .pl-mi {
+ font-style: italic;
+ color: #333;
+}
+
+.gitment-markdown .pl-mb {
+ font-weight: bold;
+ color: #333;
+}
+
+.gitment-markdown .pl-md {
+ color: #bd2c00;
+ background-color: #ffecec;
+}
+
+.gitment-markdown .pl-mi1 {
+ color: #55a532;
+ background-color: #eaffea;
+}
+
+.gitment-markdown .pl-mc {
+ color: #ef9700;
+ background-color: #ffe3b4;
+}
+
+.gitment-markdown .pl-mi2 {
+ color: #d8d8d8;
+ background-color: #808080;
+}
+
+.gitment-markdown .pl-mdr {
+ font-weight: bold;
+ color: #795da3;
+}
+
+.gitment-markdown .pl-mo {
+ color: #1d3e81;
+}
+
+.gitment-markdown .pl-ba {
+ color: #595e62;
+}
+
+.gitment-markdown .pl-sg {
+ color: #c0c0c0;
+}
+
+.gitment-markdown .pl-corl {
+ text-decoration: underline;
+ color: #183691;
+}
+
+.gitment-markdown .octicon {
+ display: inline-block;
+ vertical-align: text-top;
+ fill: currentColor;
+}
+
+.gitment-markdown a {
+ background-color: transparent;
+ -webkit-text-decoration-skip: objects;
+}
+
+.gitment-markdown a:active,
+.gitment-markdown a:hover {
+ outline-width: 0;
+}
+
+.gitment-markdown strong {
+ font-weight: inherit;
+}
+
+.gitment-markdown strong {
+ font-weight: bolder;
+}
+
+.gitment-markdown h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+.gitment-markdown img {
+ border-style: none;
+}
+
+.gitment-markdown svg:not(:root) {
+ overflow: hidden;
+}
+
+.gitment-markdown code,
+.gitment-markdown kbd,
+.gitment-markdown pre {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+
+.gitment-markdown hr {
+ box-sizing: content-box;
+ height: 0;
+ overflow: visible;
+}
+
+.gitment-markdown input {
+ font: inherit;
+ margin: 0;
+}
+
+.gitment-markdown input {
+ overflow: visible;
+}
+
+.gitment-markdown [type="checkbox"] {
+ box-sizing: border-box;
+ padding: 0;
+}
+
+.gitment-markdown * {
+ box-sizing: border-box;
+}
+
+.gitment-markdown input {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+
+.gitment-markdown a {
+ color: #0366d6;
+ text-decoration: none;
+}
+
+.gitment-markdown a:hover {
+ text-decoration: underline;
+}
+
+.gitment-markdown strong {
+ font-weight: 600;
+}
+
+.gitment-markdown hr {
+ height: 0;
+ margin: 15px 0;
+ overflow: hidden;
+ background: transparent;
+ border: 0;
+ border-bottom: 1px solid #dfe2e5;
+}
+
+.gitment-markdown hr::before {
+ display: table;
+ content: "";
+}
+
+.gitment-markdown hr::after {
+ display: table;
+ clear: both;
+ content: "";
+}
+
+.gitment-markdown table {
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+
+.gitment-markdown td,
+.gitment-markdown th {
+ padding: 0;
+}
+
+.gitment-markdown h1,
+.gitment-markdown h2,
+.gitment-markdown h3,
+.gitment-markdown h4,
+.gitment-markdown h5,
+.gitment-markdown h6 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.gitment-markdown h1 {
+ font-size: 32px;
+ font-weight: 600;
+}
+
+.gitment-markdown h2 {
+ font-size: 24px;
+ font-weight: 600;
+}
+
+.gitment-markdown h3 {
+ font-size: 20px;
+ font-weight: 600;
+}
+
+.gitment-markdown h4 {
+ font-size: 16px;
+ font-weight: 600;
+}
+
+.gitment-markdown h5 {
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.gitment-markdown h6 {
+ font-size: 12px;
+ font-weight: 600;
+}
+
+.gitment-markdown p {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+
+.gitment-markdown blockquote {
+ margin: 0;
+}
+
+.gitment-markdown ul,
+.gitment-markdown ol {
+ padding-left: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.gitment-markdown ol ol,
+.gitment-markdown ul ol {
+ list-style-type: lower-roman;
+}
+
+.gitment-markdown ul ul ol,
+.gitment-markdown ul ol ol,
+.gitment-markdown ol ul ol,
+.gitment-markdown ol ol ol {
+ list-style-type: lower-alpha;
+}
+
+.gitment-markdown dd {
+ margin-left: 0;
+}
+
+.gitment-markdown code {
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ font-size: 12px;
+}
+
+.gitment-markdown pre {
+ margin-top: 0;
+ margin-bottom: 0;
+ font: 12px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+}
+
+.gitment-markdown .octicon {
+ vertical-align: text-bottom;
+}
+
+.gitment-markdown .pl-0 {
+ padding-left: 0 !important;
+}
+
+.gitment-markdown .pl-1 {
+ padding-left: 4px !important;
+}
+
+.gitment-markdown .pl-2 {
+ padding-left: 8px !important;
+}
+
+.gitment-markdown .pl-3 {
+ padding-left: 16px !important;
+}
+
+.gitment-markdown .pl-4 {
+ padding-left: 24px !important;
+}
+
+.gitment-markdown .pl-5 {
+ padding-left: 32px !important;
+}
+
+.gitment-markdown .pl-6 {
+ padding-left: 40px !important;
+}
+
+.gitment-markdown::before {
+ display: table;
+ content: "";
+}
+
+.gitment-markdown::after {
+ display: table;
+ clear: both;
+ content: "";
+}
+
+.gitment-markdown>*:first-child {
+ margin-top: 0 !important;
+}
+
+.gitment-markdown>*:last-child {
+ margin-bottom: 0 !important;
+}
+
+.gitment-markdown a:not([href]) {
+ color: inherit;
+ text-decoration: none;
+}
+
+.gitment-markdown .anchor {
+ float: left;
+ padding-right: 4px;
+ margin-left: -20px;
+ line-height: 1;
+}
+
+.gitment-markdown .anchor:focus {
+ outline: none;
+}
+
+.gitment-markdown p,
+.gitment-markdown blockquote,
+.gitment-markdown ul,
+.gitment-markdown ol,
+.gitment-markdown dl,
+.gitment-markdown table,
+.gitment-markdown pre {
+ margin-top: 0;
+ margin-bottom: 16px;
+}
+
+.gitment-markdown hr {
+ height: 0.25em;
+ padding: 0;
+ margin: 24px 0;
+ background-color: #e1e4e8;
+ border: 0;
+}
+
+.gitment-markdown blockquote {
+ padding: 0 1em;
+ color: #6a737d;
+ border-left: 0.25em solid #dfe2e5;
+}
+
+.gitment-markdown blockquote>:first-child {
+ margin-top: 0;
+}
+
+.gitment-markdown blockquote>:last-child {
+ margin-bottom: 0;
+}
+
+.gitment-markdown kbd {
+ display: inline-block;
+ padding: 3px 5px;
+ font-size: 11px;
+ line-height: 10px;
+ color: #444d56;
+ vertical-align: middle;
+ background-color: #fafbfc;
+ border: solid 1px #c6cbd1;
+ border-bottom-color: #959da5;
+ border-radius: 0;
+ box-shadow: inset 0 -1px 0 #959da5;
+}
+
+.gitment-markdown h1,
+.gitment-markdown h2,
+.gitment-markdown h3,
+.gitment-markdown h4,
+.gitment-markdown h5,
+.gitment-markdown h6 {
+ margin-top: 24px;
+ margin-bottom: 16px;
+ font-weight: 600;
+ line-height: 1.25;
+}
+
+.gitment-markdown h1 .octicon-link,
+.gitment-markdown h2 .octicon-link,
+.gitment-markdown h3 .octicon-link,
+.gitment-markdown h4 .octicon-link,
+.gitment-markdown h5 .octicon-link,
+.gitment-markdown h6 .octicon-link {
+ color: #1b1f23;
+ vertical-align: middle;
+ visibility: hidden;
+}
+
+.gitment-markdown h1:hover .anchor,
+.gitment-markdown h2:hover .anchor,
+.gitment-markdown h3:hover .anchor,
+.gitment-markdown h4:hover .anchor,
+.gitment-markdown h5:hover .anchor,
+.gitment-markdown h6:hover .anchor {
+ text-decoration: none;
+}
+
+.gitment-markdown h1:hover .anchor .octicon-link,
+.gitment-markdown h2:hover .anchor .octicon-link,
+.gitment-markdown h3:hover .anchor .octicon-link,
+.gitment-markdown h4:hover .anchor .octicon-link,
+.gitment-markdown h5:hover .anchor .octicon-link,
+.gitment-markdown h6:hover .anchor .octicon-link {
+ visibility: visible;
+}
+
+.gitment-markdown h1 {
+ padding-bottom: 0.3em;
+ font-size: 2em;
+ border-bottom: 1px solid #eaecef;
+}
+
+.gitment-markdown h2 {
+ padding-bottom: 0.3em;
+ font-size: 1.5em;
+ border-bottom: 1px solid #eaecef;
+}
+
+.gitment-markdown h3 {
+ font-size: 1.25em;
+}
+
+.gitment-markdown h4 {
+ font-size: 1em;
+}
+
+.gitment-markdown h5 {
+ font-size: 0.875em;
+}
+
+.gitment-markdown h6 {
+ font-size: 0.85em;
+ color: #6a737d;
+}
+
+.gitment-markdown ul,
+.gitment-markdown ol {
+ padding-left: 2em;
+}
+
+.gitment-markdown ul ul,
+.gitment-markdown ul ol,
+.gitment-markdown ol ol,
+.gitment-markdown ol ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.gitment-markdown li>p {
+ margin-top: 16px;
+}
+
+.gitment-markdown li+li {
+ margin-top: 0.25em;
+}
+
+.gitment-markdown dl {
+ padding: 0;
+}
+
+.gitment-markdown dl dt {
+ padding: 0;
+ margin-top: 16px;
+ font-size: 1em;
+ font-style: italic;
+ font-weight: 600;
+}
+
+.gitment-markdown dl dd {
+ padding: 0 16px;
+ margin-bottom: 16px;
+}
+
+.gitment-markdown table {
+ display: block;
+ width: 100%;
+ overflow: auto;
+}
+
+.gitment-markdown table th {
+ font-weight: 600;
+}
+
+.gitment-markdown table th,
+.gitment-markdown table td {
+ padding: 6px 13px;
+ border: 1px solid #dfe2e5;
+}
+
+.gitment-markdown table tr {
+ background-color: #fff;
+ border-top: 1px solid #c6cbd1;
+}
+
+.gitment-markdown table tr:nth-child(2n) {
+ background-color: #f5f5f5;
+}
+
+.gitment-markdown img {
+ max-width: 100%;
+ box-sizing: content-box;
+ background-color: #fff;
+}
+
+.gitment-markdown code {
+ padding: 0;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+ margin: 0;
+ font-size: 85%;
+ background-color: rgba(27,31,35,0.05);
+ border-radius: 0;
+}
+
+.gitment-markdown code::before,
+.gitment-markdown code::after {
+ letter-spacing: -0.2em;
+ content: "\00a0";
+}
+
+.gitment-markdown pre {
+ word-wrap: normal;
+}
+
+.gitment-markdown pre>code {
+ padding: 0;
+ margin: 0;
+ font-size: 100%;
+ word-break: normal;
+ white-space: pre;
+ background: transparent;
+ border: 0;
+}
+
+.gitment-markdown .highlight {
+ margin-bottom: 16px;
+}
+
+.gitment-markdown .highlight pre {
+ margin-bottom: 0;
+ word-break: normal;
+}
+
+.gitment-markdown .highlight pre,
+.gitment-markdown pre {
+ padding: 16px;
+ overflow: auto;
+ font-size: 85%;
+ line-height: 1.45;
+ background-color: #f5f5f5;
+ border-radius: 0;
+}
+
+.gitment-markdown pre code {
+ display: inline;
+ max-width: auto;
+ padding: 0;
+ margin: 0;
+ overflow: visible;
+ line-height: inherit;
+ word-wrap: normal;
+ background-color: transparent;
+ border: 0;
+}
+
+.gitment-markdown pre code::before,
+.gitment-markdown pre code::after {
+ content: normal;
+}
+
+.gitment-markdown .full-commit .btn-outline:not(:disabled):hover {
+ color: #005cc5;
+ border-color: #005cc5;
+}
+
+.gitment-markdown kbd {
+ display: inline-block;
+ padding: 3px 5px;
+ font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ line-height: 10px;
+ color: #444d56;
+ vertical-align: middle;
+ background-color: #fcfcfc;
+ border: solid 1px #c6cbd1;
+ border-bottom-color: #959da5;
+ border-radius: 0;
+ box-shadow: inset 0 -1px 0 #959da5;
+}
+
+.gitment-markdown :checked+.radio-label {
+ position: relative;
+ z-index: 1;
+ border-color: #0366d6;
+}
+
+.gitment-markdown .task-list-item {
+ list-style-type: none;
+}
+
+.gitment-markdown .task-list-item+.task-list-item {
+ margin-top: 3px;
+}
+
+.gitment-markdown .task-list-item input {
+ margin: 0 0.2em 0.25em -1.6em;
+ vertical-align: middle;
+}
+
+.gitment-markdown hr {
+ border-bottom-color: #eee;
+}
\ No newline at end of file
diff --git a/filecap/index.html b/filecap/index.html
index e69de29..bdf245a 100644
--- a/filecap/index.html
+++ b/filecap/index.html
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用文件预处理预览/查看/播放一切可下载资源
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用文件预处理预览/查看/播放一切可下载资源
+
+
+
+
Post:2019-06-05 17:55:34
+
+
Tags:/
+
+ termux
+ /
+
+ curl
+ /
+
+
+
+
+
+
+
+
技巧等级:中级
+
文件预处理配置文件为/sdcard/uweb/default.filecap,每行格式如下:
[文件后缀]:[mimetype]:[处理命令]
+
其中文件后缀可允许最多两段后缀,譬如”txt.xz”,”html.gz”。
mimetype表示命令处理后的输出内容格式。
处理命令与default.cmds相同,主要可能用到如下替换:
%u(网址或文件路径)、%U(编码以后的网址)、%c(当前网址cookie)、%p(密码保护网站中的密码,curl格式)。
+
利用文件预处理,超微浏览器现在可以预览/查看/播放一切可下载资源,并且可以利用不同网站在线服务预览不同的文件,而手机上一个应用都不用装。
+
配置/sdcard/uweb/default.filecap如下:
+
txt:text/html:curl %p "%u"
+mp3:text/html:echo '<audio controls width=100% height=100%><source src="%u"></audio>'
+m4b:text/html:echo '<audio controls width=100% height=100%><source src="%u"></audio>'
+m3u8:text/html:echo '<video controls width=100% height=100%><source src="%u"></video>'
+mp4:text/html:echo '<video controls width=100% height=100%><source src="%u"></video>'
+mkv:text/html:echo '<video controls width=100% height=100%><source src="%u"></video>'
+doc::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+xls::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+ppt::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+docx::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+xlsx::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+pptx::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+xz:text/plain:curl %p "%u"|xz -d --
+
+
长按窗口按钮,勾选“文件预处理”,重启浏览器。则点击下载按钮时上述文件类型会自动预览。
+
如果用户配置中处理命令用到curl,则需要安装Termux,并在Termux中安装curl (“apt install curl”)。
如果用户不安装Termux,则上述配置命令中的”am”需要全部路径,需用”/system/bin/am”替换。
+
以上配置使用了微软服务预览office文档,微软服务必需当前UA为PC,否则会出现空白页面。有条件的用户建议使用google docs (“http://docs.google.com/gview?embedded=true&url=") 服务替换。
+
若使用手机应用预览文件,则docx处理命令可改为:
+
am start --user 0 -a android.intent.action.VIEW -d "%u" -t "application/docx"
+
+
其余常见文件的类型名:
application/msword
application/msexcel
application/pdf
+
目前已知服务:
google docs, 功能强大,可查看几乎一切文档,但 “我的所爱在山腰,想要得到山太高。”
+
微软office, 可预览office文档,ua必须是pc。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/filenames/index.html b/filenames/index.html
index e69de29..376ed81 100644
--- a/filenames/index.html
+++ b/filenames/index.html
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 超微浏览器配置文件列表
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 超微浏览器配置文件列表
+
+
+
+ Post:2020-04-08 16:31:59
+
+
+
+
+
+
+
下面列表中以”/“结尾者为目录,其余为文件。如果用户勾选“使用内部目录配置”,”sitejs/“,”sitecache/“等位于应用内部保护目录下。否则以下所有文件/目录均位于”/sdcard/uweb”:
“css/“:全局样式目录
“js/“: 全局脚本目录
“sitejs/“:类油猴脚本,针对特定网址
“sitecss/“:针对特定网址css样式
“bookmarklet/“:js脚本目录
“offline/“:
“sbookmark/“:超级书签默认目录
“sitecache/“:用户供应网站离线数据
“longclick/“:长按链接菜单(js)
“default.longclick”:长按链接菜单
“default.uas”:浏览器标识
“default.urls”:特色服务
“default.acmd”:浏览器地址栏功能配置
“default.hosts”:广告屏蔽文件
“default.redirect”:重定向配置
“default.select”:长按“书签”按钮配置
“default.cmds”:长按“历史”按钮配置
“default.links”:长按“链接”按钮配置
“default.filecap”:
“default.rjs”:远程及简单脚本
“default.siteconf”:网站独立设置
“default.autoc”:地址栏autocomplete候选字符串
“query.autoc”:主屏搜索autocomplete候选字符串
“home5.html”:自定义主屏
“home5.search”:主屏搜索引擎
“bookmark.html”:主书签
“quickstart.html”:快速访问
“colors.txt”:护眼背景色
“default.css”:勾选网址特定样式后无匹配情形下的默认样式
“night.css”:夜间模式,代替超微内部实现
“types.sniff”:嗅探类型
“sniff.log”:嗅探结果
“history.log”:访问历史
“query.log”:查询历史
+
应用内部保护目录(/data/data/info.torapp.uweb/files/):
“shortcut/“:动态shortcut刷新目录,若不存在则默认为”/sdcard/uweb/bookmark”目录。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/globalcss/index.html b/globalcss/index.html
index e69de29..077da2b 100644
--- a/globalcss/index.html
+++ b/globalcss/index.html
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CSS样式
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CSS样式
+
+
+
+ Post:2020-04-12 19:22:06
+
+
+
+
+
+
+
超微浏览器自动装载”/sdcard/uweb/css”目录下所有.css文件作为全局样式供用户选用。点击以下配置链接可自动添加为全局样式:
+
配合透明状态栏(沉浸)
+
文件”/sdcard/uweb/night.css”为用户自定义夜间模式样式,点击以下配置链接安装不同的夜间模式:
webview 81+ 夜间模式
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gnuplot/index.html b/gnuplot/index.html
index e69de29..de4a5ec 100644
--- a/gnuplot/index.html
+++ b/gnuplot/index.html
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用浏览器地址栏对函数作图
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用浏览器地址栏对函数作图
+
+
+
+
Post:2019-06-05 17:55:34
+
+
Tags:/
+
+ termux
+ /
+
+
+
+
+
+
+
+
使用Android端uweb浏览器。
Termux提供了方便的软件包管理系统,缺省的uWeb地址栏功能配置需用到作图软件gnuplot。
+
安装gnuplot
- 安装uweb定制Termux应用
- Termux下运行以下命令:
apt update
apt upgrade
apt install gnuplot
+
+
地址栏功能配置:
+- 配置文件<a href=e:/sdcard/uweb/default.acmd>/sdcard/uweb/default.acmd每行格式如下:
菜单名:mimeType:命令行
+- 命令行可包含参数%s,运行时自动用地址栏输入内容替换。
+- 如果浏览器窗口当前地址为本地url,则此目录同时作为命令行工作目录。
+
+
配置文件/sdcard/uweb/default.acmd如下:
命令:text/plain:%s
+函数作图:image/svg+xml:gnuplot -e 'set term svg;set output; plot %s'
+函数作图(3d):image/svg+xml:gnuplot -e 'set term svg;set output; splot %s'
+超级计算器:text/html:echo "%s"|bc -l -q
+
长按uweb浏览器底部工具条刷新按钮弹出地址栏功能选择,选择“函数作图”,地址栏内输入函数如sin(x)**5就可显示函数图案。
+
常见问题及诊断
+- 确保gnuplot正确安装,在Termux提示符下,敲入gnuplot,然后回车,保证出现”gnuplot>”。
+- 确保gnuplot正常运行, 在Termux提示符下,执行下面命令:
gnuplot -e 'set term svg;set output; plot x'
屏幕输出应该为正常的svg文件(类似html文本)。
+- Termux应为uweb定制包,否则有一堆设定需要修改。
+- 超微浏览器下长按设置按钮,勾选“标准错误输出”。再次在地址栏执行画图操作,此时浏览器会显示出错信息。
+- 为保证地址栏输入函数符合gnuplot规范,首个测试函数建议为”x”,即整个地址栏内输入为”x”。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hosts/index.html b/hosts/index.html
index e69de29..338cd16 100644
--- a/hosts/index.html
+++ b/hosts/index.html
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用超级hosts文件加速访问国外网站
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用超级hosts文件加速访问国外网站
+
+
+
+
Post:2019-06-05 17:55:34
+
+
Tags:/
+
+ 广告屏蔽
+ /
+
+ 国外网址
+ /
+
+
+
+
+
+
+
+
不少国外网站本身虽可访问,但由于网站需要下载google,
facebook等屏蔽网址的资源而导致无法访问。超级hosts文件可屏蔽文件中域名的一切子域名、孙域名、……,从而主动屏蔽这些网址,最终允许浏览器快速访问合法网站。
+
使用Android端uweb浏览器。
/sdcard/uweb/default.hosts内容如下:
googleadservices.com
googlesyndication.com
adsense.com
google.com
google-analytics.com
googletagservices.com
twitter.com
facebook.com
fbcdn.net
+
其它国外网址访问技巧:
+
+- 尝试关闭javascript, 譬如程序员网站stackoverflow.com在关闭javascript的情况下国内一般均可快速访问。
+- 关闭网页图片
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/index.html b/index.html
index e69de29..3428a00 100644
--- a/index.html
+++ b/index.html
@@ -0,0 +1,490 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/js/gitment.js b/js/gitment.js
index e69de29..ef8778b 100644
--- a/js/gitment.js
+++ b/js/gitment.js
@@ -0,0 +1,3757 @@
+/**
+ * Created by Xiaotao.Nie on 11/04/2018.
+ * All right reserved
+ * IF you have any question please email onlythen@yeah.net
+ */
+
+var Gitment =
+ /******/ (function(modules) { // webpackBootstrap
+ /******/ // The module cache
+ /******/ var installedModules = {};
+ /******/
+ /******/ // The require function
+ /******/ function __webpack_require__(moduleId) {
+ /******/
+ /******/ // Check if module is in cache
+ /******/ if(installedModules[moduleId])
+ /******/ return installedModules[moduleId].exports;
+ /******/
+ /******/ // Create a new module (and put it into the cache)
+ /******/ var module = installedModules[moduleId] = {
+ /******/ i: moduleId,
+ /******/ l: false,
+ /******/ exports: {}
+ /******/ };
+ /******/
+ /******/ // Execute the module function
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+ /******/
+ /******/ // Flag the module as loaded
+ /******/ module.l = true;
+ /******/
+ /******/ // Return the exports of the module
+ /******/ return module.exports;
+ /******/ }
+ /******/
+ /******/
+ /******/ // expose the modules object (__webpack_modules__)
+ /******/ __webpack_require__.m = modules;
+ /******/
+ /******/ // expose the module cache
+ /******/ __webpack_require__.c = installedModules;
+ /******/
+ /******/ // identity function for calling harmony imports with the correct context
+ /******/ __webpack_require__.i = function(value) { return value; };
+ /******/
+ /******/ // define getter function for harmony exports
+ /******/ __webpack_require__.d = function(exports, name, getter) {
+ /******/ if(!__webpack_require__.o(exports, name)) {
+ /******/ Object.defineProperty(exports, name, {
+ /******/ configurable: false,
+ /******/ enumerable: true,
+ /******/ get: getter
+ /******/ });
+ /******/ }
+ /******/ };
+ /******/
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
+ /******/ __webpack_require__.n = function(module) {
+ /******/ var getter = module && module.__esModule ?
+ /******/ function getDefault() { return module['default']; } :
+ /******/ function getModuleExports() { return module; };
+ /******/ __webpack_require__.d(getter, 'a', getter);
+ /******/ return getter;
+ /******/ };
+ /******/
+ /******/ // Object.prototype.hasOwnProperty.call
+ /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+ /******/
+ /******/ // __webpack_public_path__
+ /******/ __webpack_require__.p = "";
+ /******/
+ /******/ // Load entry module and return exports
+ /******/ return __webpack_require__(__webpack_require__.s = 5);
+ /******/ })
+/************************************************************************/
+/******/ ([
+ /* 0 */
+ /***/ (function(module, exports, __webpack_require__) {
+
+ "use strict";
+
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ var LS_ACCESS_TOKEN_KEY = exports.LS_ACCESS_TOKEN_KEY = 'gitment-comments-token';
+ var LS_USER_KEY = exports.LS_USER_KEY = 'gitment-user-info';
+
+ var NOT_INITIALIZED_ERROR = exports.NOT_INITIALIZED_ERROR = new Error('Comments Not Initialized');
+
+ /***/ }),
+ /* 1 */
+ /***/ (function(module, exports, __webpack_require__) {
+
+ "use strict";
+ /* WEBPACK VAR INJECTION */(function(global) {
+
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+ var __extends = undefined && undefined.__extends || function () {
+ var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) {
+ d.__proto__ = b;
+ } || function (d, b) {
+ for (var p in b) {
+ if (b.hasOwnProperty(p)) d[p] = b[p];
+ }
+ };
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() {
+ this.constructor = d;
+ }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+ }();
+ Object.defineProperty(exports, "__esModule", { value: true });
+ registerGlobals();
+ exports.extras = {
+ allowStateChanges: allowStateChanges,
+ deepEqual: deepEqual,
+ getAtom: getAtom,
+ getDebugName: getDebugName,
+ getDependencyTree: getDependencyTree,
+ getAdministration: getAdministration,
+ getGlobalState: getGlobalState,
+ getObserverTree: getObserverTree,
+ isComputingDerivation: isComputingDerivation,
+ isSpyEnabled: isSpyEnabled,
+ onReactionError: onReactionError,
+ resetGlobalState: resetGlobalState,
+ shareGlobalState: shareGlobalState,
+ spyReport: spyReport,
+ spyReportEnd: spyReportEnd,
+ spyReportStart: spyReportStart,
+ setReactionScheduler: setReactionScheduler
+ };
+ if ((typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__ === "undefined" ? "undefined" : _typeof(__MOBX_DEVTOOLS_GLOBAL_HOOK__)) === "object") {
+ __MOBX_DEVTOOLS_GLOBAL_HOOK__.injectMobx(module.exports);
+ }
+ module.exports.default = module.exports;
+ var actionFieldDecorator = createClassPropertyDecorator(function (target, key, value, args, originalDescriptor) {
+ var actionName = args && args.length === 1 ? args[0] : value.name || key || "";
+ var wrappedAction = action(actionName, value);
+ addHiddenProp(target, key, wrappedAction);
+ }, function (key) {
+ return this[key];
+ }, function () {
+ invariant(false, getMessage("m001"));
+ }, false, true);
+ var boundActionDecorator = createClassPropertyDecorator(function (target, key, value) {
+ defineBoundAction(target, key, value);
+ }, function (key) {
+ return this[key];
+ }, function () {
+ invariant(false, getMessage("m001"));
+ }, false, false);
+ var action = function action(arg1, arg2, arg3, arg4) {
+ if (arguments.length === 1 && typeof arg1 === "function") return createAction(arg1.name || "", arg1);
+ if (arguments.length === 2 && typeof arg2 === "function") return createAction(arg1, arg2);
+ if (arguments.length === 1 && typeof arg1 === "string") return namedActionDecorator(arg1);
+ return namedActionDecorator(arg2).apply(null, arguments);
+ };
+ exports.action = action;
+ action.bound = function boundAction(arg1, arg2, arg3) {
+ if (typeof arg1 === "function") {
+ var action_1 = createAction("", arg1);
+ action_1.autoBind = true;
+ return action_1;
+ }
+ return boundActionDecorator.apply(null, arguments);
+ };
+ function namedActionDecorator(name) {
+ return function (target, prop, descriptor) {
+ if (descriptor && typeof descriptor.value === "function") {
+ descriptor.value = createAction(name, descriptor.value);
+ descriptor.enumerable = false;
+ descriptor.configurable = true;
+ return descriptor;
+ }
+ return actionFieldDecorator(name).apply(this, arguments);
+ };
+ }
+ function runInAction(arg1, arg2, arg3) {
+ var actionName = typeof arg1 === "string" ? arg1 : arg1.name || "";
+ var fn = typeof arg1 === "function" ? arg1 : arg2;
+ var scope = typeof arg1 === "function" ? arg2 : arg3;
+ invariant(typeof fn === "function", getMessage("m002"));
+ invariant(fn.length === 0, getMessage("m003"));
+ invariant(typeof actionName === "string" && actionName.length > 0, "actions should have valid names, got: '" + actionName + "'");
+ return executeAction(actionName, fn, scope, undefined);
+ }
+ exports.runInAction = runInAction;
+ function isAction(thing) {
+ return typeof thing === "function" && thing.isMobxAction === true;
+ }
+ exports.isAction = isAction;
+ function defineBoundAction(target, propertyName, fn) {
+ var res = function res() {
+ return executeAction(propertyName, fn, target, arguments);
+ };
+ res.isMobxAction = true;
+ addHiddenProp(target, propertyName, res);
+ }
+ function autorun(arg1, arg2, arg3) {
+ var name, view, scope;
+ if (typeof arg1 === "string") {
+ name = arg1;
+ view = arg2;
+ scope = arg3;
+ } else {
+ name = arg1.name || "Autorun@" + getNextId();
+ view = arg1;
+ scope = arg2;
+ }
+ invariant(typeof view === "function", getMessage("m004"));
+ invariant(isAction(view) === false, getMessage("m005"));
+ if (scope) view = view.bind(scope);
+ var reaction = new Reaction(name, function () {
+ this.track(reactionRunner);
+ });
+ function reactionRunner() {
+ view(reaction);
+ }
+ reaction.schedule();
+ return reaction.getDisposer();
+ }
+ exports.autorun = autorun;
+ function when(arg1, arg2, arg3, arg4) {
+ var name, predicate, effect, scope;
+ if (typeof arg1 === "string") {
+ name = arg1;
+ predicate = arg2;
+ effect = arg3;
+ scope = arg4;
+ } else {
+ name = "When@" + getNextId();
+ predicate = arg1;
+ effect = arg2;
+ scope = arg3;
+ }
+ var disposer = autorun(name, function (r) {
+ if (predicate.call(scope)) {
+ r.dispose();
+ var prevUntracked = untrackedStart();
+ effect.call(scope);
+ untrackedEnd(prevUntracked);
+ }
+ });
+ return disposer;
+ }
+ exports.when = when;
+ function autorunAsync(arg1, arg2, arg3, arg4) {
+ var name, func, delay, scope;
+ if (typeof arg1 === "string") {
+ name = arg1;
+ func = arg2;
+ delay = arg3;
+ scope = arg4;
+ } else {
+ name = arg1.name || "AutorunAsync@" + getNextId();
+ func = arg1;
+ delay = arg2;
+ scope = arg3;
+ }
+ invariant(isAction(func) === false, getMessage("m006"));
+ if (delay === void 0) delay = 1;
+ if (scope) func = func.bind(scope);
+ var isScheduled = false;
+ var r = new Reaction(name, function () {
+ if (!isScheduled) {
+ isScheduled = true;
+ setTimeout(function () {
+ isScheduled = false;
+ if (!r.isDisposed) r.track(reactionRunner);
+ }, delay);
+ }
+ });
+ function reactionRunner() {
+ func(r);
+ }
+ r.schedule();
+ return r.getDisposer();
+ }
+ exports.autorunAsync = autorunAsync;
+ function reaction(expression, effect, arg3) {
+ if (arguments.length > 3) {
+ fail(getMessage("m007"));
+ }
+ if (isModifierDescriptor(expression)) {
+ fail(getMessage("m008"));
+ }
+ var opts;
+ if ((typeof arg3 === "undefined" ? "undefined" : _typeof(arg3)) === "object") {
+ opts = arg3;
+ } else {
+ opts = {};
+ }
+ opts.name = opts.name || expression.name || effect.name || "Reaction@" + getNextId();
+ opts.fireImmediately = arg3 === true || opts.fireImmediately === true;
+ opts.delay = opts.delay || 0;
+ opts.compareStructural = opts.compareStructural || opts.struct || false;
+ effect = action(opts.name, opts.context ? effect.bind(opts.context) : effect);
+ if (opts.context) {
+ expression = expression.bind(opts.context);
+ }
+ var firstTime = true;
+ var isScheduled = false;
+ var nextValue;
+ var r = new Reaction(opts.name, function () {
+ if (firstTime || opts.delay < 1) {
+ reactionRunner();
+ } else if (!isScheduled) {
+ isScheduled = true;
+ setTimeout(function () {
+ isScheduled = false;
+ reactionRunner();
+ }, opts.delay);
+ }
+ });
+ function reactionRunner() {
+ if (r.isDisposed) return;
+ var changed = false;
+ r.track(function () {
+ var v = expression(r);
+ changed = valueDidChange(opts.compareStructural, nextValue, v);
+ nextValue = v;
+ });
+ if (firstTime && opts.fireImmediately) effect(nextValue, r);
+ if (!firstTime && changed === true) effect(nextValue, r);
+ if (firstTime) firstTime = false;
+ }
+ r.schedule();
+ return r.getDisposer();
+ }
+ exports.reaction = reaction;
+ function createComputedDecorator(compareStructural) {
+ return createClassPropertyDecorator(function (target, name, _, __, originalDescriptor) {
+ invariant(typeof originalDescriptor !== "undefined", getMessage("m009"));
+ invariant(typeof originalDescriptor.get === "function", getMessage("m010"));
+ var adm = asObservableObject(target, "");
+ defineComputedProperty(adm, name, originalDescriptor.get, originalDescriptor.set, compareStructural, false);
+ }, function (name) {
+ var observable = this.$mobx.values[name];
+ if (observable === undefined) return undefined;
+ return observable.get();
+ }, function (name, value) {
+ this.$mobx.values[name].set(value);
+ }, false, false);
+ }
+ var computedDecorator = createComputedDecorator(false);
+ var computedStructDecorator = createComputedDecorator(true);
+ var computed = function computed(arg1, arg2, arg3) {
+ if (typeof arg2 === "string") {
+ return computedDecorator.apply(null, arguments);
+ }
+ invariant(typeof arg1 === "function", getMessage("m011"));
+ invariant(arguments.length < 3, getMessage("m012"));
+ var opts = (typeof arg2 === "undefined" ? "undefined" : _typeof(arg2)) === "object" ? arg2 : {};
+ opts.setter = typeof arg2 === "function" ? arg2 : opts.setter;
+ return new ComputedValue(arg1, opts.context, opts.compareStructural || opts.struct || false, opts.name || arg1.name || "", opts.setter);
+ };
+ exports.computed = computed;
+ computed.struct = computedStructDecorator;
+ function createTransformer(transformer, onCleanup) {
+ invariant(typeof transformer === "function" && transformer.length < 2, "createTransformer expects a function that accepts one argument");
+ var objectCache = {};
+ var resetId = globalState.resetId;
+ var Transformer = function (_super) {
+ __extends(Transformer, _super);
+ function Transformer(sourceIdentifier, sourceObject) {
+ var _this = _super.call(this, function () {
+ return transformer(sourceObject);
+ }, undefined, false, "Transformer-" + transformer.name + "-" + sourceIdentifier, undefined) || this;
+ _this.sourceIdentifier = sourceIdentifier;
+ _this.sourceObject = sourceObject;
+ return _this;
+ }
+ Transformer.prototype.onBecomeUnobserved = function () {
+ var lastValue = this.value;
+ _super.prototype.onBecomeUnobserved.call(this);
+ delete objectCache[this.sourceIdentifier];
+ if (onCleanup) onCleanup(lastValue, this.sourceObject);
+ };
+ return Transformer;
+ }(ComputedValue);
+ return function (object) {
+ if (resetId !== globalState.resetId) {
+ objectCache = {};
+ resetId = globalState.resetId;
+ }
+ var identifier = getMemoizationId(object);
+ var reactiveTransformer = objectCache[identifier];
+ if (reactiveTransformer) return reactiveTransformer.get();
+ reactiveTransformer = objectCache[identifier] = new Transformer(identifier, object);
+ return reactiveTransformer.get();
+ };
+ }
+ exports.createTransformer = createTransformer;
+ function getMemoizationId(object) {
+ if (object === null || (typeof object === "undefined" ? "undefined" : _typeof(object)) !== "object") throw new Error("[mobx] transform expected some kind of object, got: " + object);
+ var tid = object.$transformId;
+ if (tid === undefined) {
+ tid = getNextId();
+ addHiddenProp(object, "$transformId", tid);
+ }
+ return tid;
+ }
+ function expr(expr, scope) {
+ if (!isComputingDerivation()) console.warn(getMessage("m013"));
+ return computed(expr, { context: scope }).get();
+ }
+ exports.expr = expr;
+ function extendObservable(target) {
+ var properties = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ properties[_i - 1] = arguments[_i];
+ }
+ return extendObservableHelper(target, deepEnhancer, properties);
+ }
+ exports.extendObservable = extendObservable;
+ function extendShallowObservable(target) {
+ var properties = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ properties[_i - 1] = arguments[_i];
+ }
+ return extendObservableHelper(target, referenceEnhancer, properties);
+ }
+ exports.extendShallowObservable = extendShallowObservable;
+ function extendObservableHelper(target, defaultEnhancer, properties) {
+ invariant(arguments.length >= 2, getMessage("m014"));
+ invariant((typeof target === "undefined" ? "undefined" : _typeof(target)) === "object", getMessage("m015"));
+ invariant(!isObservableMap(target), getMessage("m016"));
+ properties.forEach(function (propSet) {
+ invariant((typeof propSet === "undefined" ? "undefined" : _typeof(propSet)) === "object", getMessage("m017"));
+ invariant(!isObservable(propSet), getMessage("m018"));
+ });
+ var adm = asObservableObject(target);
+ var definedProps = {};
+ for (var i = properties.length - 1; i >= 0; i--) {
+ var propSet = properties[i];
+ for (var key in propSet) {
+ if (definedProps[key] !== true && hasOwnProperty(propSet, key)) {
+ definedProps[key] = true;
+ if (target === propSet && !isPropertyConfigurable(target, key)) continue;
+ var descriptor = Object.getOwnPropertyDescriptor(propSet, key);
+ defineObservablePropertyFromDescriptor(adm, key, descriptor, defaultEnhancer);
+ }
+ }
+ }
+ return target;
+ }
+ function getDependencyTree(thing, property) {
+ return nodeToDependencyTree(getAtom(thing, property));
+ }
+ function nodeToDependencyTree(node) {
+ var result = {
+ name: node.name
+ };
+ if (node.observing && node.observing.length > 0) result.dependencies = unique(node.observing).map(nodeToDependencyTree);
+ return result;
+ }
+ function getObserverTree(thing, property) {
+ return nodeToObserverTree(getAtom(thing, property));
+ }
+ function nodeToObserverTree(node) {
+ var result = {
+ name: node.name
+ };
+ if (hasObservers(node)) result.observers = getObservers(node).map(nodeToObserverTree);
+ return result;
+ }
+ function intercept(thing, propOrHandler, handler) {
+ if (typeof handler === "function") return interceptProperty(thing, propOrHandler, handler);else return interceptInterceptable(thing, propOrHandler);
+ }
+ exports.intercept = intercept;
+ function interceptInterceptable(thing, handler) {
+ return getAdministration(thing).intercept(handler);
+ }
+ function interceptProperty(thing, property, handler) {
+ return getAdministration(thing, property).intercept(handler);
+ }
+ function isComputed(value, property) {
+ if (value === null || value === undefined) return false;
+ if (property !== undefined) {
+ if (isObservableObject(value) === false) return false;
+ var atom = getAtom(value, property);
+ return isComputedValue(atom);
+ }
+ return isComputedValue(value);
+ }
+ exports.isComputed = isComputed;
+ function isObservable(value, property) {
+ if (value === null || value === undefined) return false;
+ if (property !== undefined) {
+ if (isObservableArray(value) || isObservableMap(value)) throw new Error(getMessage("m019"));else if (isObservableObject(value)) {
+ var o = value.$mobx;
+ return o.values && !!o.values[property];
+ }
+ return false;
+ }
+ return isObservableObject(value) || !!value.$mobx || isAtom(value) || isReaction(value) || isComputedValue(value);
+ }
+ exports.isObservable = isObservable;
+ var deepDecorator = createDecoratorForEnhancer(deepEnhancer);
+ var shallowDecorator = createDecoratorForEnhancer(shallowEnhancer);
+ var refDecorator = createDecoratorForEnhancer(referenceEnhancer);
+ var deepStructDecorator = createDecoratorForEnhancer(deepStructEnhancer);
+ var refStructDecorator = createDecoratorForEnhancer(refStructEnhancer);
+ function createObservable(v) {
+ if (v === void 0) {
+ v = undefined;
+ }
+ if (typeof arguments[1] === "string") return deepDecorator.apply(null, arguments);
+ invariant(arguments.length <= 1, getMessage("m021"));
+ invariant(!isModifierDescriptor(v), getMessage("m020"));
+ if (isObservable(v)) return v;
+ var res = deepEnhancer(v, undefined, undefined);
+ if (res !== v) return res;
+ return observable.box(v);
+ }
+ var IObservableFactories = function () {
+ function IObservableFactories() {}
+ IObservableFactories.prototype.box = function (value, name) {
+ if (arguments.length > 2) incorrectlyUsedAsDecorator("box");
+ return new ObservableValue(value, deepEnhancer, name);
+ };
+ IObservableFactories.prototype.shallowBox = function (value, name) {
+ if (arguments.length > 2) incorrectlyUsedAsDecorator("shallowBox");
+ return new ObservableValue(value, referenceEnhancer, name);
+ };
+ IObservableFactories.prototype.array = function (initialValues, name) {
+ if (arguments.length > 2) incorrectlyUsedAsDecorator("array");
+ return new ObservableArray(initialValues, deepEnhancer, name);
+ };
+ IObservableFactories.prototype.shallowArray = function (initialValues, name) {
+ if (arguments.length > 2) incorrectlyUsedAsDecorator("shallowArray");
+ return new ObservableArray(initialValues, referenceEnhancer, name);
+ };
+ IObservableFactories.prototype.map = function (initialValues, name) {
+ if (arguments.length > 2) incorrectlyUsedAsDecorator("map");
+ return new ObservableMap(initialValues, deepEnhancer, name);
+ };
+ IObservableFactories.prototype.shallowMap = function (initialValues, name) {
+ if (arguments.length > 2) incorrectlyUsedAsDecorator("shallowMap");
+ return new ObservableMap(initialValues, referenceEnhancer, name);
+ };
+ IObservableFactories.prototype.object = function (props, name) {
+ if (arguments.length > 2) incorrectlyUsedAsDecorator("object");
+ var res = {};
+ asObservableObject(res, name);
+ extendObservable(res, props);
+ return res;
+ };
+ IObservableFactories.prototype.shallowObject = function (props, name) {
+ if (arguments.length > 2) incorrectlyUsedAsDecorator("shallowObject");
+ var res = {};
+ asObservableObject(res, name);
+ extendShallowObservable(res, props);
+ return res;
+ };
+ IObservableFactories.prototype.ref = function () {
+ if (arguments.length < 2) {
+ return createModifierDescriptor(referenceEnhancer, arguments[0]);
+ } else {
+ return refDecorator.apply(null, arguments);
+ }
+ };
+ IObservableFactories.prototype.shallow = function () {
+ if (arguments.length < 2) {
+ return createModifierDescriptor(shallowEnhancer, arguments[0]);
+ } else {
+ return shallowDecorator.apply(null, arguments);
+ }
+ };
+ IObservableFactories.prototype.deep = function () {
+ if (arguments.length < 2) {
+ return createModifierDescriptor(deepEnhancer, arguments[0]);
+ } else {
+ return deepDecorator.apply(null, arguments);
+ }
+ };
+ IObservableFactories.prototype.struct = function () {
+ if (arguments.length < 2) {
+ return createModifierDescriptor(deepStructEnhancer, arguments[0]);
+ } else {
+ return deepStructDecorator.apply(null, arguments);
+ }
+ };
+ return IObservableFactories;
+ }();
+ exports.IObservableFactories = IObservableFactories;
+ var observable = createObservable;
+ exports.observable = observable;
+ Object.keys(IObservableFactories.prototype).forEach(function (key) {
+ return observable[key] = IObservableFactories.prototype[key];
+ });
+ observable.deep.struct = observable.struct;
+ observable.ref.struct = function () {
+ if (arguments.length < 2) {
+ return createModifierDescriptor(refStructEnhancer, arguments[0]);
+ } else {
+ return refStructDecorator.apply(null, arguments);
+ }
+ };
+ function incorrectlyUsedAsDecorator(methodName) {
+ fail("Expected one or two arguments to observable." + methodName + ". Did you accidentally try to use observable." + methodName + " as decorator?");
+ }
+ function createDecoratorForEnhancer(enhancer) {
+ invariant(!!enhancer, ":(");
+ return createClassPropertyDecorator(function (target, name, baseValue, _, baseDescriptor) {
+ assertPropertyConfigurable(target, name);
+ invariant(!baseDescriptor || !baseDescriptor.get, getMessage("m022"));
+ var adm = asObservableObject(target, undefined);
+ defineObservableProperty(adm, name, baseValue, enhancer);
+ }, function (name) {
+ var observable = this.$mobx.values[name];
+ if (observable === undefined) return undefined;
+ return observable.get();
+ }, function (name, value) {
+ setPropertyValue(this, name, value);
+ }, true, false);
+ }
+ function observe(thing, propOrCb, cbOrFire, fireImmediately) {
+ if (typeof cbOrFire === "function") return observeObservableProperty(thing, propOrCb, cbOrFire, fireImmediately);else return observeObservable(thing, propOrCb, cbOrFire);
+ }
+ exports.observe = observe;
+ function observeObservable(thing, listener, fireImmediately) {
+ return getAdministration(thing).observe(listener, fireImmediately);
+ }
+ function observeObservableProperty(thing, property, listener, fireImmediately) {
+ return getAdministration(thing, property).observe(listener, fireImmediately);
+ }
+ function toJS(source, detectCycles, __alreadySeen) {
+ if (detectCycles === void 0) {
+ detectCycles = true;
+ }
+ if (__alreadySeen === void 0) {
+ __alreadySeen = [];
+ }
+ function cache(value) {
+ if (detectCycles) __alreadySeen.push([source, value]);
+ return value;
+ }
+ if (isObservable(source)) {
+ if (detectCycles && __alreadySeen === null) __alreadySeen = [];
+ if (detectCycles && source !== null && (typeof source === "undefined" ? "undefined" : _typeof(source)) === "object") {
+ for (var i = 0, l = __alreadySeen.length; i < l; i++) {
+ if (__alreadySeen[i][0] === source) return __alreadySeen[i][1];
+ }
+ }
+ if (isObservableArray(source)) {
+ var res = cache([]);
+ var toAdd = source.map(function (value) {
+ return toJS(value, detectCycles, __alreadySeen);
+ });
+ res.length = toAdd.length;
+ for (var i = 0, l = toAdd.length; i < l; i++) {
+ res[i] = toAdd[i];
+ }return res;
+ }
+ if (isObservableObject(source)) {
+ var res = cache({});
+ for (var key in source) {
+ res[key] = toJS(source[key], detectCycles, __alreadySeen);
+ }return res;
+ }
+ if (isObservableMap(source)) {
+ var res_1 = cache({});
+ source.forEach(function (value, key) {
+ return res_1[key] = toJS(value, detectCycles, __alreadySeen);
+ });
+ return res_1;
+ }
+ if (isObservableValue(source)) return toJS(source.get(), detectCycles, __alreadySeen);
+ }
+ return source;
+ }
+ exports.toJS = toJS;
+ function transaction(action, thisArg) {
+ if (thisArg === void 0) {
+ thisArg = undefined;
+ }
+ deprecated(getMessage("m023"));
+ return runInTransaction.apply(undefined, arguments);
+ }
+ exports.transaction = transaction;
+ function runInTransaction(action, thisArg) {
+ if (thisArg === void 0) {
+ thisArg = undefined;
+ }
+ return executeAction("", action);
+ }
+ function log(msg) {
+ console.log(msg);
+ return msg;
+ }
+ function whyRun(thing, prop) {
+ switch (arguments.length) {
+ case 0:
+ thing = globalState.trackingDerivation;
+ if (!thing) return log(getMessage("m024"));
+ break;
+ case 2:
+ thing = getAtom(thing, prop);
+ break;
+ }
+ thing = getAtom(thing);
+ if (isComputedValue(thing)) return log(thing.whyRun());else if (isReaction(thing)) return log(thing.whyRun());
+ return fail(getMessage("m025"));
+ }
+ exports.whyRun = whyRun;
+ function createAction(actionName, fn) {
+ invariant(typeof fn === "function", getMessage("m026"));
+ invariant(typeof actionName === "string" && actionName.length > 0, "actions should have valid names, got: '" + actionName + "'");
+ var res = function res() {
+ return executeAction(actionName, fn, this, arguments);
+ };
+ res.originalFn = fn;
+ res.isMobxAction = true;
+ return res;
+ }
+ function executeAction(actionName, fn, scope, args) {
+ var runInfo = startAction(actionName, fn, scope, args);
+ try {
+ return fn.apply(scope, args);
+ } finally {
+ endAction(runInfo);
+ }
+ }
+ function startAction(actionName, fn, scope, args) {
+ var notifySpy = isSpyEnabled() && !!actionName;
+ var startTime = 0;
+ if (notifySpy) {
+ startTime = Date.now();
+ var l = args && args.length || 0;
+ var flattendArgs = new Array(l);
+ if (l > 0) for (var i = 0; i < l; i++) {
+ flattendArgs[i] = args[i];
+ }spyReportStart({
+ type: "action",
+ name: actionName,
+ fn: fn,
+ object: scope,
+ arguments: flattendArgs
+ });
+ }
+ var prevDerivation = untrackedStart();
+ startBatch();
+ var prevAllowStateChanges = allowStateChangesStart(true);
+ return {
+ prevDerivation: prevDerivation,
+ prevAllowStateChanges: prevAllowStateChanges,
+ notifySpy: notifySpy,
+ startTime: startTime
+ };
+ }
+ function endAction(runInfo) {
+ allowStateChangesEnd(runInfo.prevAllowStateChanges);
+ endBatch();
+ untrackedEnd(runInfo.prevDerivation);
+ if (runInfo.notifySpy) spyReportEnd({ time: Date.now() - runInfo.startTime });
+ }
+ function useStrict(strict) {
+ invariant(globalState.trackingDerivation === null, getMessage("m028"));
+ globalState.strictMode = strict;
+ globalState.allowStateChanges = !strict;
+ }
+ exports.useStrict = useStrict;
+ function isStrictModeEnabled() {
+ return globalState.strictMode;
+ }
+ exports.isStrictModeEnabled = isStrictModeEnabled;
+ function allowStateChanges(allowStateChanges, func) {
+ var prev = allowStateChangesStart(allowStateChanges);
+ var res;
+ try {
+ res = func();
+ } finally {
+ allowStateChangesEnd(prev);
+ }
+ return res;
+ }
+ function allowStateChangesStart(allowStateChanges) {
+ var prev = globalState.allowStateChanges;
+ globalState.allowStateChanges = allowStateChanges;
+ return prev;
+ }
+ function allowStateChangesEnd(prev) {
+ globalState.allowStateChanges = prev;
+ }
+ var BaseAtom = function () {
+ function BaseAtom(name) {
+ if (name === void 0) {
+ name = "Atom@" + getNextId();
+ }
+ this.name = name;
+ this.isPendingUnobservation = true;
+ this.observers = [];
+ this.observersIndexes = {};
+ this.diffValue = 0;
+ this.lastAccessedBy = 0;
+ this.lowestObserverState = IDerivationState.NOT_TRACKING;
+ }
+ BaseAtom.prototype.onBecomeUnobserved = function () {};
+ BaseAtom.prototype.reportObserved = function () {
+ reportObserved(this);
+ };
+ BaseAtom.prototype.reportChanged = function () {
+ startBatch();
+ propagateChanged(this);
+ endBatch();
+ };
+ BaseAtom.prototype.toString = function () {
+ return this.name;
+ };
+ return BaseAtom;
+ }();
+ exports.BaseAtom = BaseAtom;
+ var Atom = function (_super) {
+ __extends(Atom, _super);
+ function Atom(name, onBecomeObservedHandler, onBecomeUnobservedHandler) {
+ if (name === void 0) {
+ name = "Atom@" + getNextId();
+ }
+ if (onBecomeObservedHandler === void 0) {
+ onBecomeObservedHandler = noop;
+ }
+ if (onBecomeUnobservedHandler === void 0) {
+ onBecomeUnobservedHandler = noop;
+ }
+ var _this = _super.call(this, name) || this;
+ _this.name = name;
+ _this.onBecomeObservedHandler = onBecomeObservedHandler;
+ _this.onBecomeUnobservedHandler = onBecomeUnobservedHandler;
+ _this.isPendingUnobservation = false;
+ _this.isBeingTracked = false;
+ return _this;
+ }
+ Atom.prototype.reportObserved = function () {
+ startBatch();
+ _super.prototype.reportObserved.call(this);
+ if (!this.isBeingTracked) {
+ this.isBeingTracked = true;
+ this.onBecomeObservedHandler();
+ }
+ endBatch();
+ return !!globalState.trackingDerivation;
+ };
+ Atom.prototype.onBecomeUnobserved = function () {
+ this.isBeingTracked = false;
+ this.onBecomeUnobservedHandler();
+ };
+ return Atom;
+ }(BaseAtom);
+ exports.Atom = Atom;
+ var isAtom = createInstanceofPredicate("Atom", BaseAtom);
+ var ComputedValue = function () {
+ function ComputedValue(derivation, scope, compareStructural, name, setter) {
+ this.derivation = derivation;
+ this.scope = scope;
+ this.compareStructural = compareStructural;
+ this.dependenciesState = IDerivationState.NOT_TRACKING;
+ this.observing = [];
+ this.newObserving = null;
+ this.isPendingUnobservation = false;
+ this.observers = [];
+ this.observersIndexes = {};
+ this.diffValue = 0;
+ this.runId = 0;
+ this.lastAccessedBy = 0;
+ this.lowestObserverState = IDerivationState.UP_TO_DATE;
+ this.unboundDepsCount = 0;
+ this.__mapid = "#" + getNextId();
+ this.value = undefined;
+ this.isComputing = false;
+ this.isRunningSetter = false;
+ this.name = name || "ComputedValue@" + getNextId();
+ if (setter) this.setter = createAction(name + "-setter", setter);
+ }
+ ComputedValue.prototype.onBecomeStale = function () {
+ propagateMaybeChanged(this);
+ };
+ ComputedValue.prototype.onBecomeUnobserved = function () {
+ invariant(this.dependenciesState !== IDerivationState.NOT_TRACKING, getMessage("m029"));
+ clearObserving(this);
+ this.value = undefined;
+ };
+ ComputedValue.prototype.get = function () {
+ invariant(!this.isComputing, "Cycle detected in computation " + this.name, this.derivation);
+ if (globalState.inBatch === 0) {
+ startBatch();
+ if (shouldCompute(this)) this.value = this.computeValue(false);
+ endBatch();
+ } else {
+ reportObserved(this);
+ if (shouldCompute(this)) if (this.trackAndCompute()) propagateChangeConfirmed(this);
+ }
+ var result = this.value;
+ if (isCaughtException(result)) throw result.cause;
+ return result;
+ };
+ ComputedValue.prototype.peek = function () {
+ var res = this.computeValue(false);
+ if (isCaughtException(res)) throw res.cause;
+ return res;
+ };
+ ComputedValue.prototype.set = function (value) {
+ if (this.setter) {
+ invariant(!this.isRunningSetter, "The setter of computed value '" + this.name + "' is trying to update itself. Did you intend to update an _observable_ value, instead of the computed property?");
+ this.isRunningSetter = true;
+ try {
+ this.setter.call(this.scope, value);
+ } finally {
+ this.isRunningSetter = false;
+ }
+ } else invariant(false, "[ComputedValue '" + this.name + "'] It is not possible to assign a new value to a computed value.");
+ };
+ ComputedValue.prototype.trackAndCompute = function () {
+ if (isSpyEnabled()) {
+ spyReport({
+ object: this.scope,
+ type: "compute",
+ fn: this.derivation
+ });
+ }
+ var oldValue = this.value;
+ var newValue = this.value = this.computeValue(true);
+ return isCaughtException(newValue) || valueDidChange(this.compareStructural, newValue, oldValue);
+ };
+ ComputedValue.prototype.computeValue = function (track) {
+ this.isComputing = true;
+ globalState.computationDepth++;
+ var res;
+ if (track) {
+ res = trackDerivedFunction(this, this.derivation, this.scope);
+ } else {
+ try {
+ res = this.derivation.call(this.scope);
+ } catch (e) {
+ res = new CaughtException(e);
+ }
+ }
+ globalState.computationDepth--;
+ this.isComputing = false;
+ return res;
+ };
+ ;
+ ComputedValue.prototype.observe = function (listener, fireImmediately) {
+ var _this = this;
+ var firstTime = true;
+ var prevValue = undefined;
+ return autorun(function () {
+ var newValue = _this.get();
+ if (!firstTime || fireImmediately) {
+ var prevU = untrackedStart();
+ listener({
+ type: "update",
+ object: _this,
+ newValue: newValue,
+ oldValue: prevValue
+ });
+ untrackedEnd(prevU);
+ }
+ firstTime = false;
+ prevValue = newValue;
+ });
+ };
+ ComputedValue.prototype.toJSON = function () {
+ return this.get();
+ };
+ ComputedValue.prototype.toString = function () {
+ return this.name + "[" + this.derivation.toString() + "]";
+ };
+ ComputedValue.prototype.valueOf = function () {
+ return toPrimitive(this.get());
+ };
+ ;
+ ComputedValue.prototype.whyRun = function () {
+ var isTracking = Boolean(globalState.trackingDerivation);
+ var observing = unique(this.isComputing ? this.newObserving : this.observing).map(function (dep) {
+ return dep.name;
+ });
+ var observers = unique(getObservers(this).map(function (dep) {
+ return dep.name;
+ }));
+ return "\nWhyRun? computation '" + this.name + "':\n * Running because: " + (isTracking ? "[active] the value of this computation is needed by a reaction" : this.isComputing ? "[get] The value of this computed was requested outside a reaction" : "[idle] not running at the moment") + "\n" + (this.dependenciesState === IDerivationState.NOT_TRACKING ? getMessage("m032") : " * This computation will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + (this.isComputing && isTracking ? " (... or any observable accessed during the remainder of the current run)" : "") + "\n\t" + getMessage("m038") + "\n\n * If the outcome of this computation changes, the following observers will be re-run:\n " + joinStrings(observers) + "\n");
+ };
+ return ComputedValue;
+ }();
+ ComputedValue.prototype[primitiveSymbol()] = ComputedValue.prototype.valueOf;
+ var isComputedValue = createInstanceofPredicate("ComputedValue", ComputedValue);
+ var IDerivationState;
+ (function (IDerivationState) {
+ IDerivationState[IDerivationState["NOT_TRACKING"] = -1] = "NOT_TRACKING";
+ IDerivationState[IDerivationState["UP_TO_DATE"] = 0] = "UP_TO_DATE";
+ IDerivationState[IDerivationState["POSSIBLY_STALE"] = 1] = "POSSIBLY_STALE";
+ IDerivationState[IDerivationState["STALE"] = 2] = "STALE";
+ })(IDerivationState || (IDerivationState = {}));
+ exports.IDerivationState = IDerivationState;
+ var CaughtException = function () {
+ function CaughtException(cause) {
+ this.cause = cause;
+ }
+ return CaughtException;
+ }();
+ function isCaughtException(e) {
+ return e instanceof CaughtException;
+ }
+ function shouldCompute(derivation) {
+ switch (derivation.dependenciesState) {
+ case IDerivationState.UP_TO_DATE:
+ return false;
+ case IDerivationState.NOT_TRACKING:
+ case IDerivationState.STALE:
+ return true;
+ case IDerivationState.POSSIBLY_STALE:
+ {
+ var prevUntracked = untrackedStart();
+ var obs = derivation.observing,
+ l = obs.length;
+ for (var i = 0; i < l; i++) {
+ var obj = obs[i];
+ if (isComputedValue(obj)) {
+ try {
+ obj.get();
+ } catch (e) {
+ untrackedEnd(prevUntracked);
+ return true;
+ }
+ if (derivation.dependenciesState === IDerivationState.STALE) {
+ untrackedEnd(prevUntracked);
+ return true;
+ }
+ }
+ }
+ changeDependenciesStateTo0(derivation);
+ untrackedEnd(prevUntracked);
+ return false;
+ }
+ }
+ }
+ function isComputingDerivation() {
+ return globalState.trackingDerivation !== null;
+ }
+ function checkIfStateModificationsAreAllowed(atom) {
+ var hasObservers = atom.observers.length > 0;
+ if (globalState.computationDepth > 0 && hasObservers) fail(getMessage("m031") + atom.name);
+ if (!globalState.allowStateChanges && hasObservers) fail(getMessage(globalState.strictMode ? "m030a" : "m030b") + atom.name);
+ }
+ function trackDerivedFunction(derivation, f, context) {
+ changeDependenciesStateTo0(derivation);
+ derivation.newObserving = new Array(derivation.observing.length + 100);
+ derivation.unboundDepsCount = 0;
+ derivation.runId = ++globalState.runId;
+ var prevTracking = globalState.trackingDerivation;
+ globalState.trackingDerivation = derivation;
+ var result;
+ try {
+ result = f.call(context);
+ } catch (e) {
+ result = new CaughtException(e);
+ }
+ globalState.trackingDerivation = prevTracking;
+ bindDependencies(derivation);
+ return result;
+ }
+ function bindDependencies(derivation) {
+ var prevObserving = derivation.observing;
+ var observing = derivation.observing = derivation.newObserving;
+ derivation.newObserving = null;
+ var i0 = 0,
+ l = derivation.unboundDepsCount;
+ for (var i = 0; i < l; i++) {
+ var dep = observing[i];
+ if (dep.diffValue === 0) {
+ dep.diffValue = 1;
+ if (i0 !== i) observing[i0] = dep;
+ i0++;
+ }
+ }
+ observing.length = i0;
+ l = prevObserving.length;
+ while (l--) {
+ var dep = prevObserving[l];
+ if (dep.diffValue === 0) {
+ removeObserver(dep, derivation);
+ }
+ dep.diffValue = 0;
+ }
+ while (i0--) {
+ var dep = observing[i0];
+ if (dep.diffValue === 1) {
+ dep.diffValue = 0;
+ addObserver(dep, derivation);
+ }
+ }
+ }
+ function clearObserving(derivation) {
+ var obs = derivation.observing;
+ var i = obs.length;
+ while (i--) {
+ removeObserver(obs[i], derivation);
+ }derivation.dependenciesState = IDerivationState.NOT_TRACKING;
+ obs.length = 0;
+ }
+ function untracked(action) {
+ var prev = untrackedStart();
+ var res = action();
+ untrackedEnd(prev);
+ return res;
+ }
+ exports.untracked = untracked;
+ function untrackedStart() {
+ var prev = globalState.trackingDerivation;
+ globalState.trackingDerivation = null;
+ return prev;
+ }
+ function untrackedEnd(prev) {
+ globalState.trackingDerivation = prev;
+ }
+ function changeDependenciesStateTo0(derivation) {
+ if (derivation.dependenciesState === IDerivationState.UP_TO_DATE) return;
+ derivation.dependenciesState = IDerivationState.UP_TO_DATE;
+ var obs = derivation.observing;
+ var i = obs.length;
+ while (i--) {
+ obs[i].lowestObserverState = IDerivationState.UP_TO_DATE;
+ }
+ }
+ var persistentKeys = ["mobxGuid", "resetId", "spyListeners", "strictMode", "runId"];
+ var MobXGlobals = function () {
+ function MobXGlobals() {
+ this.version = 5;
+ this.trackingDerivation = null;
+ this.computationDepth = 0;
+ this.runId = 0;
+ this.mobxGuid = 0;
+ this.inBatch = 0;
+ this.pendingUnobservations = [];
+ this.pendingReactions = [];
+ this.isRunningReactions = false;
+ this.allowStateChanges = true;
+ this.strictMode = false;
+ this.resetId = 0;
+ this.spyListeners = [];
+ this.globalReactionErrorHandlers = [];
+ }
+ return MobXGlobals;
+ }();
+ var globalState = new MobXGlobals();
+ function shareGlobalState() {
+ var global = getGlobal();
+ var ownState = globalState;
+ if (global.__mobservableTrackingStack || global.__mobservableViewStack) throw new Error("[mobx] An incompatible version of mobservable is already loaded.");
+ if (global.__mobxGlobal && global.__mobxGlobal.version !== ownState.version) throw new Error("[mobx] An incompatible version of mobx is already loaded.");
+ if (global.__mobxGlobal) globalState = global.__mobxGlobal;else global.__mobxGlobal = ownState;
+ }
+ function getGlobalState() {
+ return globalState;
+ }
+ function registerGlobals() {}
+ function resetGlobalState() {
+ globalState.resetId++;
+ var defaultGlobals = new MobXGlobals();
+ for (var key in defaultGlobals) {
+ if (persistentKeys.indexOf(key) === -1) globalState[key] = defaultGlobals[key];
+ }globalState.allowStateChanges = !globalState.strictMode;
+ }
+ function hasObservers(observable) {
+ return observable.observers && observable.observers.length > 0;
+ }
+ function getObservers(observable) {
+ return observable.observers;
+ }
+ function invariantObservers(observable) {
+ var list = observable.observers;
+ var map = observable.observersIndexes;
+ var l = list.length;
+ for (var i = 0; i < l; i++) {
+ var id = list[i].__mapid;
+ if (i) {
+ invariant(map[id] === i, "INTERNAL ERROR maps derivation.__mapid to index in list");
+ } else {
+ invariant(!(id in map), "INTERNAL ERROR observer on index 0 shouldnt be held in map.");
+ }
+ }
+ invariant(list.length === 0 || Object.keys(map).length === list.length - 1, "INTERNAL ERROR there is no junk in map");
+ }
+ function addObserver(observable, node) {
+ var l = observable.observers.length;
+ if (l) {
+ observable.observersIndexes[node.__mapid] = l;
+ }
+ observable.observers[l] = node;
+ if (observable.lowestObserverState > node.dependenciesState) observable.lowestObserverState = node.dependenciesState;
+ }
+ function removeObserver(observable, node) {
+ if (observable.observers.length === 1) {
+ observable.observers.length = 0;
+ queueForUnobservation(observable);
+ } else {
+ var list = observable.observers;
+ var map_1 = observable.observersIndexes;
+ var filler = list.pop();
+ if (filler !== node) {
+ var index = map_1[node.__mapid] || 0;
+ if (index) {
+ map_1[filler.__mapid] = index;
+ } else {
+ delete map_1[filler.__mapid];
+ }
+ list[index] = filler;
+ }
+ delete map_1[node.__mapid];
+ }
+ }
+ function queueForUnobservation(observable) {
+ if (!observable.isPendingUnobservation) {
+ observable.isPendingUnobservation = true;
+ globalState.pendingUnobservations.push(observable);
+ }
+ }
+ function startBatch() {
+ globalState.inBatch++;
+ }
+ function endBatch() {
+ if (--globalState.inBatch === 0) {
+ runReactions();
+ var list = globalState.pendingUnobservations;
+ for (var i = 0; i < list.length; i++) {
+ var observable_1 = list[i];
+ observable_1.isPendingUnobservation = false;
+ if (observable_1.observers.length === 0) {
+ observable_1.onBecomeUnobserved();
+ }
+ }
+ globalState.pendingUnobservations = [];
+ }
+ }
+ function reportObserved(observable) {
+ var derivation = globalState.trackingDerivation;
+ if (derivation !== null) {
+ if (derivation.runId !== observable.lastAccessedBy) {
+ observable.lastAccessedBy = derivation.runId;
+ derivation.newObserving[derivation.unboundDepsCount++] = observable;
+ }
+ } else if (observable.observers.length === 0) {
+ queueForUnobservation(observable);
+ }
+ }
+ function invariantLOS(observable, msg) {
+ var min = getObservers(observable).reduce(function (a, b) {
+ return Math.min(a, b.dependenciesState);
+ }, 2);
+ if (min >= observable.lowestObserverState) return;
+ throw new Error("lowestObserverState is wrong for " + msg + " because " + min + " < " + observable.lowestObserverState);
+ }
+ function propagateChanged(observable) {
+ if (observable.lowestObserverState === IDerivationState.STALE) return;
+ observable.lowestObserverState = IDerivationState.STALE;
+ var observers = observable.observers;
+ var i = observers.length;
+ while (i--) {
+ var d = observers[i];
+ if (d.dependenciesState === IDerivationState.UP_TO_DATE) d.onBecomeStale();
+ d.dependenciesState = IDerivationState.STALE;
+ }
+ }
+ function propagateChangeConfirmed(observable) {
+ if (observable.lowestObserverState === IDerivationState.STALE) return;
+ observable.lowestObserverState = IDerivationState.STALE;
+ var observers = observable.observers;
+ var i = observers.length;
+ while (i--) {
+ var d = observers[i];
+ if (d.dependenciesState === IDerivationState.POSSIBLY_STALE) d.dependenciesState = IDerivationState.STALE;else if (d.dependenciesState === IDerivationState.UP_TO_DATE) observable.lowestObserverState = IDerivationState.UP_TO_DATE;
+ }
+ }
+ function propagateMaybeChanged(observable) {
+ if (observable.lowestObserverState !== IDerivationState.UP_TO_DATE) return;
+ observable.lowestObserverState = IDerivationState.POSSIBLY_STALE;
+ var observers = observable.observers;
+ var i = observers.length;
+ while (i--) {
+ var d = observers[i];
+ if (d.dependenciesState === IDerivationState.UP_TO_DATE) {
+ d.dependenciesState = IDerivationState.POSSIBLY_STALE;
+ d.onBecomeStale();
+ }
+ }
+ }
+ var Reaction = function () {
+ function Reaction(name, onInvalidate) {
+ if (name === void 0) {
+ name = "Reaction@" + getNextId();
+ }
+ this.name = name;
+ this.onInvalidate = onInvalidate;
+ this.observing = [];
+ this.newObserving = [];
+ this.dependenciesState = IDerivationState.NOT_TRACKING;
+ this.diffValue = 0;
+ this.runId = 0;
+ this.unboundDepsCount = 0;
+ this.__mapid = "#" + getNextId();
+ this.isDisposed = false;
+ this._isScheduled = false;
+ this._isTrackPending = false;
+ this._isRunning = false;
+ }
+ Reaction.prototype.onBecomeStale = function () {
+ this.schedule();
+ };
+ Reaction.prototype.schedule = function () {
+ if (!this._isScheduled) {
+ this._isScheduled = true;
+ globalState.pendingReactions.push(this);
+ runReactions();
+ }
+ };
+ Reaction.prototype.isScheduled = function () {
+ return this._isScheduled;
+ };
+ Reaction.prototype.runReaction = function () {
+ if (!this.isDisposed) {
+ startBatch();
+ this._isScheduled = false;
+ if (shouldCompute(this)) {
+ this._isTrackPending = true;
+ this.onInvalidate();
+ if (this._isTrackPending && isSpyEnabled()) {
+ spyReport({
+ object: this,
+ type: "scheduled-reaction"
+ });
+ }
+ }
+ endBatch();
+ }
+ };
+ Reaction.prototype.track = function (fn) {
+ startBatch();
+ var notify = isSpyEnabled();
+ var startTime;
+ if (notify) {
+ startTime = Date.now();
+ spyReportStart({
+ object: this,
+ type: "reaction",
+ fn: fn
+ });
+ }
+ this._isRunning = true;
+ var result = trackDerivedFunction(this, fn, undefined);
+ this._isRunning = false;
+ this._isTrackPending = false;
+ if (this.isDisposed) {
+ clearObserving(this);
+ }
+ if (isCaughtException(result)) this.reportExceptionInDerivation(result.cause);
+ if (notify) {
+ spyReportEnd({
+ time: Date.now() - startTime
+ });
+ }
+ endBatch();
+ };
+ Reaction.prototype.reportExceptionInDerivation = function (error) {
+ var _this = this;
+ if (this.errorHandler) {
+ this.errorHandler(error, this);
+ return;
+ }
+ var message = "[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '" + this;
+ var messageToUser = getMessage("m037");
+ console.error(message || messageToUser, error);
+ if (isSpyEnabled()) {
+ spyReport({
+ type: "error",
+ message: message,
+ error: error,
+ object: this
+ });
+ }
+ globalState.globalReactionErrorHandlers.forEach(function (f) {
+ return f(error, _this);
+ });
+ };
+ Reaction.prototype.dispose = function () {
+ if (!this.isDisposed) {
+ this.isDisposed = true;
+ if (!this._isRunning) {
+ startBatch();
+ clearObserving(this);
+ endBatch();
+ }
+ }
+ };
+ Reaction.prototype.getDisposer = function () {
+ var r = this.dispose.bind(this);
+ r.$mobx = this;
+ r.onError = registerErrorHandler;
+ return r;
+ };
+ Reaction.prototype.toString = function () {
+ return "Reaction[" + this.name + "]";
+ };
+ Reaction.prototype.whyRun = function () {
+ var observing = unique(this._isRunning ? this.newObserving : this.observing).map(function (dep) {
+ return dep.name;
+ });
+ return "\nWhyRun? reaction '" + this.name + "':\n * Status: [" + (this.isDisposed ? "stopped" : this._isRunning ? "running" : this.isScheduled() ? "scheduled" : "idle") + "]\n * This reaction will re-run if any of the following observables changes:\n " + joinStrings(observing) + "\n " + (this._isRunning ? " (... or any observable accessed during the remainder of the current run)" : "") + "\n\t" + getMessage("m038") + "\n";
+ };
+ return Reaction;
+ }();
+ exports.Reaction = Reaction;
+ function registerErrorHandler(handler) {
+ invariant(this && this.$mobx && isReaction(this.$mobx), "Invalid `this`");
+ invariant(!this.$mobx.errorHandler, "Only one onErrorHandler can be registered");
+ this.$mobx.errorHandler = handler;
+ }
+ function onReactionError(handler) {
+ globalState.globalReactionErrorHandlers.push(handler);
+ return function () {
+ var idx = globalState.globalReactionErrorHandlers.indexOf(handler);
+ if (idx >= 0) globalState.globalReactionErrorHandlers.splice(idx, 1);
+ };
+ }
+ var MAX_REACTION_ITERATIONS = 100;
+ var reactionScheduler = function reactionScheduler(f) {
+ return f();
+ };
+ function runReactions() {
+ if (globalState.inBatch > 0 || globalState.isRunningReactions) return;
+ reactionScheduler(runReactionsHelper);
+ }
+ function runReactionsHelper() {
+ globalState.isRunningReactions = true;
+ var allReactions = globalState.pendingReactions;
+ var iterations = 0;
+ while (allReactions.length > 0) {
+ if (++iterations === MAX_REACTION_ITERATIONS) {
+ console.error("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations." + (" Probably there is a cycle in the reactive function: " + allReactions[0]));
+ allReactions.splice(0);
+ }
+ var remainingReactions = allReactions.splice(0);
+ for (var i = 0, l = remainingReactions.length; i < l; i++) {
+ remainingReactions[i].runReaction();
+ }
+ }
+ globalState.isRunningReactions = false;
+ }
+ var isReaction = createInstanceofPredicate("Reaction", Reaction);
+ function setReactionScheduler(fn) {
+ var baseScheduler = reactionScheduler;
+ reactionScheduler = function reactionScheduler(f) {
+ return fn(function () {
+ return baseScheduler(f);
+ });
+ };
+ }
+ function isSpyEnabled() {
+ return !!globalState.spyListeners.length;
+ }
+ function spyReport(event) {
+ if (!globalState.spyListeners.length) return;
+ var listeners = globalState.spyListeners;
+ for (var i = 0, l = listeners.length; i < l; i++) {
+ listeners[i](event);
+ }
+ }
+ function spyReportStart(event) {
+ var change = objectAssign({}, event, { spyReportStart: true });
+ spyReport(change);
+ }
+ var END_EVENT = { spyReportEnd: true };
+ function spyReportEnd(change) {
+ if (change) spyReport(objectAssign({}, change, END_EVENT));else spyReport(END_EVENT);
+ }
+ function spy(listener) {
+ globalState.spyListeners.push(listener);
+ return once(function () {
+ var idx = globalState.spyListeners.indexOf(listener);
+ if (idx !== -1) globalState.spyListeners.splice(idx, 1);
+ });
+ }
+ exports.spy = spy;
+ function hasInterceptors(interceptable) {
+ return interceptable.interceptors && interceptable.interceptors.length > 0;
+ }
+ function registerInterceptor(interceptable, handler) {
+ var interceptors = interceptable.interceptors || (interceptable.interceptors = []);
+ interceptors.push(handler);
+ return once(function () {
+ var idx = interceptors.indexOf(handler);
+ if (idx !== -1) interceptors.splice(idx, 1);
+ });
+ }
+ function interceptChange(interceptable, change) {
+ var prevU = untrackedStart();
+ try {
+ var interceptors = interceptable.interceptors;
+ if (interceptors) for (var i = 0, l = interceptors.length; i < l; i++) {
+ change = interceptors[i](change);
+ invariant(!change || change.type, "Intercept handlers should return nothing or a change object");
+ if (!change) break;
+ }
+ return change;
+ } finally {
+ untrackedEnd(prevU);
+ }
+ }
+ function hasListeners(listenable) {
+ return listenable.changeListeners && listenable.changeListeners.length > 0;
+ }
+ function registerListener(listenable, handler) {
+ var listeners = listenable.changeListeners || (listenable.changeListeners = []);
+ listeners.push(handler);
+ return once(function () {
+ var idx = listeners.indexOf(handler);
+ if (idx !== -1) listeners.splice(idx, 1);
+ });
+ }
+ function notifyListeners(listenable, change) {
+ var prevU = untrackedStart();
+ var listeners = listenable.changeListeners;
+ if (!listeners) return;
+ listeners = listeners.slice();
+ for (var i = 0, l = listeners.length; i < l; i++) {
+ listeners[i](change);
+ }
+ untrackedEnd(prevU);
+ }
+ function asReference(value) {
+ deprecated("asReference is deprecated, use observable.ref instead");
+ return observable.ref(value);
+ }
+ exports.asReference = asReference;
+ function asStructure(value) {
+ deprecated("asStructure is deprecated. Use observable.struct, computed.struct or reaction options instead.");
+ return observable.struct(value);
+ }
+ exports.asStructure = asStructure;
+ function asFlat(value) {
+ deprecated("asFlat is deprecated, use observable.shallow instead");
+ return observable.shallow(value);
+ }
+ exports.asFlat = asFlat;
+ function asMap(data) {
+ deprecated("asMap is deprecated, use observable.map or observable.shallowMap instead");
+ return observable.map(data || {});
+ }
+ exports.asMap = asMap;
+ function isModifierDescriptor(thing) {
+ return (typeof thing === "undefined" ? "undefined" : _typeof(thing)) === "object" && thing !== null && thing.isMobxModifierDescriptor === true;
+ }
+ exports.isModifierDescriptor = isModifierDescriptor;
+ function createModifierDescriptor(enhancer, initialValue) {
+ invariant(!isModifierDescriptor(initialValue), "Modifiers cannot be nested");
+ return {
+ isMobxModifierDescriptor: true,
+ initialValue: initialValue,
+ enhancer: enhancer
+ };
+ }
+ function deepEnhancer(v, _, name) {
+ if (isModifierDescriptor(v)) fail("You tried to assign a modifier wrapped value to a collection, please define modifiers when creating the collection, not when modifying it");
+ if (isObservable(v)) return v;
+ if (Array.isArray(v)) return observable.array(v, name);
+ if (isPlainObject(v)) return observable.object(v, name);
+ if (isES6Map(v)) return observable.map(v, name);
+ return v;
+ }
+ function shallowEnhancer(v, _, name) {
+ if (isModifierDescriptor(v)) fail("You tried to assign a modifier wrapped value to a collection, please define modifiers when creating the collection, not when modifying it");
+ if (v === undefined || v === null) return v;
+ if (isObservableObject(v) || isObservableArray(v) || isObservableMap(v)) return v;
+ if (Array.isArray(v)) return observable.shallowArray(v, name);
+ if (isPlainObject(v)) return observable.shallowObject(v, name);
+ if (isES6Map(v)) return observable.shallowMap(v, name);
+ return fail("The shallow modifier / decorator can only used in combination with arrays, objects and maps");
+ }
+ function referenceEnhancer(newValue) {
+ return newValue;
+ }
+ function deepStructEnhancer(v, oldValue, name) {
+ if (deepEqual(v, oldValue)) return oldValue;
+ if (isObservable(v)) return v;
+ if (Array.isArray(v)) return new ObservableArray(v, deepStructEnhancer, name);
+ if (isES6Map(v)) return new ObservableMap(v, deepStructEnhancer, name);
+ if (isPlainObject(v)) {
+ var res = {};
+ asObservableObject(res, name);
+ extendObservableHelper(res, deepStructEnhancer, [v]);
+ return res;
+ }
+ return v;
+ }
+ function refStructEnhancer(v, oldValue, name) {
+ if (deepEqual(v, oldValue)) return oldValue;
+ return v;
+ }
+ var MAX_SPLICE_SIZE = 10000;
+ var safariPrototypeSetterInheritanceBug = function () {
+ var v = false;
+ var p = {};
+ Object.defineProperty(p, "0", { set: function set() {
+ v = true;
+ } });
+ Object.create(p)["0"] = 1;
+ return v === false;
+ }();
+ var OBSERVABLE_ARRAY_BUFFER_SIZE = 0;
+ var StubArray = function () {
+ function StubArray() {}
+ return StubArray;
+ }();
+ StubArray.prototype = [];
+ var ObservableArrayAdministration = function () {
+ function ObservableArrayAdministration(name, enhancer, array, owned) {
+ this.array = array;
+ this.owned = owned;
+ this.lastKnownLength = 0;
+ this.interceptors = null;
+ this.changeListeners = null;
+ this.atom = new BaseAtom(name || "ObservableArray@" + getNextId());
+ this.enhancer = function (newV, oldV) {
+ return enhancer(newV, oldV, name + "[..]");
+ };
+ }
+ ObservableArrayAdministration.prototype.intercept = function (handler) {
+ return registerInterceptor(this, handler);
+ };
+ ObservableArrayAdministration.prototype.observe = function (listener, fireImmediately) {
+ if (fireImmediately === void 0) {
+ fireImmediately = false;
+ }
+ if (fireImmediately) {
+ listener({
+ object: this.array,
+ type: "splice",
+ index: 0,
+ added: this.values.slice(),
+ addedCount: this.values.length,
+ removed: [],
+ removedCount: 0
+ });
+ }
+ return registerListener(this, listener);
+ };
+ ObservableArrayAdministration.prototype.getArrayLength = function () {
+ this.atom.reportObserved();
+ return this.values.length;
+ };
+ ObservableArrayAdministration.prototype.setArrayLength = function (newLength) {
+ if (typeof newLength !== "number" || newLength < 0) throw new Error("[mobx.array] Out of range: " + newLength);
+ var currentLength = this.values.length;
+ if (newLength === currentLength) return;else if (newLength > currentLength) {
+ var newItems = new Array(newLength - currentLength);
+ for (var i = 0; i < newLength - currentLength; i++) {
+ newItems[i] = undefined;
+ }this.spliceWithArray(currentLength, 0, newItems);
+ } else this.spliceWithArray(newLength, currentLength - newLength);
+ };
+ ObservableArrayAdministration.prototype.updateArrayLength = function (oldLength, delta) {
+ if (oldLength !== this.lastKnownLength) throw new Error("[mobx] Modification exception: the internal structure of an observable array was changed. Did you use peek() to change it?");
+ this.lastKnownLength += delta;
+ if (delta > 0 && oldLength + delta + 1 > OBSERVABLE_ARRAY_BUFFER_SIZE) reserveArrayBuffer(oldLength + delta + 1);
+ };
+ ObservableArrayAdministration.prototype.spliceWithArray = function (index, deleteCount, newItems) {
+ var _this = this;
+ checkIfStateModificationsAreAllowed(this.atom);
+ var length = this.values.length;
+ if (index === undefined) index = 0;else if (index > length) index = length;else if (index < 0) index = Math.max(0, length + index);
+ if (arguments.length === 1) deleteCount = length - index;else if (deleteCount === undefined || deleteCount === null) deleteCount = 0;else deleteCount = Math.max(0, Math.min(deleteCount, length - index));
+ if (newItems === undefined) newItems = [];
+ if (hasInterceptors(this)) {
+ var change = interceptChange(this, {
+ object: this.array,
+ type: "splice",
+ index: index,
+ removedCount: deleteCount,
+ added: newItems
+ });
+ if (!change) return EMPTY_ARRAY;
+ deleteCount = change.removedCount;
+ newItems = change.added;
+ }
+ newItems = newItems.map(function (v) {
+ return _this.enhancer(v, undefined);
+ });
+ var lengthDelta = newItems.length - deleteCount;
+ this.updateArrayLength(length, lengthDelta);
+ var res = this.spliceItemsIntoValues(index, deleteCount, newItems);
+ if (deleteCount !== 0 || newItems.length !== 0) this.notifyArraySplice(index, newItems, res);
+ return res;
+ };
+ ObservableArrayAdministration.prototype.spliceItemsIntoValues = function (index, deleteCount, newItems) {
+ if (newItems.length < MAX_SPLICE_SIZE) {
+ return (_a = this.values).splice.apply(_a, [index, deleteCount].concat(newItems));
+ } else {
+ var res = this.values.slice(index, index + deleteCount);
+ this.values = this.values.slice(0, index).concat(newItems, this.values.slice(index + deleteCount));
+ return res;
+ }
+ var _a;
+ };
+ ObservableArrayAdministration.prototype.notifyArrayChildUpdate = function (index, newValue, oldValue) {
+ var notifySpy = !this.owned && isSpyEnabled();
+ var notify = hasListeners(this);
+ var change = notify || notifySpy ? {
+ object: this.array,
+ type: "update",
+ index: index, newValue: newValue, oldValue: oldValue
+ } : null;
+ if (notifySpy) spyReportStart(change);
+ this.atom.reportChanged();
+ if (notify) notifyListeners(this, change);
+ if (notifySpy) spyReportEnd();
+ };
+ ObservableArrayAdministration.prototype.notifyArraySplice = function (index, added, removed) {
+ var notifySpy = !this.owned && isSpyEnabled();
+ var notify = hasListeners(this);
+ var change = notify || notifySpy ? {
+ object: this.array,
+ type: "splice",
+ index: index, removed: removed, added: added,
+ removedCount: removed.length,
+ addedCount: added.length
+ } : null;
+ if (notifySpy) spyReportStart(change);
+ this.atom.reportChanged();
+ if (notify) notifyListeners(this, change);
+ if (notifySpy) spyReportEnd();
+ };
+ return ObservableArrayAdministration;
+ }();
+ var ObservableArray = function (_super) {
+ __extends(ObservableArray, _super);
+ function ObservableArray(initialValues, enhancer, name, owned) {
+ if (name === void 0) {
+ name = "ObservableArray@" + getNextId();
+ }
+ if (owned === void 0) {
+ owned = false;
+ }
+ var _this = _super.call(this) || this;
+ var adm = new ObservableArrayAdministration(name, enhancer, _this, owned);
+ addHiddenFinalProp(_this, "$mobx", adm);
+ if (initialValues && initialValues.length) {
+ adm.updateArrayLength(0, initialValues.length);
+ adm.values = initialValues.map(function (v) {
+ return enhancer(v, undefined, name + "[..]");
+ });
+ adm.notifyArraySplice(0, adm.values.slice(), EMPTY_ARRAY);
+ } else {
+ adm.values = [];
+ }
+ if (safariPrototypeSetterInheritanceBug) {
+ Object.defineProperty(adm.array, "0", ENTRY_0);
+ }
+ return _this;
+ }
+ ObservableArray.prototype.intercept = function (handler) {
+ return this.$mobx.intercept(handler);
+ };
+ ObservableArray.prototype.observe = function (listener, fireImmediately) {
+ if (fireImmediately === void 0) {
+ fireImmediately = false;
+ }
+ return this.$mobx.observe(listener, fireImmediately);
+ };
+ ObservableArray.prototype.clear = function () {
+ return this.splice(0);
+ };
+ ObservableArray.prototype.concat = function () {
+ var arrays = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ arrays[_i] = arguments[_i];
+ }
+ this.$mobx.atom.reportObserved();
+ return Array.prototype.concat.apply(this.peek(), arrays.map(function (a) {
+ return isObservableArray(a) ? a.peek() : a;
+ }));
+ };
+ ObservableArray.prototype.replace = function (newItems) {
+ return this.$mobx.spliceWithArray(0, this.$mobx.values.length, newItems);
+ };
+ ObservableArray.prototype.toJS = function () {
+ return this.slice();
+ };
+ ObservableArray.prototype.toJSON = function () {
+ return this.toJS();
+ };
+ ObservableArray.prototype.peek = function () {
+ return this.$mobx.values;
+ };
+ ObservableArray.prototype.find = function (predicate, thisArg, fromIndex) {
+ if (fromIndex === void 0) {
+ fromIndex = 0;
+ }
+ this.$mobx.atom.reportObserved();
+ var items = this.$mobx.values,
+ l = items.length;
+ for (var i = fromIndex; i < l; i++) {
+ if (predicate.call(thisArg, items[i], i, this)) return items[i];
+ }return undefined;
+ };
+ ObservableArray.prototype.splice = function (index, deleteCount) {
+ var newItems = [];
+ for (var _i = 2; _i < arguments.length; _i++) {
+ newItems[_i - 2] = arguments[_i];
+ }
+ switch (arguments.length) {
+ case 0:
+ return [];
+ case 1:
+ return this.$mobx.spliceWithArray(index);
+ case 2:
+ return this.$mobx.spliceWithArray(index, deleteCount);
+ }
+ return this.$mobx.spliceWithArray(index, deleteCount, newItems);
+ };
+ ObservableArray.prototype.spliceWithArray = function (index, deleteCount, newItems) {
+ return this.$mobx.spliceWithArray(index, deleteCount, newItems);
+ };
+ ObservableArray.prototype.push = function () {
+ var items = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ items[_i] = arguments[_i];
+ }
+ var adm = this.$mobx;
+ adm.spliceWithArray(adm.values.length, 0, items);
+ return adm.values.length;
+ };
+ ObservableArray.prototype.pop = function () {
+ return this.splice(Math.max(this.$mobx.values.length - 1, 0), 1)[0];
+ };
+ ObservableArray.prototype.shift = function () {
+ return this.splice(0, 1)[0];
+ };
+ ObservableArray.prototype.unshift = function () {
+ var items = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ items[_i] = arguments[_i];
+ }
+ var adm = this.$mobx;
+ adm.spliceWithArray(0, 0, items);
+ return adm.values.length;
+ };
+ ObservableArray.prototype.reverse = function () {
+ this.$mobx.atom.reportObserved();
+ var clone = this.slice();
+ return clone.reverse.apply(clone, arguments);
+ };
+ ObservableArray.prototype.sort = function (compareFn) {
+ this.$mobx.atom.reportObserved();
+ var clone = this.slice();
+ return clone.sort.apply(clone, arguments);
+ };
+ ObservableArray.prototype.remove = function (value) {
+ var idx = this.$mobx.values.indexOf(value);
+ if (idx > -1) {
+ this.splice(idx, 1);
+ return true;
+ }
+ return false;
+ };
+ ObservableArray.prototype.move = function (fromIndex, toIndex) {
+ function checkIndex(index) {
+ if (index < 0) {
+ throw new Error("[mobx.array] Index out of bounds: " + index + " is negative");
+ }
+ var length = this.$mobx.values.length;
+ if (index >= length) {
+ throw new Error("[mobx.array] Index out of bounds: " + index + " is not smaller than " + length);
+ }
+ }
+ checkIndex.call(this, fromIndex);
+ checkIndex.call(this, toIndex);
+ if (fromIndex === toIndex) {
+ return;
+ }
+ var oldItems = this.$mobx.values;
+ var newItems;
+ if (fromIndex < toIndex) {
+ newItems = oldItems.slice(0, fromIndex).concat(oldItems.slice(fromIndex + 1, toIndex + 1), [oldItems[fromIndex]], oldItems.slice(toIndex + 1));
+ } else {
+ newItems = oldItems.slice(0, toIndex).concat([oldItems[fromIndex]], oldItems.slice(toIndex, fromIndex), oldItems.slice(fromIndex + 1));
+ }
+ this.replace(newItems);
+ };
+ ObservableArray.prototype.toString = function () {
+ this.$mobx.atom.reportObserved();
+ return Array.prototype.toString.apply(this.$mobx.values, arguments);
+ };
+ ObservableArray.prototype.toLocaleString = function () {
+ this.$mobx.atom.reportObserved();
+ return Array.prototype.toLocaleString.apply(this.$mobx.values, arguments);
+ };
+ return ObservableArray;
+ }(StubArray);
+ declareIterator(ObservableArray.prototype, function () {
+ return arrayAsIterator(this.slice());
+ });
+ makeNonEnumerable(ObservableArray.prototype, ["constructor", "intercept", "observe", "clear", "concat", "replace", "toJS", "toJSON", "peek", "find", "splice", "spliceWithArray", "push", "pop", "shift", "unshift", "reverse", "sort", "remove", "move", "toString", "toLocaleString"]);
+ Object.defineProperty(ObservableArray.prototype, "length", {
+ enumerable: false,
+ configurable: true,
+ get: function get() {
+ return this.$mobx.getArrayLength();
+ },
+ set: function set(newLength) {
+ this.$mobx.setArrayLength(newLength);
+ }
+ });
+ ["every", "filter", "forEach", "indexOf", "join", "lastIndexOf", "map", "reduce", "reduceRight", "slice", "some"].forEach(function (funcName) {
+ var baseFunc = Array.prototype[funcName];
+ invariant(typeof baseFunc === "function", "Base function not defined on Array prototype: '" + funcName + "'");
+ addHiddenProp(ObservableArray.prototype, funcName, function () {
+ this.$mobx.atom.reportObserved();
+ return baseFunc.apply(this.$mobx.values, arguments);
+ });
+ });
+ var ENTRY_0 = {
+ configurable: true,
+ enumerable: false,
+ set: createArraySetter(0),
+ get: createArrayGetter(0)
+ };
+ function createArrayBufferItem(index) {
+ var set = createArraySetter(index);
+ var get = createArrayGetter(index);
+ Object.defineProperty(ObservableArray.prototype, "" + index, {
+ enumerable: false,
+ configurable: true,
+ set: set, get: get
+ });
+ }
+ function createArraySetter(index) {
+ return function (newValue) {
+ var adm = this.$mobx;
+ var values = adm.values;
+ if (index < values.length) {
+ checkIfStateModificationsAreAllowed(adm.atom);
+ var oldValue = values[index];
+ if (hasInterceptors(adm)) {
+ var change = interceptChange(adm, {
+ type: "update",
+ object: adm.array,
+ index: index, newValue: newValue
+ });
+ if (!change) return;
+ newValue = change.newValue;
+ }
+ newValue = adm.enhancer(newValue, oldValue);
+ var changed = newValue !== oldValue;
+ if (changed) {
+ values[index] = newValue;
+ adm.notifyArrayChildUpdate(index, newValue, oldValue);
+ }
+ } else if (index === values.length) {
+ adm.spliceWithArray(index, 0, [newValue]);
+ } else throw new Error("[mobx.array] Index out of bounds, " + index + " is larger than " + values.length);
+ };
+ }
+ function createArrayGetter(index) {
+ return function () {
+ var impl = this.$mobx;
+ if (impl) {
+ if (index < impl.values.length) {
+ impl.atom.reportObserved();
+ return impl.values[index];
+ }
+ console.warn("[mobx.array] Attempt to read an array index (" + index + ") that is out of bounds (" + impl.values.length + "). Please check length first. Out of bound indices will not be tracked by MobX");
+ }
+ return undefined;
+ };
+ }
+ function reserveArrayBuffer(max) {
+ for (var index = OBSERVABLE_ARRAY_BUFFER_SIZE; index < max; index++) {
+ createArrayBufferItem(index);
+ }OBSERVABLE_ARRAY_BUFFER_SIZE = max;
+ }
+ reserveArrayBuffer(1000);
+ var isObservableArrayAdministration = createInstanceofPredicate("ObservableArrayAdministration", ObservableArrayAdministration);
+ function isObservableArray(thing) {
+ return isObject(thing) && isObservableArrayAdministration(thing.$mobx);
+ }
+ exports.isObservableArray = isObservableArray;
+ var ObservableMapMarker = {};
+ var ObservableMap = function () {
+ function ObservableMap(initialData, enhancer, name) {
+ if (enhancer === void 0) {
+ enhancer = deepEnhancer;
+ }
+ if (name === void 0) {
+ name = "ObservableMap@" + getNextId();
+ }
+ this.enhancer = enhancer;
+ this.name = name;
+ this.$mobx = ObservableMapMarker;
+ this._data = {};
+ this._hasMap = {};
+ this._keys = new ObservableArray(undefined, referenceEnhancer, this.name + ".keys()", true);
+ this.interceptors = null;
+ this.changeListeners = null;
+ this.merge(initialData);
+ }
+ ObservableMap.prototype._has = function (key) {
+ return typeof this._data[key] !== "undefined";
+ };
+ ObservableMap.prototype.has = function (key) {
+ if (!this.isValidKey(key)) return false;
+ key = "" + key;
+ if (this._hasMap[key]) return this._hasMap[key].get();
+ return this._updateHasMapEntry(key, false).get();
+ };
+ ObservableMap.prototype.set = function (key, value) {
+ this.assertValidKey(key);
+ key = "" + key;
+ var hasKey = this._has(key);
+ if (hasInterceptors(this)) {
+ var change = interceptChange(this, {
+ type: hasKey ? "update" : "add",
+ object: this,
+ newValue: value,
+ name: key
+ });
+ if (!change) return this;
+ value = change.newValue;
+ }
+ if (hasKey) {
+ this._updateValue(key, value);
+ } else {
+ this._addValue(key, value);
+ }
+ return this;
+ };
+ ObservableMap.prototype.delete = function (key) {
+ var _this = this;
+ this.assertValidKey(key);
+ key = "" + key;
+ if (hasInterceptors(this)) {
+ var change = interceptChange(this, {
+ type: "delete",
+ object: this,
+ name: key
+ });
+ if (!change) return false;
+ }
+ if (this._has(key)) {
+ var notifySpy = isSpyEnabled();
+ var notify = hasListeners(this);
+ var change = notify || notifySpy ? {
+ type: "delete",
+ object: this,
+ oldValue: this._data[key].value,
+ name: key
+ } : null;
+ if (notifySpy) spyReportStart(change);
+ runInTransaction(function () {
+ _this._keys.remove(key);
+ _this._updateHasMapEntry(key, false);
+ var observable = _this._data[key];
+ observable.setNewValue(undefined);
+ _this._data[key] = undefined;
+ });
+ if (notify) notifyListeners(this, change);
+ if (notifySpy) spyReportEnd();
+ return true;
+ }
+ return false;
+ };
+ ObservableMap.prototype._updateHasMapEntry = function (key, value) {
+ var entry = this._hasMap[key];
+ if (entry) {
+ entry.setNewValue(value);
+ } else {
+ entry = this._hasMap[key] = new ObservableValue(value, referenceEnhancer, this.name + "." + key + "?", false);
+ }
+ return entry;
+ };
+ ObservableMap.prototype._updateValue = function (name, newValue) {
+ var observable = this._data[name];
+ newValue = observable.prepareNewValue(newValue);
+ if (newValue !== UNCHANGED) {
+ var notifySpy = isSpyEnabled();
+ var notify = hasListeners(this);
+ var change = notify || notifySpy ? {
+ type: "update",
+ object: this,
+ oldValue: observable.value,
+ name: name, newValue: newValue
+ } : null;
+ if (notifySpy) spyReportStart(change);
+ observable.setNewValue(newValue);
+ if (notify) notifyListeners(this, change);
+ if (notifySpy) spyReportEnd();
+ }
+ };
+ ObservableMap.prototype._addValue = function (name, newValue) {
+ var _this = this;
+ runInTransaction(function () {
+ var observable = _this._data[name] = new ObservableValue(newValue, _this.enhancer, _this.name + "." + name, false);
+ newValue = observable.value;
+ _this._updateHasMapEntry(name, true);
+ _this._keys.push(name);
+ });
+ var notifySpy = isSpyEnabled();
+ var notify = hasListeners(this);
+ var change = notify || notifySpy ? {
+ type: "add",
+ object: this,
+ name: name, newValue: newValue
+ } : null;
+ if (notifySpy) spyReportStart(change);
+ if (notify) notifyListeners(this, change);
+ if (notifySpy) spyReportEnd();
+ };
+ ObservableMap.prototype.get = function (key) {
+ key = "" + key;
+ if (this.has(key)) return this._data[key].get();
+ return undefined;
+ };
+ ObservableMap.prototype.keys = function () {
+ return arrayAsIterator(this._keys.slice());
+ };
+ ObservableMap.prototype.values = function () {
+ return arrayAsIterator(this._keys.map(this.get, this));
+ };
+ ObservableMap.prototype.entries = function () {
+ var _this = this;
+ return arrayAsIterator(this._keys.map(function (key) {
+ return [key, _this.get(key)];
+ }));
+ };
+ ObservableMap.prototype.forEach = function (callback, thisArg) {
+ var _this = this;
+ this.keys().forEach(function (key) {
+ return callback.call(thisArg, _this.get(key), key, _this);
+ });
+ };
+ ObservableMap.prototype.merge = function (other) {
+ var _this = this;
+ if (isObservableMap(other)) {
+ other = other.toJS();
+ }
+ runInTransaction(function () {
+ if (isPlainObject(other)) Object.keys(other).forEach(function (key) {
+ return _this.set(key, other[key]);
+ });else if (Array.isArray(other)) other.forEach(function (_a) {
+ var key = _a[0],
+ value = _a[1];
+ return _this.set(key, value);
+ });else if (isES6Map(other)) other.forEach(function (value, key) {
+ return _this.set(key, value);
+ });else if (other !== null && other !== undefined) fail("Cannot initialize map from " + other);
+ });
+ return this;
+ };
+ ObservableMap.prototype.clear = function () {
+ var _this = this;
+ runInTransaction(function () {
+ untracked(function () {
+ _this.keys().forEach(_this.delete, _this);
+ });
+ });
+ };
+ ObservableMap.prototype.replace = function (values) {
+ var _this = this;
+ runInTransaction(function () {
+ _this.clear();
+ _this.merge(values);
+ });
+ return this;
+ };
+ Object.defineProperty(ObservableMap.prototype, "size", {
+ get: function get() {
+ return this._keys.length;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ ObservableMap.prototype.toJS = function () {
+ var _this = this;
+ var res = {};
+ this.keys().forEach(function (key) {
+ return res[key] = _this.get(key);
+ });
+ return res;
+ };
+ ObservableMap.prototype.toJSON = function () {
+ return this.toJS();
+ };
+ ObservableMap.prototype.isValidKey = function (key) {
+ if (key === null || key === undefined) return false;
+ if (typeof key === "string" || typeof key === "number" || typeof key === "boolean") return true;
+ return false;
+ };
+ ObservableMap.prototype.assertValidKey = function (key) {
+ if (!this.isValidKey(key)) throw new Error("[mobx.map] Invalid key: '" + key + "', only strings, numbers and booleans are accepted as key in observable maps.");
+ };
+ ObservableMap.prototype.toString = function () {
+ var _this = this;
+ return this.name + "[{ " + this.keys().map(function (key) {
+ return key + ": " + ("" + _this.get(key));
+ }).join(", ") + " }]";
+ };
+ ObservableMap.prototype.observe = function (listener, fireImmediately) {
+ invariant(fireImmediately !== true, getMessage("m033"));
+ return registerListener(this, listener);
+ };
+ ObservableMap.prototype.intercept = function (handler) {
+ return registerInterceptor(this, handler);
+ };
+ return ObservableMap;
+ }();
+ exports.ObservableMap = ObservableMap;
+ declareIterator(ObservableMap.prototype, function () {
+ return this.entries();
+ });
+ function map(initialValues) {
+ deprecated("`mobx.map` is deprecated, use `new ObservableMap` or `mobx.observable.map` instead");
+ return observable.map(initialValues);
+ }
+ exports.map = map;
+ var isObservableMap = createInstanceofPredicate("ObservableMap", ObservableMap);
+ exports.isObservableMap = isObservableMap;
+ var ObservableObjectAdministration = function () {
+ function ObservableObjectAdministration(target, name) {
+ this.target = target;
+ this.name = name;
+ this.values = {};
+ this.changeListeners = null;
+ this.interceptors = null;
+ }
+ ObservableObjectAdministration.prototype.observe = function (callback, fireImmediately) {
+ invariant(fireImmediately !== true, "`observe` doesn't support the fire immediately property for observable objects.");
+ return registerListener(this, callback);
+ };
+ ObservableObjectAdministration.prototype.intercept = function (handler) {
+ return registerInterceptor(this, handler);
+ };
+ return ObservableObjectAdministration;
+ }();
+ function asObservableObject(target, name) {
+ if (isObservableObject(target)) return target.$mobx;
+ invariant(Object.isExtensible(target), getMessage("m035"));
+ if (!isPlainObject(target)) name = (target.constructor.name || "ObservableObject") + "@" + getNextId();
+ if (!name) name = "ObservableObject@" + getNextId();
+ var adm = new ObservableObjectAdministration(target, name);
+ addHiddenFinalProp(target, "$mobx", adm);
+ return adm;
+ }
+ function defineObservablePropertyFromDescriptor(adm, propName, descriptor, defaultEnhancer) {
+ if (adm.values[propName]) {
+ invariant("value" in descriptor, "The property " + propName + " in " + adm.name + " is already observable, cannot redefine it as computed property");
+ adm.target[propName] = descriptor.value;
+ return;
+ }
+ if ("value" in descriptor) {
+ if (isModifierDescriptor(descriptor.value)) {
+ var modifierDescriptor = descriptor.value;
+ defineObservableProperty(adm, propName, modifierDescriptor.initialValue, modifierDescriptor.enhancer);
+ } else if (isAction(descriptor.value) && descriptor.value.autoBind === true) {
+ defineBoundAction(adm.target, propName, descriptor.value.originalFn);
+ } else if (isComputedValue(descriptor.value)) {
+ defineComputedPropertyFromComputedValue(adm, propName, descriptor.value);
+ } else {
+ defineObservableProperty(adm, propName, descriptor.value, defaultEnhancer);
+ }
+ } else {
+ defineComputedProperty(adm, propName, descriptor.get, descriptor.set, false, true);
+ }
+ }
+ function defineObservableProperty(adm, propName, newValue, enhancer) {
+ assertPropertyConfigurable(adm.target, propName);
+ if (hasInterceptors(adm)) {
+ var change = interceptChange(adm, {
+ object: adm.target,
+ name: propName,
+ type: "add",
+ newValue: newValue
+ });
+ if (!change) return;
+ newValue = change.newValue;
+ }
+ var observable = adm.values[propName] = new ObservableValue(newValue, enhancer, adm.name + "." + propName, false);
+ newValue = observable.value;
+ Object.defineProperty(adm.target, propName, generateObservablePropConfig(propName));
+ notifyPropertyAddition(adm, adm.target, propName, newValue);
+ }
+ function defineComputedProperty(adm, propName, getter, setter, compareStructural, asInstanceProperty) {
+ if (asInstanceProperty) assertPropertyConfigurable(adm.target, propName);
+ adm.values[propName] = new ComputedValue(getter, adm.target, compareStructural, adm.name + "." + propName, setter);
+ if (asInstanceProperty) {
+ Object.defineProperty(adm.target, propName, generateComputedPropConfig(propName));
+ }
+ }
+ function defineComputedPropertyFromComputedValue(adm, propName, computedValue) {
+ var name = adm.name + "." + propName;
+ computedValue.name = name;
+ if (!computedValue.scope) computedValue.scope = adm.target;
+ adm.values[propName] = computedValue;
+ Object.defineProperty(adm.target, propName, generateComputedPropConfig(propName));
+ }
+ var observablePropertyConfigs = {};
+ var computedPropertyConfigs = {};
+ function generateObservablePropConfig(propName) {
+ return observablePropertyConfigs[propName] || (observablePropertyConfigs[propName] = {
+ configurable: true,
+ enumerable: true,
+ get: function get() {
+ return this.$mobx.values[propName].get();
+ },
+ set: function set(v) {
+ setPropertyValue(this, propName, v);
+ }
+ });
+ }
+ function generateComputedPropConfig(propName) {
+ return computedPropertyConfigs[propName] || (computedPropertyConfigs[propName] = {
+ configurable: true,
+ enumerable: false,
+ get: function get() {
+ return this.$mobx.values[propName].get();
+ },
+ set: function set(v) {
+ return this.$mobx.values[propName].set(v);
+ }
+ });
+ }
+ function setPropertyValue(instance, name, newValue) {
+ var adm = instance.$mobx;
+ var observable = adm.values[name];
+ if (hasInterceptors(adm)) {
+ var change = interceptChange(adm, {
+ type: "update",
+ object: instance,
+ name: name, newValue: newValue
+ });
+ if (!change) return;
+ newValue = change.newValue;
+ }
+ newValue = observable.prepareNewValue(newValue);
+ if (newValue !== UNCHANGED) {
+ var notify = hasListeners(adm);
+ var notifySpy = isSpyEnabled();
+ var change = notify || notifySpy ? {
+ type: "update",
+ object: instance,
+ oldValue: observable.value,
+ name: name, newValue: newValue
+ } : null;
+ if (notifySpy) spyReportStart(change);
+ observable.setNewValue(newValue);
+ if (notify) notifyListeners(adm, change);
+ if (notifySpy) spyReportEnd();
+ }
+ }
+ function notifyPropertyAddition(adm, object, name, newValue) {
+ var notify = hasListeners(adm);
+ var notifySpy = isSpyEnabled();
+ var change = notify || notifySpy ? {
+ type: "add",
+ object: object, name: name, newValue: newValue
+ } : null;
+ if (notifySpy) spyReportStart(change);
+ if (notify) notifyListeners(adm, change);
+ if (notifySpy) spyReportEnd();
+ }
+ var isObservableObjectAdministration = createInstanceofPredicate("ObservableObjectAdministration", ObservableObjectAdministration);
+ function isObservableObject(thing) {
+ if (isObject(thing)) {
+ runLazyInitializers(thing);
+ return isObservableObjectAdministration(thing.$mobx);
+ }
+ return false;
+ }
+ exports.isObservableObject = isObservableObject;
+ var UNCHANGED = {};
+ var ObservableValue = function (_super) {
+ __extends(ObservableValue, _super);
+ function ObservableValue(value, enhancer, name, notifySpy) {
+ if (name === void 0) {
+ name = "ObservableValue@" + getNextId();
+ }
+ if (notifySpy === void 0) {
+ notifySpy = true;
+ }
+ var _this = _super.call(this, name) || this;
+ _this.enhancer = enhancer;
+ _this.hasUnreportedChange = false;
+ _this.value = enhancer(value, undefined, name);
+ if (notifySpy && isSpyEnabled()) {
+ spyReport({ type: "create", object: _this, newValue: _this.value });
+ }
+ return _this;
+ }
+ ObservableValue.prototype.set = function (newValue) {
+ var oldValue = this.value;
+ newValue = this.prepareNewValue(newValue);
+ if (newValue !== UNCHANGED) {
+ var notifySpy = isSpyEnabled();
+ if (notifySpy) {
+ spyReportStart({
+ type: "update",
+ object: this,
+ newValue: newValue, oldValue: oldValue
+ });
+ }
+ this.setNewValue(newValue);
+ if (notifySpy) spyReportEnd();
+ }
+ };
+ ObservableValue.prototype.prepareNewValue = function (newValue) {
+ checkIfStateModificationsAreAllowed(this);
+ if (hasInterceptors(this)) {
+ var change = interceptChange(this, { object: this, type: "update", newValue: newValue });
+ if (!change) return UNCHANGED;
+ newValue = change.newValue;
+ }
+ newValue = this.enhancer(newValue, this.value, this.name);
+ return this.value !== newValue ? newValue : UNCHANGED;
+ };
+ ObservableValue.prototype.setNewValue = function (newValue) {
+ var oldValue = this.value;
+ this.value = newValue;
+ this.reportChanged();
+ if (hasListeners(this)) {
+ notifyListeners(this, {
+ type: "update",
+ object: this,
+ newValue: newValue,
+ oldValue: oldValue
+ });
+ }
+ };
+ ObservableValue.prototype.get = function () {
+ this.reportObserved();
+ return this.value;
+ };
+ ObservableValue.prototype.intercept = function (handler) {
+ return registerInterceptor(this, handler);
+ };
+ ObservableValue.prototype.observe = function (listener, fireImmediately) {
+ if (fireImmediately) listener({
+ object: this,
+ type: "update",
+ newValue: this.value,
+ oldValue: undefined
+ });
+ return registerListener(this, listener);
+ };
+ ObservableValue.prototype.toJSON = function () {
+ return this.get();
+ };
+ ObservableValue.prototype.toString = function () {
+ return this.name + "[" + this.value + "]";
+ };
+ ObservableValue.prototype.valueOf = function () {
+ return toPrimitive(this.get());
+ };
+ return ObservableValue;
+ }(BaseAtom);
+ ObservableValue.prototype[primitiveSymbol()] = ObservableValue.prototype.valueOf;
+ var isObservableValue = createInstanceofPredicate("ObservableValue", ObservableValue);
+ exports.isBoxedObservable = isObservableValue;
+ function getAtom(thing, property) {
+ if ((typeof thing === "undefined" ? "undefined" : _typeof(thing)) === "object" && thing !== null) {
+ if (isObservableArray(thing)) {
+ invariant(property === undefined, getMessage("m036"));
+ return thing.$mobx.atom;
+ }
+ if (isObservableMap(thing)) {
+ var anyThing = thing;
+ if (property === undefined) return getAtom(anyThing._keys);
+ var observable_2 = anyThing._data[property] || anyThing._hasMap[property];
+ invariant(!!observable_2, "the entry '" + property + "' does not exist in the observable map '" + getDebugName(thing) + "'");
+ return observable_2;
+ }
+ runLazyInitializers(thing);
+ if (isObservableObject(thing)) {
+ if (!property) return fail("please specify a property");
+ var observable_3 = thing.$mobx.values[property];
+ invariant(!!observable_3, "no observable property '" + property + "' found on the observable object '" + getDebugName(thing) + "'");
+ return observable_3;
+ }
+ if (isAtom(thing) || isComputedValue(thing) || isReaction(thing)) {
+ return thing;
+ }
+ } else if (typeof thing === "function") {
+ if (isReaction(thing.$mobx)) {
+ return thing.$mobx;
+ }
+ }
+ return fail("Cannot obtain atom from " + thing);
+ }
+ function getAdministration(thing, property) {
+ invariant(thing, "Expecting some object");
+ if (property !== undefined) return getAdministration(getAtom(thing, property));
+ if (isAtom(thing) || isComputedValue(thing) || isReaction(thing)) return thing;
+ if (isObservableMap(thing)) return thing;
+ runLazyInitializers(thing);
+ if (thing.$mobx) return thing.$mobx;
+ invariant(false, "Cannot obtain administration from " + thing);
+ }
+ function getDebugName(thing, property) {
+ var named;
+ if (property !== undefined) named = getAtom(thing, property);else if (isObservableObject(thing) || isObservableMap(thing)) named = getAdministration(thing);else named = getAtom(thing);
+ return named.name;
+ }
+ function createClassPropertyDecorator(onInitialize, _get, _set, enumerable, allowCustomArguments) {
+ function classPropertyDecorator(target, key, descriptor, customArgs, argLen) {
+ if (argLen === void 0) {
+ argLen = 0;
+ }
+ invariant(allowCustomArguments || quacksLikeADecorator(arguments), "This function is a decorator, but it wasn't invoked like a decorator");
+ if (!descriptor) {
+ var newDescriptor = {
+ enumerable: enumerable,
+ configurable: true,
+ get: function get() {
+ if (!this.__mobxInitializedProps || this.__mobxInitializedProps[key] !== true) typescriptInitializeProperty(this, key, undefined, onInitialize, customArgs, descriptor);
+ return _get.call(this, key);
+ },
+ set: function set(v) {
+ if (!this.__mobxInitializedProps || this.__mobxInitializedProps[key] !== true) {
+ typescriptInitializeProperty(this, key, v, onInitialize, customArgs, descriptor);
+ } else {
+ _set.call(this, key, v);
+ }
+ }
+ };
+ if (arguments.length < 3 || arguments.length === 5 && argLen < 3) {
+ Object.defineProperty(target, key, newDescriptor);
+ }
+ return newDescriptor;
+ } else {
+ if (!hasOwnProperty(target, "__mobxLazyInitializers")) {
+ addHiddenProp(target, "__mobxLazyInitializers", target.__mobxLazyInitializers && target.__mobxLazyInitializers.slice() || []);
+ }
+ var value_1 = descriptor.value,
+ initializer_1 = descriptor.initializer;
+ target.__mobxLazyInitializers.push(function (instance) {
+ onInitialize(instance, key, initializer_1 ? initializer_1.call(instance) : value_1, customArgs, descriptor);
+ });
+ return {
+ enumerable: enumerable, configurable: true,
+ get: function get() {
+ if (this.__mobxDidRunLazyInitializers !== true) runLazyInitializers(this);
+ return _get.call(this, key);
+ },
+ set: function set(v) {
+ if (this.__mobxDidRunLazyInitializers !== true) runLazyInitializers(this);
+ _set.call(this, key, v);
+ }
+ };
+ }
+ }
+ if (allowCustomArguments) {
+ return function () {
+ if (quacksLikeADecorator(arguments)) return classPropertyDecorator.apply(null, arguments);
+ var outerArgs = arguments;
+ var argLen = arguments.length;
+ return function (target, key, descriptor) {
+ return classPropertyDecorator(target, key, descriptor, outerArgs, argLen);
+ };
+ };
+ }
+ return classPropertyDecorator;
+ }
+ function typescriptInitializeProperty(instance, key, v, onInitialize, customArgs, baseDescriptor) {
+ if (!hasOwnProperty(instance, "__mobxInitializedProps")) addHiddenProp(instance, "__mobxInitializedProps", {});
+ instance.__mobxInitializedProps[key] = true;
+ onInitialize(instance, key, v, customArgs, baseDescriptor);
+ }
+ function runLazyInitializers(instance) {
+ if (instance.__mobxDidRunLazyInitializers === true) return;
+ if (instance.__mobxLazyInitializers) {
+ addHiddenProp(instance, "__mobxDidRunLazyInitializers", true);
+ instance.__mobxDidRunLazyInitializers && instance.__mobxLazyInitializers.forEach(function (initializer) {
+ return initializer(instance);
+ });
+ }
+ }
+ function quacksLikeADecorator(args) {
+ return (args.length === 2 || args.length === 3) && typeof args[1] === "string";
+ }
+ function iteratorSymbol() {
+ return typeof Symbol === "function" && Symbol.iterator || "@@iterator";
+ }
+ var IS_ITERATING_MARKER = "__$$iterating";
+ function arrayAsIterator(array) {
+ invariant(array[IS_ITERATING_MARKER] !== true, "Illegal state: cannot recycle array as iterator");
+ addHiddenFinalProp(array, IS_ITERATING_MARKER, true);
+ var idx = -1;
+ addHiddenFinalProp(array, "next", function next() {
+ idx++;
+ return {
+ done: idx >= this.length,
+ value: idx < this.length ? this[idx] : undefined
+ };
+ });
+ return array;
+ }
+ function declareIterator(prototType, iteratorFactory) {
+ addHiddenFinalProp(prototType, iteratorSymbol(), iteratorFactory);
+ }
+ var messages = {
+ "m001": "It is not allowed to assign new values to @action fields",
+ "m002": "`runInAction` expects a function",
+ "m003": "`runInAction` expects a function without arguments",
+ "m004": "autorun expects a function",
+ "m005": "Warning: attempted to pass an action to autorun. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action.",
+ "m006": "Warning: attempted to pass an action to autorunAsync. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action.",
+ "m007": "reaction only accepts 2 or 3 arguments. If migrating from MobX 2, please provide an options object",
+ "m008": "wrapping reaction expression in `asReference` is no longer supported, use options object instead",
+ "m009": "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'. It looks like it was used on a property.",
+ "m010": "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'",
+ "m011": "First argument to `computed` should be an expression. If using computed as decorator, don't pass it arguments",
+ "m012": "computed takes one or two arguments if used as function",
+ "m013": "[mobx.expr] 'expr' should only be used inside other reactive functions.",
+ "m014": "extendObservable expected 2 or more arguments",
+ "m015": "extendObservable expects an object as first argument",
+ "m016": "extendObservable should not be used on maps, use map.merge instead",
+ "m017": "all arguments of extendObservable should be objects",
+ "m018": "extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540",
+ "m019": "[mobx.isObservable] isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.",
+ "m020": "modifiers can only be used for individual object properties",
+ "m021": "observable expects zero or one arguments",
+ "m022": "@observable can not be used on getters, use @computed instead",
+ "m023": "Using `transaction` is deprecated, use `runInAction` or `(@)action` instead.",
+ "m024": "whyRun() can only be used if a derivation is active, or by passing an computed value / reaction explicitly. If you invoked whyRun from inside a computation; the computation is currently suspended but re-evaluating because somebody requested its value.",
+ "m025": "whyRun can only be used on reactions and computed values",
+ "m026": "`action` can only be invoked on functions",
+ "m028": "It is not allowed to set `useStrict` when a derivation is running",
+ "m029": "INTERNAL ERROR only onBecomeUnobserved shouldn't be called twice in a row",
+ "m030a": "Since strict-mode is enabled, changing observed observable values outside actions is not allowed. Please wrap the code in an `action` if this change is intended. Tried to modify: ",
+ "m030b": "Side effects like changing state are not allowed at this point. Are you trying to modify state from, for example, the render function of a React component? Tried to modify: ",
+ "m031": "Computed values are not allowed to not cause side effects by changing observables that are already being observed. Tried to modify: ",
+ "m032": "* This computation is suspended (not in use by any reaction) and won't run automatically.\n Didn't expect this computation to be suspended at this point?\n 1. Make sure this computation is used by a reaction (reaction, autorun, observer).\n 2. Check whether you are using this computation synchronously (in the same stack as they reaction that needs it).",
+ "m033": "`observe` doesn't support the fire immediately property for observable maps.",
+ "m034": "`mobx.map` is deprecated, use `new ObservableMap` or `mobx.observable.map` instead",
+ "m035": "Cannot make the designated object observable; it is not extensible",
+ "m036": "It is not possible to get index atoms from arrays",
+ "m037": "Hi there! I'm sorry you have just run into an exception.\nIf your debugger ends up here, know that some reaction (like the render() of an observer component, autorun or reaction)\nthrew an exception and that mobx caught it, to avoid that it brings the rest of your application down.\nThe original cause of the exception (the code that caused this reaction to run (again)), is still in the stack.\n\nHowever, more interesting is the actual stack trace of the error itself.\nHopefully the error is an instanceof Error, because in that case you can inspect the original stack of the error from where it was thrown.\nSee `error.stack` property, or press the very subtle \"(...)\" link you see near the console.error message that probably brought you here.\nThat stack is more interesting than the stack of this console.error itself.\n\nIf the exception you see is an exception you created yourself, make sure to use `throw new Error(\"Oops\")` instead of `throw \"Oops\"`,\nbecause the javascript environment will only preserve the original stack trace in the first form.\n\nYou can also make sure the debugger pauses the next time this very same exception is thrown by enabling \"Pause on caught exception\".\n(Note that it might pause on many other, unrelated exception as well).\n\nIf that all doesn't help you out, feel free to open an issue https://github.com/mobxjs/mobx/issues!\n",
+ "m038": "Missing items in this list?\n 1. Check whether all used values are properly marked as observable (use isObservable to verify)\n 2. Make sure you didn't dereference values too early. MobX observes props, not primitives. E.g: use 'person.name' instead of 'name' in your computation.\n"
+ };
+ function getMessage(id) {
+ return messages[id];
+ }
+ var EMPTY_ARRAY = [];
+ Object.freeze(EMPTY_ARRAY);
+ function getGlobal() {
+ return global;
+ }
+ function getNextId() {
+ return ++globalState.mobxGuid;
+ }
+ function fail(message, thing) {
+ invariant(false, message, thing);
+ throw "X";
+ }
+ function invariant(check, message, thing) {
+ if (!check) throw new Error("[mobx] Invariant failed: " + message + (thing ? " in '" + thing + "'" : ""));
+ }
+ var deprecatedMessages = [];
+ function deprecated(msg) {
+ if (deprecatedMessages.indexOf(msg) !== -1) return false;
+ deprecatedMessages.push(msg);
+ console.error("[mobx] Deprecated: " + msg);
+ return true;
+ }
+ function once(func) {
+ var invoked = false;
+ return function () {
+ if (invoked) return;
+ invoked = true;
+ return func.apply(this, arguments);
+ };
+ }
+ var noop = function noop() {};
+ function unique(list) {
+ var res = [];
+ list.forEach(function (item) {
+ if (res.indexOf(item) === -1) res.push(item);
+ });
+ return res;
+ }
+ function joinStrings(things, limit, separator) {
+ if (limit === void 0) {
+ limit = 100;
+ }
+ if (separator === void 0) {
+ separator = " - ";
+ }
+ if (!things) return "";
+ var sliced = things.slice(0, limit);
+ return "" + sliced.join(separator) + (things.length > limit ? " (... and " + (things.length - limit) + "more)" : "");
+ }
+ function isObject(value) {
+ return value !== null && (typeof value === "undefined" ? "undefined" : _typeof(value)) === "object";
+ }
+ function isPlainObject(value) {
+ if (value === null || (typeof value === "undefined" ? "undefined" : _typeof(value)) !== "object") return false;
+ var proto = Object.getPrototypeOf(value);
+ return proto === Object.prototype || proto === null;
+ }
+ function objectAssign() {
+ var res = arguments[0];
+ for (var i = 1, l = arguments.length; i < l; i++) {
+ var source = arguments[i];
+ for (var key in source) {
+ if (hasOwnProperty(source, key)) {
+ res[key] = source[key];
+ }
+ }
+ }
+ return res;
+ }
+ function valueDidChange(compareStructural, oldValue, newValue) {
+ if (typeof oldValue === 'number' && isNaN(oldValue)) {
+ return typeof newValue !== 'number' || !isNaN(newValue);
+ }
+ return compareStructural ? !deepEqual(oldValue, newValue) : oldValue !== newValue;
+ }
+ var prototypeHasOwnProperty = Object.prototype.hasOwnProperty;
+ function hasOwnProperty(object, propName) {
+ return prototypeHasOwnProperty.call(object, propName);
+ }
+ function makeNonEnumerable(object, propNames) {
+ for (var i = 0; i < propNames.length; i++) {
+ addHiddenProp(object, propNames[i], object[propNames[i]]);
+ }
+ }
+ function addHiddenProp(object, propName, value) {
+ Object.defineProperty(object, propName, {
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ value: value
+ });
+ }
+ function addHiddenFinalProp(object, propName, value) {
+ Object.defineProperty(object, propName, {
+ enumerable: false,
+ writable: false,
+ configurable: true,
+ value: value
+ });
+ }
+ function isPropertyConfigurable(object, prop) {
+ var descriptor = Object.getOwnPropertyDescriptor(object, prop);
+ return !descriptor || descriptor.configurable !== false && descriptor.writable !== false;
+ }
+ function assertPropertyConfigurable(object, prop) {
+ invariant(isPropertyConfigurable(object, prop), "Cannot make property '" + prop + "' observable, it is not configurable and writable in the target object");
+ }
+ function getEnumerableKeys(obj) {
+ var res = [];
+ for (var key in obj) {
+ res.push(key);
+ }return res;
+ }
+ function deepEqual(a, b) {
+ if (a === null && b === null) return true;
+ if (a === undefined && b === undefined) return true;
+ if ((typeof a === "undefined" ? "undefined" : _typeof(a)) !== "object") return a === b;
+ var aIsArray = isArrayLike(a);
+ var aIsMap = isMapLike(a);
+ if (aIsArray !== isArrayLike(b)) {
+ return false;
+ } else if (aIsMap !== isMapLike(b)) {
+ return false;
+ } else if (aIsArray) {
+ if (a.length !== b.length) return false;
+ for (var i = a.length - 1; i >= 0; i--) {
+ if (!deepEqual(a[i], b[i])) return false;
+ }return true;
+ } else if (aIsMap) {
+ if (a.size !== b.size) return false;
+ var equals_1 = true;
+ a.forEach(function (value, key) {
+ equals_1 = equals_1 && deepEqual(b.get(key), value);
+ });
+ return equals_1;
+ } else if ((typeof a === "undefined" ? "undefined" : _typeof(a)) === "object" && (typeof b === "undefined" ? "undefined" : _typeof(b)) === "object") {
+ if (a === null || b === null) return false;
+ if (isMapLike(a) && isMapLike(b)) {
+ if (a.size !== b.size) return false;
+ return deepEqual(observable.shallowMap(a).entries(), observable.shallowMap(b).entries());
+ }
+ if (getEnumerableKeys(a).length !== getEnumerableKeys(b).length) return false;
+ for (var prop in a) {
+ if (!(prop in b)) return false;
+ if (!deepEqual(a[prop], b[prop])) return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ function createInstanceofPredicate(name, clazz) {
+ var propName = "isMobX" + name;
+ clazz.prototype[propName] = true;
+ return function (x) {
+ return isObject(x) && x[propName] === true;
+ };
+ }
+ function isArrayLike(x) {
+ return Array.isArray(x) || isObservableArray(x);
+ }
+ exports.isArrayLike = isArrayLike;
+ function isMapLike(x) {
+ return isES6Map(x) || isObservableMap(x);
+ }
+ function isES6Map(thing) {
+ if (getGlobal().Map !== undefined && thing instanceof getGlobal().Map) return true;
+ return false;
+ }
+ function primitiveSymbol() {
+ return typeof Symbol === "function" && Symbol.toPrimitive || "@@toPrimitive";
+ }
+ function toPrimitive(value) {
+ return value === null ? null : (typeof value === "undefined" ? "undefined" : _typeof(value)) === "object" ? "" + value : value;
+ }
+ /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4)))
+
+ /***/ }),
+ /* 2 */
+ /***/ (function(module, exports, __webpack_require__) {
+
+ "use strict";
+
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+
+ var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+ var _icons = __webpack_require__(6);
+
+ var _constants = __webpack_require__(0);
+
+ function renderHeader(_ref, instance) {
+ var meta = _ref.meta,
+ user = _ref.user,
+ reactions = _ref.reactions;
+
+ var container = document.createElement('div');
+ container.lang = "en-US";
+ container.className = 'gitment-container gitment-header-container';
+
+ var likeButton = document.createElement('span');
+ var likedReaction = reactions.find(function (reaction) {
+ return reaction.content === 'heart' && reaction.user.login === user.login;
+ });
+ likeButton.className = 'gitment-header-like-btn';
+ likeButton.innerHTML = '\n ' + _icons.heart + '\n ' + (likedReaction ? 'Unlike' : 'Like') + '\n ' + (meta.reactions && meta.reactions.heart ? ' \u2022 ' + meta.reactions.heart + ' Liked' : '') + '\n ';
+
+ if (likedReaction) {
+ likeButton.classList.add('liked');
+ likeButton.onclick = function () {
+ return instance.unlike();
+ };
+ } else {
+ likeButton.classList.remove('liked');
+ likeButton.onclick = function () {
+ return instance.like();
+ };
+ }
+ container.appendChild(likeButton);
+
+ var commentsCount = document.createElement('span');
+ commentsCount.innerHTML = '\n ' + (meta.comments ? ' \u2022 ' + meta.comments + ' Comments' : '') + '\n ';
+ container.appendChild(commentsCount);
+
+ var issueLink = document.createElement('a');
+ issueLink.className = 'gitment-header-issue-link';
+ issueLink.href = meta.html_url;
+ issueLink.target = '_blank';
+ issueLink.innerText = 'Issue Page';
+ container.appendChild(issueLink);
+
+ return container;
+ }
+
+ function renderComments(_ref2, instance) {
+ var meta = _ref2.meta,
+ comments = _ref2.comments,
+ commentReactions = _ref2.commentReactions,
+ currentPage = _ref2.currentPage,
+ user = _ref2.user,
+ error = _ref2.error;
+
+ var container = document.createElement('div');
+ container.lang = "en-US";
+ container.className = 'gitment-container gitment-comments-container';
+
+ if (error) {
+ var errorBlock = document.createElement('div');
+ errorBlock.className = 'gitment-comments-error';
+
+ if (error === _constants.NOT_INITIALIZED_ERROR && user.login && user.login.toLowerCase() === instance.owner.toLowerCase()) {
+ var initHint = document.createElement('div');
+ var initButton = document.createElement('button');
+ initButton.className = 'gitment-comments-init-btn';
+ initButton.onclick = function () {
+ initButton.setAttribute('disabled', true);
+ instance.init().catch(function (e) {
+ initButton.removeAttribute('disabled');
+ alert(e);
+ });
+ };
+ initButton.innerText = 'Initialize Comments';
+ initHint.appendChild(initButton);
+ errorBlock.appendChild(initHint);
+ } else {
+ errorBlock.innerText = error;
+ }
+ container.appendChild(errorBlock);
+ return container;
+ } else if (comments === undefined) {
+ var loading = document.createElement('div');
+ loading.innerText = 'Loading comments...';
+ loading.className = 'gitment-comments-loading';
+ container.appendChild(loading);
+ return container;
+ } else if (!comments.length) {
+ var emptyBlock = document.createElement('div');
+ emptyBlock.className = 'gitment-comments-empty';
+ emptyBlock.innerText = 'No Comment Yet';
+ container.appendChild(emptyBlock);
+ return container;
+ }
+
+ var commentsList = document.createElement('ul');
+ commentsList.className = 'gitment-comments-list';
+
+ comments.forEach(function (comment) {
+ var createDate = new Date(comment.created_at);
+ var updateDate = new Date(comment.updated_at);
+ var commentItem = document.createElement('li');
+ commentItem.className = 'gitment-comment';
+ commentItem.innerHTML = '\n \n \n \n
' + comment.body_html + '
\n
\n ';
+ var likeButton = commentItem.querySelector('.gitment-comment-like-btn');
+ var likedReaction = commentReactions[comment.id] && commentReactions[comment.id].find(function (reaction) {
+ return reaction.content === 'heart' && reaction.user.login === user.login;
+ });
+ if (likedReaction) {
+ likeButton.classList.add('liked');
+ likeButton.onclick = function () {
+ return instance.unlikeAComment(comment.id);
+ };
+ } else {
+ likeButton.classList.remove('liked');
+ likeButton.onclick = function () {
+ return instance.likeAComment(comment.id);
+ };
+ }
+
+ // dirty
+ // use a blank image to trigger height calculating when element rendered
+ var imgTrigger = document.createElement('img');
+ var markdownBody = commentItem.querySelector('.gitment-comment-body');
+ imgTrigger.className = 'gitment-hidden';
+ imgTrigger.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
+ imgTrigger.onload = function () {
+ if (markdownBody.clientHeight > instance.maxCommentHeight) {
+ markdownBody.classList.add('gitment-comment-body-folded');
+ markdownBody.style.maxHeight = instance.maxCommentHeight + 'px';
+ markdownBody.title = 'Click to Expand';
+ markdownBody.onclick = function () {
+ markdownBody.classList.remove('gitment-comment-body-folded');
+ markdownBody.style.maxHeight = '';
+ markdownBody.title = '';
+ markdownBody.onclick = null;
+ };
+ }
+ };
+ commentItem.appendChild(imgTrigger);
+
+ commentsList.appendChild(commentItem);
+ });
+
+ container.appendChild(commentsList);
+
+ if (meta) {
+ var pageCount = Math.ceil(meta.comments / instance.perPage);
+ if (pageCount > 1) {
+ var pagination = document.createElement('ul');
+ pagination.className = 'gitment-comments-pagination';
+
+ if (currentPage > 1) {
+ var previousButton = document.createElement('li');
+ previousButton.className = 'gitment-comments-page-item';
+ previousButton.innerText = 'Previous';
+ previousButton.onclick = function () {
+ return instance.goto(currentPage - 1);
+ };
+ pagination.appendChild(previousButton);
+ }
+
+ var _loop = function _loop(i) {
+ var pageItem = document.createElement('li');
+ pageItem.className = 'gitment-comments-page-item';
+ pageItem.innerText = i;
+ pageItem.onclick = function () {
+ return instance.goto(i);
+ };
+ if (currentPage === i) pageItem.classList.add('gitment-selected');
+ pagination.appendChild(pageItem);
+ };
+
+ for (var i = 1; i <= pageCount; i++) {
+ _loop(i);
+ }
+
+ if (currentPage < pageCount) {
+ var nextButton = document.createElement('li');
+ nextButton.className = 'gitment-comments-page-item';
+ nextButton.innerText = 'Next';
+ nextButton.onclick = function () {
+ return instance.goto(currentPage + 1);
+ };
+ pagination.appendChild(nextButton);
+ }
+
+ container.appendChild(pagination);
+ }
+ }
+
+ return container;
+ }
+
+ function renderEditor(_ref3, instance) {
+ var user = _ref3.user,
+ error = _ref3.error;
+
+ var container = document.createElement('div');
+ container.lang = "en-US";
+ container.className = 'gitment-container gitment-editor-container';
+
+ var shouldDisable = user.login && !error ? '' : 'disabled';
+ var disabledTip = user.login ? '' : 'Login to Comment';
+ container.innerHTML = '\n ' + (user.login ? '\n \n ' : user.isLoggingIn ? '' + _icons.spinner + '
' : '\n ' + _icons.github + '\n ') + '\n \n \n \n ';
+ if (user.login) {
+ container.querySelector('.gitment-editor-logout-link').onclick = function () {
+ return instance.logout();
+ };
+ }
+
+ var writeField = container.querySelector('.gitment-editor-write-field');
+ var previewField = container.querySelector('.gitment-editor-preview-field');
+
+ var textarea = writeField.querySelector('textarea');
+ textarea.oninput = function () {
+ textarea.style.height = 'auto';
+ var style = window.getComputedStyle(textarea, null);
+ var height = parseInt(style.height, 10);
+ var clientHeight = textarea.clientHeight;
+ var scrollHeight = textarea.scrollHeight;
+ if (clientHeight < scrollHeight) {
+ textarea.style.height = height + scrollHeight - clientHeight + 'px';
+ }
+ };
+
+ var _container$querySelec = container.querySelectorAll('.gitment-editor-tab'),
+ _container$querySelec2 = _slicedToArray(_container$querySelec, 2),
+ writeTab = _container$querySelec2[0],
+ previewTab = _container$querySelec2[1];
+
+ writeTab.onclick = function () {
+ writeTab.classList.add('gitment-selected');
+ previewTab.classList.remove('gitment-selected');
+ writeField.classList.remove('gitment-hidden');
+ previewField.classList.add('gitment-hidden');
+
+ textarea.focus();
+ };
+ previewTab.onclick = function () {
+ previewTab.classList.add('gitment-selected');
+ writeTab.classList.remove('gitment-selected');
+ previewField.classList.remove('gitment-hidden');
+ writeField.classList.add('gitment-hidden');
+
+ var preview = previewField.querySelector('.gitment-editor-preview');
+ var content = textarea.value.trim();
+ if (!content) {
+ preview.innerText = 'Nothing to preview';
+ return;
+ }
+
+ preview.innerText = 'Loading preview...';
+ instance.markdown(content).then(function (html) {
+ return preview.innerHTML = html;
+ });
+ };
+
+ var submitButton = container.querySelector('.gitment-editor-submit');
+ submitButton.onclick = function () {
+ submitButton.innerText = 'Submitting...';
+ submitButton.setAttribute('disabled', true);
+ instance.post(textarea.value.trim()).then(function (data) {
+ textarea.value = '';
+ textarea.style.height = 'auto';
+ submitButton.removeAttribute('disabled');
+ submitButton.innerText = 'Comment';
+ }).catch(function (e) {
+ alert(e);
+ submitButton.removeAttribute('disabled');
+ submitButton.innerText = 'Comment';
+ });
+ };
+
+ return container;
+ }
+
+ function renderFooter() {
+ var container = document.createElement('div');
+ container.lang = "en-US";
+ container.className = 'gitment-container gitment-footer-container';
+ container.innerHTML = '\n Powered by\n \n ';
+ return container;
+ }
+
+ function render(state, instance) {
+ var container = document.createElement('div');
+ container.lang = "en-US";
+ container.className = 'gitment-container gitment-root-container';
+ container.appendChild(instance.renderHeader(state, instance));
+ container.appendChild(instance.renderComments(state, instance));
+ container.appendChild(instance.renderEditor(state, instance));
+ container.appendChild(instance.renderFooter(state, instance));
+ return container;
+ }
+
+ exports.default = { render: render, renderHeader: renderHeader, renderComments: renderComments, renderEditor: renderEditor, renderFooter: renderFooter };
+
+ /***/ }),
+ /* 3 */
+ /***/ (function(module, exports, __webpack_require__) {
+
+ "use strict";
+
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ exports.http = exports.Query = exports.isString = undefined;
+
+ var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+ exports.getTargetContainer = getTargetContainer;
+
+ var _constants = __webpack_require__(0);
+
+ var isString = exports.isString = function isString(s) {
+ return toString.call(s) === '[object String]';
+ };
+
+ function getTargetContainer(container) {
+ var targetContainer = void 0;
+ if (container instanceof Element) {
+ targetContainer = container;
+ } else if (isString(container)) {
+ targetContainer = document.getElementById(container);
+ } else {
+ targetContainer = document.createElement('div');
+ }
+
+ return targetContainer;
+ }
+
+ var Query = exports.Query = {
+ parse: function parse() {
+ var search = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window.location.search;
+
+ if (!search) return {};
+ var queryString = search[0] === '?' ? search.substring(1) : search;
+ var query = {};
+ queryString.split('&').forEach(function (queryStr) {
+ var _queryStr$split = queryStr.split('='),
+ _queryStr$split2 = _slicedToArray(_queryStr$split, 2),
+ key = _queryStr$split2[0],
+ value = _queryStr$split2[1];
+
+ if (key) query[key] = value;
+ });
+
+ return query;
+ },
+ stringify: function stringify(query) {
+ var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '?';
+
+ var queryString = Object.keys(query).map(function (key) {
+ return key + '=' + encodeURIComponent(query[key] || '');
+ }).join('&');
+ return queryString ? prefix + queryString : '';
+ }
+ };
+
+ function ajaxFactory(method) {
+ return function (apiPath) {
+ var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ var base = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'https://api.github.com';
+
+ var req = new XMLHttpRequest();
+ var token = localStorage.getItem(_constants.LS_ACCESS_TOKEN_KEY);
+
+ var url = '' + base + apiPath;
+ var body = null;
+ if (method === 'GET' || method === 'DELETE') {
+ url += Query.stringify(data);
+ }
+
+ var p = new Promise(function (resolve, reject) {
+ req.addEventListener('load', function () {
+ var contentType = req.getResponseHeader('content-type');
+ var res = req.responseText;
+ if (!/json/.test(contentType)) {
+ resolve(res);
+ return;
+ }
+ var data = req.responseText ? JSON.parse(res) : {};
+ if (data.message) {
+ reject(new Error(data.message));
+ } else {
+ resolve(data);
+ }
+ });
+ req.addEventListener('error', function (error) {
+ return reject(error);
+ });
+ });
+ req.open(method, url, true);
+
+ req.setRequestHeader('Accept', 'application/vnd.github.squirrel-girl-preview, application/vnd.github.html+json');
+ if (token) {
+ req.setRequestHeader('Authorization', 'token ' + token);
+ }
+ if (method !== 'GET' && method !== 'DELETE') {
+ body = JSON.stringify(data);
+ req.setRequestHeader('Content-Type', 'application/json');
+ }
+
+ req.send(body);
+ return p;
+ };
+ }
+
+ var http = exports.http = {
+ get: ajaxFactory('GET'),
+ post: ajaxFactory('POST'),
+ delete: ajaxFactory('DELETE'),
+ put: ajaxFactory('PUT')
+ };
+
+ /***/ }),
+ /* 4 */
+ /***/ (function(module, exports, __webpack_require__) {
+
+ "use strict";
+
+
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+ var g;
+
+// This works in non-strict mode
+ g = function () {
+ return this;
+ }();
+
+ try {
+ // This works if eval is allowed (see CSP)
+ g = g || Function("return this")() || (1, eval)("this");
+ } catch (e) {
+ // This works if the window reference is available
+ if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === "object") g = window;
+ }
+
+// g can still be undefined, but nothing to do about it...
+// We return undefined, instead of nothing here, so it's
+// easier to handle this case. if(!global) { ...}
+
+ module.exports = g;
+
+ /***/ }),
+ /* 5 */
+ /***/ (function(module, exports, __webpack_require__) {
+
+ "use strict";
+
+
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+ var _mobx = __webpack_require__(1);
+
+ var _constants = __webpack_require__(0);
+
+ var _utils = __webpack_require__(3);
+
+ var _default = __webpack_require__(2);
+
+ var _default2 = _interopRequireDefault(_default);
+
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+ var scope = 'public_repo';
+
+ function extendRenderer(instance, renderer) {
+ instance[renderer] = function (container) {
+ var targetContainer = (0, _utils.getTargetContainer)(container);
+ var render = instance.theme[renderer] || instance.defaultTheme[renderer];
+
+ (0, _mobx.autorun)(function () {
+ var e = render(instance.state, instance);
+ if (targetContainer.firstChild) {
+ targetContainer.replaceChild(e, targetContainer.firstChild);
+ } else {
+ targetContainer.appendChild(e);
+ }
+ });
+
+ return targetContainer;
+ };
+ }
+
+ var Gitment = function () {
+ _createClass(Gitment, [{
+ key: 'accessToken',
+ get: function get() {
+ return localStorage.getItem(_constants.LS_ACCESS_TOKEN_KEY);
+ },
+ set: function set(token) {
+ localStorage.setItem(_constants.LS_ACCESS_TOKEN_KEY, token);
+ }
+ }, {
+ key: 'loginLink',
+ get: function get() {
+ var oauthUri = 'https://github.com/login/oauth/authorize';
+ var redirect_uri = this.oauth.redirect_uri || window.location.href;
+
+ var oauthParams = Object.assign({
+ scope: scope,
+ redirect_uri: redirect_uri
+ }, this.oauth);
+
+ return '' + oauthUri + _utils.Query.stringify(oauthParams);
+ }
+ }]);
+
+ function Gitment() {
+ var _this = this;
+
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ _classCallCheck(this, Gitment);
+
+ this.defaultTheme = _default2.default;
+ this.useTheme(_default2.default);
+
+ Object.assign(this, {
+ id: window.location.href,
+ title: window.document.title,
+ link: window.location.href,
+ desc: '',
+ labels: [],
+ theme: _default2.default,
+ oauth: {},
+ perPage: 20,
+ maxCommentHeight: 250
+ }, options);
+
+ this.useTheme(this.theme);
+
+ var user = {};
+ try {
+ var userInfo = localStorage.getItem(_constants.LS_USER_KEY);
+ if (this.accessToken && userInfo) {
+ Object.assign(user, JSON.parse(userInfo), {
+ fromCache: true
+ });
+ }
+ } catch (e) {
+ localStorage.removeItem(_constants.LS_USER_KEY);
+ }
+
+ this.state = (0, _mobx.observable)({
+ user: user,
+ error: null,
+ meta: {},
+ comments: undefined,
+ reactions: [],
+ commentReactions: {},
+ currentPage: 1
+ });
+
+ var query = _utils.Query.parse();
+ if (query.code) {
+ var _oauth = this.oauth,
+ client_id = _oauth.client_id,
+ client_secret = _oauth.client_secret;
+
+ var code = query.code;
+ delete query.code;
+ var search = _utils.Query.stringify(query);
+ var replacedUrl = '' + window.location.origin + window.location.pathname + search + window.location.hash;
+ history.replaceState({}, '', replacedUrl);
+
+ Object.assign(this, {
+ id: replacedUrl,
+ link: replacedUrl
+ }, options);
+
+ this.state.user.isLoggingIn = true;
+ _utils.http.post('https://gh-oauth.imsun.net', {
+ code: code,
+ client_id: client_id,
+ client_secret: client_secret
+ }, '').then(function (data) {
+ _this.accessToken = data.access_token;
+ _this.update();
+ }).catch(function (e) {
+ _this.state.user.isLoggingIn = false;
+ alert(e);
+ });
+ } else {
+ this.update();
+ }
+ }
+
+ _createClass(Gitment, [{
+ key: 'init',
+ value: function init() {
+ var _this2 = this;
+
+ return this.createIssue().then(function () {
+ return _this2.loadComments();
+ }).then(function (comments) {
+ _this2.state.error = null;
+ return comments;
+ });
+ }
+ }, {
+ key: 'useTheme',
+ value: function useTheme() {
+ var _this3 = this;
+
+ var theme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ this.theme = theme;
+
+ var renderers = Object.keys(this.theme);
+ renderers.forEach(function (renderer) {
+ return extendRenderer(_this3, renderer);
+ });
+ }
+ }, {
+ key: 'update',
+ value: function update() {
+ var _this4 = this;
+
+ return Promise.all([this.loadMeta(), this.loadUserInfo()]).then(function () {
+ return Promise.all([_this4.loadComments().then(function () {
+ return _this4.loadCommentReactions();
+ }), _this4.loadReactions()]);
+ }).catch(function (e) {
+ return _this4.state.error = e;
+ });
+ }
+ }, {
+ key: 'markdown',
+ value: function markdown(text) {
+ return _utils.http.post('/markdown', {
+ text: text,
+ mode: 'gfm'
+ });
+ }
+ }, {
+ key: 'createIssue',
+ value: function createIssue() {
+ var _this5 = this;
+
+ var id = this.id,
+ owner = this.owner,
+ repo = this.repo,
+ title = this.title,
+ link = this.link,
+ desc = this.desc,
+ labels = this.labels;
+
+
+ return _utils.http.post('/repos/' + owner + '/' + repo + '/issues', {
+ title: title,
+ labels: labels.concat(['gitment', id]),
+ body: link + '\n\n' + desc
+ }).then(function (meta) {
+ _this5.state.meta = meta;
+ return meta;
+ });
+ }
+ }, {
+ key: 'getIssue',
+ value: function getIssue() {
+ if (this.state.meta.id) return Promise.resolve(this.state.meta);
+
+ return this.loadMeta();
+ }
+ }, {
+ key: 'post',
+ value: function post(body) {
+ var _this6 = this;
+
+ return this.getIssue().then(function (issue) {
+ return _utils.http.post(issue.comments_url, { body: body }, '');
+ }).then(function (data) {
+ _this6.state.meta.comments++;
+ var pageCount = Math.ceil(_this6.state.meta.comments / _this6.perPage);
+ if (_this6.state.currentPage === pageCount) {
+ _this6.state.comments.push(data);
+ }
+ return data;
+ });
+ }
+ }, {
+ key: 'loadMeta',
+ value: function loadMeta() {
+ var _this7 = this;
+
+ var id = this.id,
+ owner = this.owner,
+ repo = this.repo;
+
+ return _utils.http.get('/repos/' + owner + '/' + repo + '/issues', {
+ creator: owner,
+ labels: id
+ }).then(function (issues) {
+ if (!issues.length) return Promise.reject(_constants.NOT_INITIALIZED_ERROR);
+ _this7.state.meta = issues[0];
+ return issues[0];
+ });
+ }
+ }, {
+ key: 'loadComments',
+ value: function loadComments() {
+ var _this8 = this;
+
+ var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state.currentPage;
+
+ return this.getIssue().then(function (issue) {
+ return _utils.http.get(issue.comments_url, { page: page, per_page: _this8.perPage }, '');
+ }).then(function (comments) {
+ _this8.state.comments = comments;
+ return comments;
+ });
+ }
+ }, {
+ key: 'loadUserInfo',
+ value: function loadUserInfo() {
+ var _this9 = this;
+
+ if (!this.accessToken) {
+ this.logout();
+ return Promise.resolve({});
+ }
+
+ return _utils.http.get('/user').then(function (user) {
+ _this9.state.user = user;
+ localStorage.setItem(_constants.LS_USER_KEY, JSON.stringify(user));
+ return user;
+ });
+ }
+ }, {
+ key: 'loadReactions',
+ value: function loadReactions() {
+ var _this10 = this;
+
+ if (!this.accessToken) {
+ this.state.reactions = [];
+ return Promise.resolve([]);
+ }
+
+ return this.getIssue().then(function (issue) {
+ if (!issue.reactions.total_count) return [];
+ return _utils.http.get(issue.reactions.url, {}, '');
+ }).then(function (reactions) {
+ _this10.state.reactions = reactions;
+ return reactions;
+ });
+ }
+ }, {
+ key: 'loadCommentReactions',
+ value: function loadCommentReactions() {
+ var _this11 = this;
+
+ if (!this.accessToken) {
+ this.state.commentReactions = {};
+ return Promise.resolve([]);
+ }
+
+ var comments = this.state.comments;
+ var comentReactions = {};
+
+ return Promise.all(comments.map(function (comment) {
+ if (!comment.reactions.total_count) return [];
+
+ var owner = _this11.owner,
+ repo = _this11.repo;
+
+ return _utils.http.get('/repos/' + owner + '/' + repo + '/issues/comments/' + comment.id + '/reactions', {});
+ })).then(function (reactionsArray) {
+ comments.forEach(function (comment, index) {
+ comentReactions[comment.id] = reactionsArray[index];
+ });
+ _this11.state.commentReactions = comentReactions;
+
+ return comentReactions;
+ });
+ }
+ }, {
+ key: 'login',
+ value: function login() {
+ window.location.href = this.loginLink;
+ }
+ }, {
+ key: 'logout',
+ value: function logout() {
+ localStorage.removeItem(_constants.LS_ACCESS_TOKEN_KEY);
+ localStorage.removeItem(_constants.LS_USER_KEY);
+ this.state.user = {};
+ }
+ }, {
+ key: 'goto',
+ value: function goto(page) {
+ this.state.currentPage = page;
+ this.state.comments = undefined;
+ return this.loadComments(page);
+ }
+ }, {
+ key: 'like',
+ value: function like() {
+ var _this12 = this;
+
+ if (!this.accessToken) {
+ alert('Login to Like');
+ return Promise.reject();
+ }
+
+ var owner = this.owner,
+ repo = this.repo;
+
+
+ return _utils.http.post('/repos/' + owner + '/' + repo + '/issues/' + this.state.meta.number + '/reactions', {
+ content: 'heart'
+ }).then(function (reaction) {
+ _this12.state.reactions.push(reaction);
+ _this12.state.meta.reactions.heart++;
+ });
+ }
+ }, {
+ key: 'unlike',
+ value: function unlike() {
+ var _this13 = this;
+
+ if (!this.accessToken) return Promise.reject();
+
+ var _state = this.state,
+ user = _state.user,
+ reactions = _state.reactions;
+
+ var index = reactions.findIndex(function (reaction) {
+ return reaction.user.login === user.login;
+ });
+ return _utils.http.delete('/reactions/' + reactions[index].id).then(function () {
+ reactions.splice(index, 1);
+ _this13.state.meta.reactions.heart--;
+ });
+ }
+ }, {
+ key: 'likeAComment',
+ value: function likeAComment(commentId) {
+ var _this14 = this;
+
+ if (!this.accessToken) {
+ alert('Login to Like');
+ return Promise.reject();
+ }
+
+ var owner = this.owner,
+ repo = this.repo;
+
+ var comment = this.state.comments.find(function (comment) {
+ return comment.id === commentId;
+ });
+
+ return _utils.http.post('/repos/' + owner + '/' + repo + '/issues/comments/' + commentId + '/reactions', {
+ content: 'heart'
+ }).then(function (reaction) {
+ _this14.state.commentReactions[commentId].push(reaction);
+ comment.reactions.heart++;
+ });
+ }
+ }, {
+ key: 'unlikeAComment',
+ value: function unlikeAComment(commentId) {
+ if (!this.accessToken) return Promise.reject();
+
+ var reactions = this.state.commentReactions[commentId];
+ var comment = this.state.comments.find(function (comment) {
+ return comment.id === commentId;
+ });
+ var user = this.state.user;
+
+ var index = reactions.findIndex(function (reaction) {
+ return reaction.user.login === user.login;
+ });
+
+ return _utils.http.delete('/reactions/' + reactions[index].id).then(function () {
+ reactions.splice(index, 1);
+ comment.reactions.heart--;
+ });
+ }
+ }]);
+
+ return Gitment;
+ }();
+
+ module.exports = Gitment;
+
+ /***/ }),
+ /* 6 */
+ /***/ (function(module, exports, __webpack_require__) {
+
+ "use strict";
+
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+ /**
+ * Modified from https://github.com/evil-icons/evil-icons
+ */
+
+ var close = exports.close = '';
+ var github = exports.github = '';
+ var heart = exports.heart = '';
+ var spinner = exports.spinner = '';
+
+ /***/ })
+ /******/ ]);
+//# sourceMappingURL=gitment.browser.js.map
\ No newline at end of file
diff --git a/js/index.js b/js/index.js
index e69de29..776bbb9 100644
--- a/js/index.js
+++ b/js/index.js
@@ -0,0 +1,348 @@
+/**
+ * Created by Xiaotao.Nie on 09/04/2018.
+ * All right reserved
+ * IF you have any question please email onlythen@yeah.net
+ */
+
+// Global functions and listeners
+window.onresize = () => {
+ // when window resize , we show remove some class that me be added
+ // often for debug
+ if(window.document.documentElement.clientWidth > 680){
+ let aboutContent = document.getElementById('nav-content')
+ aboutContent.classList.remove('hide-block')
+ aboutContent.classList.remove('show-block');
+ }
+ // if(window.isPost){
+ // reLayout()
+ // }
+
+ reHeightToc();
+};
+
+// Nav switch function on mobile
+/*****************************************************************************/
+const navToggle = document.getElementById('site-nav-toggle');
+navToggle.addEventListener('click', () => {
+ let aboutContent = document.getElementById('nav-content')
+ if (!aboutContent.classList.contains('show-block')) {
+ aboutContent.classList.add('show-block');
+ aboutContent.classList.remove('hide-block')
+ } else {
+ aboutContent.classList.add('hide-block')
+ aboutContent.classList.remove('show-block');
+ }
+})
+
+
+// global search
+/*****************************************************************************/
+
+const searchButton = document.getElementById('search')
+const searchField = document.getElementById('search-field')
+const searchInput = document.getElementById('search-input')
+const searchResultContainer = document.getElementById('search-result-container')
+const escSearch = document.getElementById('esc-search')
+const beginSearch = document.getElementById('begin-search')
+
+searchField.addEventListener('mousewheel',(e) => {
+ // e.preventDefault()
+ e.stopPropagation()
+ return false
+}, false)
+
+var searchJson;
+var caseSensitive = false
+
+searchButton.addEventListener('click', () => {
+ search()
+});
+
+escSearch.addEventListener('click',() => {
+ hideSearchField()
+})
+
+beginSearch.addEventListener('click',() => {
+ let keyword = searchInput.value;
+ if(keyword){
+ searchFromKeyWord(keyword)
+ }
+})
+
+function toggleSeachField(){
+ if (!searchField.classList.contains('show-flex-fade')) {
+ showSearchField()
+ } else {
+ hideSearchField()
+ }
+}
+
+function showSearchField() {
+ searchInput.focus()
+ searchField.classList.add('show-flex-fade');
+ searchField.classList.remove('hide-flex-fade');
+}
+
+function hideSearchField(){
+ window.onkeydown = null;
+ searchField.classList.add('hide-flex-fade');
+ searchField.classList.remove('show-flex-fade');
+}
+
+function searchFromKeyWord(keyword = ""){
+ let result = [];
+
+ let sildeWindowSize = 100;
+
+ let handleKeyword = keyword
+
+ if(!caseSensitive){
+ handleKeyword = keyword.toLowerCase()
+ }
+ if(!searchJson) return -1;
+ else {
+ searchJson.forEach((item) => {
+
+ if(!item.title || !item.content) return 0; // break
+
+ let title = item.title
+ let content = item.content.trim().replace(/<[^>]+>/g,"").replace(/[`#\n]/g,"");
+
+ let lowerTitle = title,lowerContent = content;
+
+ if(!caseSensitive){
+ lowerTitle = title.toLowerCase();
+ lowerContent = content.toLowerCase();
+ }
+
+
+ if(lowerTitle.indexOf(handleKeyword) !== -1 || lowerContent.indexOf(handleKeyword) !== -1){
+ let resultItem = {}
+ resultItem.title = title.replace(keyword, "" + keyword + '');
+ resultItem.url = item.url;
+
+ resultItem.content = [];
+
+ let lastend = 0
+
+ while(lowerContent.indexOf(handleKeyword) !== -1){
+ let begin = lowerContent.indexOf(handleKeyword) - sildeWindowSize / 2 < 0 ? 0 : lowerContent.indexOf(handleKeyword) - sildeWindowSize / 2
+ let end = begin + sildeWindowSize;
+ let reg = caseSensitive ? new RegExp('('+keyword+')','g') : new RegExp('('+keyword+')','ig')
+ resultItem.content.push("..." + content.slice(lastend + begin, lastend + end).replace(reg, "$1") + "...")
+ lowerContent = lowerContent.slice(end, lowerContent.length)
+ lastend = end
+ }
+ // resultItem.title = title.replace(keyword, "" + keyword + '');
+ result.push(resultItem)
+ }
+ })
+ }
+
+ if(!result.length){
+ searchResultContainer.innerHTML = `
+ No Result
+ `
+ return;
+ }
+
+ let searchFragment = document.createElement('ul')
+
+ for(let item of result){
+ let searchItem = document.createElement('li');
+ let searchTitle = document.createElement('a');
+ searchTitle.href = item.url
+ searchTitle.innerHTML = item.title;
+ searchItem.appendChild(searchTitle)
+ if(item.content.length) {
+ let searchContentLiContainer = document.createElement('ul')
+ for (let citem of item.content) {
+ let searchContentFragment = document.createElement('li')
+ searchContentFragment.innerHTML = citem;
+ searchContentLiContainer.appendChild(searchContentFragment)
+ }
+ searchItem.appendChild(searchContentLiContainer)
+ }
+ searchFragment.appendChild(searchItem)
+ }
+ while(searchResultContainer.firstChild){
+ searchResultContainer.removeChild(searchResultContainer.firstChild)
+ }
+ searchResultContainer.appendChild(searchFragment)
+}
+
+function search(){
+
+ toggleSeachField()
+
+ window.onkeydown = (e) => {
+ if (e.which === 27) {
+ /** 这里编写当ESC按下时的处理逻辑! */
+ toggleSeachField()
+ } else if(e.which === 13){
+ // 回车按下
+ let keyword = searchInput.value;
+ if(keyword){
+ searchFromKeyWord(keyword)
+ }
+ }
+ }
+
+
+ if(!searchJson){
+ let isXml;
+ let search_path = window.hexo_search_path;
+ if (search_path.length === 0) {
+ search_path = "search.json";
+ } else if (/json$/i.test(search_path)) {
+ isXml = false;
+ }
+ let path = window.hexo_root+ search_path;
+ $.ajax({
+ url: path,
+ dataType: isXml ? "xml" : "json",
+ async: true,
+ success: function (res) {
+ searchJson = isXml ? $("entry", res).map(function() {
+ return {
+ title: $("title", this).text(),
+ content: $("content",this).text(),
+ url: $("url" , this).text()
+ };
+ }).get() : res;
+ }
+ });
+ }
+
+}
+
+// directory function in post pages
+/*****************************************************************************/
+function getDistanceOfLeft(obj) {
+ let left = 0;
+ let top = 0;
+ while (obj) {
+ left += obj.offsetLeft;
+ top += obj.offsetTop;
+ obj = obj.offsetParent;
+ }
+ return {
+ left:left,
+ top:top
+ };
+}
+
+var toc = document.getElementById('toc')
+
+var tocToTop = getDistanceOfLeft(toc).top;
+
+function reHeightToc(){
+ if(toc) { // resize toc height
+ toc.style.height = ( document.documentElement.clientHeight - 10 ) + 'px';
+ toc.style.overflowY = 'scroll';
+ }
+}
+
+reHeightToc();
+
+if(window.isPost){
+ var result = []
+
+ var nameSet = new Set();
+
+ if(!toc || !toc.children || !toc.children[0]){
+ // do nothing
+ }
+ else {
+ if (toc.children[0].nodeName === "OL") {
+ let ol = Array.from(toc.children[0].children)
+
+ function getArrayFromOl(ol) {
+ let result = []
+
+ // let escape = function (item) {
+ // return item.replace(/<[^>]+>/g, "").replace(/^\s\s*/, '').replace(/\s\s*$/, '').replace(/[\. _]/g, '-')
+ // }
+
+ ol.forEach((item) => {
+ if (item.children.length === 1) {
+ // TODO: need change
+ let value = item.children[0].getAttribute('href').replace(/^#/,"")
+ result.push({
+ value: [value],
+ dom: item
+ })
+ nameSet.add(value)
+ }
+ else {
+ let concatArray = getArrayFromOl(Array.from(item.children[1].children))
+ nameSet.add(item.children[0].getAttribute('href').replace(/^#/,""))
+ result.push({
+ value: [item.children[0].getAttribute('href').replace(/^#/,"")].concat(concatArray.reduce((p, n) => {
+ p = p.concat(n.value)
+ return p;
+ }, [])),
+ dom: item
+ })
+ result = result.concat(concatArray)
+ }
+ })
+ return result
+ }
+
+ result = getArrayFromOl(ol)
+ }
+
+ var nameArray = Array.from(nameSet)
+
+ function reLayout() {
+ let scrollToTop = document.documentElement.scrollTop || window.pageYOffset // Safari is special
+ if(tocToTop === 0) {
+ // Fix bug that when resize window the toc layout may be wrong
+ toc = document.getElementById('toc')
+ toc.classList.remove('toc-fixed')
+ tocToTop = getDistanceOfLeft(toc).top;
+ }
+ if (tocToTop <= scrollToTop + 10) {
+ if (!toc.classList.contains('toc-fixed'))
+ toc.classList.add('toc-fixed')
+ } else {
+ if (toc.classList.contains('toc-fixed'))
+ toc.classList.remove('toc-fixed')
+ }
+
+ let minTop = 9999;
+ let minTopsValue = ""
+
+ for (let item of nameArray) {
+ let dom = document.getElementById(item) || document.getElementById(item.replace(/\s/g, ''))
+ if (!dom) continue
+ let toTop = getDistanceOfLeft(dom).top - scrollToTop;
+
+ if (Math.abs(toTop) < minTop) {
+ minTop = Math.abs(toTop)
+ minTopsValue = item
+ }
+
+ // console.log(minTopsValue, minTop)
+ }
+
+ if (minTopsValue) {
+ for (let item of result) {
+ if (item.value.indexOf(minTopsValue) !== -1) {
+ item.dom.classList.add("active")
+ } else {
+ item.dom.classList.remove("active")
+ }
+ }
+ }
+ }
+
+ reLayout()
+
+ window.addEventListener('scroll', (e) => {
+ reLayout()
+ })
+ }
+}
+
diff --git a/links/index.html b/links/index.html
index e69de29..251f512 100644
--- a/links/index.html
+++ b/links/index.html
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 常用链接
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 常用链接
+
+
+
+ Post:2020-04-18 09:26:10
+
+
+
+
+
+
+
uweb浏览器中长按链接按钮可弹出常用链接菜单,这些链接定义在文件”default.links”中。每行格式如下:
[菜单名]:[url][空格][javascript脚本]
其中空格及之后的脚本为可选项。url及之后的脚本支持“%u”,”%s”等替换。
脚本将在链接访问结束时自动执行。
+
url除支持所有标准的http(s):,javascript:等链接外,还支持超微内部链接(”:”为链接第二个字符)及特殊链接(”:”为链接首字符)。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/loadbt/index.html b/loadbt/index.html
index e69de29..6b7bc6a 100644
--- a/loadbt/index.html
+++ b/loadbt/index.html
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用国外离线网盘囤积资源
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用国外离线网盘囤积资源
+
+
+
+
Post:2019-06-05 17:55:34
+
+
Tags:/
+
+ termux
+ /
+
+ 网盘
+ /
+
+ 离线
+ /
+
+ 资源
+ /
+
+
+
+
+
+
+
+
百度网盘存储空间大,还支持离线下载。但其离线下载限制很多,可能由于某些重要节点被屏蔽的原因,下载国外资料基本都会失败。国外离线网盘空间小,但下载成功率很高。
本文介绍一种技术,使用国外离线网盘下载资源,然后一键离线至百度网盘。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/logcat/index.html b/logcat/index.html
index e69de29..c5dcc48 100644
--- a/logcat/index.html
+++ b/logcat/index.html
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 安卓系统出错诊断
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 安卓系统出错诊断
+
+
+
+ Post:2020-03-30 11:17:41
+
+
+
+
+
+
+
超微浏览器如果闪退,会生成出错文件”/sdcard/uweb/error.log”。
+
如果超微或安卓系统或任何应用出现问题,则可利用超微浏览器进行诊断,方法如下:
+
+- 访问常用命令网页,点击安装logcat相关的两个命令。
+- 清空后台并重启超微浏览器。
+- 长按历史按钮,执行命令”清空logcat”。
+- 触发有问题的功能。
+- 长按历史按钮,执行命令”输出logcat.log”.
+- 检查文件”/sdcard/uweb/logcat.log”内容。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/multiaccount/index.html b/multiaccount/index.html
index e69de29..24f924f 100644
--- a/multiaccount/index.html
+++ b/multiaccount/index.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用多账号登录获取资源
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 利用多账号登录获取资源
+
+
+
+ Post:2019-06-07 16:22:01
+
+
+
+
+
+
+
谈到资源就离不开bt, bt下载费时费力,离线bt是最佳选择。国内离线下载由于关键节点屏蔽,基本没啥用。我的个人体验是彻彻底底完全没用,但别人也许还有点用?国外唯一一个有好体验的是seedr, 不过seedr有个大问题需要解决。
+
其它我曾推荐过的台湾bt, bug实在太多,现在看来也成了半个垃圾。万般无奈之下只能重拾seedr.
+
seedr的问题是首次登录需要google人机验证,登录成功以后可以永久使用,无需小飞机辅助。
+
以前偶尔飞飞一点问题也没有,毕竟1分钟飞行就可解决很长时间问题了。但目前的状态是信息基本被彻底封死,1分钟飞行也成了奢望。所以十分有必要珍惜这来之不易的1分钟飞行成果。
+
现在直接上方案,使用超微浏览器多账号登录。飞行1分钟以后成功登录seedr, 此时退出浏览器,千万不能强退,一定要让运存中的登录信息写到内部存储。然后用户可备份应用内部目录下的.cjar文件,一旦浏览器失去登录状态,可恢复此文件,即可使用多账号登录重新登录,让这1分钟飞行成果保存下来,供万万年使用。需要注意的一点是:用户退出seedr账号会使保存的文件作废。故千万不要退出账号,需要用其它账号登录的请使用多账号登录。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/offlinecache/index.html b/offlinecache/index.html
index e69de29..bab1a3a 100644
--- a/offlinecache/index.html
+++ b/offlinecache/index.html
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 装载网站离线资源
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 装载网站离线资源
+
+
+
+ Post:2019-11-10 16:44:23
+
+
+
+
+
+
+
uweb浏览器支持装载网站离线资源。只需要将离线资源存为文件”/sdcard/uweb/sitecache/[域名]/[全部路径,包括文件名,?,&,=, 与url一模一样]”。如果应用内部目录有文件夹”sitejs”存在,则“/sdcard/uweb”下的离线资源不再生效,此时生效离线资源为内部目录下的”sitecache”文件夹。
+
打开选项以后超微将自动装载这些离线资源。
+
离线资源可作为缓存提高浏览器性能; 可作为国外网站部分备份修复服务访问; 也可替换部分网站资源达到定制网站的作用。
+
下面以google翻译为例说明如何发现并备份离线资源。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pccopy/index.html b/pccopy/index.html
index e69de29..98a64cd 100644
--- a/pccopy/index.html
+++ b/pccopy/index.html
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 笔记及手机复制(富)文本至PC剪贴板
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 笔记及手机复制(富)文本至PC剪贴板
+
+
+
+
Post:2019-06-05 17:55:34
+
+
Tags:/
+
+ termux
+ /
+
+ ssh
+ /
+
+ 剪贴板
+ /
+
+ PC
+ /
+
+ Windows
+ /
+
+
+
+
+
+
+
+
技巧等级:笔记(中级) PC剪贴板(高级)
+
手机需安装uweb定制Termux。如使用剪贴板功能,termux还需安装openssl。
+
配置/sdcard/uweb/default.select如下:
+
笔记::(cat;echo;echo;)>>notes.txt
+富文本笔记:html:(cat;echo '<p></p>';echo;)>>notes.html
+命名笔记:(cat;echo;echo;)>>%s
+复制至PC剪贴板::ssh [user:password]@192.168.2.102 "DISPLAY=:0 xsel -i"
+复制富文本至PC剪贴板:html:ssh [user:password]@192.168.2.102 "DISPLAY=:0 xsel -i"
+
+
此处假定远程PC的IP地址为192.168.2.102,PC已经开通了ssh服务。建议用户配置ssh服务为免密码登录,此时用户无需将密码写入文件default.select。用户PC上安装有xsel剪贴板工具。使用其它工具请酌情修改。
+
重启浏览器,长按“书签”按钮,将弹出菜单。若用户当前窗口并无选中文本,则选取整个页面作相应操作,否则以选中文本为准。
+
采用以上配置,笔记将储存在/sdcard/uweb目录下文件note.txt或note.html中(富文本)。命名笔记储存文件则由用户在地址栏输入框内指定。
+
手机其它应用中的文本可选中后分享给超微浏览器,再由超微浏览器作笔记或进一步分享给PC。如果其它应用无法分享选中文本,这种情况可以先复制文本至剪贴板。
在超微浏览器中长按并在新窗口打开此链接,然后点击窗口并粘贴文本。长按书签按钮选择适当功能即可复制至PC剪贴板。
+
通过新窗口打开上述链接,超微浏览器因此亦可用作简单的文本/html编辑器。用户可通过“命名笔记”存为地址栏输入框指定文件。
+
Windows PC
对Windows PC而言,vista及以后自带clip.exe,此时配置如下:
复制文本至PC剪贴板::ssh [user:password]@192.168.2.102 clip.exe
+
其它推荐工具(读取PC剪贴板):
pclip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pcdown/index.html b/pcdown/index.html
index e69de29..b782cb6 100644
--- a/pcdown/index.html
+++ b/pcdown/index.html
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 浏览器一键控制台式机/服务器下载资源
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 浏览器一键控制台式机/服务器下载资源
+
+
+
+
Post:2019-06-05 17:55:34
+
+
Tags:/
+
+ termux
+ /
+
+ ssh
+ /
+
+ PC
+ /
+
+ 下载
+ /
+
+
+
+
+
+
+
+
技巧等级:高级
+
小孩要听英文有声书“The lying games”,国内服务器没一个能下的,最后还是在手机上用seedr秒下。但seedr的登录要用google人机交互确认,用过代理、tunnel至手机等方法,台式机死活登录不上。下面言归正传,讲一下超微浏览器直接下载资源至台式机的方法:
+
手机需安装uweb定制Termux,并在termux下安装openssl,在Termux窗口下依次敲入如下命令:
apt update
apt upgrade
apt install openssl
+
脚本pcdownload内容如下(可放置在任意应用内部目录下,并相应修改default.longclick配置中文件路径):
#!/data/data/com.termux/files/usr/bin/sh
ssh [user:password]@192.168.2.102 "DISPLAY=:0 firefox \"$1\""
+
脚本需设置为可执行,Termux下执行命令:
chmod 755 /data/data/com.termux/files/usr/bin/pcdownload
+
这里假定用户已经在台式机上设好ssh服务,台式机IP地址为192.168.2.102,准备用firefox下载。如果下载工具不是图形程序,则上述脚本中可删去“DISPLAY=:0”。
+
配置文件/sdcard/uweb/default.longclick如下:
PCdown:/data/data/com.termux/files/usr/bin/pcdownload
+
重启超微浏览器,点击链接下载时会弹出菜单,选择”PCdown”,台式机会启动firefox下载手机指定文档。
+
可能大家有疑问,台式机无法登录,为什么手机可以登录?这是因为手机上应用多哈。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/redirect/index.html b/redirect/index.html
index e69de29..d23ca4d 100644
--- a/redirect/index.html
+++ b/redirect/index.html
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 重定向国外网址至国内镜像(附编辑本地文件)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 重定向国外网址至国内镜像(附编辑本地文件)
+
+
+
+
Post:2019-11-13 20:46:18
+
+
Tags:/
+
+ 国外网址
+ /
+
+ 重定向
+ /
+
+
+
+
+
+
+
+
使用服务器在国外的搜索引擎体验往往不如国内的引擎。由于网站屏蔽的原因,两者之间索引权重差别很大。国外受欢迎的技术类网站因此难以在百度上搜到;国外引擎能搜到但由于其中不少结果无法访问而体验糟糕。
+
其实,很多技术类网站在国内早有镜像,但由于镜像并非众所周知,其索引权重在百度上微不足道,非专门搜索不可得。
+
本文介绍一种技术,可重定向国外网址至国内镜像,极大的提高国外引擎的体验,让更多用户更客观的理解全球技术。
+
配置/sdcard/uweb/default.redirect:
文件每一行格式为:
域名:正则表达式:替换表达式
+
其中正则表达式以java语言规定为准,表达式中不能包含’:’。正则表达式为空时系统默认为与域名相同。
+
例子文件内容如下:
developer.android.com::developer.android.google.cn
+
四种使用重定向的方法:
+
+长按链接
添加文件”国内镜像.js”至”/sdcard/uweb/longclick”目录下。
文件内容如下:
+//e:%u
+
+其中”e:”为uweb特殊url协议,意为”edit”,即”编辑”。当后面紧跟url网址的情况下会重定向网址。
+重启uweb后长按链接弹出菜单选”国内镜像”,浏览器将访问网址的国内镜像。若网址为本地文件,则浏览器会自动调用此类文件编辑器。
+
+长按工具条图像按钮。
+
+- 长按设置,选中”自定义重定向”。
+- 长按设置,选中”自定义资源重定向”。此选项除访问url重定向之外,还可重定向网页中一切资源。
+
+
更多重定向网址:
www.bilibili.com::www.ibilibili.com
pan.baidu.com::pan.baiduwp.com
www.docin.com::www.docin365.com
wenku.baidu.com::wenku.baiduvvv.com
detail.tmall.com::detail.tmallvvv.com
detail.m.tmall.com::detail.m.tmallvvv.com
item.taobao.com::item.taobaovvv.com
h5.m.taobao.com::h5.m.taobaovvv.com
jd.com::jdvvv.com
item.yhd.com::item.yhdvvv.com
goods.kaola.com::goods.kaolavvv.com
product.dangdang.com::product.dangdangvvv.com
item.gome.com.cn::item.gomevvv.com.cn
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/rjs/index.html b/rjs/index.html
index e69de29..bc8fd41 100644
--- a/rjs/index.html
+++ b/rjs/index.html
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 运行javascript脚本
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 运行javascript脚本
+
+
+
+
Post:2020-04-05 10:20:37
+
+
Tags:/
+
+ javascript
+ /
+
+
+
+
+
+
+
+
uweb浏览器支持运行本地及远程javascript脚本。
大型脚本可安装到”/sdcard/uweb/bookmarklet”目录下:
彩云小译
+
远程及小型脚本可安装到default.rjs文件中:
点击安装站内搜索、背景图、新窗口打开链接、移除覆盖物等
+
远程脚本配置文件/sdcard/uweb/default.rjs示例如下:
+
彩云小译:'https://caiyunapp.com/dest/trs.js'
+移除覆盖物:'https://jamesfengcao.gitee.io/uweb/searchurl/bml/content/rmo.js'
+新窗口打开链接:'';{d=document,b=d.createElement('base');b.setAttribute('target','_blank');d.head.appendChild(b);}
+google translate:'https://translate.google.cn/translate_a/element.js?cb=googleTranslateElementInit';b=d.body;v=d.createElement('div');v.id='google_translate_element';v.style.display='none';b.insertBefore(v,b.firstChild);p=d.createElement('script');p.text="function googleTranslateElementInit(){new google.translate.TranslateElement({pageLanguage: 'auto',includedLanguages:'zh-CN,zh-TW,en'},'google_translate_element');}";p.type='text/javascript';b.appendChild(p)
+
+
+
default.rjs每行格式如下 (url部分支持js代码运算):
[远程脚本名]:[返回字符串的javascript代码]
+
重启浏览器,长按搜索按钮,则弹出远程脚本菜单。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/searchcat/index.html b/searchcat/index.html
index e69de29..dcb482f 100644
--- a/searchcat/index.html
+++ b/searchcat/index.html
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 分类多引擎搜索
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 分类多引擎搜索
+
+
+
+
Post:2020-01-11 11:10:14
+
+
Tags:/
+
+ 搜索
+ /
+
+
+
+
+
+
+
+
长按下面链接可直接下载为分类多引擎搜索配置文件,点击本链接自动安装所有文件至”/sdcard/uweb/bookmark”目录下:
影视搜索
小说搜索
+
超微浏览器中通过“设置”->“总目录”->“↑”->“Download”,点击后缀为.search的下载文件,超微浏览器将自动显示分类多引擎搜索。此时可按菜单键(或长按底部工具条后退按钮)选择“添加到桌面”方便以后访问。
+
.search文件每行格式为如下几种:
[搜索引擎名]:[不含%s的url]
[搜索引擎名]:[含%s的url]
[搜索引擎名]:POST:[含%s的post参数]:[url]
+
.search文件首行必须为第一种类型的搜索引擎。由于其它两种类型的引擎数量稀少,为性能考虑,超微限制了首个引擎的种类。
+
本地引擎
搜索引擎已经支持命令行url,现在可添加离线字典查询至主页。命令行url格式为
c:[含%s的命令行]
d:mimetype:[含%s的命令行]:[外部资源url]
查询时关键词会自动替换命令行中的%s。
+
笔者用来查询各式词典,发现效果非常好。百兆以内的文本文件压缩以后可以直接快速检索,定位至特定位置以后可上下滚动阅读全部文本。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/searchurl/alipay.png b/searchurl/alipay.png
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..83fb1526efd822241783d1f5882506ea51fed002 100644
GIT binary patch
literal 5538
zcmaJ_XH-+$y4?vys)mmAqM&pT1)>6Cl+ck5LMRG?2na}#l7uEfQA9yN=}iQrOA!bW
zDGEw8^o|&$1*9Y^;_6`x|quudF%0I8$R?b`}8^007wa;4m`)
z0MR}{023qaW$#zy1^_%Bdaz3t!Rf1$sHfcch$HL7S81-ON?g?-D=VuUYdtz!EMzLp
zUR5B+MWJ8zn1A6n7wzuG5~#nFlqF*mJh#E(e)6}IR>d{Zqq1KUou4n{nej5
zxb5j-eB6my7b~Q7}IM6Sx6DJmNvx`O1tyV#ohFAZrKYpTqd*N5ldcmv<3G^zhT`tCZDWj*onQ
zMKYoru1&DUi2^gOCaQ)^aj{>bgWbPxyGfo#nHD|gI{_H`a2Gzs@Xgu7K&0$6$T9s0
zi@iV(a=3~k9d1Gldn`hJw?f)a7vAb)2>zB(HfSjb-6hXUhyP$FIsTCEShL{7TXJ(^k
z3*`VB8b0ku#T1OYz2jLfm*m7G151m-6M&gu8!IGJVPE*F*;Ib6Jgi`?EhAUvT=Xzd
z+ExAV#US&BOSl>GgXi@NM{uLj^;RtP-k7KLC#PgkYumf9OM~l}6}k$_;P9L1;A`OF
z`Zt$>;q=K9Lp>8xC}M&96xgW*a}#9E{)ws7V?<&4*F8ioBrYNB*(>G^Pr%VH#D1ui
zSYZj-HAu*+cRbX{NlP;(tL6YT+>lZQU
za->*kB{Ih6r?0sg;^c>E2Mnuw?sv7seh#YvOX`N}&z_+F61}MW%&+*>`_12srZ=o{
zsgX+;mQLm}!)F3OyJ<$s!^0U`4(QpKqp*BUI4euM#!&`n?Qoj{<
zayQj#m3mSqS-b#9;>AD9S&e|Cu`%Dea0`6s7DIS~4qktim}e0!MFaLfi|)`C+1+iS
zuEeaJ;cG;;po~9)1p(N1;Xlx0&H)z0%fyiB-{9W!q2VpaEXQsB*x~8&B}x?Z2V@Ko
zlL-B5ix^ej5nw$86}GlfJY3u8l^|Tc%1jYK6?a-(AWB2}G*M;$dFE&xt%Rwy;5z+P
z+YlttF`LrBfEXw2kSmysXj}Q)ZlMuSw08N&ulL5dC)3MES(>dJw}}P;SyRi^$D?#!
z0b;qE$^b^S7_}sRAds5*5uNnA*t$FmrN5WaJQKlA^Z9^|
z)+^)fRP<6P$F4~AI)#`Q;t;vCCmAVG0n&y|{jqD~4%Xgo3dkWWO#TXW46W-7oy_Z#
zZy5%yBLE4Oi;UWF&;7QdKCeo@_u@$CJpWcJDJ$Li0}YUk6P@;UHPxd0v330|hip>r
zt3{IOZPL;Dizu58`hT6ZShjKcxk@h*#|pf+{lf8}%>euM
zRcAqMeI)?A_%&~0d?0b~AiL_0o_o#8=yxS^0h{rEDdS;T0W(G-?D*-_9@abq*L$L}_
zc8OP`R_l0G!^l_l-tnrVS66QX9ijbkw%+$W_Q>8k^1fK2XAwQkA-dP
zGbvBx?-4~?4NwAGLcsjH)$~fX0umxPgFvDp60(`@0H*t0rC%1?O+x-kK8OT94QX+G
zuXdr(>Pkn`lPh^j0}e$sjM5hsWL?w+OCrA4#rDyD3wAJA+ab^r!@g$P*KvzjDLQS}
z*i~yEfM2+QQ0w(+D^m;{6Cq9Y&y(jq@Q1iq8oyGVg`#zcql*EC;-xgF+`}SS;Q?cg
zpLCcktgREUJ#N+N<9K!hW6jo)(epTygQw0w^rt*mKFQx!9kmldE{&DHI~3!w`!kEm
z_P=$rUzdhF%L7=?@?(rQCX8i-+0YQZNBje=`&p{bH!u0<#qGOmP$bejhmG86;jy{U
zJT;xASa*Jt34TXt;&E?Bx0GDaCL+15c&Wr$3GrahU7_)xHze9hVmB!xJV
z9g>Otmbnb!&S3{K!le)ou9xq9$#<<9U0FOROM~*LIr=l8XE!3?H&^673^wjK&5Vp3
zB(z3=AS#^TV;L_aq(u&HAUYLG>5-IV15;aD4g0L5;Gf?iRkLJVo)8T()b#AJBfl;L
z-dIuU>h9Kc3<^L+rVIv5jGf8n2e{T7dx@P;07#XP`vN)sjcq&I5YDEb?W52B{_QEo
zE8JZ7HbH=^&fEiyN@WMM+IT|tMU~FYo@k_&tZ6`a6CWCU8L)}>p0GfImw638wo;(q
zECewyiBE3Ti-P=ZZ=M_#Qpd*}Xvl6nbj@}!{^-z%7@@UKt6gA>#P
z=XQXp-p{69GLVUc=#PFt=@u`DPU6(T^dGnx9{KU5xO1rh_th+y`dp-Ge=3%Y?^n(2
zJvXB&BX;tx=hx$3Qn7by*7Br{XKhP-pH-XpDFa|R#<)<~abMyXesNh;d$~t#Lq~tk
z5XFc$&rP)km8Q%1jy6H%(zN(2lanDjPLvt}`_P~I_Wp4(hjtq1R)bfcpRRYsNA@?;
z7bKDK*m-r^$i`!d&ALnD1!R_dzl!)l-^7J^Fpw^YcL58xzuqqiuRnZwuR*#X!W8744to=G!rIc
ze`P3=8jtl5=-F8B0E=b%Hubmq?@sTQ9jxMvHTJCon6q^|*59YcsfD=B>H4tEQ6{~}
zjW6ER2Y=RSbNPq@6A-%qBo21hzg_RbwDlvpT;68hPEacb1TpRIi|AHxZPr2L{wF6TC?{&9Cls~2p|VKicVehV{6e$Z}p+x$~O9z
z(=8+WIh^@3txjsc%A*WDoo<0$GLFdsln;5g?QIW
zZg)~zY|glOR^;S}=R={&0_bJ
zhDP6B&WfZ#v#-6Q?7io%B_eFE^ixI)aF1u3xin9Y4QzM4p>U_WYMtyE>Wk`?2$RSQ
zR-cTQ-YN8*oH{pASp-I5YmW2qa81hy#lcLiuRrP?9x4tAwGgA(4mqR3>J|HBX28{8
z{i7^jjvE0~bF}9&3(pM-8(2GozioR?a>Db;g4ZCd<91a9>T1f}Cn*DarD>KPo*a7=l3&_FB1^cOtO&SCkc
zK9I^CBHrNf_1PYp3hpm`LerBtiJ}@0QOFWH6Wd3LflmvLGu7C>BU=T@Bbz({wW|lw
z<94@w`{xRMUvr%1=LbM9VsIvd26q?LR_jq$&MMeVsQ#=$oO{)tI4`}iS(~r{CkhF1
z?KmeIfYseBXQYQXYt{_ri-V52m|teJcBp3>yxo({uwg#t;&U%m|!SFQdZ)r1UO7AF%i$7
zgok%yd`d_IW;62NoKYr1K?K{_rBL}@Hr
zJj22s;Kse%l%&O|jVnzM?nJ1jOxT4*%+`X~+r3#DZ~#-PQ3+vQ%TXihVpWaRgo9j<
z)8K7V)I$sVLvU1kZ)z%nC|@Ca@a91X-MCfY{7xLg2Mor^&}c^&lfcqr=5C&l
zsY#-8ZUyZIUR-(h;!1GYP+RR}Y=z_*z9UCuI)wSR%sp
zbz$FTtSvoLQ82>poTb%wC~*(NZR*yP*Ise2nqGLsS}2mD$-R~^vq&%=U$Fjt$P6Hf
zL2T#&wKeI4VOs|L`BO35Tq-Mv{|=r5ns&r3d#Rxpv&MfFQ~SJ^H>sr6cbX2^es>zP
zZKH8AfkSe8$o@zKg3M0!T%@K?*?SZ3&Sk3Q9*K*aHY4%tZ+=b-!eT19VWD~Fz9q@S
zGNspYkxH;6Rqi3nF56@Y^N-LNF!7Htms17J1Rz@aLa}c$t*s}I)Ri~}{I*9>w_>o@
zRf=@DXw3R=Q9xtXyP14eM%(YBb*6pFLqwYUdR_0YUtF%JQGvr(rIp-YlpsZyBcSPH|n^Zsv(W
z@MTlT+5hC|ykh|5Jappgqw;b~iX61@7a?PM-VTKiw`w85ESis@aFU%oGyzM^1=gPG4`#Dc(OS<}c!x4X-53TK2vwSvy1BOJ~4q4KLV6{81f;
zwBN>^4!1gn9NunR$qSWtyiH{&%G4!=PEC34IrIEeqr3!8?bvzYJttS61cf5YS@!mu
zp4=}InP*z&zw}R`hhx<4qugwtdObyaw^~e-Tnwwk0@Hs{_P>?gAKme913#nyDCo;h
zi8w6(fe_Y8*jETJo6!)jRBe&sxCYuA^SIOrf(W*fs$9u#$W?I(9w_IW;%Zmhz{paK
zW+zB#lX=uj>dp&uA0Cb{YdhoR6B0oxoa4^^$9uwb0?)rS`6=eKba~}59ba+jb4-tT
zg^g=~KAkqW+j2-3w(rLSaPo8FxLX7+!?+AiwxKjmy$CdaT>=!DA)Xw?w;Q;Zw
zq}lWBLqBwHrZ^JBSk9jj&)lfqr*%2pue41l{dN)qzOm(S>A=J$w+%2%N?dcx0Cpw6
zwErQ~v$fvDX*J;V$rUSxCrWC#B_qsOVg9|aC~)GM8S};|^m!rCr-ax$Qw}sBF@spW
zvwhCq5G`f9h2hPMqKOK$_6NvxwWcWr6l8J(FqcvGFA}{a%)?vXZHQ@9Kd-Hd{U+5f
zA>Xw8BlXv*rKa>jbHMN*ZAD4#VT$<1{nwrGVV<7^^geHcVSup|%$%EyTlLkMS@1~E
zyCsU_S`Xt87+=5}H-ZW3K{6W-d3>_#`Cmf3Sg)C;*BjXjJaUmnFS%z1wAFQ&G}m7K
z{JP@R2HIEdY)PUovv$_A3~gDoVAvGG#}4Z)`il&j)s-s8Qa#w|ARQmDB^F@e@V;JK&V(@-ayX^gq#
zt$0boM_qA)38|C
z0Zwk+!6iC=3c9*4$s%v^h{PkCM$_S~f4U_9ce|3R
+
+备份与恢复
+支持安卓6+。
+
+备份目录"/sdcard/uweb"至坚果云 恢复
+
+备份Cookie至坚果云(webview 76+,注意账号信息泄露危险) 恢复
+
+设置坚果云用户及密码
+
+
+用户可将下列表格提交后访问的网址设为书签,方便以后再次备份恢复。
+
+
+坚果云 易云
+uweb目录
+Cookie (webview 76+)
+
+
+
diff --git a/searchurl/bml/content/comparecells.js b/searchurl/bml/content/comparecells.js
index e69de29..a8fe372 100644
--- a/searchurl/bml/content/comparecells.js
+++ b/searchurl/bml/content/comparecells.js
@@ -0,0 +1,197 @@
+/**
+ * Try to color the cells of comparison tables based on their contents.
+ *
+ * @title Compare cells
+ */
+(function comparecells() {
+ /* Create a new IFRAME to get a "clean" Window object, so we can use its
+ * console. Sometimes sites (e.g. Twitter) override console.log and even
+ * the entire console object. "delete console.log" or "delete console"
+ * does not always work, and messing with the prototype seemed more
+ * brittle than this. */
+ let console = (function () {
+ let iframe = document.getElementById('xxxJanConsole');
+ if (!iframe) {
+ iframe = document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe');
+ iframe.id = 'xxxJanConsole';
+ iframe.style.display = 'none';
+
+ (document.body || document.documentElement).appendChild(iframe);
+ }
+
+ return iframe && iframe.contentWindow && iframe.contentWindow.console || {
+ log: function () {}
+ };
+ })();
+
+ /**
+ * Get the text content for the given element.
+ */
+ function getTextFromElement(element) {
+ /* TODO: take IMG@alt, BUTTON@value etc. into account */
+ return element.textContent.trim().toLowerCase();
+ }
+
+ /**
+ * Get a Uint8Array of the SHA-256 bytes for the given string.
+ */
+ async function getSha256Bytes(string) {
+ try {
+ if (
+ typeof crypto === 'object' && typeof crypto.subtle === 'object' && typeof crypto.subtle.digest === 'function'
+ && typeof Uint8Array === 'function'
+ && typeof TextEncoder === 'function'
+ ) {
+ return new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder('utf-8').encode(string)));
+ }
+ } catch (e) {
+ return null;
+ }
+ }
+
+ async function getColorsForValue(value) {
+ /* Cache the calculated values. */
+ getColorsForValue.cellValuesToRgb = getColorsForValue.cellValuesToRgb || {};
+
+ if (!getColorsForValue.cellValuesToRgb[value]) {
+ let normalizedValue = value.trim().toLowerCase();
+ let hash;
+
+ let yesValues = [
+ '✔',
+ 'yes',
+ 'ja',
+ 'oui',
+ 'si',
+ 'sí'
+ ];
+
+ let noValues = [
+ 'x',
+ 'no',
+ 'nee',
+ 'neen',
+ 'nein',
+ 'non',
+ 'no'
+ ];
+
+ if (yesValues.indexOf(normalizedValue) > -1) {
+ /* Make "Yes" cells green. */
+ getColorsForValue.cellValuesToRgb[value] = [ 150, 255, 32 ];
+ } else if (noValues.indexOf(normalizedValue) > -1) {
+ /* Make "No" cells green. */
+ getColorsForValue.cellValuesToRgb[value] = [ 238, 32, 32 ];
+ } else if ((shaBytes = await getSha256Bytes(normalizedValue))) {
+ /* Give other cells a color based on their content’s SHA
+ * hash to ensure “consistent random colors” every time. */
+ getColorsForValue.cellValuesToRgb[value] = [
+ shaBytes[0],
+ shaBytes[1],
+ shaBytes[2]
+ ];
+ } else {
+ /* If the SHA hash could not be calculated, just use random
+ * values. These will change on every execution. */
+ getColorsForValue.cellValuesToRgb[value] = [
+ Math.random() * 255,
+ Math.random() * 255,
+ Math.random() * 255
+ ];
+ }
+ }
+
+ /* Calculate/approximate the lightness (tweaked from “RGB to HSL”) to
+ * determine whether black or white text is best suited. */
+ let isLight = 150 < (
+ getColorsForValue.cellValuesToRgb[value][0] * 0.299
+ + getColorsForValue.cellValuesToRgb[value][1] * 0.587
+ + getColorsForValue.cellValuesToRgb[value][2] * 0.114
+ );
+
+ return {
+ backgroundColor: 'rgb(' + getColorsForValue.cellValuesToRgb[value].join(', ') + ')',
+ color: isLight
+ ? 'black'
+ : 'white',
+ textShadow: isLight
+ ? '1px 1px 3px white'
+ : '1px 1px 3px black'
+ };
+ }
+
+ /* The main function. */
+ (function execute(document) {
+ Array.from(document.querySelectorAll('table')).forEach(table => {
+ Array.from(table.tBodies).forEach(tBody => {
+ if (tBody.rows.length < 3) {
+ console.log('Compare cells: skipping table body ', tBody, ' because it only has ', tBody.rows.length, ' rows');
+ return;
+ }
+
+ Array.from(tBody.rows).forEach(tr => {
+ /* Determine the values. */
+ let cellValues = [];
+ let uniqueCellValues = new Set();
+
+ Array.from(tr.cells).forEach((cell, i) => {
+ /* Don't take the header cells into account. */
+ if (cell.tagName.toUpperCase() === 'TH') {
+ return;
+ }
+
+ /* Assume the first cell is a header cell, even if it is not a TH. */
+ if (i === 0) {
+ return;
+ }
+
+ cellValues[i] = getTextFromElement(cell);
+ uniqueCellValues.add(cellValues[i]);
+ });
+
+ /* Color (or not) the cells based on the values. */
+ let isFirstValue = true;
+ let firstValue;
+ cellValues.forEach(async function(cellValue, i) {
+ let hasTwoUniqueValues = uniqueCellValues.size == 2;
+ if (isFirstValue) {
+ firstValue = cellValue;
+ isFirstValue = false;
+ }
+
+ let backgroundColor;
+ let color;
+ let textShadow;
+
+ if (
+ uniqueCellValues.size == 1 ||
+ (hasTwoUniqueValues && cellValue === firstValue) ||
+ cellValue.trim() === ''
+ ) {
+ backgroundColor = 'inherit';
+ color = 'inherit';
+ textShadow = 'inherit';
+ } else {
+ backgroundColor = (await getColorsForValue(cellValue)).backgroundColor;
+ color = (await getColorsForValue(cellValue)).color;
+ textShadow = (await getColorsForValue(cellValue)).textShadow;
+ }
+
+ tr.cells[i].style.setProperty('background-color', backgroundColor, 'important');
+ tr.cells[i].style.setProperty('color', color, 'important');
+ tr.cells[i].style.setProperty('text-shadow', textShadow, 'important');
+ });
+ });
+ });
+ });
+
+ /* Recurse for frames and iframes. */
+ try {
+ Array.from(document.querySelectorAll('frame, iframe, object[type^="text/html"], object[type^="application/xhtml+xml"]')).forEach(function (elem) {
+ execute(elem.contentDocument);
+ });
+ } catch (e) {
+ /* Catch exceptions for out-of-domain access, but do not do anything with them. */
+ }
+ })(document);
+})();
diff --git a/searchurl/bml/content/designmode.js b/searchurl/bml/content/designmode.js
index e69de29..1a4a3b9 100644
--- a/searchurl/bml/content/designmode.js
+++ b/searchurl/bml/content/designmode.js
@@ -0,0 +1 @@
+(function(){if (document.designMode == 'off'){document.designMode = 'on';}else{document.designMode = 'off';}})()
diff --git a/searchurl/bml/content/freeviddy.js b/searchurl/bml/content/freeviddy.js
index e69de29..2393588 100644
--- a/searchurl/bml/content/freeviddy.js
+++ b/searchurl/bml/content/freeviddy.js
@@ -0,0 +1,54 @@
+/**
+ * Free the VIDEO elements: get rid of overlays, and enable the native controls.
+ *
+ * Useful on https://www.instagram.com/ where the stupid overlays prevent
+ * showing the controls and triggering the context menu, so you don’t know how
+ * long the video will take and can't play the video in full screen mode.
+ *
+ * @title Free Viddy
+ */
+(function freeviddy() {
+ /* Recursively execute the main logic on the document and its sub-documents. */
+ function execute(document) {
+ document.addEventListener('touchmove mousemove', function debouncer(event) {
+ clearTimeout(debouncer.timeoutId);
+ debouncer.timeoutId = setTimeout(function () {
+ let elementsUnderPointer = document.elementsFromPoint(event.clientX, event.clientY);
+ let overlaysToRemove = [];
+
+ for (let i = 0; i < elementsUnderPointer.length; i++) {
+ if ((elementsUnderPointer[i].tagName.toUpperCase() === 'VIDEO' ||
+ elementsUnderPointer[i].tagName.toUpperCase() === 'IFRAME') && !elementsUnderPointer[i].xxxJanFreeViddyProcessed) {
+ let video = elementsUnderPointer[i];
+ video.controls = true;
+ video.xxxJanFreeViddyProcessed = true;
+
+ if (i === 0) {
+ } else {
+ overlaysToRemove = elementsUnderPointer.slice(0, i);
+ }
+
+ break;
+ }
+ }
+
+ if (overlaysToRemove.length) {
+ overlaysToRemove.forEach(element => element.remove());
+ }
+ }, 50);
+ });
+
+ /* Recurse for frames and iframes. */
+ try {
+ Array.from(
+ document.querySelectorAll('frame, iframe, object[type^="text/html"], object[type^="application/xhtml+xml"]')
+ ).forEach(
+ elem => execute(elem.contentDocument)
+ );
+ } catch (e) {
+ /* Catch exceptions for out-of-domain access, but do not do anything with them. */
+ }
+ }
+
+ execute(document);
+})();
diff --git a/searchurl/bml/content/fullimg.js b/searchurl/bml/content/fullimg.js
index e69de29..649b492 100644
--- a/searchurl/bml/content/fullimg.js
+++ b/searchurl/bml/content/fullimg.js
@@ -0,0 +1,497 @@
+/**
+ * Load the full-size versions of resized images based on their "src"
+ * attribute, or their containing link's "href" attribute. Also, make IFRAMEs
+ * take up the entire width of their offset parent (useful for embedded videos
+ * and whatnot). Same goes for the VIDEO elements.
+ *
+ * @title Load full images
+ */
+(function fullimg() {
+ /* Create a new IFRAME to get a "clean" Window object, so we can use its
+ * console. Sometimes sites (e.g. Twitter) override console.log and even
+ * the entire console object. "delete console.log" or "delete console"
+ * does not always work, and messing with the prototype seemed more
+ * brittle than this. */
+ var console = (function () {
+ var iframe = document.getElementById('xxxJanConsole');
+ if (!iframe) {
+ iframe = document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe');
+ iframe.id = 'xxxJanConsole';
+ iframe.style.display = 'none';
+
+ (document.body || document.documentElement).appendChild(iframe);
+ }
+
+ return iframe && iframe.contentWindow && iframe.contentWindow.console || {
+ log: function () {}
+ };
+ })();
+
+ /* Get rid of "width=", "height=" etc. followed by numbers or number pairs
+ * in IMG@src query strings. */
+ var parameterNames = [
+ 'width',
+ 'Width',
+
+ 'height',
+ 'Height',
+
+ 'maxwidth',
+ 'maxWidth',
+ 'MaxWidth',
+
+ 'maxheight',
+ 'maxHeight',
+ 'MaxHeight',
+
+ 'w',
+ 'W',
+
+ 'h',
+ 'H',
+
+ 'fit',
+ 'Fit',
+
+ 'resize',
+ 'reSize',
+ 'Resize',
+
+ 'size',
+ 'Size'
+ ];
+
+ parameterNames.forEach(function (parameterName) {
+ var selector = 'img[src*="?' + parameterName + '="]'
+ + ', img[src*="?"][src*="&' + parameterName + '="]';
+
+ /* Match query string parameters (?[…&]name=value[&…]) where the value is
+ * a number (e.g. "width=1200") or a pair of numbers (e.g. * "resize=640x480"). */
+ var parameterReplacementRegexp = new RegExp('(\\?[^#]*&)?' + parameterName + '=[1-9][0-9]+(?:(?:[xX,*:]|%2[CcAa]|%3[Aa])[1-9][0-9]+)?([^]*)');
+
+ [].forEach.call(document.querySelectorAll(selector), function (img) {
+ var newSrc = img.src
+ /* Remove the parameter "name=value" pair from the query string. */
+ .replace(parameterReplacementRegexp, '$1$2')
+
+ /* Remove trailing "&" from the query string. */
+ .replace(/(\?[^#]*)&(#.*)?$/, '$1$2')
+
+ /* Remove empty query strings ("?" not followed by
+ * anything) from the URL. */
+ .replace(/\?(#.*)?$/, '$1')
+
+ /* Remove empty fragment identifiers from the URL. */
+ .replace(/#$/, '')
+ ;
+
+ changeSrc(img, newSrc, 'found image with parameter "' + parameterName + '" in query string');
+ });
+ });
+
+ /* Show the original image for Polopoly CMS "generated derivatives".
+ *
+ * Example:
+ * https://sporza.be/polopoly_fs/1.2671026!image/1706320883.jpg_gen/derivatives/landscape670/1706320883.jpg
+ * https://sporza.be/polopoly_fs/1.2671026!image/1706320883.jpg
+ */
+ [].forEach.call(
+ document.querySelectorAll('img[src*="_gen/derivatives/"]'),
+ function (img) {
+ var matches = img.src.match(/(.*\.(jpe?g|png|gif))_gen.*\.\2(\?.*)?$/);
+ if (matches && matches[1]) {
+ changeSrc(img, matches[1], 'found image with Polopoly CMS "generated derivative" URL');
+ }
+ }
+ );
+
+ /* Try to load the originals for images whose source URLs look like
+ * thumbnail/resized versions with dimensions.
+ */
+ [].forEach.call(
+ document.images,
+ function (img) {
+ var oldSrc = img.src;
+ /* Example:
+ * https://www.cycling-challenge.com/wp-content/uploads/2014/08/IMG_6197-150x150.jpg
+ * https://www.cycling-challenge.com/wp-content/uploads/2014/08/IMG_6197.jpg
+ */
+ var matches = oldSrc.match(/(.*)[-_.@]\d+x\d+(\.[^\/.]+)/);
+ if (matches && matches[1] && matches[2]) {
+ var newSrc = matches[1] + matches[2];
+
+ return changeSrc(img, newSrc, 'found image whose URL looks like a thumbnail/resized version');
+ }
+
+ /* Example:
+ * https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Kowloon-Walled-City-1898.jpg/220px-Kowloon-Walled-City-1898.jpg
+ * https://upload.wikimedia.org/wikipedia/commons/8/83/Kowloon-Walled-City-1898.jpg
+ */
+ matches = oldSrc.match(/(.*\/)thumb\/(.*)\/[^\/]+$/);
+ if (matches) {
+ var newSrc = matches[1] + matches[2];
+
+ return changeSrc(img, newSrc, 'found image whose URL looks like a MediaWiki thumbnail/resized version');
+ }
+
+ }
+ );
+
+ /* Try to load the originals for images whose source URLs look like
+ * thumbnail/resized versions with a text label.
+ *
+ * Example:
+ * https://www.crazyguyonabike.com/pics/docs/00/01/27/84/small/DSCF3555.JPG
+ * https://www.crazyguyonabike.com/pics/docs/00/01/27/84/large/DSCF3555.JPG
+ */
+ var thumbnailPathRegexp = /(.*[/.-])(small|thumb|thumbnail|resized|preview|medium)([/.-].*)/;
+
+ var fullSizePathParts = [
+ 'large',
+ 'original',
+ 'source',
+ 'normal',
+ 'xlarge',
+ ];
+
+ [].forEach.call(
+ document.images,
+ function (img) {
+ var oldSrc = img.src;
+ var matches = oldSrc.match(thumbnailPathRegexp);
+ if (matches) {
+ var newSources = [];
+
+ fullSizePathParts.forEach(function (part) {
+ newSources.push(matches[1] + part + matches[3]);
+ });
+
+ changeSrc(img, newSources, 'found image whose URL looks like a thumbnail/resized version');
+ }
+ }
+ );
+
+ /* Change the IMG@src of linked images to their link's A@href if they look
+ * similar, assuming that the linked version is larger. */
+ [].forEach.call(
+ document.querySelectorAll('a img'),
+ function (img) {
+ if (!img.src) {
+ return;
+ }
+
+ var a = img.parentNode;
+ while (a && a.tagName && a.tagName.toLowerCase() !== 'a') {
+ a = a.parentNode;
+ }
+
+ if (!a) {
+ return;
+ }
+
+ var aHref = a.href;
+
+ if (a.hostname.match(/\.blogspot\.com$/)) {
+ /* Get rid of Blogspot's links to useless HTML wrappers. */
+ aHref = aHref.replace(/\/(s\d+)-h\/([^\/]+)$/, '/$1/$2');
+ }
+
+ if (aHref === img.src) {
+ return;
+ }
+
+ /* Simplify a URL for similarity calculation. */
+ function simplifyUrl(url) {
+ return ('' + url)
+ .replace(/\d+/g, '0')
+ .replace(/^https?:/, '');
+ }
+
+ var similarity = getSimilarity(simplifyUrl(img.src), simplifyUrl(a.href));
+
+ if (similarity > 0.66) {
+ changeSrc(img, aHref, 'found linked image with ' + Math.round(similarity * 100) + '% similarity');
+ }
+ }
+ );
+
+ /* Change all Blogspot images that have not been changed yet. */
+ Array.from(
+ document.querySelectorAll('img[src*="bp.blogspot.com/"]')
+ ).forEach(img => {
+ let matches;
+ if ((matches = img.src.match(/^(.*\/)s(\d+)(\/[^/]+)$/)) && matches[2] < 9999) {
+ let newSrc = matches[1] + 's9999' + matches[3];
+ changeSrc(img, newSrc, 'found Blogspot image with restricted size (' + matches[2] + ')');
+ }
+ });
+
+ /* Use larger YouTube thumbnails. */
+ Array.from(
+ document.querySelectorAll('img[src*="//yt"][src*=".ggpht.com"]')
+ ).forEach(img => {
+ let matches;
+ if ((matches = img.src.match(/^(.*\/)s(\d+)([^/]+\/photo\.[^/.]+)$/)) && matches[2] < 1024) {
+ let newSrc = matches[1] + 's1024' + matches[3];
+ changeSrc(img, newSrc, 'found YouTube avatar with restricted size (' + matches[2] + ')');
+ }
+ });
+
+ /* Get rid of all IMG@srcset attributes that have not been removed in the
+ * previous steps.
+ */
+ [].forEach.call(
+ document.querySelectorAll('img[srcset]'),
+ function (img) {
+ console.log('Load full images: removing srcset attribute: ', img);
+
+ img.originalSrcset = img.getAttribute('srcset');
+ img.removeAttribute('srcset');
+ }
+ );
+
+ /* Make native VIDEO elements and video IFRAMEs take up the entire width
+ * of their offset parent. */
+ var elementsToEnlargeSelectors = [
+ 'video',
+ 'iframe.twitter-tweet-rendered',
+ 'iframe[src*="embed"]',
+ 'iframe[src*="video"]',
+ 'iframe[src*="syndication"]',
+ 'iframe[class*="altura"]',
+ 'iframe[id*="altura"]',
+ 'iframe[src*="altura"]',
+ 'iframe[src*="//e.infogr.am/"]',
+ 'iframe[src*="//www.kickstarter.com/projects/"]',
+ 'iframe[src*="//media-service.vara.nl/player.php"]',
+ 'iframe[src*="//player.vimeo.com/video/"]'
+ ];
+
+ [].forEach.call(
+ document.querySelectorAll(elementsToEnlargeSelectors.join(', ')),
+ function (element) {
+ var scale = element.offsetParent.offsetWidth / element.offsetWidth;
+ var newWidth = Math.round(element.offsetWidth * scale);
+ var newHeight = Math.round(element.offsetHeight * scale);
+
+ console.log(
+ 'Load full images: resizing element ', element,
+ ' from ' + element.offsetWidth + 'x' + element.offsetHeight
+ + ' to ' + newWidth + 'x' + newHeight
+ );
+
+ element.xxxJanReadableAllowStyle = true;
+ element.style.width = newWidth + 'px';
+ element.style.height = newHeight + 'px';
+ }
+ );
+
+ /* Show controls on AUDIO and VIDEO elements. */
+ [].forEach.call(
+ document.querySelectorAll('audio, video'),
+ function (element) {
+ element.controls = true;
+ }
+ );
+
+ /* Show controls on YouTube embeds. */
+ [].forEach.call(
+ document.querySelectorAll('iframe[src^="https://www.youtube.com/embed/"][src*="?"][src*="=0"]'),
+ function (iframe) {
+ var beforeAndAfterHash = iframe.src.split('#');
+ var beforeAndAfterQuery = beforeAndAfterHash[0].split('?');
+
+
+ var newPrefix = beforeAndAfterQuery[0];
+
+ var newQueryString = '';
+ if (beforeAndAfterQuery.length > 1) {
+ beforeAndAfterQuery.shift();
+
+ var newQueryParts = beforeAndAfterQuery
+ .join('?')
+ .split('&')
+ .filter(function (keyValuePair) {
+ return !keyValuePair.match(/^(controls|showinfo|rel)=0$/);
+ }
+ );
+
+ if (newQueryParts.length) {
+ newQueryString = '?' + newQueryParts.join('&');
+ }
+ }
+
+ var newHash = '';
+ if (beforeAndAfterHash.length > 1) {
+ beforeAndAfterHash.shift();
+ newHash = '#' + beforeAndAfterHash.join('#');
+ }
+
+ var newSrc = newPrefix + newQueryString + newHash;
+
+ if (newSrc !== iframe.src) {
+ iframe.src = newSrc;
+ }
+ }
+ );
+
+ /**
+ * Crudely calculate the similarity between two strings. Taken from
+ * https://stackoverflow.com/a/10473855. An alternative would be the
+ * Levenshtein distance, implemented in JavaScript here:
+ * https://andrew.hedges.name/experiments/levenshtein/
+ */
+ function getSimilarity(strA, strB) {
+ var result = 0;
+
+ var i = Math.min(strA.length, strB.length);
+
+ if (i === 0) {
+ return;
+ }
+
+ while (--i) {
+ if (strA[i] === strB[i]) {
+ continue;
+ }
+
+ if (strA[i].toLowerCase() === strB[i].toLowerCase()) {
+ result++;
+ } else {
+ result += 4;
+ }
+ }
+
+ return 1 - (result + 4 * Math.abs(strA.length - strB.length)) / (2 * (strA.length + strB.length));
+ }
+
+ /**
+ * Change the IMG@src and fall back to the original source if the new
+ * source triggers an error. You can specify an array of new sources that
+ * will be tried in order. When all of the new sources fail, the original
+ * source will be used.
+ */
+ function changeSrc(img, newSrc, reason)
+ {
+ var basename = img.src.replace(/[?#].*/, '').replace(/.*?([^\/]*)\/*$/, '$1');
+
+ console.log('[' + basename + '] Load full images: ' + reason + ': ', img);
+
+ if (img.hasNewSource) {
+ console.log('[' + basename + '] Image already has a new source: ', img);
+ return;
+ }
+
+ var newSources = Array.isArray(newSrc)
+ ? newSrc
+ : [ newSrc ];
+
+ while ((newSrc = newSources.shift())) {
+ if (newSrc && img.src !== newSrc) {
+ break;
+ }
+ }
+
+ if (!newSrc) {
+ return;
+ }
+
+ console.log('[' + basename + '] → Old img.src: ' + img.src);
+ console.log('[' + basename + '] → Try img.src: ' + newSrc);
+
+ /* Save the original source. */
+ if (!img.originalSrc) {
+ img.originalSrc = img.src;
+ }
+
+ if (!img.originalNaturalWidth) {
+ img.originalNaturalWidth = img.naturalWidth;
+ }
+
+ if (!img.originalNaturalHeight) {
+ img.originalNaturalHeight = img.naturalHeight;
+ }
+
+ /* Save and disable the srcset on the IMG element. */
+ if (img.hasAttribute('srcset')) {
+ img.originalSrcset = img.getAttribute('srcset');
+ img.removeAttribute('srcset');
+ }
+
+ /* Save and disable the srcset in the container PICTURE element's SOURCE descendants. */
+ if (img.parentNode.tagName.toLowerCase() === 'picture') {
+ [].forEach.call(
+ img.parentNode.querySelectorAll('source[srcset]'),
+ function (source) {
+ source.originalSrcset = source.getAttribute('srcset');
+ source.removeAttribute('srcset');
+ }
+ );
+ }
+
+ /* When the new source has failed to load, load the next one from the
+ * list of possible new sources. If there are no more left, revert to
+ * the original source. */
+ var errorHandler;
+
+ if (newSources.length) {
+ console.log('[' + basename + '] Setting errorHandler to loadNextNewSrc for ', img, '; newSources: "' + newSources.join('", "') + '"; reason:', reason);
+ errorHandler = function loadNextNewSrc() {
+ img.removeEventListener('error', loadNextNewSrc);
+ changeSrc(img, newSources, reason);
+ };
+ } else {
+ console.log('[' + basename + '] Setting errorHandler to restoreOriginalSrc for ', img, '; originalSrc: "' + img.originalSrc + '"; reason:', reason);
+ errorHandler = function restoreOriginalSrc() {
+ console.log('[' + basename + '] Load full images: error while loading new source for image: ', img);
+ console.log('[' + basename + '] → Unable to load new img.src: ' + newSrc);
+ console.log('[' + basename + '] → Resetting to original img.src: ' + img.originalSrc);
+
+ img.removeEventListener('error', restoreOriginalSrc);
+
+ /* Restore the original source. */
+ img.src = img.originalSrc;
+
+ /* Re-enable the original srcset on the IMG element. */
+ if (img.originalSrcset) {
+ img.setAttribute('srcset', img.originalSrcset);
+ delete img.originalSrcset;
+ }
+
+ /* Re-enable the original srcset in the container PICTURE element's SOURCE descendants. */
+ if (img.parentNode.tagName.toLowerCase() === 'picture') {
+ [].forEach.call(
+ img.parentNode.querySelectorAll('source'),
+ function (source) {
+ if (source.originalSrcset) {
+ source.setAttribute('srcset', source.originalSrcset);
+ delete source.originalSrcset;
+ }
+ }
+ );
+ }
+
+ };
+ }
+
+ img.addEventListener('error', errorHandler);
+
+ /* When the new source image is smaller than the original image,
+ * treat that as an error, too. */
+ img.addEventListener('load', function () {
+ if (img.naturalWidth * img.naturalHeight < img.originalNaturalWidth * img.originalNaturalHeight) {
+ console.log('[' + basename + '] Load full images: new image (', img.naturalWidth, 'x', img.naturalHeight, ') is smaller than old image (', img.originalNaturalWidth, 'x', img.originalNaturalHeight, '): ', img);
+
+ return errorHandler();
+ }
+
+ if (img.src !== img.originalSrc) {
+ console.log('[' + basename + '] → Success: ' + img.src);
+ img.hasNewSource = true;
+ }
+ });
+
+ /* Finally, actually try to load the image. */
+ img.src = newSrc;
+ }
+})();
diff --git a/searchurl/bml/content/read.js b/searchurl/bml/content/read.js
index e69de29..ba578fb 100644
--- a/searchurl/bml/content/read.js
+++ b/searchurl/bml/content/read.js
@@ -0,0 +1,1447 @@
+/**
+ * Make a page more readable by disabling all page styling and applying a
+ * bare minimum of our own. Go to the first thing that looks like the start
+ * of the actual content so no time is wasted scrolling past initial
+ * navigation etc.
+ *
+ * @title Readable++
+ */
+(function read() {
+ /* Create a new IFRAME to get a "clean" Window object, so we can use its
+ * console. Sometimes sites (e.g. Twitter) override console.log and even
+ * the entire console object. "delete console.log" or "delete console"
+ * does not always work, and messing with the prototype seemed more
+ * brittle than this. */
+ var console = (function () {
+ var iframe = document.getElementById('xxxJanConsole');
+ if (!iframe) {
+ iframe = document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe');
+ iframe.id = 'xxxJanConsole';
+ iframe.style.display = 'none';
+
+ (document.body || document.documentElement).appendChild(iframe);
+ }
+
+ return iframe && iframe.contentWindow && iframe.contentWindow.console || {
+ log: function () {}
+ };
+ })();
+
+ /* The style sheet for more readable content. */
+ var css = (function () { /*@charset "utf-8";
+ @namespace svg "http://www.w3.org/2000/svg";
+
+ -jancss-comment { content:
+ "General styles -------------------------------------------";
+ }
+
+ * {
+ line-height: 1.5;
+ }
+
+ html {
+ background: rgb(245, 245, 225);
+ color: rgb(0, 0, 30);
+ }
+
+ body {
+ max-width: 48em;
+ margin: 0 auto;
+ padding: 1em;
+ font-family: "Calibri", sans-serif;
+ font-size: 1.05rem;
+ }
+
+ p {
+ line-height: 1.7;
+ }
+
+ :link {
+ color: #00e;
+ }
+
+ :visited {
+ color: #528;
+ }
+
+ :link:focus,
+ :visited:focus,
+ :link:hover,
+ :visited:hover {
+ color: #e30;
+ }
+
+ :link:active,
+ :visited:active {
+ color: #e00;
+ }
+
+ center,
+ [align] {
+ text-align: left;
+ }
+
+ b:not(.jancss-probably-structure),
+ u,
+ blink {
+ font-weight: inherit;
+ font-style: inherit;
+ text-decoration: inherit
+ }
+
+ b.jancss-probably-structure {
+ font-size: larger;
+ }
+
+ .jancss-probably-layout {
+ font: inherit;
+ }
+
+ -jancss-comment { content:
+ "Headers --------------------------------------------------";
+ }
+
+ h1:not(.jancss-probably-layout),
+ h2:not(.jancss-probably-layout),
+ h3:not(.jancss-probably-layout) {
+ font-family: "Cambria", serif;
+ }
+
+ h1, h1.jancss-probably-layout {
+ border-bottom: 1px solid #888;
+ font-size: 200%;
+ font-weight: 100;
+ }
+
+ h2, h2.jancss-probably-layout * {
+ border-bottom: 1px solid #bbb;
+ font-size: 150%;
+ font-weight: 100;
+ }
+
+ h3, h3.jancss-probably-layout {
+ border-bottom: 1px dotted #bbb;
+ font-size: 117%;
+ font-weight: 100;
+ }
+
+ h1.jancss-probably-layout *,
+ h2.jancss-probably-layout *,
+ h3.jancss-probably-layout * {
+ font-size: 1rem;
+ }
+
+ -jancss-comment { content:
+ "Links in headers (probably permalinks) -------------------";
+ }
+
+ h1 a[href]:not(:hover),
+ h2 a[href]:not(:hover),
+ h3 a[href]:not(:hover) {
+ text-decoration: none;
+ }
+
+ h1 a[href]::after,
+ h2 a[href]::after,
+ h3 a[href]::after {
+ font-size: 75%;
+ content: " #";
+ }
+
+ -jancss-comment { content:
+ "Pre-formatted text and source code -----------------------";
+ }
+
+ pre {
+ padding: 1ex;
+ border: 1px dotted;
+ }
+
+ code,
+ pre,
+ .syntaxhighlighter,
+ .dp-highlighter {
+ font-family: "Consolas", monospace;
+ font-size: small;
+ background: #ffe;
+ }
+
+ .dp-highlighter + pre[name="code"] {
+ display: none;
+ }
+
+ -jancss-comment { content:
+ "Forms ----------------------------------------------------";
+ }
+
+ textarea {
+ width: 100%;
+ height: 32ex;
+ }
+
+ -jancss-comment { content:
+ "Tables ---------------------------------------------------";
+ }
+
+ table.jancss-probably-for-data th,
+ table.jancss-probably-for-data td {
+ vertical-align: top;
+ text-align: left;
+ padding: 0.5ex;
+ }
+
+ table.jancss-probably-for-data caption {
+ font-weight: bold;
+ border-bottom: 1px dotted;
+ }
+
+ table.jancss-probably-for-layout td {
+ display: inline-block;
+ }
+
+ table.jancss-probably-for-data tr:nth-child(odd) td:not(.jancss-active-col) {
+ background: #ffe;
+ }
+
+ table.jancss-probably-for-data tr:hover td:not(.code),
+ table.jancss-probably-for-data .jancss-active-col {
+ background: #ffc;
+ }
+
+ table.jancss-probably-for-data th,
+ table.jancss-probably-for-data tr td:not(.code):hover {
+ background: #ff9;
+ }
+
+ table.jancss-probably-for-data th code,
+ table.jancss-probably-for-data td code {
+ background: inherit;
+ }
+
+ -jancss-comment { content:
+ "Make images use the full page width ----------------------";
+ }
+
+ img,
+ input[type="image"],
+ object,
+ embed,
+ video,
+ audio,
+ iframe,
+ canvas,
+ :not(svg|*) > svg|* {
+ max-width: 100%;
+ }
+
+ figure {
+ margin: 0;
+ }
+
+ iframe {
+ width: 100%;
+ }
+
+ iframe[class*="twitter"] {
+ min-height: 15em;
+ }
+
+ -jancss-comment { content:
+ "Dim images and media until :hover ------------------------";
+ }
+
+ body:not(:hover) img,
+ body:not(:hover) input[type="image"],
+ body:not(:hover) object,
+ body:not(:hover) embed,
+ body:not(:hover) video,
+ body:not(:hover) audio,
+ body:not(:hover) iframe,
+ body:not(:hover) canvas,
+ body:not(:hover) :not(svg|*) > svg|* {
+ opacity: 0.25;
+ }
+
+ -jancss-comment { content:
+ "Limit icon dimensions --------------------------------";
+ }
+
+ a[href*="facebook.com"] svg,
+ a[href*="instagram.com"] svg,
+ a[href*="twitter.com"] svg,
+ a[href*=".pinterest."] svg,
+ svg[id*="icon"],
+ svg[class*="icon"],
+ svg[class*="inline"],
+ svg[data-icon],
+ svg[role="img"],
+ [class*="icon"] svg,
+ [class*="Icon"] svg,
+ img[class*="icon"][src*=".svg"],
+ img[class*="Icon"][src*=".svg"],
+ span > svg,
+ button svg,
+ [class*="button"] svg,
+ [role*="button"] svg,
+ [class*="controls"] svg,
+ .svg-icon,
+ .inline-icon,
+ .wp-smiley,
+ .smiley,
+ .emoticon,
+ :not(html).emoji {
+ max-width: 1.4em;
+ max-height: 1.4em;
+ }
+
+ -jancss-comment { content:
+ "Make everything scrollable -------------------------------";
+ }
+
+ [style*="position: fixed"],
+ [style*="position:fixed"] {
+ position: static !important;
+ }
+
+ -jancss-comment { content:
+ "Make side notes and pull quotes less conspicuous ---------";
+ }
+
+ aside:not(:hover),
+ [data-expander-id],
+ [id^="footnote_plugin_tooltip_text_"]:not(:hover),
+ blockquote[class*="quote"]:not(:hover),
+ q[class*="pull"]:not(:hover),
+ blockquote[class*="pull"]:not(:hover),
+ .quote-box:not(:hover),
+ .su-pullquote:not(:hover),
+ .pullquote:not(:hover),
+ .pullQuote:not(:hover),
+ .pull-quote:not(:hover) {
+ opacity: 0.25;
+ }
+
+ -jancss-comment { content:
+ "Decrease common forum and metadata font size -------------";
+ }
+
+ .postprofile,
+ .signature {
+ font-size: smaller;
+ border-top: 1px dotted;
+ opacity: 0.5;
+ }
+
+ -jancss-comment { content:
+ "Hide common social media elements ------------------------";
+ }
+
+ iframe[src*=".facebook.com/"],
+ iframe[src*=".twitter.com/widgets/"],
+ iframe[src*="//plusone.google.com/_/+1/"],
+ iframe[src*="//www.reddit.com/static/button/"],
+ iframe[src*="//s7.addthis.com/"],
+ iframe[src*="//www.stumbleupon.com/badge/embed/"],
+ iframe[src*="//widgets.bufferapp.com/"] {
+ width: 12em;
+ height: 4ex;
+ border: 1px dotted;
+ }
+
+ .twtr-widget.twtr-scroll {
+ max-height: 30ex;
+ overflow: auto;
+ }
+
+ .article__share {
+ display: none;
+ }
+
+ #social_btns {
+ display: none;
+ }
+
+ .taboola {
+ display: none;
+ }
+
+ .social-media > .share {
+ display: none;
+ }
+
+ :-moz-any(
+ div,
+ ul,
+ li
+ ):-moz-any(
+ :-moz-any(
+ [id*="social"],
+ [id*="Social"]
+ ):-moz-any(
+ [id*="media"],
+ [id*="Media"]
+ ):-moz-any(
+ [id*="share"],
+ [id*="Share"],
+ [id*="sharing"],
+ [id*="Sharing"]
+ ),
+ :-moz-any(
+ [id*="social"],
+ [id*="Social"]
+ [id*="share"],
+ [id*="Share"],
+ [id*="sharing"],
+ [id*="Sharing"]
+ ):-moz-any(
+ [id*="toolbar"],
+ [id*="Toolbar"],
+ [id*="buttons"],
+ [id*="Buttons"],
+ ),
+ :-moz-any(
+ [class*="social"],
+ [class*="Social"]
+ ):-moz-any(
+ [class*="media"],
+ [class*="Media"]
+ ):-moz-any(
+ [class*="share"],
+ [class*="Share"],
+ [class*="sharing"],
+ [class*="Sharing"]
+ ),
+ :-moz-any(
+ [class*="social"],
+ [class*="Social"]
+ [class*="share"],
+ [class*="Share"],
+ [class*="sharing"],
+ [class*="Sharing"]
+ ):-moz-any(
+ [class*="toolbar"],
+ [class*="Toolbar"],
+ [class*="buttons"],
+ [class*="Buttons"],
+ )
+ ) {
+ display: none;
+ }
+
+ :matches(
+ div,
+ ul,
+ li
+ ):matches(
+ :matches(
+ [id*="social"],
+ [id*="Social"]
+ ):matches(
+ [id*="media"],
+ [id*="Media"]
+ ):matches(
+ [id*="share"],
+ [id*="Share"],
+ [id*="sharing"],
+ [id*="Sharing"]
+ ),
+ :matches(
+ [id*="social"],
+ [id*="Social"]
+ [id*="share"],
+ [id*="Share"],
+ [id*="sharing"],
+ [id*="Sharing"]
+ ):matches(
+ [id*="toolbar"],
+ [id*="Toolbar"],
+ [id*="buttons"],
+ [id*="Buttons"],
+ ),
+ :matches(
+ [class*="social"],
+ [class*="Social"]
+ ):matches(
+ [class*="media"],
+ [class*="Media"]
+ ):matches(
+ [class*="share"],
+ [class*="Share"],
+ [class*="sharing"],
+ [class*="Sharing"]
+ ),
+ :matches(
+ [class*="social"],
+ [class*="Social"]
+ [class*="share"],
+ [class*="Share"],
+ [class*="sharing"],
+ [class*="Sharing"]
+ ):matches(
+ [class*="toolbar"],
+ [class*="Toolbar"],
+ [class*="buttons"],
+ [class*="Buttons"],
+ )
+ ) {
+ display: none;
+ }
+
+ -jancss-comment { content:
+ "Hide ad elements that slipped through my ad blocker ------";
+ }
+
+ iframe[id^="google_ads_"] {
+ display: none;
+ }
+
+ -jancss-comment { content:
+ "Hide empty list items ------------------------------------";
+ }
+
+ li:empty, li.jancss-emptyish {
+ display: none;
+ }
+
+ -jancss-comment { content:
+ "Make common navigation elements more compact -------------";
+ }
+
+ :-moz-any(
+ nav,
+ body [class*="avigat"],
+ body [id*="avigat"],
+ body [class*="-nav-"],
+ body [class*="nav-"],
+ body [class$="-nav"],
+ body [id*="-nav-"],
+ body [id*="nav-"],
+ body [id$="-nav"],
+ body [role="navigation"]
+ ) ul {
+ display: inline;
+ margin: 0;
+ padding: 0;
+ }
+
+ :-webkit-any(
+ nav,
+ body [class*="avigat"],
+ body [id*="avigat"],
+ body [class*="-nav-"],
+ body [class*="nav-"],
+ body [class$="-nav"],
+ body [id*="-nav-"],
+ body [id*="nav-"],
+ body [id$="-nav"],
+ body [role="navigation"]
+ ) ul {
+ display: inline;
+ margin: 0;
+ padding: 0;
+ }
+
+ :any(
+ nav,
+ body [class*="avigat"],
+ body [id*="avigat"],
+ body [class*="-nav-"],
+ body [class*="nav-"],
+ body [class$="-nav"],
+ body [id*="-nav-"],
+ body [id*="nav-"],
+ body [id$="-nav"],
+ body [role="navigation"]
+ ) ul {
+ display: inline;
+ margin: 0;
+ padding: 0;
+ }
+
+ :-moz-any(
+ nav,
+ body [class*="avigat"],
+ body [id*="avigat"],
+ body [class*="-nav-"],
+ body [class*="nav-"],
+ body [class$="-nav"],
+ body [id*="-nav-"],
+ body [id*="nav-"],
+ body [id$="-nav"],
+ body [role="navigation"]
+ ) li {
+ display: inline;
+ margin: 0;
+ padding: 0 .5em;
+ border-right: 1px dotted;
+ }
+
+ :-webkit-any(
+ nav,
+ body [class*="avigat"],
+ body [id*="avigat"],
+ body [class*="-nav-"],
+ body [class*="nav-"],
+ body [class$="-nav"],
+ body [id*="-nav-"],
+ body [id*="nav-"],
+ body [id$="-nav"],
+ body [role="navigation"]
+ ) li {
+ display: inline;
+ margin: 0;
+ padding: 0 .5em;
+ border-right: 1px dotted;
+ }
+
+ :any(
+ nav,
+ body [class*="avigat"],
+ body [id*="avigat"],
+ body [class*="-nav-"],
+ body [class*="nav-"],
+ body [class$="-nav"],
+ body [id*="-nav-"],
+ body [id*="nav-"],
+ body [id$="-nav"],
+ body [role="navigation"]
+ ) li {
+ display: inline;
+ margin: 0;
+ padding: 0 .5em;
+ border-right: 1px dotted;
+ }
+
+ -jancss-comment { content:
+ "Hide old cufón text replacement --------------------------";
+ }
+
+ .cufon-canvas canvas {
+ display: none;
+ }
+
+ -jancss-comment { content:
+ "Make notes on decorrespondent.nl less conspicuous --------";
+ }
+
+ .contentitem-sidenote:not(:hover) > :not(.contentitem-sidenote-snippet),
+ .contentitem-infocard-toggle-container + .contentitem-infocard-contents:not(:hover) {
+ opacity: 0.25;
+ }
+
+ .contentitem-sidenote:hover > :not(.contentitem-sidenote-snippet),
+ .contentitem-infocard-toggle-container + .contentitem-infocard-contents:hover {
+ background: #ffc;
+ }
+
+ -jancss-comment { content:
+ "Hide the source text on Google Translate-d pages ---------";
+ }
+
+ .google-src-text {
+ display: none;
+ }
+
+ -jancss-comment { content:
+ "Hide big ScrollMagic spacers, e.g. on Co.Design ----------";
+ }
+
+ .scrollmagic-pin-spacer {
+ display: none;
+ }
+
+ -jancss-comment { content:
+ "Always hide our IFRAME used to restore console.log -------";
+ }
+
+ #xxxJanConsole {
+ display: none;
+ }
+
+ */; }).toString()
+ .replace(/^function\s*\(\s*\)\s*\{\s*\/\*/, '')
+ .replace(/\*\/\s*\;?\s*\}\s*$/, '');
+
+ /* The attributes to disable. */
+ var attrs = [
+ 'style',
+ 'background', 'bgcolor', 'color', 'text', 'link', 'vlink', 'alink', 'hlink',
+ 'table@width', 'colgroup@width', 'col@width', 'tr@width', 'td@width', 'th@width', 'table@height', 'tr@height', 'td@height', 'th@height',
+ 'img@width', 'img@height',
+ 'border',
+ 'frameborder',
+ 'align',
+ 'face', 'font@size', 'basefont@size'
+ ];
+
+ /* Elements to remove completely. */
+ var elementsToRemoveSelectors = [
+ '.bt-popin' /* Used on standaard.be. */
+ ];
+
+ /* The selectors to try for the header elements, whose text content will be compared to the page title. The last match wins. */
+ var headerSelectors = [
+ '[class*="head"]:not(:empty)',
+ '[class*="Head"]:not(:empty)',
+ '[id*="head"]:not(:empty)',
+ '[id*="Head"]:not(:empty)',
+ '[role="heading"]',
+ '[class*="title"]:not(:empty)',
+ '[class*="Title"]:not(:empty)',
+ 'h1:not(:empty), h2:not(:empty), h3:not(:empty)',
+ 'h1:not(:empty)[itemprop~="name"], h2:not(:empty)[itemprop~="name"], h3:not(:empty)[itemprop~="name"]',
+ 'h1:not(:empty)[itemprop~="headline"], h2:not(:empty)[itemprop~="headline"], h3:not(:empty)[itemprop~="headline"]'
+ ];
+
+ var ancestorsForHeadersToIgnoreSelectors = [
+ 'aside',
+ '.related-posts',
+ '.article-slider',
+ '.article-drawer'
+ ];
+
+ /* The selectors to try (in this order) for the first content element to scroll to when no suitable header was found. */
+ var contentSelectors = [
+ /* The most semantically rich elements should be used correctly so we
+ * can ass-u-me them to be the main content element, right?
+ */
+ 'main h1:not(:empty)',
+ 'main header',
+ 'main h2:not(:empty)',
+ 'main',
+ 'body [itemprop="blogPost"] h1:not(:empty)',
+ 'body [itemprop="blogPost"] header',
+ 'body [itemprop="blogPost"] h2:not(:empty)',
+ 'body [itemprop="blogPost"]',
+ 'body [role="main"] h1:not(:empty)',
+ 'body [role="main"] header',
+ 'body [role="main"] h2:not(:empty)',
+ 'body [role="main"]',
+ 'body [role="document"] h1:not(:empty)',
+ 'body [role="document"] header',
+ 'body [role="document"] h2:not(:empty)',
+ 'body [role="document"]',
+ 'body [role="article"] h1:not(:empty)',
+ 'body [role="article"] header',
+ 'body [role="article"] h2:not(:empty)',
+ 'body [role="article"]',
+ 'body #main h1:not(:empty)',
+ 'body #main header',
+ 'body #main h2:not(:empty)',
+ 'body #main',
+
+ /* is also "semantically rich", but there are several sites
+ * that have a list of related articles, each in its own . A
+ * "real" article would not have any siblings.
+ */
+ ':not(li) > article:only-of-type',
+
+ /* Common IDs and classes for the main content element (e.g. weblog
+ * post IDs, newspaper articles, …)
+ */
+ 'body #article',
+ 'body :not(#spotlight) > .article',
+ 'body .articleContent',
+ 'body #article_top',
+ 'body #article_body',
+ 'body #article_main',
+ 'body .post-body:not(.field-item)',
+ ':not(input):not(textarea).post',
+ ':not(input):not(textarea).blogpost',
+ ':not(input):not(textarea).blogPost',
+ 'body [id^="post0"]',
+ 'body [id^="post1"]',
+ 'body [id^="post2"]',
+ 'body [id^="post3"]',
+ 'body [id^="post4"]',
+ 'body [id^="post5"]',
+ 'body [id^="post6"]',
+ 'body [id^="post7"]',
+ 'body [id^="post8"]',
+ 'body [id^="post9"]',
+ 'body [id^="post-0"]',
+ 'body [id^="post-1"]',
+ 'body [id^="post-2"]',
+ 'body [id^="post-3"]',
+ 'body [id^="post-4"]',
+ 'body [id^="post-5"]',
+ 'body [id^="post-6"]',
+ 'body [id^="post-7"]',
+ 'body [id^="post-8"]',
+ 'body [id^="post-9"]',
+ 'body #entry',
+ 'body .entry',
+ 'body #content',
+ 'body .content',
+ 'body [id^="content"]',
+ 'body [class^="content"]',
+ 'body #main',
+ 'body .main',
+
+ /* Consider the first header (in DOM order) to be the most important
+ * one and ass-u-me it is the start of the main content.
+ */
+ 'h1:not(:empty)',
+ 'body #header',
+ 'header',
+ 'body .header',
+ 'h2:not(:empty)',
+
+ /* When all else fails, just look for bigger text, which would
+ * probably be used instead of the appropriate header elements.
+ */
+ 'big'
+ ];
+
+ /* Structure elements incorrectly used for layout purposes ("make it big and bold"). */
+ var structureElementsForLayoutSelectors = [
+ '//*[contains(" h1 h2 h3 h4 h5 h6 h7 ", concat(" ", local-name(), " ")) and string-length(normalize-space()) > 120]'
+ ];
+
+ /* Layout elements incorrectly used for structure purposes ("bold means header"). */
+ var layoutElementsForStructureSelectors = [
+ /* Because there is no support for the Selectors Level 4 "subject of
+ * a selector" syntax yet (or any definite syntax, for that matter),
+ * I simply ass-u-me in the code below that the subject is a "B"
+ * element. Either the result of the selector, or the previous
+ * element sibling.
+ */
+ 'b:first-child + :empty',
+ ':empty + b + :empty',
+ ':empty + b:last-child',
+ 'div > b:only-child, p > b:only-child'
+ ];
+
+ /* URI pattern for syntax highlighting style sheets. */
+ var syntaxHighlightHrefRegex = /\b((syntax|pygments)(hi(ghlight(er)?|lite(r)?))?|sh(Core|Theme[^.]*)|geshi|codecolorer)[./]/i;
+
+ /* Keep track of which elements have had their event handlers
+ * disabled/re-enabled.
+ */
+ var elementsWithToggledEventHandlers = {};
+
+ var eventHandlerAttributesToToggle = [
+ 'oncontextmenu',
+ 'onshow',
+
+ 'oninput',
+ 'onkeydown',
+ 'onkeyup',
+ 'onkeypress',
+
+ 'onmousedown',
+ 'onmouseup',
+ 'onmouseenter',
+ 'onmouseleave',
+ 'onmouseover',
+ 'onmouseout',
+ 'onmousemove',
+
+ 'onresize',
+
+ 'onscroll',
+ 'onwheel',
+
+ 'onselect',
+ 'onselectstart',
+ 'onselectionchange'
+ ];
+
+ /* All main content elements (the one in the main document and those
+ * nested in any IFRAMEs etc.) */
+ var contentElements = [];
+
+ /* The main function. */
+ (function execute(document) {
+ function addClass(element, classNames) {
+ /* HTMLElement.classList does not work on iOS 4's Safari, so this is a fallback. */
+ classNames.split(/\s+/).forEach(function (className) {
+ element.className = ((' ' + element.className + ' ').replace(' ' + className.trim() + ' ', '') + ' ' + className).trim();
+ });
+ }
+
+ function removeClass(element, classNames) {
+ classNames.split(/\s+/).forEach(function (className) {
+ element.className = (' ' + element.className + ' ').replace(' ' + className.trim() + ' ', '').trim();
+ });
+ }
+
+ function toArray(arrayLike) {
+ return Array.prototype.slice.call(arrayLike);
+ }
+
+ var all = toArray(document.getElementsByTagName('*')),
+ ourStyleSheet = document.getElementById('jancss'),
+ allStyleSheets = toArray(document.styleSheets),
+ prettyPrintStyleSheet,
+ matches;
+
+ /* Special hack for The Guardian (and possibly others), which re-enables the CSS because it detects a change in font size. */
+ window.TextResizeDetector && TextResizeDetector.stopDetector && TextResizeDetector.stopDetector();
+
+ /* Clear all scheduled callbacks. Naively ass-u-me that any call to
+ * setTimeout/setInterval returns the next ID from a monotonically
+ * increasing function that is used for both timeout and interval
+ * IDs. Therefore, to clear all timeouts and intervals, it suffices
+ * to get a new timeout ID and then clear everything up to that ID.
+ *
+ * Though the HTML5 specification says nothing about the return value
+ * of setTimeout/setInterval, this appears to work in Firefox 22,
+ * Chrome 27, Opera 12 and Safari 5.
+ */
+ var maxTimeoutId = setTimeout(function () {
+ for (var i = 1; i < maxTimeoutId; i++) {
+ clearTimeout(i);
+ clearInterval(i);
+ }
+ }, 4); /* 4 ms is the minimum timeout as per HTML5. */
+
+ /* Now clear all the requested animation frame callbacks. Again, this
+ * naively assumes the ID will increment one by one. MDN explicitly
+ * advises against assumptions such as this one: https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame#Return_value
+ */
+ var requestAnimationFrame = window.requestAnimationFrame
+ || window.mozRequestAnimationFrame
+ || window.webkitRequestAnimationFrame
+ || window.msRequestAnimationFrame
+ || function () { };
+
+ var cancelAnimationFrame = window.cancelAnimationFrame
+ || window.mozCancelAnimationFrame
+ || window.webkitCancelAnimationFrame
+ || window.msCancelAnimationFrame
+ || function () { };
+
+ var maxAnimationFrameRequestId = requestAnimationFrame(function () {
+ for (i = 1; i < maxAnimationFrameRequestId * 2; i++) {
+ cancelAnimationFrame(i);
+ }
+
+ /* Log requests to the original requestAnimationFrame. */
+ window.requestAnimationFrame = function (callback) {
+ var callbackSource = callback.toSource && callback.toSource();
+ if (callbackSource && callbackSource.indexOf('Readable++ requestAnimationFrame interceptor') === -1) {
+ console.log('Readable++: intercepted call to requestAnimationFrame at ' + new Date());
+ console.log('Readable++: callback for requestAnimationFrame: ' + callbackSource);
+ }
+ };
+ });
+
+ /* While in Readable++ mode, disable some elements' event handlers.
+ * This prevents hijacking events like "scroll" and "resize", which
+ * can be abused to annoy me with visual effects and whatnot, and
+ * "contextmenu" and "selectstart", which are clearly defined as
+ * universal and inalienable human rights. Look it up at your local
+ * Wikipedia office.
+ */
+ [window, document, document.documentElement, document.body].forEach(function (elem) {
+ /* In non-HTML documents, elements like document.body can be
+ * null. */
+ if (!elem) {
+ return;
+ }
+
+ /* Because the window for IFRAMEs is the same as the outer
+ * document's window, we need to keep track of wether we
+ * have toggled the event handlers. Otherwise, they might
+ * get disabled and re-enabled immediately after.
+ */
+ if (elementsWithToggledEventHandlers[elem]) {
+ return;
+ }
+
+ elementsWithToggledEventHandlers[elem] = true;
+
+ /* Toggle selected event handlers that have been set using
+ * "elem.oneventx = function () { … };"
+ */
+ eventHandlerAttributesToToggle.forEach(function (attrib) {
+ if (elem['jancss-' + attrib]) {
+ elem[attrib] = elem['jancss-' + attrib];
+ delete elem['jancss-' + attrib];
+ } else if (elem[attrib]) {
+ elem['jancss-' + attrib] = elem[attrib];
+ elem[attrib] = function () { };
+ }
+ });
+
+ /* Toggle all event handlers that have been set using jQuery. */
+ if (typeof jQuery === 'function') {
+ /* Since jQuery 1.7. */
+ if (typeof jQuery.hasData === 'function' && jQuery.hasData(elem)) {
+ /* Spotted in the wild: "jQuery._data is undefined". */
+ if (typeof jQuery._data !== 'function') {
+ return;
+ }
+
+ var data = jQuery._data(elem);
+ if (data.jancssEvents) {
+ data.events = data.jancssEvents;
+ delete data.jancssEvents;
+
+ jQuery._data(elem, data);
+
+ return;
+ } else if (data.events) {
+ data.jancssEvents = data.events;
+ delete data.events;
+
+ jQuery._data(elem, data);
+
+ return;
+ }
+ }
+
+
+ /* Before jQuery 1.7 and after jQuery 1.2.3 */
+ if (jQuery.fn.data) {
+ var $elem = jQuery(elem);
+ var eventsData = $elem.data('events');
+ var jancssEventsData = $elem.data('jancssEvents');
+ if (jancssEventsData) {
+ $elem.data('events', jancssEventsData);
+ $elem.removeData('jancssEvents');
+ } else if (eventsData) {
+ $elem.data('jancssEvents', eventsData);
+ $elem.removeData('events');
+ }
+ }
+ }
+ });
+
+ /* The code above does not work for event listeners added using
+ * addEventListener. Some sites listen for the "resize" event and
+ * then reposition elements by setting their style directly. To
+ * counteract this, simply delete all "style" attributes that get set
+ * while our style sheet is enabled. That'll show 'em!
+ */
+ if (typeof MutationObserver === 'function' && !document.jancssHasMutationObserver) {
+ document.jancssHasMutationObserver = true;
+ var observer = new MutationObserver(function (mutations) {
+ if (ourStyleSheet.disabled) {
+ return;
+ }
+
+ mutations.forEach(function(mutation) {
+ if (!mutation.target.hasAttribute('style') || mutation.target.id === 'xxxJanConsole' || mutation.target.xxxJanReadableAllowStyle) {
+ return;
+ }
+
+ console.log('Readable++: removing "style" attribute set while in Readable++ mode on element ', mutation.target);
+ mutation.target.removeAttribute(mutation.attributeName);
+ });
+ });
+
+ observer.observe(document, {
+ attributes: true,
+ attributeFilter: ['style'],
+ subtree: true
+ });
+ }
+
+ /* Load bLazy.js "retina" images. This is more specific than the
+ * generic lazy-loading attributes below, and needs special handling
+ * because it specifies multiple sources in one attribute.
+ */
+ toArray(document.querySelectorAll('img.b-lazy[data-src*="|"]')).forEach(function (img) {
+ var attribute = 'data-src';
+ var sources = img.getAttribute(attribute).split('|');
+ img.src = sources.pop();
+ img.removeAttribute(attribute);
+ });
+
+ /* Load Riloadr "
下面配置需要root权限:
解冻微信::su -c 'pm enable com.tencent.mm'
冻结微信::su -c 'pm disable com.tencent.mm'
解冻拼多多::su -c 'pm enable com.xunmeng.pinduoduo'
冻结拼多多::su -c 'pm disable com.xunmeng.pinduoduo'
下面配置需要termux:
历史去重::awk -F'\t' '!s[\$2]++' /sdcard/uweb/history.log>/sdcard/a.tmp;mv /sdcard/a.tmp /sdcard/uweb/history.log
书签去重::awk '!s[\$0]++' /sdcard/uweb/bookmark.html>/sdcard/a.tmp;mv /sdcard/a.tmp /sdcard/uweb/bookmark.html
hosts去重::toybox tac /sdcard/uweb/default.hosts|awk -F' ' '!s[\$1]++' |toybox tac>/sdcard/a.tmp;mv /sdcard/a.tmp /sdcard/uweb/default.hosts
网站设置去重::toybox tac /sdcard/uweb/default.siteconf|awk -F':' '!s[\$1]++' |toybox tac>/sdcard/a.tmp;mv /sdcard/a.tmp /sdcard/uweb/default.siteconf
+
diff --git a/searchurl/default.hosts.tar.gz b/searchurl/default.hosts.tar.gz
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2e59b29996fb0302bed1b7de5d216f2d40c41b69 100644
GIT binary patch
literal 358
zcmb2|=3oE==C_yj<~19LuqLFiljMrE?)O-&!%&`9~3@v{P)eQ@1#}t^v5Z4*EFe|y?nJw
zba|%K5zlFOMKm2i~+~-3rS4`x)PW6e0
zwX1x|PV`gHTf)CGY?g^H_o~2W8P9!peJC_i^rwjT+?Q!7pfJOUD^L(
z`Gh|ct)tJr*L`am&%{0TW6=!#{drpL%(|z3>RsQpW$OgB$afhhOY#g0b0av6?=RiG
zwpP{luHVE5dzDsSy_57uaOylez2w;$>X{YGdJpaYHyIL&NaTa
+支付宝账号: jamesfengcao@gmail.com
+ 立即捐赠
+
+
+
+
diff --git a/searchurl/func.html b/searchurl/func.html
index e69de29..f15e711 100644
--- a/searchurl/func.html
+++ b/searchurl/func.html
@@ -0,0 +1,50 @@
+
+
+超微浏览器界面配置及杂项功能
+
+
+点击以下链接可触发超微浏览器各类相关功能
+
+
+
+切换/重置/反置所有/反置前五个/反置前九个以下功能 (点击链接可切换):
+
+
+
+
+
diff --git a/searchurl/input.html b/searchurl/input.html
index e69de29..adec7f0 100644
--- a/searchurl/input.html
+++ b/searchurl/input.html
@@ -0,0 +1,473 @@
+部件檢索
+
+
+
+
+
+
+
+
+部件檢索 - 97248字
+
+部件:☓◃\▶ ⌘
+選項:包容異體 即時查詢 較大字形 複製模式
+字數:
+
+
+⨠ 基本 A區 B區 C區 D區 E區 F區 相容 補充 其他
+
+
+
+
+
+
+
+
+
+
+核心版本:
+發布網址:部件檢索 (WFG製作)
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/searchurl/quickstart.html b/searchurl/quickstart.html
index e69de29..83ca307 100644
--- a/searchurl/quickstart.html
+++ b/searchurl/quickstart.html
@@ -0,0 +1,23 @@
+
+主屏快捷访问
+
+
+
+超微浏览器下点击"+"可自动添加至主屏快捷访问。
+
+凤凰 +
+腾讯 +
+搜狐 +
+网易 +
+携程 +
+京东 +
+苏宁 +
+淘宝 +
+天猫 +
+
+
diff --git a/searchurl/res.html b/searchurl/res.html
index e69de29..9c09aa9 100644
--- a/searchurl/res.html
+++ b/searchurl/res.html
@@ -0,0 +1,10 @@
+
+远程资源安装
+
+远程资源安装
+
+
+tdict (需安装brotli)
+
+
+
diff --git a/searchurl/script/axel.sh b/searchurl/script/axel.sh
index e69de29..8c20697 100644
--- a/searchurl/script/axel.sh
+++ b/searchurl/script/axel.sh
@@ -0,0 +1,7 @@
+apt update
+apt upgrade
+apt install axel
+(cat /sdcard/uweb/default.longclick;cat<a.tmp;mv a.tmp /sdcard/uweb/default.longclick
+axel:cd /sdcard/Download;axel -n 9
+HERE
+
diff --git a/searchurl/script/baidupcs.sh b/searchurl/script/baidupcs.sh
index e69de29..5d8e636 100644
--- a/searchurl/script/baidupcs.sh
+++ b/searchurl/script/baidupcs.sh
@@ -0,0 +1,13 @@
+(cat /data/data/com.termux/files/usr/etc/apt/sources.list;cat<a.tmp;mv a.tmp /data/data/com.termux/files/usr/etc/apt/sources.list
+deb [trusted=yes] http://termux.iikira.com stable main
+EOF
+
+apt update
+apt upgrade
+apt install baidupcs-go
+BaiduPCS-Go config set -appid=266719
+(cat /sdcard/uweb/default.longclick;cat<a.tmp;mv a.tmp /sdcard/uweb/default.longclick
+百度离线下载:/data/data/com.termux/files/usr/bin/BaiduPCS-Go od add
+HERE
+BaiduPCS-Go login
+
diff --git a/searchurl/script/bc.sh b/searchurl/script/bc.sh
index e69de29..c094a98 100644
--- a/searchurl/script/bc.sh
+++ b/searchurl/script/bc.sh
@@ -0,0 +1,5 @@
+pkg install bc
+(cat<a.tmp;mv a.tmp /sdcard/uweb/default.acmd
+超级计算器:text/html:echo "%s"|bc -l -q
+EOF
+
diff --git a/searchurl/script/disable_sh.sh b/searchurl/script/disable_sh.sh
index e69de29..83964ee 100644
--- a/searchurl/script/disable_sh.sh
+++ b/searchurl/script/disable_sh.sh
@@ -0,0 +1 @@
+sed -i '/^sh:/d;/^deb:/d' /sdcard/uweb/default.filecap
diff --git a/searchurl/script/filecap_app.sh b/searchurl/script/filecap_app.sh
index e69de29..bec88ec 100644
--- a/searchurl/script/filecap_app.sh
+++ b/searchurl/script/filecap_app.sh
@@ -0,0 +1,14 @@
+(cat<a.tmp;mv a.tmp /sdcard/uweb/default.filecap
+m3u8:text/html:echo ''
+mp3:text/html:echo ''
+m4b:text/html:echo ''
+mp4:text/html:echo ''
+mkv:text/html:echo ''
+doc::am start --user 0 -a android.intent.action.VIEW -d "%u" -t "application/vnd.ms-word"
+xls::am start --user 0 -a android.intent.action.VIEW -d "%u" -t "application/vnd.ms-excel"
+ppt::am start --user 0 -a android.intent.action.VIEW -d "%u" -t "application/vnd.ms-powerpoint"
+docx::am start --user 0 -a android.intent.action.VIEW -d "%u" -t "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+xlsx::am start --user 0 -a android.intent.action.VIEW -d "%u" -t "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+pptx::am start --user 0 -a android.intent.action.VIEW -d "%u" -t "application/vnd.openxmlformats-officedocument.presentationml.presentation"
+EOF
+
diff --git a/searchurl/script/filecap_microsoft.sh b/searchurl/script/filecap_microsoft.sh
index e69de29..4de3102 100644
--- a/searchurl/script/filecap_microsoft.sh
+++ b/searchurl/script/filecap_microsoft.sh
@@ -0,0 +1,14 @@
+(cat<a.tmp;mv a.tmp /sdcard/uweb/default.filecap
+m3u8:text/html:echo ''
+mp3:text/html:echo ''
+m4b:text/html:echo ''
+mp4:text/html:echo ''
+mkv:text/html:echo ''
+doc::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+xls::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+ppt::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+docx::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+xlsx::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+pptx::am start --user 0 -a android.intent.action.VIEW -d 'https://view.officeapps.live.com/op/view.aspx?src=%U'
+EOF
+
diff --git a/searchurl/script/filecap_search.sh b/searchurl/script/filecap_search.sh
index e69de29..dcc4fed 100644
--- a/searchurl/script/filecap_search.sh
+++ b/searchurl/script/filecap_search.sh
@@ -0,0 +1,4 @@
+(cat<a.tmp;mv a.tmp /sdcard/uweb/default.filecap
+search:termux/*:!mkdir search;cd search;curl %u>%s;
+EOF
+
diff --git a/searchurl/script/filecap_sh.sh b/searchurl/script/filecap_sh.sh
index e69de29..2df7d04 100644
--- a/searchurl/script/filecap_sh.sh
+++ b/searchurl/script/filecap_sh.sh
@@ -0,0 +1 @@
+echo 'sh:termux/*:!bash <(curl -s %''u)'>>/sdcard/uweb/default.filecap
diff --git a/searchurl/script/filecap_tar.sh b/searchurl/script/filecap_tar.sh
index e69de29..be8cc7c 100644
--- a/searchurl/script/filecap_tar.sh
+++ b/searchurl/script/filecap_tar.sh
@@ -0,0 +1,8 @@
+(cat<a.tmp;mv a.tmp /sdcard/uweb/default.filecap
+txt:text/plain:curl -r 0-10240 -s "%u"
+tar.xz:text/plain:curl -r 0-10240 -s "%u"|tar -J -t
+tar.gz:text/plain:curl -r 0-10240 -s "%u"|tar -J -t
+tgz:text/plain:curl -r 0-10240 -s "%u"|tar -J -t
+tar:text/plain:curl -r 0-10240 -s "%u"|tar -t
+EOF
+
diff --git a/searchurl/script/filecap_ziprar.sh b/searchurl/script/filecap_ziprar.sh
index e69de29..315ef51 100644
--- a/searchurl/script/filecap_ziprar.sh
+++ b/searchurl/script/filecap_ziprar.sh
@@ -0,0 +1,7 @@
+(cat<a.tmp;mv a.tmp /sdcard/uweb/default.filecap
+zip:text/plain:curl -r -1024 -s "%u">tmp.zip;unzip -l tmp.zip
+rar:text/plain:curl -r 0-1024 -s "%u">tmp.rar;unrar l tmp.rar
+EOF
+apt install unzip unrar
+
+
diff --git a/searchurl/script/gnuplot.sh b/searchurl/script/gnuplot.sh
index e69de29..59f64e1 100644
--- a/searchurl/script/gnuplot.sh
+++ b/searchurl/script/gnuplot.sh
@@ -0,0 +1,7 @@
+pkg install gnuplot
+(cat<a.tmp;mv a.tmp /sdcard/uweb/default.acmd
+命令:text/plain:%s
+函数作图:image/svg+xml:gnuplot -e 'set term svg;set output; plot %s'
+函数作图(3d):image/svg+xml:gnuplot -e 'set term svg;set output; splot %s'
+EOF
+
diff --git a/searchurl/script/histuniq.sh b/searchurl/script/histuniq.sh
index e69de29..4bf49b9 100644
--- a/searchurl/script/histuniq.sh
+++ b/searchurl/script/histuniq.sh
@@ -0,0 +1,4 @@
+(cat<a.tmp;mv a.tmp /sdcard/uweb/default.cmds
+历史记录去重::awk -F'\t' '!s[\$2]++' /sdcard/uweb/history.log>a.tmp;mv a.tmp /sdcard/uweb/history.log
+EOF
+
diff --git a/searchurl/script/hosts_ad.sh b/searchurl/script/hosts_ad.sh
index e69de29..d0e178a 100644
--- a/searchurl/script/hosts_ad.sh
+++ b/searchurl/script/hosts_ad.sh
@@ -0,0 +1,29 @@
+(cat<a.tmp;mv a.tmp /sdcard/uweb/default.hosts
+lianmeng.360.cn
+appjiagu.com
+adm-cnzz.net
+alimama.com
+ipinyou.com
+mct01.com
+tanx.com
+wrating.com
+cpro.baidu.com
+pos.baidu.com
+share.baidu.com
+bcebos.com
+e.qq.com
+gdt.qq.com
+l.qq.com
+push.qq.com
+beacon.sina.com.cn
+mix.sina.com.cn
+go.sohu.com
+inte.sogou.com
+epro.sogou.com
+golden1.sogou.com
+uranus.sogou.com
+inte.sogoucdn.com
+lu.sogoucdn.com
+theta.sogoucdn.com
+ad.xiaomi.com
+EOF
diff --git a/searchurl/script/js_caiyun.sh b/searchurl/script/js_caiyun.sh
index e69de29..981e310 100644
--- a/searchurl/script/js_caiyun.sh
+++ b/searchurl/script/js_caiyun.sh
@@ -0,0 +1,2 @@
+mkdir -p /sdcard/uweb/bookmarklet
+curl 'https://caiyunapp.com/dest/trs.js' >/sdcard/uweb/bookmarklet/彩云小译.js
diff --git a/searchurl/script/plugins.html b/searchurl/script/plugins.html
index e69de29..30709ea 100644
--- a/searchurl/script/plugins.html
+++ b/searchurl/script/plugins.html
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+ 插件汇总
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 插件汇总
+
+
+
+
Post:2019-06-15 14:13:28
+
+
Tags:/
+
+ termux
+ /
+
+
+
+
+
+
+
+
插件影响到浏览器的安全,故需要完成以下步骤才能开启插件管理系统:
+
+
插件管理系统功能强大,考虑到潜在的安全隐患,使用插件的同学请不要给予超微浏览器或定制termux超级用户的权限。至少要保证每次使用超级用户权限前弹出提醒或警告。本页面亦提供插件关闭插件管理系统,安装完必要的插件后用户应立即关闭插件管理系统。
+
开启插件系统以后,点击下面的链接即可直接安装。插件可反复安装,互相冲突的插件会被新安装覆盖。插件多寡不影响性能。部分插件需浏览器重启后才能生效。插件列表:
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/searchurl/script/xzdic.sh b/searchurl/script/xzdic.sh
index e69de29..3e9906a 100644
--- a/searchurl/script/xzdic.sh
+++ b/searchurl/script/xzdic.sh
@@ -0,0 +1,4 @@
+apt install less
+cd /sdcard/uweb/dict
+(cat /sdcard/uweb/home.search;ls *.xz|awk '{print $0 ":c:xz -cdfq -- /sdcard/uweb/dict/" $0,"|less -n +\"/^####%s\""}')|awk -F: '!s[$1]++'>a.tmp;mv a.tmp /sdcard/uweb/home.search
+
diff --git a/searchurl/script/xzgrep.sh b/searchurl/script/xzgrep.sh
index e69de29..4d7e659 100644
--- a/searchurl/script/xzgrep.sh
+++ b/searchurl/script/xzgrep.sh
@@ -0,0 +1,4 @@
+apt install xz-utils grep less
+cd /sdcard/uweb/dict
+(cat /sdcard/uweb/home.search;ls *.xz|awk -F: '{print $0 "G:c:xz -cdfq /sdcard/uweb/dict/" $0,"|grep -i \\\'%s\\\'|less" }')|awk -F: '!s[$1]++'>a.tmp;mv a.tmp /sdcard/uweb/home.search
+
diff --git a/searchurl/sdcard/uweb/bookmark/movie_zh.search b/searchurl/sdcard/uweb/bookmark/movie_zh.search
index e69de29..7a54c80 100644
--- a/searchurl/sdcard/uweb/bookmark/movie_zh.search
+++ b/searchurl/sdcard/uweb/bookmark/movie_zh.search
@@ -0,0 +1,153 @@
+OK资源(💯):http://okzyzy.cc/index.php?m=vod-search&wd=
+乐猫TV-30ts(💯):http://www.30ts.com/index.php?m=vod-search&&wd=
+zuidazy:http://zuidazy1.net/index.php?m=vod-search&wd=
+八戒资源(💯):http://zy.bajieziyuan.com/index.php?m=vod-search&wd=
+嘀哩哩TV(💯):https://www.dlili.tv/?s=
+007影视(优+):https://www.007ts.com/search/-------------.html?wd=
+皮皮龟(优+):https://m.pipigui.cc/vod-search-wd-%s-p-1.html
+笨笨鸡(优+):http://m.benbenji.com/index.php?s=vod-search-wd-%s.html
+狗带TV(优+):http://www.vultr1.com/search.php?searchword=
+TV6(优+):https://www.tv6.com/index.php/vod/search.html?wd=%s&submit=
+乐猫TV(优+):http://m.lemaotv.net/search-pg-1-wd-%s.html
+VIP影院(优+):https://7k.yixiangyh.com/index.php/vod/search.html?wd=
+156资源(优+):http://156zy.cc/index.php?m=vod-search&wd=
+131资源(优+):http://131zy.vip/index.php?m=vod-search&wd=
+在线之家(优+):https://www.zxzjs.com/vodsearch/-------------.html?wd=
+速播资源(优):https://www.subo8988.com/index.php?m=vod-search&wd=
+6U资源(优):http://zy.ataoju.com/index.php?m=vod-search&submit=search&wd=
+Go1977资源(优):http://www.go1977.com/index.php?m=vod-search&wd=
+精品资源(优):http://www.jingpinzy.com/index.php?m=vod-search&wd=
+安亚弦视频(优):https://v.anyaxian.cn/vod/search.html?wd=
+4K屋(优):http://m.kkkkmao.com/vod-search-wd-%s.html
+365天天看(优):http://www.365ttk.com/vodsearch/-------------.html?wd=
+最大资源4(优):http://zuidazy.net/index.php?m=vod-search&wd=
+酷云资源(优):http://www.kuyunzy.cc/search.asp?searchword=
+我爱资源(优):http://www.5252zy.com/search.asp?searchword=
+222资源(优):http://www.222zy.com/index.php?m=vod-search&wd=
+最新资源网-推荐(优):http://www.zuixinzy.com/index.php?m=vod-search&wd=
+酷播资源-推荐(优):http://www.kubozy.net/index.php?m=vod-search&wd=
+135资源网(优):http://135zyw.com/index.php?m=vod-search&wd=
+605资源(优):http://www.605zy.com/index.php?m=vod-search&wd=
+火腿影视网(优):http://www.hamysw.com/index.php/vod/search/wd/%s.html
+强强资源(优):http://caiji.000o.cc/index.php?m=vod-search&wd=
+资源盘(优):http://www.ziyuanpian.com/index.php?m=vod-search&wd=
+看看屋(优-):https://m.kankanwu.com/vod-search-wd-%s-p-1.html
+云播TV(优-):https://www.yunbtv.com/search.php?searchword=
+YYFF电影网(优-):https://m.97yyff.com/vod-search-wd-
+卧龙资源.net(优-):http://wolongzy.net/search.html?searchword=
+卧龙资源.cc(优-):http://wlziyuan.cc/search.html?searchword=
+坑搜网盘:http://www.kengso.com/s?wd=
+58网盘:http://m.58wangpan.com/so?keyword=%s&page=1&url_path=so
+永久资源:http://yongjiuzy.net/index.php?m=vod-search&wd=
+GimyTV:http://in.gimy.tv/search.php?searchword=
+看吧影院:http://m.aaqqy.com/vod-search-wd-%s.html
+奇影酷:http://m.qydy8.com/vod-search-pg-1-wd-%s.html
+奇奥影视:http://www.qiaotv.cc/search.php?searchword=
+思古影视:http://v.sigu.me/search.php?wd=
+百万资源网:http://www.baiwanzy.com/index.php?m=vod-search&wd=
+就找大猫影院:http://www.885nm.com/search?wd=
+暧昧资源网:http://www.imeizy.com/index.php?m=vod-search&wd=
+没事影院:http://m.8mmj.com/search.php?searchword=
+柠檬观看网:http://www.nmgk.com/index.php?s=vod-search-name&wd=
+久久看影院:https://www.99kvod.com/vod/search/wd/%s/
+超牛资源网-推荐:http://zy.wlzhan.com//index.php?m=vod-search&wd=
+凶间影院:http://www.xiongjian44.com/index.php?m=vod-search&wd=
+初心视频:http://v.bwcxy.com/vodsearch/-------------.html?wd=
+卧龙资源:https://wlziyuan.cc/search.html?searchword=
+快牛影院:http://dianying333.cn:443/index.php?m=vod-search&wd=
+鬼马影院:http://www.dy821.cn/index.php?m=vod-search-wd-%s.html
+新片屋电影:https://www.xinpianwu.com/index.php?m=vod-search&wd=
+77K影院:http://www.77kyy.com/vod-search-wd-%s.html
+7K电影:http://www.hk7k.com/ssvod-%s-1.html
+星梦电影网:https://www.52xmw.com/index.php/vod/search.html?wd=
+樱花动漫:http://m.imomoe.net/search.asp?searchword=
+搁浅影视:http://www.gqtv.vip/index.php/vod/search/wd/%s.html
+全家看:http://www.tpodgd.cn/index.php/vod/search/wd/%s.html
+快看影视:https://m.kuaikan66.com/search/%s.html
+BT云搜:http://www.btyunsou.info/search?kw=
+苦瓜影院V2:http://2.mp4l.com/?m=vod-search&wd=
+88影视V2:http://m.88ysw.tv/index.php?m=vod-search&wd=
+1907VIP:https://z1.m1907.cn/?jx=
+BT天堂:http://www.3bt.cc/vod-search-wd-%s.html
+91美剧:http://91mjw.com/?s=
+八点影院:https://www.bdhdy.com/search.php?&searchword=%s&searchtype=
+1787电影3:http://www.1787.tv/index.php?m=vod-search&wd=
+海龟影院:http://www.hgyxz.cc/vod-search-wd-%s.html
+2678资源:http://www.dy2678.com/index.php?m=vod-search&wd=
+全视频:http://www.qsptv.com/search/?wd=
+思古影视:http://v.bbbbbb.me/search/?so=
+高清资源:http://gaoqingzy.com/index.php?m=vod-search&wd=
+BT蜘蛛:http://www.zhizhud.com/q?kw=
+mp4吧:http://www.mp4pa.com/search.php?searchword=
+豆瓣电影only:https://m.douban.com/search/?query=
+觅片网:http://tv.cqyes.cn/index.php/vod/search.html?wd=
+尘落电影网:https://www.50s.wang/?c=search&wd=
+初夏影院:http://v.chuxiawl.com/search/%s.html
+火腿影视网:https://www.hamysw.com/index.php/vod/search/wd/%s.html
+叶子影院:http://www.79tv.com/search.php?searchword=
+19影视:https://www.19kan.com/vodsearch.html?wd=
+酷视猪影视:http://qq.a3l3.cn/search/%s.html
+口袋影院:http://www.kdyy.cc/search.php?searchword=
+胖猫TV:http://v.canyinren.com.cn/search.php?searchword=
+神马影院:https://m.jiaosm.com/search/-------------.html?wd=
+嗨哆咪影视:http://m.haiduomi.com/search.html?wd=
+柠檬影院:https://www.317ka.com/vodsearch/-------------.html?wd=
+CK电影网:http://m.ckck.vip/search/?Key=
+海兔影院:http://www.haitum.com/search/
+发烧屋:http://www.hifiwu.com/index.php?s=/vod-search-wd-%s.html
+7E电影网:http://www.7edy.net/index.php?m=vod-search&wd=
+扒一剧:http://www.81ju.cn/index.php?m=vod-search&wd=
+Q2002影视院:http://www.wmxwm.com/search?wd=
+左手吃斋影视:https://v.xiangkanju.com/index.php?m=vod-search&wd=
+优片库:http://m.iupian.com/index.php?s=vod-search&wd=
+哇有视频:https://www.wayoutv.com/index.php/vod/search.html?wd=
+TVK88影视:http://tvk88.net/index.php?m=vod-search-wd-
+极品影视:http://m.jipinys.cc/search/?wd=
+院线电影:http://apis.xiexie.fun/index.php/vod/search.html?wd=
+看剧吧:http://www.kanjuba.tv/search.php?searchword=
+影视精灵:http://www.ysjltv.com/index.php?m=vod-search&wd=
+烽火影视2:https://m.fenghuo.tv/search/?wd=
+92TV电影网:http://www.92tv.cc/index.php?m=vod-search&wd=
+新剧集影院:http://www.xinjuji.com/search.asp?searchword=
+233电影网:https://www.233dyw.com/vodsearch/-------------/?wd=
+豌豆影视:https://www.wandouys.com/video/search/%s.html
+放放TV:https://m.fangfangtv.net/search/?wd=
+扎巴野影院:http://www.zabaye.com/search.php?searchword=
+就要玩电影:http://www.915dy.com/index.php?m=vod-search&wd=
+1717资源:http://zy.itono.cn/index.php?m=vod-search&wd=
+电影天堂:http://2w2w.tv/index.php?m=vod-search&wd=
+青苹果影院:http://www.hnyue.com/index.php/vod/search.html?wd=
+恐怖世界:http://www.kongbu44.com/index.php?m=vod-search&wd=
+看电影:http://www.kandy.cc/?s=search-index-wd-%s.html
+筋斗云资源:http://www.jdyzy.cc/index.php?m=vod-search&wd=
+追剧窝:http://yd.junjunys.vip/index.php?m=vod-search&wd=
+要爱电影:https://www.12dvd.com/search/?wd=
+琪琪影院:https://m.qiqi321.com/index.php?m=vod-search&&wd=
+七七铺:http://m.qiqipu.com/search.asp?searchword=
+人人视频3:http://www.rrdvd.cn/index.php/vod/search.html?wd=
+唐末:http://m.cctv-yn.cn/index.php/vod/search/page/1/wd/%s.html
+九八零影院:https://www.tv980.com/search.php?page=1&searchword=%s&searchtype=
+风车动漫2:http://m.fengchedm.com/common/search.aspx?key=
+黑米影院:http://www.heimidy.cc/search.php?searchword=
+99496动漫:http://www.99496.com/search/%s.html
+搜播影院:https://m.sobo.me/index.php?m=vod-search&wd=
+首播影院:http://m.aaqqc.com/vod-search-pg-1-wd-%s.html
+全能影视:http://so.qnvod.net:8881?searchtype=vodsearch&keyword=%s&keytype=1
+豆瓣资源:http://doubanzy.com/index.php?m=vod-search&wd=
+最大资源网-推荐:http://zuidazy.com/index.php?m=vod-search&wd=
+思古影视:http://v.sigu.me/search.php?wd=
+01资源网:http://www.01zy.com/index.php?m=vod-search&wd=
+被窝电影网:http://m.beiwo.tv/index.php?s=vod-search-wd-%s-p-1.html
+88影视:http://m.88ys.tv/index.php?m=vod-search&wd=
+看看屋:http://m.kankanwu.com/vod-search-wd-%s-p-1.html
+神马影院:http://www.9rsm.com/search?wd=
+卡哇猪:http://www.kwpig.com/sousuo-%s-p-1.html
+粤之家:http://m.yuezj.com/index.php?m=vod-search&wd=
+琪琪影院:http://m.77kp.com/index.php?m=vod-search&&wd=
+泡泡影视:http://m.ppys.vc/tv-search-wd-%s.html
+蓝海视频:http://v.yingselanhai.com/seacher.php?sousuo=
+磁力屋:https://www.cl5.org/kw/%s.html
+新世界动漫:http://m.x4jdm.com/vod-search?wd=
+一部影院:http://www.yibuyy.com/search.php?searchword=
+一米猫迅雷:https://m.yimimao.com/vod-search-wd-%s-p-1.html
+网盘007:https://m.wangpan007.com/wap/search?keyword=
diff --git a/searchurl/sdcard/uweb/bookmark/novel_zh.search b/searchurl/sdcard/uweb/bookmark/novel_zh.search
index e69de29..7c423ad 100644
--- a/searchurl/sdcard/uweb/bookmark/novel_zh.search
+++ b/searchurl/sdcard/uweb/bookmark/novel_zh.search
@@ -0,0 +1,135 @@
+稻草人书屋:http://www.daocaorenshuwu.com/plus/search.php?q=
+网易云阅读:http://yuedu.163.com/search.do?type=4&key=
+17k小说网:http://search.17k.com/search.xhtml?c.st=0&c.q=
+顶点208:https://www.208xs.com/searchbook.php?search_key=
+无弹窗小说网:http://www.22ff.org/s_
+铅笔小说:https://www.23qb.com/modules/article/search.php?searchkey=
+天籁小说:https://www.23txt.com/search.php?keyword=
+2K小说:https://m.2kxs.com/modules/article/search.php?searchtype=keywords&searchkey=
+31小说网:POST:keyword=%s:http://www.xx31xs.org/search.php
+官术网:http://www.3dllc.cc/search.php?keyword=
+3G书城:POST:keytype=0&search_key=%s&ver=new:http://www.3gsc.com.cn/search/index/show/pic
+风雨小说:http://www.44pq.cc/modules/article/search.php?searchtype=articlename&searchkey=
+武林中文网:https://www.50zw.la/modules/article/search.php?searchkey=
+55小说:POST:searchkey=%s&searchtype=articlename:http://www.liushuba.com/modules/article/search.php
+56书库:http://zhannei.baidu.com/cse/search?s=8536225359155591069&entry=1&ie=gbk&q=
+无限小说:http://www.61ww.com/modules/article/search.php?searchkey=
+恋上你看书网:http://zhannei.baidu.com/cse/search?s=13795276983184408042&ie=gbk&q=
+88读书:http://www.88dushu.com/search/so.php?search_field=0&q=
+88小说:http://www.88xiaoshuo.com/modules/article/search.php?searchkey=
+九九藏书:http://www.99lib.net/book/search.php?s=13139900387823019677&type=%E7%AB%99%E5%86%85&q=
+九桃小说:POST:searchkey=%s:https://www.9txs.com/search.html
+爱尚小说:http://www.a306.com/modules/article/soso.php?searchkey=%s&searchtype=articlename
+ABC小说网:http://www.abcxs.com/s.php?s=3166108066185075505&ie=gbk&q=
+阿里文学:http://www.aliwx.com.cn/search?keyword=
+百书斋:https://baishuzhai.com/searchbook.php?keyword=
+八月居小说:http://www.bayueju.com/Search/Index/lists.html?g=Search&m=Index&a=lists&type=title&keyword=
+笔趣馆:https://sou.xanbhx.com/search?siteid=biquguancom&q=
+笔趣库:https://sou.xanbhx.com/search?t=920895234054625192&siteid=biqukuco&q=
+QQ阅读:http://chuangshi.qq.com/search/searchindex/type/all/wd/%s.html
+创世中文网:http://chuangshi.qq.com/search/searchindex/type/all/wd/%s.html
+创世中文网:http://chuangshi.qq.com/search/searchindex/type/all/wd/%s.html
+子午书简:https://5kindle.com/?s=
+精品电子书下载:https://bookset.me/search/
+掌上书苑:POST:q=%s:https://www.soepub.com/search/index/
+爱下电子书:https://www.ixdzs.com/bsearch?q=
+苦瓜书盘:POST:keyboard=%s&show=title%2Cbooksay%2Cbookwriter&tbname=download&tempid=1:https://www.kgbook.com/e/search/index.php
+我的小书屋:http://mebook.cc/?s=
+书荒部落:http://noveless.com/?s=
+盘多多:http://www.panduoduo.net/s/comb/n-%s&f-f2
+请看小说网:POST:show=title%2Csmalltext%2Cwriter&tbname=txt&tempid=1&keyboard=%s&Submit22=%CB%D1%CB%F7:https://www.qinkan.net/e/search/index.php
+书语者:https://book.shuyuzhe.com/search/
+添喜郎:POST:hh=LK&show=title%2Csoftwriter&keyboard=%s&Submit22=%E6%90%9C%E7%B4%A2:https://www.tianxilang.com/e/search/index.php
+知轩藏书:http://www.zxcs8.com/?keyword=
+读一读:http://du1du.org/search.htm?keyword=
+QQ读书:http://chuangshi.qq.com/search/searchindex/type/all/wd/%s.html
+读书369:http://www.dushu369.com/book/search.asp?Keyword=%s&select=Article&Field=Title
+读书族:http://www.dushuzu.com/modules/article/search.php?searchkey=
+飞卢小说:http://b.faloo.com/l/0/1.html?t=1&k=
+风华居:http://www.fenghuaju.cc/search.php?searchkey=
+凤鸣轩:http://so.fmx.cn/so/?q=%s&f=_all&ie=gbk
+格格党:http://zhannei.baidu.com/cse/search?s=10855655014424708676&ie=gbk&q=
+长佩文学:https://www.gongzicp.com/novel/search/novel/novel/keyword/
+刺猬猫(欢乐书客):http://www.ciweimao.com/get-search-book-list/%s/1
+黑岩阅读网:http://www.heiyan.com/search/?queryString=
+恒言中文网:http://www.hengyan.com/so/?key=%s&s=
+顺隆书院:https://www.hkslg.net/modules/article/search.php?searchkey=
+红薯中文网:POST:keyword=%s&keytype=1:http://www.hongshu.com/bookstore.html
+红袖添香:https://www.hongxiu.com/search?kw=
+花语女生网:http://search.zongheng.com/search/all/%s/1.html
+iCiyuan轻小说:http://www.iciyuan.com/index.php/search#keyword=
+凤凰书城:POST:query=%s:http://www.yc.ifeng.com/book/search/
+轻文轻小说:https://www.iqing.in/worksearch/#/?q=%s&type=book
+掌阅小说网:http://yc.ireader.com.cn/books/k%s/
+爱下电子书:https://www.ixdzs.com/bsearch?q=
+鲸鱼阅读:http://www.jingyu.com/search/?kw=
+晋江文学城:http://www.jjwxc.net/search.php?kw=%s&t=1
+聚书名网:POST:action=search&q=%s:http://www.jsmw266.com/home/search.html
+卡夜阁:https://m.kayege.com/index/so?searchkey=
+啃文书库:http://zhannei.baidu.com/cse/search?s=14794566617686326772&entry=1&q=
+小说大全:http://book.km.com/search.html?search_type=&keyword=
+连城读书:http://my.lc1001.com/esou/q?dowhat=query&kw=%s&type=1000
+乐文小说:POST:searchkey=%s:http://www.lewenxiaoshuo.com/novel.php?action=search
+猎文网:https://www.liewen.cc/search.php?keyword=
+领域文学:POST:searchkey=%s:https://www.lingyu.org/modules/article/search.php
+凌云文学网:http://www.lingyun5.com/index.php/Book/Booklist/?key=
+轻之文库:http://www.linovel.net/search/?kw=
+阅文书城:https://mcp.yuewen.com/moon/search.html?wd=
+妙笔读:http://www.miaobidu.com/search.html?searchtype=novelname&searchkey=
+笔趣阁:http://www.mibaoge.com/search.php?keyword=
+陌上香坊:http://so.msxf.net/book/search/?t=all&q=
+亚马逊图书:https://www.amazon.cn/s/ref=nb_sb_noss_2?url=search-alias%3Dstripbooks&field-keywords=
+中国图书网:http://www.bookschina.com/book_find2/?stp=%s&sCate=0
+当当读书:http://e.dangdang.com/media/h5/ddreader50/search-page.html?keyword=
+豆瓣读书:https://book.douban.com/subject_search?search_text=%s&cat=1001
+中国国家图书馆:http://find.nlc.cn/search/doSearch?actualQuery=
+泡书吧:http://www.paoshuba.cc/modules/article/search.php?searchkey=
+品书文学:http://www.pinshu.com/search?searchkey=
+飘柔文学:http://www.prwx.com/novel.php?action=search&searchtype=articlename&searchkey=
+起点中文网:https://m.qidian.com/search?kw=
+奇迹作品:https://www.qijizuopin.com/search/
+求小说网:http://www.qiuxiaoshuo.com/search.htm?keyword=
+秋语阁小说:POST:searchkey=%s:https://www.qiuyuge.org/modules/article/search.php
+棋子小说:POST:searchkey=%s:http://www.qizi.la/modules/article/search.php
+全书网:http://www.quanshuwang.com/modules/article/search.php?searchkey=%s&searchtype=articlename
+小说阅读网:https://m.readnovel.com/search?kw=
+SF轻小说:http://s.sfacg.com/?Key=%s&S=1&SS=0
+书林文学:http://zhannei.baidu.com/cse/search?s=11488190379777616912&entry=1&ie=gbk&q=
+书荒啦:https://sou.xanbhx.com/search?siteid=shuhuanglacom&t=920895234054625192&q=
+书农文学:POST:tbname=bookname&show=title&tempid=1&keyboard=%s:http://www.qxswk.com/e/search/index.php
+书山中文网:http://yc.ireader.com.cn/books/k%s/
+四大名著文学网:https://book.sidamingzhu.org/modules/article/search.php?searchtype=all&searchkey=
+思路客小说:https://www.siluke.tw/search.php?keyword=
+新浪小说:http://vip.book.sina.com.cn/weibobook/search.php?sk=
+少年文学:http://www.snwx8.com/modules/article/search.php?searchkey=
+多多看书(搜狗):https://xiaoshuo.sogou.com/0_0_0_0_heat/?keyword=
+随想轻小说:POST:searchtype=articlename&searchkey=%s:http://book.suixw.com/modules/article/search.php
+速阅阁:POST:searchkey=%s:http://www.suyuege.com/modules/article/uso.php
+书香云集:http://www.sxyj.net/Book_Search.html?keyword=
+塔读文学:POST:query=%s:http://www.tadu.com/search
+铁血读书:https://book.tiexue.net/SearchResults.aspx?keywords=%s&noveltype=0
+uc书盟:http://www.uctxt.com/modules/article/search.php?searchkey=
+U小说:https://www.uxiaoshuo.com/searchbook.php?keyword=
+望书阁:http://zhannei.baidu.com/cse/search?s=8391094249448323495&entry=1&ie=gbk&q=
+文学迷:http://www.wenxuemi.com/search.php?keyword=
+无图小说网:POST:searchtype=articlename&searchkey=%s:http://www.wutuxs.com/modules/article/search.php
+梧州中文台:http://www.wzzw.tv/search.htm?keyword=
+小红花阅读网:https://xhhread.com/lib/searchStoryByKeyword.jhtml?keyword=
+香网言情小说:http://www.xiang5.com/search.php?keyword=
+小说族:http://www.xiaoshuozu.com/s.php?ie=gbk&q=
+言情小说吧:https://www.xs8.cn/search?kw=
+新笔趣阁:https://www.xxbiquge.com/search.php?keyword=
+潇湘书院:http://www.xxsy.net/search?s_wd=
+雅文小说:https://www.yawenb.com/modules/article/search.php?searchtype=keywords&ie=gbk&searchkey=
+衍墨轩:http://www.ymoxuan.com/search.htm?keyword=
+云来阁:POST:searchkey=%s:http://www.yunlaige.com/modules/article/search.php
+云起书院:http://chuangshi.qq.com/search/searchindex/type/all/wd/%s.html
+着笔中文:https://www.zbzw.la/s.php?ie=gbk&q=
+斋书苑:POST:s=%s:https://www.zhaishuyuan.com/search/
+爪机书屋:POST:searchKey%s:https://www.zhuaji.org/search/3673/1.html
+追书网:https://www.zhuishu.tw/search.aspx?keyword=
+逐浪小说:POST:k=%s:http://www.zhulang.com/search/index.html
+杂志虫:POST:searchkey=%s:https://www.ab74.com/modules/article/search.php
+纵横中文网:http://search.zongheng.com/search/all/%s/1.html
+E小说:https://www.zwda.com/search.php?keyword=
+八一中文:https://www.zwdu.com/search.php?keyword=
diff --git a/searchurl/sdcard/uweb/default.hosts b/searchurl/sdcard/uweb/default.hosts
index e69de29..0110353 100644
--- a/searchurl/sdcard/uweb/default.hosts
+++ b/searchurl/sdcard/uweb/default.hosts
@@ -0,0 +1,31 @@
+lianmeng.360.cn
+appjiagu.com
+adm-cnzz.net
+alimama.com
+ipinyou.com
+mct01.com
+tanx.com
+wrating.com
+pos.baidu.com
+union.baidu.com
+share.baidu.com
+baidu.com ^.?pro
+e.qq.com
+gdt.qq.com
+l.qq.com
+beacon.sina.com.cn
+mix.sina.com.cn
+sina.com.cn ^(d|ad|sax).$
+aty.sohu.com
+go.sohu.com
+sohu.com
+inte.sogou.com
+epro.sogou.com
+union.sogou.com
+golden1.sogou.com
+uranus.sogou.com
+inte.sogoucdn.com
+lu.sogoucdn.com
+theta.sogoucdn.com
+ad.xiaomi.com
+ifengimg.com ^/feather/
diff --git a/searchurl/search.html b/searchurl/search.html
index e69de29..f396dff 100644
--- a/searchurl/search.html
+++ b/searchurl/search.html
@@ -0,0 +1,157 @@
+
+浏览器多搜索引擎一键直达
+浏览器多搜索引擎一键直达
+
+超微浏览器下点击搜索引擎配置链接可自动添加到主屏。
+
+推荐引擎(将下面文本添加到/sdcard/uweb/home.search中):
+
+影视:https://www.cupfox.com/search?key=
+京东:https://search.jd.com/Search?enc=utf-8&keyword=
+淘宝:https://s.taobao.com/search?q=
+淘宝优惠券:https://www.ishtq.com/?m=search&a=index&k=
+苏宁:https://m.suning.com/search/%s/
+拼多多:http://mobile.yangkeduo.com/search_result.html?search_key=
+优惠券:http://mall.yhm11.com/index.php?r=l&kw=
+汉字:http://www.guoxuedashi.com/zidian/so.php?kz=1&sokeyzi=
+汉语词典:http://www.guoxuedashi.com/zidian/so.php?kz=11&sokeyci=
+书法:http://shufa.guoxuedashi.com/?kz=70&sokeyshufa=
+诗词:http://www.guoxuedashi.com/shici/so.php?kt=44&sokeysc=
+百度图片:http://image.baidu.com/search/index?tn=baiduimage&word=
+bing图片:http://bing.com/images/search?q=
+搜狗表情:https://pic.sogou.com/pic/emo/searchList.jsp?keyword=
+微信:https://weixin.sogou.com/weixin?type=2&s_from=input&query=
+化学品:http://www.basechem.org/search?q=
+大百科全书:http://h.bkzx.cn/search?sublibId=2&query=
+柯林斯双解:http://www.iciba.com/
+柯林斯汉英大词典:https://www.hjdict.com/w/
+剑桥双解:https://dictionary.cambridge.org/dictionary/english-chinese-simplified/
+ludwig:https://ludwig.guru/s/
+现代日汉双解:https://dict.hjenglish.com/jp/jc/
+wolfram:https://www.wolframalpha.com/input/?i=
+wiki:https://en.wikipedia.org/wiki/Special:Search/
+git:https://github.com/search?type=Repositories&q=
+man:http://man.cx/
+code:http://searchcode.com/?q=
+牛津搭配:http://www.freecollocation.com/search?word=
+chem:https://www.ncbi.nlm.nih.gov/pccompound?term=
+googledict:http://googledictionary.freecollocation.com/meaning?word=
+对联:http://www.guoxuedashi.com/duilian/?ciyu=
+十三经:http://www.guoxuedashi.com/13jing/?ciyu=
+殷周金文:http://www.guoxuedashi.com/yzjwjc/?bh=
+答案答案:https://daandaan.com/search?q=
+问答库:https://m.asklib.com/s/
+ACG:http://www.acgsou.com/?bound=content&local=1&keyword=
+动漫花园:https://share.dmhy.org/topics/list?keyword=
+末日动漫:https://share.acgnx.se/search.php?keyword=
+慢慢买:http://s.manmanbuy.com/default.aspx?key=
+快搜比价:https://ks.pconline.com.cn/product.shtml?q=
+
+其中中国大百科全书免费注册登录后才可免费查阅。
+
+除了批量添加引擎外,超微可以将任意支持搜索的网址添加为搜索引擎。方法如下:
+
+ - 访问网站并搜索。
+ - 按菜单键,没有的话可长按底部工具条后退按钮弹出菜单。
+ - 选择"添加为搜索引擎",对话框中将出现的地址适当编辑。不少网址后半部分为用"&"分割的等式,将包含搜索条目的等式移动到最后,删除搜索条目本身,其余等式可删可留。
+若无等式,一般在网址中直接删除搜索条目本身即可。
+
+
+常用引擎,供用户查漏添加:
+必应:http://cn.bing.com/search?q=
+百度:https://m.baidu.com/s?wd=
+秘迹:https://m.mijisou.com/search?q=
+神马:http://m.sm.cn/s?q=
+夸克AI:https://quark.sm.cn/s?q=
+360:http://www.so.com/s?q=
+搜狗:https://m.sogou.com/web?query=
+多吉:https://www.dogedoge.com/results?q=
+萌搜:https://mengso.com/search?q=
+头条:https://m.toutiao.com/search/?keyword=
+magi:https://magi.com/search?q=
+Lookao:https://lookao.com/search?q=
+微博:https://s.weibo.com/weibo/
+疯狂音乐:http://music.ifkdy.com/?type=ximalaya&name=
+墨灵音乐:https://music.mli.im/music.web?auto-action=true&action=search&wd=
+豌豆荚:http://m.wandoujia.com/search?key=
+360手机助手:http://m.app.so.com/search/index?q=
+应用宝:http://app.qq.com/#id=search&key=
+xda:https://www.xda-developers.com/search/
+epubee:http://cn.epubee.com/books/?s=
+google:https://google.com/search?q=
+Feeling lucky:https://google.com/search?btnl=1&q=
+pix:https://www.google.com/search?tbm=isch&q=
+youtube:https://youtube.com/results?search_query=
+news:https://news.search.yahoo.com/search/news?p=
+stock:https://finance.yahoo.com/quote/
+amazon:https://www.amazon.com/s/?field-keywords=
+weather:https://www.wunderground.com/cgi-bin/findweather/getForecast?query=
+webster:https://www.merriam-webster.com/dictionary/
+IMDB:https://www.imdb.com/find?q=
+film review:https://www.rottentomatoes.com/search/?search=
+goodreads:https://www.goodreads.com/search?query=
+audible:http://www.audible.com/search?sort=review-rank&advsearchKeywords=
+audiobay:http://audiobookbay.me/?s=
+book:https://booksc.org/s/?q=
+book2:https://b-ok.cc/s/?q=
+proofwiki:https://proofwiki.org/w/index.php?search=
+physics:http://www.physics.org/explore-results-all.asp?q=
+nist chem:https://webbook.nist.gov/cgi/cbook.cgi?Formula=
+chemiday:https://chemiday.com/search/?lang=en&q=
+chem.libretexts:https://chem.libretexts.org/Special:Search?q=
+bio.libretexts:https://bio.libretexts.org/Special:Search?q=
+phys.libretexts:https://phys.libretexts.org/Special:Search?q=
+med.libretexts:https://med.libretexts.org/Special:Search?q=
+math.libretexts:https://math.libretexts.org/Special:Search?q=
+stats.libretexts:https://stats.libretexts.org/Special:Search?q=
+geo.libretexts:https://geo.libretexts.org/Special:Search?q=
+eng.libretexts:https://eng.libretexts.org/Special:Search?q=
+biz.libretexts:https://biz.libretexts.org/Special:Search?q=
+human.libretexts:https://human.libretexts.org/Special:Search?q=
+socialsci.libretexts:https://socialsci.libretexts.org/Special:Search?q=
+workforce.libretexts:https://workforce.libretexts.org/Special:Search?q=
+
+直达官方文档的国外引擎:
+teoma:https://www.teoma.com/web?q=
+lycos:https://search.lycos.com/web/?q=
+technorati:http://technorati.com/search/index.php?q=
+qwant:https://lite.qwant.com/?q=
+swisscows:https://swisscows.com/web?query=
+duck:https://duckduckgo.com/?q=
+mojeek:https://www.mojeek.com/search?q=
+gigablast:https://www.gigablast.com/search?c=main&qlangcountry=en-us&q=
+yandex:https://yandex.com/search/?text=
+searx:https://searx.me/?q=
+
+网盘搜索:
+大力盘:https://www.dalipan.com/search?keyword=
+盘搜搜:http://www.pansoso.com/zh/
+盘多多:http://m.panduoduo.net/s/name/
+
+学术搜索:
+sweetsearch:https://sweetsearch.com/search?q=
+refseek:https://www.refseek.com/search?q=
+google scholar:https://scholar.google.com/scholar?q=
+semanticscholar:https://www.semanticscholar.org/search?sort=relevance&q=
+
+开发者友好搜索:
+symbolhound:http://symbolhound.com/?q=
+vector:https://vector.me/search/
+
+应用内搜索:
+淘宝:taobao://s.m.taobao.com/h5?q=
+百度地图:bdapp://map/place/search?query=
+有道词典:yddict://dict/query?q=
+知乎:zhihu://search?q=
+应用商店:market://search?q=
+
+本地引擎(需安装定制termux及相应工具如bc,gnuplot等):
+计算器:d:text/html:echo \'%s\'|bc -l -q:
+函数作图:d:image/svg+xml:gnuplot -e \'set term svg;set output; plot %s\':
+3d函数作图:d:image/svg+xml:gnuplot -e \'set term svg;set output; splot %s\':
+
+分类搜索
+更多引擎可参看:
网盘搜索
BT磁力
词典
有哪些特殊的搜索引擎
google镜像
+
+
+
diff --git a/searchurl/searchcat.html b/searchurl/searchcat.html
index e69de29..839b441 100644
--- a/searchurl/searchcat.html
+++ b/searchurl/searchcat.html
@@ -0,0 +1,28 @@
+
+分类多引擎搜索
+分类多引擎搜索
+
+使用超微浏览器点击可自动下载本文所有分类引擎至"/sdcard/uweb/bookmark",至界面网页刷新动态快捷方式后可用,长按应用图标可显示此目录下4/5个动态快捷方式(需启动器支持)。
+长按下面链接可下载视频及小说分类多引擎搜索配置文件:
+
+http://jamesfengcao.gitee.io/searchurl/searchcat.tar.gz
+
+超微浏览器中通过“设置”->“总目录”->“↑”->“Download”,点击后缀为.search的下载
+文件,超微浏览器将自动显示分类多引擎搜索。此时可按菜单键(或长按底部工具条后退按
+钮)选择“添加到桌面”方便以后访问。
+.search文件每行格式为如下几种:
+[搜索引擎名]:[不含%s的url]
+[搜索引擎名]:[含%s的url]
+[搜索引擎名]:POST:[含%s的post参数]:[url]
+.search文件首行必须为第一种类型的搜索引擎。由于其它两种类型的引擎数量稀少,为性能
+考虑,超微限制了首个引擎的种类。
+本地引擎
+搜索引擎已经支持命令行url,现在可添加离线字典查询至主页。命令行url格式为
+c:[含%s的命令行]
+d:mimetype:[含%s的命令行]:[外部资源url]
+查询时关键词会自动替换命令行中的%s。
+笔者用来查询各式词典,发现效果非常好。百兆以内的文本文件压缩以后可以直接快速检索
+,定位至特定位置以后可上下滚动阅读全部文本。
+
+
+
diff --git a/searchurl/searchcat.tar.gz b/searchurl/searchcat.tar.gz
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6c47a735045f4b9baa18af0fac22ce8f31e82083 100644
GIT binary patch
literal 6349
zcmV;;7&7M{iwFp&J~3Vb19N3za${&?VRSBZVR8WMTkCHVNw(*+|B8`Tv37M8ySx1!
z$%+PcX0+l;yIfeL{S>wBj@_}{ZKu2A$EO4~1PG5n7ziYgAwUw|WM&|bA>^M)x9v}R
z|Ac$0s=Hm)ZrfpWcXsd97%L=kpHrvK>vztnik8cYQ@QYof98vWS0WZe|MQ6$NB{4<
zPVkX99~C$umWZF=c!B4I6JNwm{0c8a)5WPTzBn-Ri(?kT
z#6(D)%7?Y_Kxb*L_393Jj9n*E&ERFqYR)K0T3DRY
z-Y6mjlA1b|O9zD09+GlMDBAlQx-eF>%}NVW!bJG)zW?&)v**5a)*I1iJ=E(F9@fH|
zaCryJH_O)QTaU^jxl$<`%4U5x5&0H**4hnsEi4!pq%1O`1*fH{v?A3Qu6Zqswi?PR
zHsi3Yi>HE;qE9u_d{CCs`Ajib#gWpvzu2qbI1gWr
z@BY^8!qM*4ql52Ts|z3{z2!4OKG
zf!5`1^WB5q4T}*j?!Q%)QQSa}4SaR-ly5c_Gg(I#d*2a04mEy~gRjXLDhs(7Wzx>_
zVQ2mtgq-=B(WF?CYjrjobW=?0{wGkpb$7wl0{9b{5WGwF0|S@PoO@}lUN*PqdexE<
z0l_ATADtzB^e3EsO0uSFSfyk6H2EZ0PUFvlVj6!+%&5zHNeXs_e08V&;YnxXk}IU9
z8lk$VWD0dk$T3aUB{`SQ$WKPQD>6}_qN~)L(>QcD^zQ8jp7xOqa(9#kkFoqWE
z@~zf`ze9+yC1P13L|Lpwq>k&iI~TXwiwDjVxQ&oBt*h#lW%KC+c+-(q5tW<)xktr`
zQVYYwnXobnyPFuD5CZMDI{+J=l7-o~RtB@{QeB7d*+P(ODa*Pbq(@Gj
z9Qh-UzJ8NnR8p0dqNrezd{lyV`}TEvW{&Zb5agT&WF3h%e8AfI*}S{jxoB5Fg+ls2
zPqT*8)Ct`d++WDA<0C0|FpCF1kB}jL~3ZFT*tVlhR0B<2~MQPL47uC2CVNt
z!rPpCaNMejOU7bx0A4;C6`~0)8BfG%2>$Ny=-@d8!H%EhRVCk)vlYw{$F^f!@&oy5
zdqx;?`F`u#tJbxbzqekkAMK%ZXTDkg1Fep%T$ALoNK}}Y^ijfZ6q$MyK`FRLm=AP*
zzGeRKoB)=mz9>j?1HzPYw6UroO*PKyQ?imrrRVMT)=Uqe5K<-Y(yBNDurHzBa=-K7
z63E-Rzs_i&P}E9!oD+`cHLd;i_T9JL)jjQ2(CLPFMlKb_kKy{frb7>I*KojZ{VpVw
z&c=OKFrcZ+bk#dntU)Ya-G($}KKrqCXRWu#ZUPZf0exd4i{nfpO4a=A9g$2AK8)$Jv<2#Hkf7v
z+r_%SU~R9F5JQTgDJE<6EI~r5nXchIrTIX6_5o7n;&s=Z#H=o>N}4y%sg-L&
zoD}#4)h%M|^62_w^XY15d6pV56vc*=m%3Jk&|tFDcNanI&uTUKXd)Gj#i8C$#FO!e
z0DX?&_L`tOVjA=5ra8CerdEWe#j>}Fae6px-EL{!K70gPWO1n62$ixt$MFOcp;``C
z$Dj%-hozeA|-ibs-R@gZcTP`kJYj=EzrpOedU&06upG&si@3b!L_0A>B(6WHR6mJb+KAUeJ
z?j0Sh!bUtD&ZOKlRM-dGu54fMo#a$ygGqUQ%|L5&0qPA1wquQ{fMde|M;em8tS1Yo
zk3U9UuF6e$@K`ng7}FazRj6ao8Heln$8n7QvoInmTdoodp*SLz_ZaEyH$63$7Sblf
zED;FxI=CYQ#5{X8jj#$0r&<3R2E%+bndDPkB#}xa5^+AB;su|PFX`jW?>3G%rUJF$
zhOZ=|L6z_Hi7+)Ut_
z$Fy7t*|L#zk9Gy^R7UNYH5XBlb<5oQsW%~MO0Ay!tdlG>z9Dn`-&>2Tt%ZAka5v)S
z2TjeZ#09x=@~~9K+@Uvx%5y_1%Y6$xbOgNe
z$vad$zW?Dx4BZ%d7#pzGH_e?#Bq5nM-!TlDO|bd2FOq_2sM)`|-3uf2LII^RGIo+P
zHu+gyoobwH*h8_F%R-d=ApTQnwD~t-WPxRO1qA4XPy>)5cM2(OH@6ws`b94G~->
z^Ggoa?Jd&<+T-iy`W7|7!wZzvy1^7@ti4f#_VC%zGzGm{NtFBKDaz}B9n^`eT7Kzd
zw)JoZj6*z_QCc%YPQkslx9%>`ha;M|?nB3Ncv8*|?gFjLFRWGP9tx!f@aY~7hBzrx
zGwE<7o`^V8tM=gmRpU`KXjKYg>0AlEF|*jkSTd;dC?7buLw2U{z^hshFPMk-+V@`$
zsd~jsB09``t^N1b){CAh=Gb$)uYFv+S<8w2LwxS#(e8|&jcaVr%}|~A?e+ij{$E+0
zmZe|q{vZCHkHq3}o)=Yg5|9kEB+kbq#;$$1O
z*laW#Xi(y|S7YV$w3@R|X@Uq*kMEw!)i9%
z(vbYfV+bFxJi5Sf`F6h@fbgwriT~A)3yC{X7ghWAR38qunJIqXs(dPu=);p7
zK%)nSiAC=73}Ax}^3ALyt#6;|G@mX0a4yrztyX)>5!;2#5$h3D!#50Jq^Wd
zj}+xl5nj&0w|^i;;xY5-b98ffb-{NV@PMutk7smib;f+UNpuqJwHL{@!;)=hZU^@j
zeHB}TnqDE{K;6@zvje(Hba{IKiT|pbraS|?2UXNNgw%XVI
z`GIQc$8ii_!S|xhHDy%Ay>K{Ht=DyQ5zbZTx@`v;M3uIYR$fE&m9tw^AiML
zJP^wbt=2b(GMDi_?!&u}P+3t1h=OWR9g<9Ky{s(zn+qd-MIMg!5LM_}nG>9&EbJCV
zbo
zarLcSZk#*skjY9Y55J&Ba9;Bu4_VwKWkgqEQLI)Q12VVyY#x!!?Q}`1ja(z?CGl1)
zi0;`l5^wCW7Or*tZj9Mkb>^XY^C?R>9nzq1>|R^NL^b=e^zOWyUf4U>7o6xcF|{
zy7CDC1?n?aIphX?OrdXX5CD3xX)SO1t}2%$`4~C-hsQ_z3tm$s%jL;I@nx-jZ@qZc
z-n@Xqon2Nb=Zk}CVm$jLEzTUgkt=i;cW>IKia_ERmPvZyK>Nd7>&l83W~d?wBCBBg
z{Xlikf9Tx%saMf;8T-AcM59A3cKM-sc#)JbT@T6Bvh~LC3J5w&bTx3C%y9S;l)ws)
zj;R|^ghe6|sGGiwMk52E_0`AD^H;swhlmn*RCoE)(vgMc%U9+h*^^w$j+kYP7d2y;
z4ikyfy+R}s#m1mqkT^{(>E0rA{57KECY6iCk98szl>JPi3|^YrUWAO+NW5q#mY0=?Cv~ThO0Cm@p?=6*ZU7F-Gb~
z4t|0|%vs+CVndVxiR~L~Hkm_n@*D!-#Z@MU>43WE$XZq=ROT)uzDQ3jcwTTwgiyH>
zCCBl-7EdOLJl)43<0MhN1CTMOd`oc&Xg}R;H2F{&{SN72Y_gsP!BJ`d{RO6+&**+#
zKG|uCZ+*I9UU9For1>y3{>zEN-X-nSkuqKfXC4o9hz=h~~w?Ufbw*g$R;3<45W?26!Wo@+_)n~FFH$jJ37
zVjEQ{HK-7w?^n@Rpn+%;0Ej+7K&q)WB&}aSQu+Sfa(nThPb%WH5USb2W7)I^W1ik*
zT>#cApwr=6$uE9A4F-Fo`7;`en;*~xq2An_8eDwyDNnk=zMd-D%5*W2nw`w;AW^Tq
zU|p$N4T+Ibgu0Q|741oTeW6#hVy@8`P|&q6-o>LYN{tvXr^vm@?n1p4>$68JSP~zZ
zM5ndoV@xB>dt2txCG)mthh?yboHJDRNWBX>xXkiNKoLGs6pvS7oI1^V8(uYA%oZ{F
zIG%kPU!-}zW6s_2Nj9Ra8_X`j0JmBfH$8vYUXUl`9=zAm{UH479>K78Nx7l@hIQrk
z(e4bDw{d;UqrsRmi0+KQaRRY`XN$FRz1CA)n>!oU73fqhT6et&I!zAu!KWvO7C6xN
zp(?3+y%*{R!>5>wPRZ_b@R?VxQpSrwDX0UE|lu=Qxx
zT$=Sd>!e(fm4?=hFaiUh%hvuOTabwrSpywO@D5EF!_p!uQLb!yk~davMjX&b+9~db
zPp#Sa%yGUpS@NpKXH;?V05T=vAy7e0{+LMZu1j{A63(6X_1Kg^y2wEed-omeud{N=
zuiJoKPRavEbCHNYV!#JEdt}uo4-nDY+t&c-e6ljY4ZvK(9&yV#N%dx0>&_>5+bPr5
z4>!rAXN2{7NMl23qqtc6>3vuk)~=A
zB$S^ae*8u6c#N6x7!Tc6_sDFJ#_u_E&bc!tKdw#?34(Y1hnwHQo4$CR`=xTp(X+-4
zu)qGK>-B$#(!Qu}Yf_P*=G8o}FF;rrEwg4yXn`J&myWqkP9{f#@sWRc=boOVFlNoM
z^>tiDcim4+l@>tf
zw>{W`<0%swK~u}l>Tu+C_UQV$$8sRBQRoV;Pmfv6M8Xf%Lx3^q6vY5#8oU9b|
zuC7zwbKTf8v@FS0EN&H_^0t`j+{Nk-_G({2k
z@eFhrcoU9dJC+g66Ep3mZSs5n^^F#lm*)ke!G2Xr=1Hato96R7mXzh(>oeGr_t3Hk
z8&^Q_rO0ppcno?!8C{b2u&M8sYRo4-fF2t335M4SCwks}ct2X)_ysLhcDKWsgFBr~
zCLg3@TQWC$wN;H6XL%(rC|w@}z3<|aag4I
+备份与恢复
+使用超微浏览器点击下面链接将备份(恢复)下列目录/文件至"%2%":
+ %1%
+
+备份 恢复
+
+设置用户及密码
+
+
diff --git a/searchurl/txt/cmds.txt b/searchurl/txt/cmds.txt
index e69de29..27f9275 100644
--- a/searchurl/txt/cmds.txt
+++ b/searchurl/txt/cmds.txt
@@ -0,0 +1,3 @@
+清空浏览数据::/system/bin/toybox find /data/data/info.torapp.uweb/app_webview ! -name 'Cookies' -type f -delete
+打开剪贴板链接:clip/uweb:/system/bin/toybox grep -m1 -Eo '(http|https)://[^ "'\'']+'
+淘宝比价:clip/uweb:grep -m1 -Eo '(http|https)://[^ "'\'']+'|curl -s "`cat`"|grep -m1 -Eo '(http|https)://[^ ?]+'|grep -Eo '[0-9]+'|echo "http://tool.manmanbuy.com/historyLowest.aspx?url=https://detail.tmall.com/item.htm?id=`cat`"
diff --git a/searchurl/txt/magnet.search b/searchurl/txt/magnet.search
index e69de29..99482e0 100644
--- a/searchurl/txt/magnet.search
+++ b/searchurl/txt/magnet.search
@@ -0,0 +1,22 @@
+磁力搜索:http://www.btmovi.space/
+磁力云搜索:http://www.eclyun.com/
+磁力星:https://www.cilixing.pw/
+skrbt:https://skrbtcili.buzz/
+磁力站:http://cili001.com/
+哔哩搜索:https://biliworld.xyz/
+bt1207:https://bt1207cl.icu/
+磁力蜘蛛:http://www.eclzz.com/
+Acg搜索:http://www.acgsou.com/
+种子搜:https://www.dongxingdi.com/
+燕子bt:https://www.54new.com/
+bthub:https://bthub.xyz/
+磁力天堂:http://www.cltt.me/
+磁力宝:http://www.clb.biz/
+搜bt磁力:http://www.sobt5.pw/
+bt磁力车:http://5i0.fun/6qPP
+种子搜:https://www.zhongzihu.com/
+高清MP4吧:http://www.mp4ba.com
+Bt电影天堂:http://www.btbtdy.me
+高清电影网:http://gaoqing.la
+两个BT:https://www.bttwo.com/
+磁力搜索:http://www.cilil.cn/
diff --git a/searchurl/txt/margintop.css b/searchurl/txt/margintop.css
index e69de29..51e9e77 100644
--- a/searchurl/txt/margintop.css
+++ b/searchurl/txt/margintop.css
@@ -0,0 +1 @@
+body{margin-top:30px !important}
diff --git a/searchurl/txt/night.css b/searchurl/txt/night.css
index e69de29..b53474e 100644
--- a/searchurl/txt/night.css
+++ b/searchurl/txt/night.css
@@ -0,0 +1 @@
+html,img,video{filter:invert(1) hue-rotate(180deg) !important;}body{background:white !important;}html img[src],html input[type=image]{opacity:.9;}
diff --git a/searchurl/txt/rjs.txt b/searchurl/txt/rjs.txt
index e69de29..fade0fd 100644
--- a/searchurl/txt/rjs.txt
+++ b/searchurl/txt/rjs.txt
@@ -0,0 +1,4 @@
+站内搜索:'';window.open('i:15site:' + location.hostname)
+背景图:'';{document.deepCss=function(a,b){if(!a||!a.style)return'';let c=b.replace(/\-([a-z])/g,function(a,b){return b.toUpperCase()});if(a.currentStyle)return a.style[c]||a.currentStyle[c]||'';let d=document.defaultView||window;return a.style[c]||d.getComputedStyle(a,'').getPropertyValue(b)||''};Array.prototype.indexOf=Array.prototype.indexOf||function(a,b){b=b||0;for(let c=this.length;bBackground images