From 78b044e69895c9658636770e45396c60a25b2818 Mon Sep 17 00:00:00 2001 From: hackdapp Date: Wed, 7 Apr 2021 20:16:19 +0800 Subject: [PATCH 1/3] First commit --- placeholder | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 placeholder diff --git a/placeholder b/placeholder new file mode 100644 index 00000000..e69de29b From e59d2b0435eccedd47877ed4964593425420965f Mon Sep 17 00:00:00 2001 From: hackdapp Date: Wed, 28 Apr 2021 23:30:09 +0800 Subject: [PATCH 2/3] Site updated: 2021-04-28 23:30:09 --- placeholder => CNAME | 0 about/index.html | 0 archives/2019/01/index.html | 0 archives/2019/02/index.html | 0 archives/2019/03/index.html | 0 archives/2019/04/index.html | 0 archives/2019/index.html | 0 archives/2019/page/2/index.html | 0 archives/2019metalife.html | 0 archives/2021-02-27T16:00:00.000Z.html | 0 archives/2021/02/index.html | 0 archives/2021/04/index.html | 0 archives/2021/index.html | 0 .../Sun Feb 28 2021 00:00:00 GMT+0800 (China Standard Time).html | 0 archives/eosdev_contract_abi.html | 0 archives/eosdev_cplus_basic.html | 0 archives/eosdev_cplus_intro.html | 0 archives/eosdev_datastorage_historyaction.html | 0 archives/eosdev_deploycontract_eosjs.html | 0 archives/how-to-improve-return-risk-ratio.html | 0 archives/how_to_write_ad_fast.html | 0 archives/index.html | 0 archives/page/2/index.html | 0 archives/rebuildbrain_habit.html | 0 archives/simple_cpllus_code.html | 0 archives/think_habit.html | 0 archives/tron_boilerplate.html | 0 archives/try_eoscontract_dev.html | 0 atom.xml | 0 baidu_verify_3oa53OCFMq.html | 0 baidusitemap.xml | 0 .../index.html" | 0 categories/Write/index.html | 0 .../index.html" | 0 .../\346\200\235\347\273\264\350\256\244\347\237\245/index.html" | 0 "categories/\346\212\225\350\265\204/index.html" | 0 .../index.html" | 0 "categories/\350\256\244\347\237\245/index.html" | 0 css/default.css | 0 css/donate.css | 0 css/gitalk.css | 0 css/my-gitalk.css | 0 css/style.css | 0 donate/index.html | 0 edusmart/index.html | 0 favicon.ico | 0 google1031035202c817c5.html | 0 grownth/index.html | 0 history/index.html | 0 img/AliPayQR.png | 0 img/BTCQR.png | 0 img/WeChatQR.png | 0 img/alipay.svg | 0 img/bitcoin.svg | 0 img/github.svg | 0 img/like.svg | 0 img/paypal.svg | 0 img/wechat.svg | 0 index.html | 0 js/codeblock-resizer.js | 0 js/donate.js | 0 js/fancybox.js | 0 js/gitment.browser.js | 0 js/search.js | 0 js/share.js | 0 js/smartresize.js | 0 js/totop.js | 0 page/2/index.html | 0 robots.txt | 0 sitemap.xml | 0 things/index.html | 0 tools/index.html | 0 weekly/index.html | 0 wiki/index.html | 0 74 files changed, 0 insertions(+), 0 deletions(-) rename placeholder => CNAME (100%) create mode 100644 about/index.html create mode 100644 archives/2019/01/index.html create mode 100644 archives/2019/02/index.html create mode 100644 archives/2019/03/index.html create mode 100644 archives/2019/04/index.html create mode 100644 archives/2019/index.html create mode 100644 archives/2019/page/2/index.html create mode 100644 archives/2019metalife.html create mode 100644 archives/2021-02-27T16:00:00.000Z.html create mode 100644 archives/2021/02/index.html create mode 100644 archives/2021/04/index.html create mode 100644 archives/2021/index.html create mode 100644 archives/Sun Feb 28 2021 00:00:00 GMT+0800 (China Standard Time).html create mode 100644 archives/eosdev_contract_abi.html create mode 100644 archives/eosdev_cplus_basic.html create mode 100644 archives/eosdev_cplus_intro.html create mode 100644 archives/eosdev_datastorage_historyaction.html create mode 100644 archives/eosdev_deploycontract_eosjs.html create mode 100644 archives/how-to-improve-return-risk-ratio.html create mode 100644 archives/how_to_write_ad_fast.html create mode 100644 archives/index.html create mode 100644 archives/page/2/index.html create mode 100644 archives/rebuildbrain_habit.html create mode 100644 archives/simple_cpllus_code.html create mode 100644 archives/think_habit.html create mode 100644 archives/tron_boilerplate.html create mode 100644 archives/try_eoscontract_dev.html create mode 100644 atom.xml create mode 100644 baidu_verify_3oa53OCFMq.html create mode 100644 baidusitemap.xml create mode 100644 "categories/EOS\345\256\214\345\205\250\345\274\200\345\217\221\346\214\207\345\215\227/index.html" create mode 100644 categories/Write/index.html create mode 100644 "categories/\345\214\272\345\235\227\351\223\276\346\212\200\346\234\257/index.html" create mode 100644 "categories/\346\200\235\347\273\264\350\256\244\347\237\245/index.html" create mode 100644 "categories/\346\212\225\350\265\204/index.html" create mode 100644 "categories/\346\226\260\345\271\264\350\256\241\345\210\222-2019/index.html" create mode 100644 "categories/\350\256\244\347\237\245/index.html" create mode 100644 css/default.css create mode 100644 css/donate.css create mode 100644 css/gitalk.css create mode 100644 css/my-gitalk.css create mode 100644 css/style.css create mode 100644 donate/index.html create mode 100644 edusmart/index.html create mode 100644 favicon.ico create mode 100644 google1031035202c817c5.html create mode 100644 grownth/index.html create mode 100644 history/index.html create mode 100644 img/AliPayQR.png create mode 100644 img/BTCQR.png create mode 100644 img/WeChatQR.png create mode 100644 img/alipay.svg create mode 100644 img/bitcoin.svg create mode 100644 img/github.svg create mode 100644 img/like.svg create mode 100644 img/paypal.svg create mode 100644 img/wechat.svg create mode 100644 index.html create mode 100644 js/codeblock-resizer.js create mode 100644 js/donate.js create mode 100644 js/fancybox.js create mode 100644 js/gitment.browser.js create mode 100644 js/search.js create mode 100644 js/share.js create mode 100644 js/smartresize.js create mode 100644 js/totop.js create mode 100644 page/2/index.html create mode 100644 robots.txt create mode 100644 sitemap.xml create mode 100644 things/index.html create mode 100644 tools/index.html create mode 100644 weekly/index.html create mode 100644 wiki/index.html diff --git a/placeholder b/CNAME similarity index 100% rename from placeholder rename to CNAME diff --git a/about/index.html b/about/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2019/01/index.html b/archives/2019/01/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2019/02/index.html b/archives/2019/02/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2019/03/index.html b/archives/2019/03/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2019/04/index.html b/archives/2019/04/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2019/index.html b/archives/2019/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2019/page/2/index.html b/archives/2019/page/2/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2019metalife.html b/archives/2019metalife.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2021-02-27T16:00:00.000Z.html b/archives/2021-02-27T16:00:00.000Z.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2021/02/index.html b/archives/2021/02/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2021/04/index.html b/archives/2021/04/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/2021/index.html b/archives/2021/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/Sun Feb 28 2021 00:00:00 GMT+0800 (China Standard Time).html b/archives/Sun Feb 28 2021 00:00:00 GMT+0800 (China Standard Time).html new file mode 100644 index 00000000..e69de29b diff --git a/archives/eosdev_contract_abi.html b/archives/eosdev_contract_abi.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/eosdev_cplus_basic.html b/archives/eosdev_cplus_basic.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/eosdev_cplus_intro.html b/archives/eosdev_cplus_intro.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/eosdev_datastorage_historyaction.html b/archives/eosdev_datastorage_historyaction.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/eosdev_deploycontract_eosjs.html b/archives/eosdev_deploycontract_eosjs.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/how-to-improve-return-risk-ratio.html b/archives/how-to-improve-return-risk-ratio.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/how_to_write_ad_fast.html b/archives/how_to_write_ad_fast.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/index.html b/archives/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/page/2/index.html b/archives/page/2/index.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/rebuildbrain_habit.html b/archives/rebuildbrain_habit.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/simple_cpllus_code.html b/archives/simple_cpllus_code.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/think_habit.html b/archives/think_habit.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/tron_boilerplate.html b/archives/tron_boilerplate.html new file mode 100644 index 00000000..e69de29b diff --git a/archives/try_eoscontract_dev.html b/archives/try_eoscontract_dev.html new file mode 100644 index 00000000..e69de29b diff --git a/atom.xml b/atom.xml new file mode 100644 index 00000000..e69de29b diff --git a/baidu_verify_3oa53OCFMq.html b/baidu_verify_3oa53OCFMq.html new file mode 100644 index 00000000..e69de29b diff --git a/baidusitemap.xml b/baidusitemap.xml new file mode 100644 index 00000000..e69de29b diff --git "a/categories/EOS\345\256\214\345\205\250\345\274\200\345\217\221\346\214\207\345\215\227/index.html" "b/categories/EOS\345\256\214\345\205\250\345\274\200\345\217\221\346\214\207\345\215\227/index.html" new file mode 100644 index 00000000..e69de29b diff --git a/categories/Write/index.html b/categories/Write/index.html new file mode 100644 index 00000000..e69de29b diff --git "a/categories/\345\214\272\345\235\227\351\223\276\346\212\200\346\234\257/index.html" "b/categories/\345\214\272\345\235\227\351\223\276\346\212\200\346\234\257/index.html" new file mode 100644 index 00000000..e69de29b diff --git "a/categories/\346\200\235\347\273\264\350\256\244\347\237\245/index.html" "b/categories/\346\200\235\347\273\264\350\256\244\347\237\245/index.html" new file mode 100644 index 00000000..e69de29b diff --git "a/categories/\346\212\225\350\265\204/index.html" "b/categories/\346\212\225\350\265\204/index.html" new file mode 100644 index 00000000..e69de29b diff --git "a/categories/\346\226\260\345\271\264\350\256\241\345\210\222-2019/index.html" "b/categories/\346\226\260\345\271\264\350\256\241\345\210\222-2019/index.html" new file mode 100644 index 00000000..e69de29b diff --git "a/categories/\350\256\244\347\237\245/index.html" "b/categories/\350\256\244\347\237\245/index.html" new file mode 100644 index 00000000..e69de29b diff --git a/css/default.css b/css/default.css new file mode 100644 index 00000000..e69de29b diff --git a/css/donate.css b/css/donate.css new file mode 100644 index 00000000..e69de29b diff --git a/css/gitalk.css b/css/gitalk.css new file mode 100644 index 00000000..e69de29b diff --git a/css/my-gitalk.css b/css/my-gitalk.css new file mode 100644 index 00000000..e69de29b diff --git a/css/style.css b/css/style.css new file mode 100644 index 00000000..e69de29b diff --git a/donate/index.html b/donate/index.html new file mode 100644 index 00000000..e69de29b diff --git a/edusmart/index.html b/edusmart/index.html new file mode 100644 index 00000000..e69de29b diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 00000000..e69de29b diff --git a/google1031035202c817c5.html b/google1031035202c817c5.html new file mode 100644 index 00000000..e69de29b diff --git a/grownth/index.html b/grownth/index.html new file mode 100644 index 00000000..e69de29b diff --git a/history/index.html b/history/index.html new file mode 100644 index 00000000..e69de29b diff --git a/img/AliPayQR.png b/img/AliPayQR.png new file mode 100644 index 00000000..e69de29b diff --git a/img/BTCQR.png b/img/BTCQR.png new file mode 100644 index 00000000..e69de29b diff --git a/img/WeChatQR.png b/img/WeChatQR.png new file mode 100644 index 00000000..e69de29b diff --git a/img/alipay.svg b/img/alipay.svg new file mode 100644 index 00000000..e69de29b diff --git a/img/bitcoin.svg b/img/bitcoin.svg new file mode 100644 index 00000000..e69de29b diff --git a/img/github.svg b/img/github.svg new file mode 100644 index 00000000..e69de29b diff --git a/img/like.svg b/img/like.svg new file mode 100644 index 00000000..e69de29b diff --git a/img/paypal.svg b/img/paypal.svg new file mode 100644 index 00000000..e69de29b diff --git a/img/wechat.svg b/img/wechat.svg new file mode 100644 index 00000000..e69de29b diff --git a/index.html b/index.html new file mode 100644 index 00000000..e69de29b diff --git a/js/codeblock-resizer.js b/js/codeblock-resizer.js new file mode 100644 index 00000000..e69de29b diff --git a/js/donate.js b/js/donate.js new file mode 100644 index 00000000..e69de29b diff --git a/js/fancybox.js b/js/fancybox.js new file mode 100644 index 00000000..e69de29b diff --git a/js/gitment.browser.js b/js/gitment.browser.js new file mode 100644 index 00000000..e69de29b diff --git a/js/search.js b/js/search.js new file mode 100644 index 00000000..e69de29b diff --git a/js/share.js b/js/share.js new file mode 100644 index 00000000..e69de29b diff --git a/js/smartresize.js b/js/smartresize.js new file mode 100644 index 00000000..e69de29b diff --git a/js/totop.js b/js/totop.js new file mode 100644 index 00000000..e69de29b diff --git a/page/2/index.html b/page/2/index.html new file mode 100644 index 00000000..e69de29b diff --git a/robots.txt b/robots.txt new file mode 100644 index 00000000..e69de29b diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..e69de29b diff --git a/things/index.html b/things/index.html new file mode 100644 index 00000000..e69de29b diff --git a/tools/index.html b/tools/index.html new file mode 100644 index 00000000..e69de29b diff --git a/weekly/index.html b/weekly/index.html new file mode 100644 index 00000000..e69de29b diff --git a/wiki/index.html b/wiki/index.html new file mode 100644 index 00000000..e69de29b From c2c0534dd691f384af1dd08fc7850f2d09275587 Mon Sep 17 00:00:00 2001 From: hackdapp Date: Tue, 29 Jun 2021 21:22:55 +0800 Subject: [PATCH 3/3] Site updated: 2021-06-29 21:22:55 --- CNAME | 1 + about/index.html | 55 + archives/2019/01/index.html | 13 + archives/2019/02/index.html | 13 + archives/2019/03/index.html | 13 + archives/2019/04/index.html | 13 + archives/2019/index.html | 13 + archives/2019/page/2/index.html | 13 + archives/2019metalife.html | 30 + archives/2021/02/index.html | 13 + archives/2021/04/index.html | 13 + archives/2021/06/index.html | 13 + archives/2021/index.html | 13 + ...\347\232\204\350\203\275\345\212\233.html" | 33 + ...:00:00 GMT+0800 (China Standard Time).html | 31 + archives/eosdev_contract_abi.html | 101 + archives/eosdev_cplus_basic.html | 50 + archives/eosdev_cplus_intro.html | 45 + .../eosdev_datastorage_historyaction.html | 58 + archives/eosdev_deploycontract_eosjs.html | 56 + archives/how-to-impl-nft-proj.html | 52 + .../how-to-improve-return-risk-ratio.html | 28 + archives/how-to-make-goodnotes.html | 24 + archives/how_to_write_ad_fast.html | 44 + archives/index.html | 13 + archives/page/2/index.html | 13 + archives/page/3/index.html | 13 + archives/rebuildbrain_habit.html | 47 + archives/simple_cpllus_code.html | 64 + archives/think_habit.html | 45 + archives/tron_boilerplate.html | 90 + archives/try_eoscontract_dev.html | 130 + atom.xml | 464 ++ baidu_verify_3oa53OCFMq.html | 23 + baidusitemap.xml | 71 + .../index.html" | 13 + categories/Write/index.html | 13 + .../index.html" | 13 + .../index.html" | 13 + .../index.html" | 13 + .../index.html" | 13 + .../\346\212\225\350\265\204/index.html" | 13 + .../index.html" | 13 + .../index.html" | 13 + .../\350\256\244\347\237\245/index.html" | 13 + css/default.css | 1146 +++++ css/donate.css | 273 ++ css/gitalk.css | 1207 ++++++ css/my-gitalk.css | 249 ++ css/style.css | 1465 +++++++ donate/index.html | 28 + edusmart/index.html | 138 + favicon.ico | Bin 0 -> 140513 bytes google1031035202c817c5.html | 1 + grownth/index.html | 34 + history/index.html | 27 + img/AliPayQR.png | Bin 0 -> 28743 bytes img/BTCQR.png | Bin 0 -> 20129 bytes img/WeChatQR.png | Bin 0 -> 29107 bytes img/alipay.svg | 46 + img/bitcoin.svg | 135 + img/github.svg | 1 + img/like.svg | 1 + img/paypal.svg | 63 + img/wechat.svg | 49 + index.html | 18 + js/codeblock-resizer.js | 51 + js/donate.js | 78 + js/fancybox.js | 19 + js/gitment.browser.js | 3751 +++++++++++++++++ js/search.js | 86 + js/share.js | 60 + js/smartresize.js | 32 + js/totop.js | 12 + page/2/index.html | 18 + page/3/index.html | 19 + robots.txt | 15 + sitemap.xml | 193 + things/index.html | 36 + tools/index.html | 24 + weekly/index.html | 26 + wiki/index.html | 22 + 82 files changed, 11164 insertions(+) create mode 100644 archives/2021/06/index.html create mode 100644 "archives/20210428-\345\246\202\344\275\225\346\217\220\351\253\230\351\230\262\347\214\235\346\255\273\347\232\204\350\203\275\345\212\233.html" create mode 100644 archives/how-to-impl-nft-proj.html create mode 100644 archives/how-to-make-goodnotes.html create mode 100644 archives/page/3/index.html create mode 100644 "categories/\344\273\245\345\244\252\345\235\212\350\257\276\347\250\213/index.html" create mode 100644 "categories/\345\277\203\350\204\217\345\214\273\345\255\246\350\257\276/index.html" create mode 100644 "categories/\347\237\245\350\257\206\345\215\241\347\211\207/index.html" create mode 100644 page/3/index.html diff --git a/CNAME b/CNAME index e69de29b..01c33d0e 100644 --- a/CNAME +++ b/CNAME @@ -0,0 +1 @@ +www.hackdapp.com \ No newline at end of file diff --git a/about/index.html b/about/index.html index e69de29b..5ead6d70 100644 --- a/about/index.html +++ b/about/index.html @@ -0,0 +1,55 @@ +关于我 | HackDApp

关于我

name: zhangliang
wechat: rushking2009
github: http://github.com/hackdapp
公众号: hackdapp
欢迎关注公众号

+
+

Grownth Time Line

近期要做的事

    +
  • 主题视频搬运
  • +
  • 题新闻翻译
  • +
  • 打造工具矩阵
  • +
+

相关资料收集

+
\ No newline at end of file diff --git a/archives/2019/01/index.html b/archives/2019/01/index.html index e69de29b..7f8792ba 100644 --- a/archives/2019/01/index.html +++ b/archives/2019/01/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git a/archives/2019/02/index.html b/archives/2019/02/index.html index e69de29b..b0e3cd39 100644 --- a/archives/2019/02/index.html +++ b/archives/2019/02/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git a/archives/2019/03/index.html b/archives/2019/03/index.html index e69de29b..dfe70a99 100644 --- a/archives/2019/03/index.html +++ b/archives/2019/03/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git a/archives/2019/04/index.html b/archives/2019/04/index.html index e69de29b..5c288765 100644 --- a/archives/2019/04/index.html +++ b/archives/2019/04/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git a/archives/2019/index.html b/archives/2019/index.html index e69de29b..462d76e7 100644 --- a/archives/2019/index.html +++ b/archives/2019/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp
\ No newline at end of file diff --git a/archives/2019/page/2/index.html b/archives/2019/page/2/index.html index e69de29b..7e31a457 100644 --- a/archives/2019/page/2/index.html +++ b/archives/2019/page/2/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git a/archives/2019metalife.html b/archives/2019metalife.html index e69de29b..3e81f577 100644 --- a/archives/2019metalife.html +++ b/archives/2019metalife.html @@ -0,0 +1,30 @@ +2019MetaLife | HackDApp

2019MetaLife

新年愿意清单

+
    +
  • 尝试每天500字,锻炼文字组织能力
  • +
  • 做一款自己的小众产品,用户达到100人
  • +
  • 尝试录制短视频
  • +
  • 出版一本书籍
  • +
+
波场Tron-可快捷开发的实战工程模板
\ No newline at end of file diff --git a/archives/2021/02/index.html b/archives/2021/02/index.html index e69de29b..577fae08 100644 --- a/archives/2021/02/index.html +++ b/archives/2021/02/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git a/archives/2021/04/index.html b/archives/2021/04/index.html index e69de29b..9d1bef94 100644 --- a/archives/2021/04/index.html +++ b/archives/2021/04/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git a/archives/2021/06/index.html b/archives/2021/06/index.html new file mode 100644 index 00000000..552a1c3d --- /dev/null +++ b/archives/2021/06/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git a/archives/2021/index.html b/archives/2021/index.html index e69de29b..5acfed44 100644 --- a/archives/2021/index.html +++ b/archives/2021/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git "a/archives/20210428-\345\246\202\344\275\225\346\217\220\351\253\230\351\230\262\347\214\235\346\255\273\347\232\204\350\203\275\345\212\233.html" "b/archives/20210428-\345\246\202\344\275\225\346\217\220\351\253\230\351\230\262\347\214\235\346\255\273\347\232\204\350\203\275\345\212\233.html" new file mode 100644 index 00000000..a4ed04a4 --- /dev/null +++ "b/archives/20210428-\345\246\202\344\275\225\346\217\220\351\253\230\351\230\262\347\214\235\346\255\273\347\232\204\350\203\275\345\212\233.html" @@ -0,0 +1,33 @@ +如何提高防猝死的能力 | HackDApp

如何提高防猝死的能力

猝死就是平时身体健康、或貌似健康的患者,在出乎意料的短时间内,因自然疾病而突然死亡.

+

猝死,如此可怕,是哪些原因导致的呢?
85%是心血管问题,这其中,又有80%是给心脏供血的冠状动脉突发缺血了。

+

那么,猝死我们可以预防或控制吗?
好消息是,绝大部分情况可以,前提是你要有足够的心脏储备。而储备,是心血管健康里最容易被忽视的一个维度。所谓心力储备,就是心脏因身体的需要而增加射血的能力。所以,大部分情况下,猝死是由于心力储备坍塌导致的。

+

逻辑上有三种策略可以进行预防:

+
    +
  1. 避免最后一根稻草策略。能引发猝死的事情,我们不要去做。比如: 大量喝酒或咖、心情抑郁、暴饮暴食等等。要注重先兆,要比发现最后一稻草更有效;
  2. +
  3. 关注身体信号策略。我们要注意引发猝死的先兆,也就是去注意储备透支的信号。
  4. +
  5. 拓展储备策略。这也是最重要的一种策略。既然储备是一种潜能,那我们就要努力去拓展它
  6. +
+

原文链接: https://www.dedao.cn/article/w06eGYrQb1gzVxBryXPl73kZRqOaB8

+
如何做好课堂笔记
\ No newline at end of file diff --git a/archives/Sun Feb 28 2021 00:00:00 GMT+0800 (China Standard Time).html b/archives/Sun Feb 28 2021 00:00:00 GMT+0800 (China Standard Time).html index e69de29b..34864016 100644 --- a/archives/Sun Feb 28 2021 00:00:00 GMT+0800 (China Standard Time).html +++ b/archives/Sun Feb 28 2021 00:00:00 GMT+0800 (China Standard Time).html @@ -0,0 +1,31 @@ +交易者应掌握的能力 | HackDApp

交易者应掌握的能力

无论是在股市或是币市,我们都希望通过自己的一顿神操作,买到那些可以让自己瞬间反几倍甚至几十倍的股票或数字货币,但现实情况
会告诉你,即使是牛市你也能亏钱亏的要死。

+

为什么呢?这就不得不想想其中你想赚钱的行为,是一种投机还是投资?

+

投机呢,完全可能就是全凭着几个火热大群的fomo情绪,亦或是好巧不巧的几个自己认为重要的小道消息,就认为自己拿到了人生财富密码,知道自己输的底朝天;而投资往往是通过自己对标的物,花精力与时间去研究思考,挖机出它的长期价值,尤其是那些被低估的标的,即使是自己决策失误,也会总结教训,从错误中反思,改进自己的投资方法论,不错失提升自己大脑🧠成长的机会。

+

韭菜之所以是韭菜,就因为再每一次决策失误的时候不去学习反思,丧失了每一次成长的机会,慢慢就变成了一根老韭菜。

+

所以,在赚钱这条路上,我们慢慢培养总结自己的投资方法论,并在实践过程中不断反思复盘完善自己的投资逻辑。

+
+

思考带来决策,决策带来行动,行动改变命运,,行动改变命运!

+
+
如何用61分钟写出漂亮的推广文案
\ No newline at end of file diff --git a/archives/eosdev_contract_abi.html b/archives/eosdev_contract_abi.html index e69de29b..e6ba4b62 100644 --- a/archives/eosdev_contract_abi.html +++ b/archives/eosdev_contract_abi.html @@ -0,0 +1,101 @@ +剖析EOS合约编译ABI文件 | HackDApp

剖析EOS合约编译ABI文件

相信不少开发者朋友在进行EOS合约开发时,都看到发布智能合约时的ABI文件。那ABI文件到底是什么东西?在EOS公链环境中到底发挥怎么样的作用呢以及如何解读ABI文件内容呢?

+

那么本章节将带你了解ABI文件与智能合约间的关系以及了解并学会ABI文件的编写。

+

ABI, 简称(Application Binary Interface), 是一个基于JSON语言的接口描述文档,用于描述EOS合约以及如何对合约方法进行调用。如果大家曾经接触过websocket、avro、hession、thrift等这类技术的化,那么是大体逻辑是相向的。比如websocket所提供的wsdl其实也是对websocket本身对外所提供服务的接口描述。

+

在EOS合约,ABI文件是由开发组件eosio.cdt工具包中的eosio-cpp命令执行所生成的文件。但在实际开发时,时常会碰到一些情况无法生成ABI文件。因为在合约开发,我们往往会根据业务自定义一些数据结构,或者使用一些第三方方法,而eosio.cdt本身对所有特隆并不是支持的很完善,所以时常导致编译失败,这时就需要我们理解ABI是如何定义智能合约的,以便于我们定制化修改自己的合约描述。

+

ABI文件结构是由什么组成的呢?让我们先看一个示例

+
{
"version": "eosio::abi/1.0",
"types": [],
"structs": [],
"actions": [],
"tables": [],
"ricardian_clauses": [],
"abi_extensions": [],
"___comment" : ""
}
+

上面json示例展示了一个标准智能合约所应具备的完整属性定义。

+

数据类型(type)
在项目开发过程,有时为了便于代码的理解,我们会将一些通用数据类型或数据结构进行别名定义,用一个在业务场景中更加贴合业务的名称代替。在types数组中便是对这种情况的定义描述。

+

比如:

{
"new_type_name": "age",
"type": "int"
}

或者

{
"new_type_name": "name",
"type": "string" //此处user为自定义数据结构
}

+

对于合约内嵌类型,是不会在此展示的。诸如: uint64_t、name、asset、symbol等。下图展示了EOS合约所支持的所有内置数据类型

+
+

结构体(struct)
在业务处理逻辑中,为了方便数据的传输与调用,往往我们会对针对业务数据进行建模并以结构体的形式展现。同样,它也需要在ABI文件中进行描述。

+

比如: eosio.token合约中的account结构体定义

+
    +
  • ABI文件定义

    +
    {
    "name": "account",
    "base": "",
    "fields": [
    {
    "name": "balance",
    "type": "asset"
    }
    ]
    }
    +
  • +
  • eosio.token.hpp实现

    +
    struct account {
    asset balance;

    uint64_t primary_key()const {
    return balance.symbol.code().raw();
    }
    };
    +
  • +
+

另外,需要注意的就是除了以上这种结构体定义,其实还存在一种隐性结构体,即:合约方法参数
示例:

+
    +
  • eosio.token.hpp中transfer方法定义

    +
    void transfer( name    from,
    name to,
    asset quantity,
    string memo );
    +
  • +
  • eosin.token合约中transfer方法在ABI文件中定义

    +
    {
    "name": "transfer",
    "base": "",
    "fields": [
    {
    "name": "from",
    "type": "name"
    },
    {
    "name": "to",
    "type": "name"
    },
    {
    "name": "quantity",
    "type": "asset"
    },
    {
    "name": "memo",
    "type": "string"
    }
    ]
    }
    +
  • +
+

可以看出,隐性结构体与前面所定义显性结构体定义是并没有什么不同,只是在智能合约业务逻辑中,我们仅用到显性结构体来存储我们的业务数据进行逻辑判断。

+
+

方法(Action)
Action数组主要用于描述外部可调用的方法列表以及具体的参数列表。在智能合约中,如果需要对外公开合约方法,往往会在合约头文件中进行如下定义:

[[eosio::action]]
void transfer(name from,name to, asset quantity, string memo);

+

而ABI的表现形式为:

{
"name": "transfer",
"type": "transfer",
"ricardian_contract": ""
}

+

从上述描述可以看出,在方法的类型定义关联了前面的隐性结构体类型。虽然在此处,方法名与隐性结构体类型命名一致,但实际情况并不一定非要相同。

+
+

表定义(Table)
关于表的ABI定义,相比其他几种定义要稍复杂一些。具体JSON定义如下

{
"name": "",
"type": "",
"index_type": "",
"key_names" : [],
"key_types" : []
}

+

JSON中字段说明如下:

+
    +
  • name
    合约初始化表时所要使用的名称
  • +
  • type
    表对应的数据结构体。也就是前面所说的显性结构体类型
  • +
  • index _type
    此类型为表主键类型
  • +
  • key _names
    索引字段列表
  • +
  • key_types
    索引字段数据类型列表。数据长度与索引字段列表长度一致。需要说明的是索引字段类型,只支持uint64_t,uint128 _t,uint256 _t,double,long double五种类型
    示例:eosio.token合约中的accounts表
  • +
  • ABI表定义

    +
    {
    "name": "accounts",
    "type": "account",
    "index_type": "i64",
    "key_names": ["primary_key"],
    "key_types": ["uint64"]
    }
    +
  • +
  • 表合约代码

    +
    struct [[eosio::table]] account {
    asset balance;

    uint64_t primary_key()const { return balance.symbol.code().raw(); }
    };
    +
  • +
+

从表合约代码可以看来,只需要在数据结构体代码中添加eosio-table标签就可以完成对表的定义操作。

+

之所以提供多索引的实现,主要还是为了应对业务场景中不同维度的数据查询,而且支持按升序或降序的遍历方式处理业务。

+
+

ricardian条款(ricardian_clauses)
该数组主要用于定义一种基于文本的合约宪法。通过其与智能合约的整合,来解决一些无法通过程序来判定的情况。

+

示例如下:

"ricardian_clauses": [{
"id": "Warranty",
"body": "WARRANTY. The invoker of the contract action shall uphold its Obligations under this Contract in a timely and workmanlike manner, using knowledge and recommendations for performing the services which meet generally acceptable standards set forth by EOS.IO Blockchain Block Producers.\n\n"
},{
"id": "Default",
"body": "DEFAULT. The occurrence of any of the following shall constitute a material default under this Contract: \n\n"
},{
"id": "Remedies",
"body": "REMEDIES. In addition to any and all other rights a party may have available according to law, if a party defaults by failing to substantially perform any provision, term or condition of this Contract, the other party may terminate the Contract by providing written notice to the defaulting party. This notice shall describe with sufficient detail the nature of the default. The party receiving such notice shall promptly be removed from being a Block Producer and this Contract shall be automatically terminated. \n \n"
}
]

+

我们可以针对智能合约或者具体的合约方法,附加上对应的文本合约描述。比如针对方法的文本合约定义:

+
    +
  • ABI定义

    +
    "actions": [{
    "name": "hi",
    "type": "hi",
    "ricardian_contract": "# CONTRACT FOR hello::hi## ACTION NAME: hi\n### Parameters### Parameters\nInput parameters:Input parameters:\n\n* `user` (string to include in the output)* `user` (string to include in the output)\n\nImplied parameters: Implied parameters: \n\n* `account_name` (name of the party invoking and signing the contract)* `account_name` (name of the party invoking and signing the contract)\n\n### Intent### Intent\nINTENT. The intention of the author and the invoker of this contract is to print output. It shall have no other effect.INTENT. The intention of the author and the invoker of this contract is to print output. It shall have no other effect.\n\n### Term### Term\nTERM. This Contract expires at the conclusion of code execution.TERM. This Contract expires at the conclusion of code execution.\n"
    }]
    +
  • +
  • 代码及文件定义(hello.hi_rc.md)

    +
    # CONTRACT FOR hello::hi

    ## ACTION NAME: hi

    ### Parameters
    Input parameters:

    * `user` (string to include in the output)

    Implied parameters:

    * `account_name` (name of the party invoking and signing the contract)

    ### Intent
    INTENT. The intention of the author and the invoker of this contract is to print output. It shall have no other effect.

    ### Term
    TERM. This Contract expires at the conclusion of code execution.
    +
  • +
+
+

ABI Extensions
该功能将允许用户进行自定义区块扩展, 包括对数据的签名、编码等。不过现在该属性暂未被应用支持。

+
+

到此,相信大家对于整个ABI文件的结构应该有了大体的认识与理解。这样大家可以在研究其他智能合约时,可以首先阅读对方的ABI文件,就可以熟悉对方的整体接口框架。

+
+
+

在教程中如出现错误🐛或不易理解的知识点,欢迎加我微信指正!
Name: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

+
+
+

changelog
2019-03-07 zhangliang

+
    +
  • 初次发稿
  • +
+
使用EOS.js发布EOS智能合约
\ No newline at end of file diff --git a/archives/eosdev_cplus_basic.html b/archives/eosdev_cplus_basic.html index e69de29b..3fe28a6c 100644 --- a/archives/eosdev_cplus_basic.html +++ b/archives/eosdev_cplus_basic.html @@ -0,0 +1,50 @@ +C++基础语法(EOS完全开发指南) | HackDApp

C++基础语法(EOS完全开发指南)

Author: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

+
/* filename: myapp.cpp
date: 2019-01-28 3:06 PM
auth: zhangliang<zhangliang@cldy.org> */

#include <iostream> //定义头文件
#include <stdlib.h>

int main()
{
using namespace std; //命令空间, 简化后续变量或方法调用。e.g. std::string 等同于 string

string msg = "hi, my first dapp"; //定义变量

cout << msg <<endl; //打印字符串
}

//tryit: http://tpcg.io/Tulum1
+

以上代码便是C++最简单可运行的最小示例。基本包含了在程序结构中所必须的一些语言特性。

+

根据上述程序结构,我们可以大致将它拆分成五部分内容:

+ +

1. #include <iostream>

头文件定义主要用于引用第三方函数库,通过调用第三方函数可以减少开发代码量,提高开发效率,同时也避免了不必要的重复造轮子。

+

比如:通过引用<cmath>库,可以帮助我们快速使用里面的函数进行一些数学运算。

+

函数列表

+

所以,后续我们需要学会便是如何查阅C++文档库,不断积累与完善对于第三方标准库的方法学习与理解。

+

2. int main()

main函数区别于其它普通函数之处在于: main函数默认被系统定义为应用入口调用方法。除此之外,与其他函数无任何区别。

+
#include <iostream>
#include <stdlib.h>

using namespace std;

string sayHi(string username)
{
return string("hi, ").append(username).append("!");
}

int main()
{
cout << sayHi("www.hackdapp.com") << endl;
}
//tryit: http://tpcg.io/uHUkzy
+

函数定义,其实对于所有编程语言的定义方式大致相同, 都可以表现为以下形式

+
<返回类型|void> 方法名(参数定义1, 参数定义2,参数定义...)
{
//do some stuff
return <返回数据>
}
+

如果你之前已经在使用其他编程语言,那么应该对于C++其实也可以很好的理解它的程序结构。

+

注: 在后续的第二部分,我们会详细介绍函数的多种定义及使用方式,包括形参实参、重载以及虚函数等。

+

3. string message = "hi, my first app"

变量定义,在程序开发过程,往往需要定义一些临时变量,用于存储在数据逻辑处理过程所必须的临时存储。

+

而变量的类型,主要分为字符、整型,长/短整型、单精度、双精度、布尔类型以及字符串。
我们在实际应用场景中,需要明确了解与知道这些基础数据类型的定义及边界范围,比如,无符号整型、单精度。

+

尤其是对数字类型的字段,如果不了解其边界范围,很可能会导致运算溢出等问题,特别是在合约开发过程中,数字溢出很可能导致的便是相当大的经济损失。

+

换个角度讲,合理的使用变量类型,也可能在一定程序中节省资源的浪费。因为在EOS合约中存储数据是需要消耗资源的。

+

另外,对于变量的名称定义,其名称只能是由数字、字母以及下划线组成且不可能以数字开头,而且根据不同平台,对于名称的长度其实也是存在限制的。

+

4. cout << msg <<endl

coutiostream函数库中的一个流数据输出函数,一般用于在程序调用过程向控制台输入一些调试信息;与此对应的是cin, 用于接收输入数据流。

+

不过, 在EOS合约中无法调用此函数。举而代之的是,EOSLIB库自己封装的print函数.

+

5. //单行注解 or /*多行注解*/

在程序开发过程,往往需要通过语言描述某个代码文件所要实现的整体功能或者某个函数的功能、参数及约束说明。这时候就需要用到注解。

+

而注解同样也所有的编程语言中也大致相同,一般分为单行注释与多行注释。

+

单行注释适用于短小的描述某一行运行逻辑;而多行注释多用于描述函数说明以及文件功能说明。

+
+

注: 在教程中如出现不易理解或存在错误的问题🐛,欢迎评论留言!

+
重塑思维:自律 VS 习惯
\ No newline at end of file diff --git a/archives/eosdev_cplus_intro.html b/archives/eosdev_cplus_intro.html index e69de29b..c95a88bd 100644 --- a/archives/eosdev_cplus_intro.html +++ b/archives/eosdev_cplus_intro.html @@ -0,0 +1,45 @@ +C++导读(EOS完全开发指南) | HackDApp

C++导读(EOS完全开发指南)

Contents

Author: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

+

本章节内容主要是带大家了解C++整个编程语言的体系架构,对C++编程语言有个整体的大致的认识与理解。另外,也是帮助大家在开发EOS智能合约之前做一下前期预习,易于对后面EOS合约的快速上手。

+

另外,需要说明的是,因为本身EOS智能合约是在一个沙箱机制中运行,所以它对一些标准函数库的方法进行了一些限制。所以可能导致大家可能在网上找的资料中的方法无法在合约中正常执行。

+ +

另一个角度讲,正是由于这种限制,也是减小了我们的学习范围,这样我们就不需要完全掌握的整个C++的语言体系,便可以开发智能合约。比如:文件操作读取,时间函数,随机数,这些在EOS合约里是都不可用的。 不过,有一个问题就是你无法明确知道哪些功能被禁用了,只能去试。或者官网有说明,可能我没有看到而已。

+

在整个开发过程,你只需要学会使用一些基础语法,简单数据类型、数据结构以及常用的一些工具库。比如:如何处理字符串,如何存储或操作数据结构。

+

除此之外,再掌握一些程序设计技巧,就可以实战开发自己的DApp应用了,而本身程序设计其实是与哪种程序语言不存在直接关系的,只是让你的程序有更好的应对扩展。

+

通过本章节内容你可以学会:

+
    +
  • 对基础数据类型以及它们的数据边界有清晰的认识;
  • +
  • 学会如何使用不同数据结构处理业务场景中的问题;
  • +
  • 学会如何定义自己的函数;
  • +
  • 学会如何面对对象的思维设计自己的合约;
  • +
  • 学会如何通过模板封装形成自己的工具库;
  • +
  • 了解一些常用的标准库文件及常用的函数工具方法;
  • +
  • 学会如何通过手册查找工具函数
  • +
+
+

本章节,将会从以下八个部分进行分类介绍:

+

1.1 C++基础语法
1.2 基础数据类型及变量、常量定义
1.3 结构体及函数定义
1.4 数据结构
1.5 面向对象编程
1.6 高级应用(模板定义)
1.7 标准库及库函数
1.8 资源及经验分享

+
+

注: 在教程中如出现不易理解或存在错误的问题🐛,欢迎评论留言!

+
C++基础语法(EOS完全开发指南)
\ No newline at end of file diff --git a/archives/eosdev_datastorage_historyaction.html b/archives/eosdev_datastorage_historyaction.html index e69de29b..34cecac8 100644 --- a/archives/eosdev_datastorage_historyaction.html +++ b/archives/eosdev_datastorage_historyaction.html @@ -0,0 +1,58 @@ +巧用HistoryApiAction实现对链数据的存储与查询 | HackDApp

巧用HistoryApiAction实现对链数据的存储与查询

在开发EOS DApp智能合约时,我们都知道可以使用multi_index来对合约数据的存储与查询,但合约的存储是需要消耗一定的资源的,而且随着用户的增长往往会导业务数据会越来越大,从而导致合约需要更多的资源来支撑其数据。

+

有时我们可以通过业务设计,让业务数据得到即时清理及资源释放。但大多数情况下,业务数据是不允许清理的,那么针对这种情况是否有其他办法来降低对合约存储资源的消耗呢?

+

那么,今天分享的方案就是:借用EOS链提供的history_api_action插件服务、内部合约Action调用来完成对业务数据的存储与查询。

+

举个🌰️:
在去中心化交易所中,往往搓合成功会产生大量的成交订单,那保存在合约数据库中肯定是不合适的,所以可以在搓合方法中通过调用内部日志方法的形式,通过交易日志来将订单数据写入区块中;然后通过EOS节点提供的查询历史action接口,查询合约日志数据并增量同步到中心化数据库。

+

下面,我们将通过具体的代码示例来帮助大家理解整个过程:

+
+

首先,我们新创建一个合约(dexchange.hpp/dexchange.cpp);

//dexchange.hpp
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>

using namespace eosio;

CONTRACT dexchange : public contract {
public:
using contract::contract;
dexchange(eosio::name receiver, eosio::name code, datastream<const char*> ds):contract(receiver, code, ds) {}

[[eosio::action]]
void executetrade(uint64_t pair_id, uint64_t sell_order_id, uint64_t buy_order_id);

[[eosio::action]]
void log(uint64_t deal_price, uint64_t quantity, uint64_t sell_order_id, uint64_t buy_order_id);

};

EOSIO_DISPATCH(dexchange, (executetrade)(log))

//https://gist.github.com/2b68242019242bdd12f174208e39e7d2

+

然后,定义并实现两个方法:executetrade、log。 executetrade合约方法负责搓合业务,当搓合业务处理完之后调用log方法,通过交易信息将参数调用数据写入区块中;

+
//filename: dexchange.cpp

#include "dexchange.hpp"

void dexchange::executetrade(uint64_t pair_id, uint64_t sell_order_id, uint64_t buy_order_id){
uint64_t deal_price = 1200;
uint64_t quantity = 10000;

action(
permission_level{ _self, "active"_n },
_self, "log"_n,
std::make_tuple(deal_price, pair_id, sell_order_id, buy_order_id)
).send();
}

void dexchange::log(uint64_t deal_price, uint64_t quantity, uint64_t sell_order_id, uint64_t buy_order_id){
require_auth( _self );
}

//https://gist.github.com/ea6ec431a57faee3a2823cfeee406efd
+

从以上示例可以看出,合约log日志方法其实并不需要做任何业务逻辑处理。只需要间接被调用,便可将我们需要的业务数据通过交易的形式记录在区块中,而不会浪费我们的合约存储空间,也不需要担心资源释放的问题。

+

下一步、发布智能合约,并调用一次executetrade合约方法

+
//发布合约至hackdappexch合约帐户
> cleos set contract hackdappexch contracts/ -p hackdappexch@active

//执行合约方法
> cleos push action hackdappexch executetrade '[1,2,3]' -p hackdappexch@active
+

最后,通过EOS链节点提供的RPC服务,进行历史action数据查询,通过数据过滤找到我们的日志方法及参数数据。

+

在确保之前的操作都成功之后,我们使用curl命令查询其对应服务:

+
curl --request POST \
--url https://localhost:8888/v1/history/get_actions \
--header 'content-type: application/x-www-form-urlencoded; charset=UTF-8' \
--data '{"pos":-1,"offset":-10,"account_name":"hackdappexch"}'
+

通过此接口查询出来的数据不仅仅是log合约方法数据,可能还会存在该合约的其他方法事件,需要根据情况再过滤一次数据。

+

+

补充说明

+

如果你在本地曾经搭建过EOS私链的化,那么或许看到过,EOS启动时是可以配置不同插件。而其中有一个插件history_api_plugin,就是用于监听并存储合约方法的调用信息;另外启动链节点时,是可以按规划自由指定所要监听的合约帐户及方法,如: --filter-on hackdappexch::log, 该参数配置表示只监听hackdappexch合约中的log方法。

+
nodeos -e -p eosio -d /mnt/dev/data \
--config-dir /mnt/dev/config \
--http-validate-host=false \
--plugin eosio::producer_plugin \
--plugin eosio::chain_api_plugin \
--plugin eosio::http_plugin \
--plugin eosio::history_api_plugin \
--http-server-address=0.0.0.0:8888 \
--access-control-allow-origin=* \
--contracts-console \
--filter-on hackdappexch:log: \
--max-transaction-time=1000 \
--verbose-http-errors &
+

如以上EOS节点启动命令,就展示了启动一个EOS节点的具体参数配置。其中,--filter-on参数便是指定只监听记录hackdappexch合约的log方法调用数据。

+

所以,当我们要通过链节点RPC服务查询合约方法历史调用数据时,需要先确认提供RPC服务的节点是否开启了history_api_plugin插件,以及自己所要查询的合约是否在其过滤规则之中。

+
+

小结

+

通过本篇文章,我们学会了利用内部合约方法调用 ➕️ 链节点历史Action查询的方式实现业务数据的另一种数据存储与查询方案。

+
+
+

在教程中如出现错误🐛或不易理解的知识点,欢迎加我微信指正!
Name: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

+
+

+
+

changelog

2019-03-13 zhangliang

+
    +
  • 初次发稿
  • +
+
零基础体验EOS入门合约开发
\ No newline at end of file diff --git a/archives/eosdev_deploycontract_eosjs.html b/archives/eosdev_deploycontract_eosjs.html index e69de29b..50d3514a 100644 --- a/archives/eosdev_deploycontract_eosjs.html +++ b/archives/eosdev_deploycontract_eosjs.html @@ -0,0 +1,56 @@ +使用EOS.js发布EOS智能合约 | HackDApp

使用EOS.js发布EOS智能合约

在之前的EOS合约开发文章,你可能学会了如何通过EOS系统命令cleos set contract的方式进行智能合约的发布与升级。

+

但在开发过程中,可能有的同学持续在命令容器与开发IDE间频繁切换,对开发效率有一定程序的影响,那是否有一种更好的方式帮助我们在一个窗口里快速发布合约呢?

+

那么本文将带你了解如何通过EOS.js进行智能合约的发布

+


如上图所示,在进行合约发布时,需要用到eos系统合约中的两个方法:setcode、setabi。而这两个方法分别会用到智能合约编译后的两个文件: *.wasm、*.abi。

+

注意 : 本文示例中使用的eosjs的版本为16.0.9

+

首先,需要初始化EOS-SDK实例。 事先准备好初始化SDK所必需的参数:

+
    +
  • chainid
    所要发布的目标EOS链chainid. 例如:正式chainid: aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906; jungle测试网chainid: e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473等等
  • +
  • httpEndpoint
    EOS链环境http接口地址。 例如: http://localhost:8888
  • +
  • keyProvider
    合约帐户私钥,主要用于交易签名。
  • +
+
//config.js
const Eos = require('eosjs')

const eos = Eos({
chainId: "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f",
httpEndpoint: "http://localhost:8888",
keyProvider: "5K7mtrinTFrVTduSxizUc5hjXJEtTjVTsqSHeBHes1Viep86FP5",
broadcast: true,
sign: true
})

module.exports = {
eos,
}

//https://gist.github.com/hackdapp/2522411b98b1acdadc0d842f712ca6e0
+

下一步,需要代码实现对合约文件夹中的.wasm及.abi文件的读取;

+
function getDeployableFilesFromDir(dir) {
const dirCont = fs.readdirSync(dir)
const wasmFileName = dirCont.find(filePath => filePath.match(/.*\.(wasm)$/gi))
const abiFileName = dirCont.find(filePath => filePath.match(/.*\.(abi)$/gi))
if (!wasmFileName) throw new Error(`Cannot find a ".wasm file" in ${dir}`)
if (!abiFileName) throw new Error(`Cannot find an ".abi file" in ${dir}`)
return {
wasmPath: path.join(dir, wasmFileName),
abiPath: path.join(dir, abiFileName),
}
}

//https://gist.github.com/69b29103e5cc114f4478390076d8ad39
+

然后,通过调用eos实例,分别执行系统合约的setcode/setabi方法,从而达到智能合约的发布;

+
function deployContract({ account, contractDir }) {
const { wasmPath, abiPath } = getDeployableFilesFromDir(contractDir)

const wasm = fs.readFileSync(wasmPath)
const abi = fs.readFileSync(abiPath)

const codePromise = eos.setcode(account, 0, 0, wasm)
const abiPromise = eos.setabi(account, JSON.parse(abi))
return Promise.all([codePromise, abiPromise])
}

//https://gist.github.com/69b29103e5cc114f4478390076d8ad39
+

最后,调用deployContract方法,测试合约发布功能。

+
deployContract({ account: "eosio.token", contractDir: "./contract" }).then((result) => {
console.log(`Deployment successful`, JSON.stringify(result, null , 4))
})
.catch(err => {
console.error(`Deployment failed`, err)
})

//https://gist.github.com/69b29103e5cc114f4478390076d8ad39
+
+

小结

+

通过本文我们学习了如何通过eos实例的setcode/setabi方法将合约编译文件快速发布到指定链环境。

+

另外,如果为了提高发布合约效率,我们还可以在package.json中定义发布合约的运行脚本,并配合IDE工具中的快捷键,便可达到开发效率的进一步提升。

+
+
+

在教程中如出现错误🐛或不易理解的知识点,欢迎加我微信指正!
Name: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

+
+

+

注: 有想了解愿码全思维IT工程师加速器的朋友,可以扫码加群咨询。

+
+

changelog

2019-03-12 zhangliang

+
    +
  • 初次发稿
  • +
+
巧用HistoryApiAction实现对链数据的存储与查询
\ No newline at end of file diff --git a/archives/how-to-impl-nft-proj.html b/archives/how-to-impl-nft-proj.html new file mode 100644 index 00000000..31a21c8d --- /dev/null +++ b/archives/how-to-impl-nft-proj.html @@ -0,0 +1,52 @@ +基于以太坊的NFT开发实践 | HackDApp

基于以太坊的NFT开发实践

课程大纲

第一部分、项目总览

    +
  • 项目产品介绍
  • +
  • 代码工程介绍
  • +
  • 技术架构讲解
  • +
  • 基础概念讲解(ERC20、ERC1155、ERC721)
  • +
+

第二部分、产品架构及功能设计

    +
  • 产品架构图
  • +
  • 业务流程图
  • +
  • 技术架构图
  • +
+

第三部分、产品开发及用例测试

1)智能合约开发

    +
  • 基础环境配置
  • +
  • 搭建本地链环境
  • +
  • 开发工程构建
  • +
  • 合约设计
  • +
  • 合约测试
  • +
+

2)IPFS部署与集成

3)前端页面开发

第四部分、产品部署

    +
  • 发布静态工程至github仓库gh-page,并配置公网域名
  • +
  • 发布智能合约至测试网
  • +
+

第五部分、线上演示及功能验证

    +
  • 安装MetaMask
  • +
  • 发布NFT
  • +
  • 交易NFT
  • +
  • 转帐NFT
  • +
  • ……
  • +
+
\ No newline at end of file diff --git a/archives/how-to-improve-return-risk-ratio.html b/archives/how-to-improve-return-risk-ratio.html index e69de29b..e00801c8 100644 --- a/archives/how-to-improve-return-risk-ratio.html +++ b/archives/how-to-improve-return-risk-ratio.html @@ -0,0 +1,28 @@ +如何提高收益风险比 | HackDApp

如何提高收益风险比

什么是收益风险比呢? 字面意思不难理解,就是: 收益风险比 = 可能的收益 / 未知的风险。

+

为什么需要认识并提升自己的收益风险比呢? 因为像我这样打工人,除了工资之外,就没有其他收入了,如果被辞职或家里出些什么事,无论是家庭生活质量还是自己的心理焦虑,都会受到极大的生存压力。而投资作为被动收入的一种手段,就可以提升我们在工作单一收入上的安全度,而提升收益风险比,就是在这一基础上能够获得更大的回报。

+

那么如何提高收益风险比呢?很简单:
一、提高分子值,即:让自己的可能收益的概率更高。那么如何做到呢?比如:筛选优质投资标的;选择合适的投资时机;长线持有,防止频繁操作,被甩下车的可能;
二、降低分母值,即:降低投资对自己生活的风险影响程度。如何做呢?比如:设置止损线,尽量让损失控制在自己可以接受的心理价位;按自己的风险承受能力,设置投资金额占总资产的百分比;增加场外赚钱能力,充沛的现金流在一定程序上可以降低自己的投资焦虑。

+

通过合理的收益风险比的控制,可以让我们在整个投资过程中,除了降低一些心理焦虑压力,还能获取更高的投资回报,并最终提升我们的家庭生活质量以及风险承受能力。

+

2021年,希望自己在数字货币投资领域,能够有个好的收获!

+
交易者应掌握的能力
\ No newline at end of file diff --git a/archives/how-to-make-goodnotes.html b/archives/how-to-make-goodnotes.html new file mode 100644 index 00000000..3bdd9a13 --- /dev/null +++ b/archives/how-to-make-goodnotes.html @@ -0,0 +1,24 @@ +如何做好课堂笔记 | HackDApp

如何做好课堂笔记

+
基于以太坊的NFT开发实践
\ No newline at end of file diff --git a/archives/how_to_write_ad_fast.html b/archives/how_to_write_ad_fast.html index e69de29b..6336b567 100644 --- a/archives/how_to_write_ad_fast.html +++ b/archives/how_to_write_ad_fast.html @@ -0,0 +1,44 @@ +如何用61分钟写出漂亮的推广文案 | HackDApp

如何用61分钟写出漂亮的推广文案

最近,接触了不少通过推荐产品的联盟推广平台,只要你能通过自己的语言或文字,说服别人通过你的链接购买对应商品,那么你就能从中抽取一定的佣金。比如:将京东或淘宝联盟里的产品,通过知乎、蜜源、小红书等平台进行文案宣传。

+

在推广过程,你会很快发现,如何能够更好的说报用户,就往往就要考虑一个人的文案能力,当然不仅仅是文字功度,更重要的是你更懂得将适当的产品推送给最需要的人。这其中,就需要你多思考,如何挖掘产品卖点,如何通过数据了解客户需要什么等等。

+

对于一些专门写广告文案的高手来讲,往往都有一套自己的写作套路或者方法论,以提高自己的产出效率及效果。最终考验你的不是你写了多少字,而是到底转化多少用户进行付费。

+

今天,也是机缘巧合,刷推的时候发现一篇推文觉得写得挺不错的,所以也翻译过来与大家共同学习成长。

+

推主的整个写作框架,共拆分成11个小步骤,来实现“花最小的努力产出最好的效果”。

+

01/ 花10分钟, 收集广告主资料

了解你所要推广产品的广告主是谁,经营什么产品,产品解决什么问题,这一切只需要你从对方官网都可以快速了解。除了你从广告主直接获取的信息之外,你还需要通过Google检索与之相竞争的对手与产品是什么。

+

02/ 花5分钟,阅读广告主介绍

好好阅读上一步骤所收集到的广告主资料信息。想一想,如果广告主找你聊具体的推广信息,而你对自己的客户一无所知,是不是有点说不过去,所以要提前做好功课。

+

03/ 花5分钟,找到一个卖点

你要明白每一个产品往往都会有很多优点或者好处,你不可能使用有限的篇幅来顾及所有信息。所以,你需要依照自己的推广平台的文字限制,来选择性的介绍1个或多个产品卖点。

+

04/ 花1分钟,确定CTA

通过添加CTA(Call to action)链接或按钮,可以更容易说服用户采取下一步行动,有利于促进点击率或转化率。CTA要具备三个要素:要推广人们立即行动,而不是晚点再说;应该要求行动,而不是建议行动;引导人们行动的流程要足够简单。

+

比如:错误示例,“LearnMore”,“Download”,没有告诉用户所要获得的好处;好的示例,“Get My Free EBook”、“Get 50% Off My Ebook Now”

+

05/ 花10分钟,持续输出文字

通过之前对于广告主及产品的了解、选定的推广卖点以及CTA等多方面的了解,用自己的文字进行快速组织介绍,把所有能想到的文字尽量输出出来,不要担心写的好不好,通顺不通顺,你可以理解为列草稿。

+

06/ 花10分钟,将自己的头脑冷静一下

对于刚输出的内容,自己的思维可能一直处于一种惯性思维之中。试着将这种思维冷却下来,才可能更加理性的看待问题。

+

07/ 花6分钟,重新省视自己的文案

你可以通过大声朗读自己的文案,以及换位思考,假如你是读者,感受如何。另外,尽量使用客户有依据的数字来支撑你的表达,从而提升说服力。

+

08/ 花6分钟,检查自己的表达逻辑

检查自己方案的表达逻辑是否合理,以及学会在适当的位置进行段落,可以减轻用户的阅读障碍。如何不知道写符合逻辑的推广文案,可以学习一下aida(营销模式)_百度百科

+

09/ 花8分钟,优化文案

检查自己的文案,是否存在不通顺、措词不当以及存在错别字的情况,把自己的每一段文案当成一个产品进行精打细磨。

+

10/ All done

到这一步,你能做都已经做了,剩下的就只能看广告在市场中的具体表现效果了。

+

而你呢,接下来所要做的事情,就是继续写一篇文案,以此往复,不断提高自己“Writing-》Sell”的文案能力。

+

参考资料

+
如何提高防猝死的能力
\ No newline at end of file diff --git a/archives/index.html b/archives/index.html index e69de29b..8f79337f 100644 --- a/archives/index.html +++ b/archives/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp
\ No newline at end of file diff --git a/archives/page/2/index.html b/archives/page/2/index.html index e69de29b..014fbd05 100644 --- a/archives/page/2/index.html +++ b/archives/page/2/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp
\ No newline at end of file diff --git a/archives/page/3/index.html b/archives/page/3/index.html new file mode 100644 index 00000000..0ef6bf7f --- /dev/null +++ b/archives/page/3/index.html @@ -0,0 +1,13 @@ +Archive | HackDApp \ No newline at end of file diff --git a/archives/rebuildbrain_habit.html b/archives/rebuildbrain_habit.html index e69de29b..3bf43415 100644 --- a/archives/rebuildbrain_habit.html +++ b/archives/rebuildbrain_habit.html @@ -0,0 +1,47 @@ +重塑思维:自律 VS 习惯 | HackDApp

重塑思维:自律 VS 习惯

自律使我压抑,习惯助我成长。 自律与习惯,其实目标都是一致的,只是所产生的行动动力源是不相同的。

+

相信每个人都在不停的思考一个问题,“我如何才能使明天的自己比今天的自己更加优秀一些呢?”

+

为了让自己变得更好,我们去总结规律,改变自我认知,希望能从不断的思维升级过程中,锻造出属于自己的思维工具,培养及丰富问题症结的方案库。

+

为了让自己变得更好,我们需要靠意志去坚持去做一件让自己变得优秀的事情,但你发现一段时间之后,这件事不了了知,扔那儿放下了,因为这样的事在我的人生当中简直太熟悉不过了。

+

相反,有一些行为却长期固化下来了,比如我们的一些日常洗漱习惯,即使你中途有一段时间没去做,那你也不会放弃这件事。

+

当某一种行为已经成为你的习惯时,如果你有意识的去观察一下,会发现一些许规律。比如:刷牙,可能现在没有不早晚刷牙的童鞋吧。不妨想一想这个行为大家保持了多少年,到现在是否还需要各种精神动力去推着自己去做这个事吗?

+

明显不需要,可以说这已经是写入自己骨头里的一种惯性行为,你要是不注意都不发现它原来其实就是一个号的学习榜样。因为它太习以为常了,平常的都忘掉它的存在。

+

那既然刷牙可以养成习惯,那我们其他行为为啥就不能养成一种习惯呢?

+

首先,处于习惯性的行为执行过程并不会让你特别有心理负担;
其次,习惯中的行为并不会消耗自己稀缺的精力;
最后,行为关联及导向性。也就是习惯行为之间的联动开关。比如:洗漱的时候总能与刷牙这件事产生一定的链接,而这个链接往往就是我们通过意识去不断增强脑回路而形成的。

+

之所以总结这些,就是因为我身上的一件事,当时看李笑来的专栏里曾经提到一种感受,就是“不做这件事就难受”。 当时是在是无法理解这种状态,除了吃饭这件事,找不出天天不做就难受的事来,当你无法从自身找到可以参考的例子时,你总是无法理解其概念。

+

直到我发现身上这件事,刮胡子。对,你没看错,就是刮胡子。

+

为什么讲呢?因为之前总是用电动剃须刀,总是容易忘记用,时做时不做的,而且刮的也不是太干净。直到有一天看到京东做活动卖手动剃须刀,想着买来试一试,但当时也犹豫,每天早上用这个会不会特花时间啊。

+

但事实证明,相比电动剃须刀,手动的虽然要麻烦一些,时间也要多花费一些。但这件事我却坚持了一年,直至今日从心理感受来讲,自己并没有感觉每天要逼着自己去做这件事,而是很自觉的每天洗漱后自动进入刮胡子状态。

+

为什么会这样呢?因为每一次刮完胡子,对着镜子一照,感觉干净清爽,漂亮,帅气。让我从内心看到一个舒服的自己,这算不算是一种仪式感呢。

+

后来,我总结了一下习惯养成的一个关键因素:持续的心理反馈。反馈可以让我们感受到变化与进步,或是一种心理满足;而持续性一来可以增强行为的动力,二过可以慢慢促进脑回路的链接建立。

+

那么,如何建立自己的习惯养成路径呢?那就是

+
    +
  1. 先制定一个你绝对认可其价值的目标;
  2. +
  3. 在意识中建立诱导因子,也就是你需要在已形成的习惯之中,建立一个与新行动的触感连接;
  4. +
  5. 持续反馈,每天都要总结,让自己内心见证成长,而后通过持续达到巩固行动的动力。
  6. +
+

小结

好的习惯、应用技巧及思维方式是可以产生复利效应价值的,关键在于它不是形式上的应用,不是为技巧而技巧,一定是在我们的生活或工作实际场景中解决实际问题,并以此不断反馈价值收获,而持续的价值收益又会加强我们执行的动力,最终形成一个正向向上的良性循环♻️。

+

执行力其实是落实行动的第一要素,所以我们需要学会如何去补充这项能源。而最好的方式就是让自己认可这件事的价值。并且能够在做事的过程中,有深刻的反馈与心理感受,学会记录自己的心理变化。

+

最后,通过不断的执行与反馈,增强我们的脑回路链接。久而久之,就会成为我们的习惯。

+
剖析EOS合约编译ABI文件
\ No newline at end of file diff --git a/archives/simple_cpllus_code.html b/archives/simple_cpllus_code.html index e69de29b..11deabcd 100644 --- a/archives/simple_cpllus_code.html +++ b/archives/simple_cpllus_code.html @@ -0,0 +1,64 @@ +C++简单程序入门 | HackDApp

C++简单程序入门

/* filename: myapp.cpp
date: 2019-01-28 3:06 PM
auth: 55269778@qq.com */

#include <iostream> //定义头文件
#include <stdlib.h>

int main()
{
using namespace std; //命令空间, 简化后续变量或方法调用。e.g. std::string 等同于 string

string msg = "hi, my first dapp"; //定义变量

cout << msg <<endl; //打印字符串
}

//tryit: http://tpcg.io/Tulum1
+

以上代码便是C++最简单可运行的最小示例。基本包含了在程序结构中所必须的一些语言特性。

+

根据上述程序结构,我们可以大致将它拆分成五部分内容:

+

1. #include <iostream>

头文件定义主要用于引用第三方函数库,通过调用第三方函数可以减少开发代码量,提高开发效率,同时也避免了不必要的重复造轮子。

+

比如:通过引用\<cmath>库,可以帮助我们快速使用里面的函数进行一些数学运算。

+

+

所以,后续我们需要学会便是如何查阅C

+

2. int main()

main函数区别于其它普通函数之处在于: main函数默认被系统定义为应用入口调用方法。除此之外,与其他函数无任何区别。

+
#include <iostream>
+#include <stdlib.h>
+
+using namespace std;
+
+string sayHi(string username)
+{
+    return string("hi, ").append(username).append("!");
+}
+
+int main()
+{
+    cout << sayHi("www.hackdapp.com") <<endl;
+}
+//tryit: http://tpcg.io/uHUkzy
+

函数定义,其实对于所有编程语言的定义方式大致相同, 都可以表现为以下形式

+
<返回类型|void> 方法名(参数定义1, 参数定义2,参数定义...)
+{
+    //do some stuff
+    return <返回数据>
+}
+

如果你之前已经在使用其他编程语言,那么应该对于C++其实也可以很好的理解它的程序结构。

+

注: 后续我们会详细介绍函数的多种定义及使用方式,包括形参实参、重载以及虚函数等。

+

3. string message = "hi, my first app"

变量定义,在程序开发过程,往往需要定义一些临时变量,用于存储在数据逻辑处理过程所必须的临时存储。

+

而变量的类型,主要分为字符、整型,长/短整型、单精度、双精度、布尔类型以及字符串。
我们在实际应用场景中,需要明确了解与知道这些基础数据类型的定义及边界范围,比如,无符号整型、单精度。

+

尤其是对数字类型的字段,如果不了解其边界范围,很可能会导致运算溢出等问题,特别是在合约开发过程中,数字溢出很可能导致的便是相当大的经济损失。

+

换个角度讲,合理的使用变量类型,也可能在一定程序中节省资源的浪费。因为在EOS合约中存储数据是需要消耗资源的。

+

另外,对于变量的名称定义,其名称只能是由数字、字母以及下划线组成且不可能以数字开头,而且根据不同平台,对于名称的长度其实也是存在限制的。

+

4. cout << msg <<endl

coutiostream函数库中的一个流数据输出函数,一般用于在程序调用过程向控制台输入一些调试信息;与此对应的是cin, 用于接收输入数据流。

+

不过, 在EOS合约中无法调用此函数。举而代之的是,EOSLIB库自己封装的print函数.

+

5. //单行注解 or /*多行注解*/

在程序开发过程,往往需要通过语言描述某个代码文件所要实现的整体功能或者某个函数的功能、参数及约束说明。这时候就需要用到注解。

+

而注解同样也所有的编程语言中也大致相同,一般分为单行注释与多行注释。

+

单行注释适用于短小的描述某一行运行逻辑;而多行注释多用于描述函数说明以及文件功能说明。

+
如何提高收益风险比
\ No newline at end of file diff --git a/archives/think_habit.html b/archives/think_habit.html index e69de29b..476c0a64 100644 --- a/archives/think_habit.html +++ b/archives/think_habit.html @@ -0,0 +1,45 @@ +坚持的长性 | HackDApp

坚持的长性

+

今天早上算是被媳妇嘲笑了一番,为啥呢?

+

因为之前自己有一段时间,为了背英语单词,所以早起了一个月,而如今早一天晚一天,早起完全看心情。

+

媳妇给出的评价就是:用劲过猛,要么及早要么极迟,完全是一种过激行为。

+

同时她也给出建议:只要比上班的时间多出一小时其实就可以做很多事情。重要的是常态化。

+
+

2019开始了,自己确没开始。以前都早早给自己作出各种规划,对比现在,还不如之前的自己吗?不应该是每年比前一年好一些吗或者每天比昨天好一些吗?

+

哦,也可能是最近超忙,导致各种规划的推迟。但内心同时又会想起另外一种声音:不,你不是,你只是懒。事情没把你逼到一种绝境上,你是不会立即行动的。

+

2019要做的事

    +
  1. 早起,不早起怎么做重要的事;而且希望能找到一些习惯思维方式;
  2. +
  3. 持续写作,写一本自己的技术书籍,打造自己的硬核;
  4. +
  5. 持续总结,不犯过去犯的错,少走弯路;
  6. +
  7. 思考习惯养成路径,以便培养自己新习惯的有效成功率
  8. +
+

注:事情不在多,夯实好这几点。

+

目前的状态

    +
  • 时不时早起起来做一些事情,可能是工作上的,也可能是生活上的,但缺少对书的阅读;另外,感觉早上精力特别出奇的好,是否应该做一些最重要的事情,而读书的化放在晚上的时候。
  • +
  • 未达到持续写东西的地步,需要检讨;可能存在的原因: 对于第二天早上要写的东西,前一天没有大致规划;或者说并不需要规划,每天早上写的时候就按之前的套路写就可以了,不讲究一次写完写完美,而是持续写出自己的每个内容点,草稿结束后再修改,也是告诉自己好文章是持续修改出来的,不可能写完就扔那儿了,而是要持续完善。包括今天写的这篇,其实也是由之前早上写的卡片扩展而来的。
  • +
  • 总结之前过于重视形式化。总结对于我来讲,总感觉认可但又未给予足够的重视,因为总是断断续续的写一些自检清单。可能这个和习惯的养成也是一样,归根到底是没有成长的即视感,也就是没有反馈。比如:刮胡子,为什么要举这个例子呢?因为之前用电动剃须刀时,总是时不时刮一次;而用手动刮胡刀后,发现自己几乎每天都会坚持这件事。当时再想为什么这件事能坚持的如此之前呢?那其他事情怎么不能坚持下去呢?我是否能够从刮胡子这件事情中找到自己内心的那一份认识与感受呢。后来才发现,那是因为刮胡子这件事能让我内心出现一份好形象不邋遢的意识。洗漱的时候就是在潜意识里调动这份动力,而且在刮完胡子后更加让自己内心得以满足,这不正是一种仪式感吗?
  • +
  • 正在有意识,感受自己每天坚持做一件事情的内心是如何的?
  • +
+

所以,如果要让某个行为成为你的习惯,你就要从内心上提高对它的认可,以及最重要的一件事,你要寻找你的内心感受,是什么让你满足。如果这个不好理解的话,我给你的建议就是观察你已有的习惯中想想那是一种什么感觉,做个比较可能会更形象一些。

+
C++导读(EOS完全开发指南)
\ No newline at end of file diff --git a/archives/tron_boilerplate.html b/archives/tron_boilerplate.html index e69de29b..9b3d0dcf 100644 --- a/archives/tron_boilerplate.html +++ b/archives/tron_boilerplate.html @@ -0,0 +1,90 @@ +波场Tron-可快捷开发的实战工程模板 | HackDApp

波场Tron-可快捷开发的实战工程模板

 _                         _           _ _                 _       _
| |_ _ __ ___ _ __ | |__ ___ (_) | ___ _ __ _ __ | | __ _| |_ ___
| __| '__/ _ \| '_ \ _____| '_ \ / _ \| | |/ _ \ '__| '_ \| |/ _` | __/ _ \
| |_| | | (_) | | | |_____| |_) | (_) | | | __/ | | |_) | | (_| | || __/
\__|_| \___/|_| |_| |_.__/ \___/|_|_|\___|_| | .__/|_|\__,_|\__\___|
|_|
+

Tron-Boilerplate, 是基于Tron公链的一套可快速搭建本地私链环境、发布合约以及配置完整的标准工程模板。

+

该工程模板旨在于帮助大家快速工程化本地开发环境,减少环境搭建以及调试开发流程过程中所需花费的大量时间,让大家将更多精力投入到产品设计与核心业务逻辑实现上。

+

使用提供的工程模板,可从以下四个方面提升开发效率:

+
    +
  • 一键启动或暂停私链环境
  • +
  • 一键编译智能合约
  • +
  • 一键发布智能合约
  • +
  • 一键单元测试(jtest)
  • +
+

同时,本工程模板附带了一个完整的示例代码(Todolist),可供大家参考与学习。示例效果如下:

+ +

+

最后,开发人员只需按照项目工程结构,编写自己的智能合约、前端页面及与SDK交互逻辑即可。

+
+

前置依赖

1. 安装docker

Install Docker for Mac : https://docs.docker.com/docker-for-mac/
Install Docker for Windows: https://docs.docker.com/docker-for-windows/install/

+

更多资料可参考: https://docs.docker.com

+

2. 安装node

To install or update nvm, you can use the install script using cURL:

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

+

or wget

wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

+

The script clones the nvm repository to /.nvm and adds the source line to your profile (/.bash_profile, /.zshrc, /.profile, or /.bashrc)._

+
export NVM_DIR="${XDG_CONFIG_HOME/:-$HOME/.}nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
+

更多资料可参考: https://github.com/creationix/nvm#installation

+

3. 安装jdk8

JDK8: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

+

如果大家不使用tron提供的tron-studio开发合约的化,可以选择不安装此项。因为使用tronbox同样也可以编译以及发布合约。

+

4. 安装tronbox

npm install -g tronbox
+

+

注:对于最新的 Java-Tron Odyssey 3.2 版本,最小兼容的 TronBox 版本是 TronBox 2.2.1。请确保您已安装此版本。

+

更多资料:https://cn.developers.tron.network/docs/%E5%85%A5%E9%97%A8

+

5. 开发工具

开发工具可根据自己喜好自由选择,个人比较推荐VSCode

+

官网链接:https://code.visualstudio.com/

+

工程安装与使用

1. 克隆工程

git clone git@github.com:ChainDesk/tron_boilerplate.git
+

工程结构介绍

# 项目地址: https://github.com/ChainDesk/tron_boilerplate
# 注:待工程稳定后,可能会考虑做成插件,可使用yeoman快速构建,欢迎大家star.
.
├── README.md
├── bin
│   ├── libs
│   │   └── TronStudio.jar //TronStudio开发工具包
│   ├── start_docker.sh //启动私链
│   ├── start_tronstudio.sh //启动TronStudio
│   └── stop_docker.sh //停止私链
├── build //合约编译生成目录
│   └── contracts
│   ├── HelloWorld.json //示例合约ABI, HelloWorld
│   ├── Migrations.json
│   └── TodoList.json //示例合约ABI, TodoList
├── contracts //合约目录,大家合约都放在这儿
│   ├── HelloWorld.sol
│   ├── Migrations.sol
│   └── TodoList.sol
├── migrations //发布合约目录
│   ├── 1_initial_migration.js
│   └── 2_deploy_contracts.js //新添加的合约需要在此文件中定义,否则无法通过tronbox deploy命令发布
├── package-lock.json
├── package.json //前端App工程及依赖包定义,以及多个服务启动命令。
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
├── src //前端React代码目录
│   ├── TodoList.js
│   ├── contracts
│   │   └── TodoList.json //合约ABI文件
│   ├── index.js
│   ├── serviceWorker.js
│   └── tronweb.js //新启动的工程,需要根据私链生成的私钥以及新发布的合约地址在此重新修改。
├── test //jtest测试目录,方便大家编写测试用例
│   └── web.test.js
├── tronbox-config.js
└── tronbox.js //发布合约所依赖的配置,此文件定义了本地、测试以及正式网络的http访问地址

12 directories, 27 files

+

2. 工程初始化

npm install
+

这一步主要用于更新前端框架react所依赖的包文件,依赖包安装成功后,会在工程目录下看到一个node_modules文件夹。

+

如果你的前端选型不是react的化,也可根据自己需求进行依赖包配置修改。

+

3. 正式开发流程

3.1 启动链环境

执行cmd+shift+p,调用vscode的命令列表,选择run task从中选择start_docker任务_

+


同样,如果要停止当前docker环境,只需选择stop_docker脚本即可。_

+

所有的执行任务配置默认只存在两个地方:

+
    +
  • tron_boilerplate/.vscode/tasks.json_
  • +
  • package.json中的scripts
    大家可根据自己需要进行添加或修改,而且也可以通过IDE本身的快捷键映射对应的任务。
  • +
+

3.2 发布合约

运行task任务,然后从中选择npm deploy, 即可发布当前所有合约至私链环境。

+

+

合约发布成功后,会显示如下:

+
Using network 'development'.

Running migration: 1_initial_migration.js
Replacing Migrations...
Migrations:
(base58) TBC7CqpjBxGUt9Z9hhM4QNRFF5osvG3j6r
(hex) 410d68b1bfd19d341bd0f772fad8697432d0d771be
Saving successful migration to network...
Saving artifacts...
Running migration: 2_deploy_contracts.js
Replacing TodoList...
TodoList:
(base58) TFyEw5qRRiZTJ5boLZJxZnv2hnhpBuvkjm
(hex) 4141d25df475fe0c053a9e2ed3a77faa10329185f0
Saving successful migration to network...
Saving artifacts...
+

3.3 修改配置参数

打开文件, tron_boilerplate/src/tronweb.js, 代码如下: _

...
const fullNode = new HttpProvider('http://127.0.0.1:8090');
const solidityNode = new HttpProvider('http://127.0.0.1:8091');
const eventServer = 'http://127.0.0.1:8092';

const privateKey = "<私钥地址>";
const contractAddr = "<合约地址>";
......

+

3.4 启动react服务

执行cmd+shift+p,调用vscode的命令列表,选择run task从中选择npm start即可启动前端服务。

+

+

打开浏览器,访问http://localhost:3000, 验证是否成功。

+
+

到此,整个工程的搭建及开发流程就介绍完毕,如中间出现任何问题欢迎加我个人微信咨询。

+

开发资料

+
+
+

在教程中如出现不易理解或存在错误的问题,欢迎加我微信指正!
Name: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

+
+
坚持的长性
\ No newline at end of file diff --git a/archives/try_eoscontract_dev.html b/archives/try_eoscontract_dev.html index e69de29b..afa42e0c 100644 --- a/archives/try_eoscontract_dev.html +++ b/archives/try_eoscontract_dev.html @@ -0,0 +1,130 @@ +零基础体验EOS入门合约开发 | HackDApp

零基础体验EOS入门合约开发

本教程主要面向初阶开发人员,目的在于带领大家以最简单的示例合约,通过简单但不失完整的流程,体验整个合约的编译、发布与调用过程,从而让大家从直观角度有个清晰的概念认识。

+
+

版本说明
测试网公链版本: v1.7.0-dirty
EOSjS-SDK版本:16.0.9
开发组件包(CDT): 1.5.0

+
+

一、帐户管理

1. Register EOS Account

生成公私钥

在进行帐户注册时,需要事先提供一对公私钥地址,以便在注册帐号时进行绑定使用。可通过EOS Key Generation网站进行公私钥地址生成。

+

注册帐户

通过Jungle2.0 - EOS Test Network Monitor (CryptoLions.io)网站进行EOS帐户的创建

点击图中标红create account, 在弹出界面中,填写事先生成的公钥地址


见上图中,需要填写三个信息,其中account name主要用于填写我们易于记忆的帐户名称,但其帐户名称长度只允许12位长度,且其组成字符也只能从a-z, 1-5以及一个点符号组成。
至于owner public key和 active public key分别对应该帐户owner权限和active权限。如果从安全角度讲,两个权限所对应的公钥地址应该设置成不一样的,这样当active private key丢失的时候,可以使用ower权限对active权限对应的公钥地址进行更换。因为ower和active权限是有层次关系的,只允许低级权限对下次权限进行操作。在不丢失ower私钥的情况下,也可以实现对ower权限地址的更换操作。

+

点击create, 创建成功后,会显示如下信息

+

2. Claim EOS


Jungle2.0 - EOS Test Network Monitor (CryptoLions.io)页面,点击菜单栏中的Faucet按钮,会弹出如下界面

+

3. Balance Query


Jungle2.0 - EOS Test Network Monitor (CryptoLions.io)页面,点击菜单栏中的account info按钮,弹出如下界面:

填写帐号名称后,点击get按钮, 便可以查到该用户的EOS余额及公钥地址信息。

+

4. Install Chrome Plugin: Scatter

安装scatter

在chrome浏览器中安装Chrome 网上应用店 - scatter插件。

+

注: 如果Chrome插件商店无法打开,则可以使用Start | Chrome Extension Downloader进行下载。scatter插件地址: https://chrome.google.com/webstore/detail/scatter/ammjpmhgckkpcamddpolhchgomcojkle?hl=zh-CN

+

插件安装完成后,可以chrome浏览器中看到如下高亮图标。

+

使用scatter

    +
  • 初始化scatter帐户
    填写密码,然后点击创建按钮

    点击创建操作后,会显示如下界面,提示保存12个助记词

    大家需要保存好这12个助词词,以便于在忘记密码时用助记词进行恢复。注:丢失此助记词则意味着你将永远丢失该帐户。

    +
  • +
  • 添加测试网络
    首先、打开主界面后,点击右上解系统设置

    然后,选择网络,新建网络

    填入测试网络的参数信息,比如: http://jungle2.cryptolions.io:80、chainid: e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473
    chaind的获取方式,可以直接通过http://jungle2.cryptolions.io/v1/chain/get_info进行查询

    +
  • +
  • 导入公私钥
    回到主界面,选择Key Pairs, 然后导入之前创建的私钥
  • +
  • 绑定EOS帐户
  • +
+

5. Buy(RAM、CPU、NET )

访问内存交易 - 钱包 - EOSX - Fastest EOS Block Explorer网站,绑定scatter帐号

+

+

购买RAM

购买CPU与NET资源

+

二、合约开发

1. 编写示例合约

在本地创建一个工程目录

~> mkdir -p mycontract/{utils, contracts}
~> tree
.
├── contracts
└── utils

+

在工程目录contracts文件下,创建hello.cpp,

~> touch contracts/hello.cpp

+

打开hello.cpp, 填写以下内容

#include <eosiolib/eosio.hpp>

using namespace eosio;

class [[eosio::contract]] hello : public contract {
public:
using contract::contract;

[[eosio::action]]
void hi( name user ) {
print( "Hello, ", user);
}
};

EOSIO_DISPATCH(hello, (hi))

+

2. 编译合约

该步骤需要用到EOS合约开发所必需的cdt开发工具包, 来完成对示例合约的编译工作。

+

1)在本地安装eosio-cpp工具命令

brew tap eosio/eosio.cdt //增加仓库
brew install eosio.cdt //安装工具包

+

注: 可使用eosin-cpp –help命令来查看所有参数说明

+

2)进行合约编译,生成abi合约描述文件及wasm合约文件

eosio-cpp -abigen 'contracts/hello.cpp' -o 'contracts/hello.wasm' --contract 'hackdappcom1'

+

编译完成后,会在工程目录生成hello.abi、hello.wasm两个编译文件。hello.abi就好比webservice中的wsdl描述语言一样,主要用于对合约接口及数据结构进行结构性描述, wasm文件为合约编译后的二进制文件。

+

ABI文件详细说明: 剖析EOS合约编译ABI文件 | HackDApp

+

3. 发布合约

初始化项目工程,并安装eosjs-sdk

使用npm init命令对项目进行初始化

~> npm init
package name: (mycontract)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/nolan/Desktop/mycontract/package.json:

{
"name": "mycontract",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

+

然后,使用npm install eosjs@16.0.9命令进行eos sdk组件安装

~> npm install eosjs@16.0.9

+

安装完成后, 整个项目工程目录结构显示如下:

~> tree
.
├── contracts //合约文件
├── node_modules //依赖组件
├── package-lock.json
├── package.json //工程配置定义
└── utils //工具库

3 directories, 2 files

+

编辑合约发布文件: deploy.js

首先,在工程根目录下,创建deploy.js;
然后,打开该文件,并填下以下内容;

const eos = require('./utils/eossdk')({
chainId: "e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473",
httpEndpoint: "http://jungle2.cryptolions.io:80",
//更改处一: EOS合约Active权限权限
keyProvider: "5JxqGao9rzXWBUDnNzALyxaFdmZYXiZ46EzHL4sJkHkryzCFKxu",// 更改处二: 改为要发布的合约帐户名称
authorization: 'hackdappcom1@active',
broadcast: true,
sign: true
})
const {deployContract} = require('./utils/common')

//更改处三:改为要发布的合约帐户名称
deployContract(eos, { account: "hackdappcom1", contractDir: "./contracts" }).then((result) => {
console.log(`Deployment successful`, JSON.stringify(result, null , 4))
})
.catch(err => {
console.error(`Deployment failed`, err)
})

+

最后,根据自己的帐户信息进行参数更改。

+

注:deploy.js文件头引入的两个文件eossdkcommon.js可直接点击链接下载,并放入工程目录utils文件夹中。

+

执行合约发布

编辑完成deploy.js相关参数数据, 通过node命令进行合约发布。

node deploy.js

+

运行命令之后,如果发布成功,会显示以下日志信息:

Deployment successful
[
{
"broadcast": true,
"transaction": {
"compression": "none",
"transaction": {
"expiration": "2019-04-03T06:50:55",
"ref_block_num": 25564,
"ref_block_prefix": 1344811314,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
......
"account_ram_deltas": [
{
"account": "hackdappcom1",
"delta": -27
}
],
"except": null,
"inline_traces": []
}
],
"except": null
}
}
]

+

4. 合约调用

在确保合约发布成功之后,开始编写合约调用文件 invoke.js

~> touch invoke.js

+

打开invoke.js, 填入以下代码:

const eos = require('./utils/eossdk')({
chainId: "e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473",
httpEndpoint: "http://jungle2.cryptolions.io:80",
keyProvider: "5JxqGao9rzXWBUDnNzALyxaFdmZYXiZ46EzHL4sJkHkryzCFKxu",
authorization: 'hackdappcom1@active',
broadcast: true,
sign: true
})

const data = {
actions: [
{
account: 'hackdappcom1',
name: 'hi',
authorization: [{
actor: 'hackdappcom1',
permission: 'active'
}],
data: {"user": "222"}
}
]
}
eos.transaction(data).then((result)=>{
console.log(JSON.stringify(result.processed.action_traces[0].console, null, 4))
}).catch((err)=>{
console.log(err)
})

+

执行调用命令

node invoke.js

+

如果能够正常运行,则会显示以下内容信息

"Hello, 222"

+

另外,针对教程中出现的代码,我提供了完整的工程代码示例及文字稿教程。大家可点击链接或者直接克隆到本地进行查看。项目地址: https://github.com/hackdapp/learn_eos

+
+

可能出现的问题

    +
  1. 如果你没有事先购买RAM资源,可以会提示以下错误信息
    {
    "code": 500,
    "message": "Internal Service Error",
    "error": {
    "code": 3080001,
    "name": "ram_usage_exceeded",
    "what": "Account using more than allotted RAM usage",
    "details": [
    {
    "message": "account hackdappcom1 has insufficient ram; needs 26318 bytes has 5471 bytes",
    "file": "resource_limits.cpp",
    "line_number": 213,
    "method": "verify_account_ram_usage"
    }
    ]
    }
    }
    +
  2. +
+

测试网帐号

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
帐户名公钥私钥
hackdappcom1EOS6LTWfM5ffbmjUhvwFnrU5QEBrmkzsRo2eXogr2h9oP8DUuzgAi5JxqGao9rzXWBUDnNzALyxaFdmZYXiZ46EzHL4sJkHkryzCFKxu
hackdappcom2EOS6qCqbFLuYK5rGK9LDPzcboLqy4phrUxLXLrhLgXxVBpzLzsJke5Jnw2anG8Zzy6MuCNxvwmaX5Hu4B6de1uzuae5QyRrUFtyfL2Wo
hackdappcom3EOS57B3rxRBBUiTyZf9iBxsWyQnvEhq2H95wbBbjdzcLbV1gfJ4zy5Ju2NNc24q3jQ2Yc2JcvwWjtGVeAyuWcNsaNVb37u7cmRW56zgc
hackdappcom4EOS7i5Diz2uqXSpvutmV4DftBRrL1XASzxsSdWBGrgzngPoXhT2dk5K6nyWMvpfYnQqLhS545dm53exduJgDBLHMYQ6SCNaPmeHjGZdr
hackdappcom5EOS6NcaFvvoekuBjhZLsBVywiMcN7VTVmgvAdA5srgTvQMeDmdiAH5JjN9efKokkgZYno2qjbE9C7WCGbVpPvgNArKDvcjbDic2pRGCS
+

参考资料

    +
  1. https://nadejde.github.io/eos-token-sale/
  2. +
  3. http://monitor.jungletestnet.io/#home
  4. +
  5. https://jungle.eosx.io/tools/ram/buy?symbol=10
  6. +
  7. https://github.com/hackdapp/learn_eos
  8. +
  9. https://chrome-extension-downloader.com/f944f5bf7bc58292048aa5b9bf29dc48/scatter.crx.crx.crx
  10. +
+
+

到此,整个EOS合约开发的流程就算介绍完毕。让我们再总结一下整体操作流程:

+
    +
  1. 生成两对公私地址,并进行EOS帐户注册
  2. +
  3. 通过jungle网站进行EOS币的领取,并对其进行余额查询
  4. +
  5. 安装Scatter插件,导入私钥并绑定新身份
  6. +
  7. 使用新注册的EOS帐户购买RAMCPUNET发布合约所需要的资源
  8. +
  9. 创建合约测试示例并编译
  10. +
  11. 编写发布合约脚本,替换合约帐户后进行合约发布
  12. +
  13. 编写合约方法调用脚本,调用合约中的hi方法进行日志打印。
    通过七个步骤我们了解了整个EOS合约开发的最简化操作流程。
  14. +
+
+

欢迎关注HackDApp博客或公众号, HackHook将持续为你分享IndieMaker成长路径、DAPP技术知识、高效Mac使用技巧、底层思维认知。

我的博客: https://www.hackdapp.com/
我的github: https://github.com/hackdapp
我的哔哩哔哩: https://space.bilibili.com/17360859
我的微信公众号: hackdapp

+

IndieMakers: https://www.indiemakers.cn

联系邮箱:55269778@qq.com

+
C++简单程序入门
\ No newline at end of file diff --git a/atom.xml b/atom.xml index e69de29b..501df43e 100644 --- a/atom.xml +++ b/atom.xml @@ -0,0 +1,464 @@ + + + HackDApp + + Focus on DApp tutorials, Thinking growth, Mac skills, IndieMaker, etc. + + + + 2021-06-28T15:33:38.116Z + https://www.hackdapp.com/ + + + zhangliang + + + + Hexo + + + 基于以太坊的NFT开发实践 + + https://www.hackdapp.com/archives/how-to-impl-nft-proj.html + 2021-06-28T15:22:28.000Z + 2021-06-28T15:33:38.116Z + + 课程大纲

第一部分、项目总览

  • 项目产品介绍
  • 代码工程介绍
  • 技术架构讲解
  • 基础概念讲解(ERC20、ERC1155、ERC721)

第二部分、产品架构及功能设计

  • 产品架构图
  • 业务流程图
  • 技术架构图

第三部分、产品开发及用例测试

1)智能合约开发

  • 基础环境配置
  • 搭建本地链环境
  • 开发工程构建
  • 合约设计
  • 合约测试

2)IPFS部署与集成

3)前端页面开发

第四部分、产品部署

  • 发布静态工程至github仓库gh-page,并配置公网域名
  • 发布智能合约至测试网

第五部分、线上演示及功能验证

  • 安装MetaMask
  • 发布NFT
  • 交易NFT
  • 转帐NFT
  • ……
]]>
+ + + + + + <h2 id="课程大纲"><a href="#课程大纲" class="headerlink" title="课程大纲"></a>课程大纲</h2><h3 id="第一部分、项目总览"><a href="#第一部分、项目总览" class="headerlink" title= + + + + + + + + + +
+ + + 如何做好课堂笔记 + + https://www.hackdapp.com/archives/how-to-make-goodnotes.html + 2021-06-07T09:24:31.000Z + 2021-06-07T09:29:04.609Z + +

]]>
+ + + + + + <p><img src="http://cdn.hackdapp.com/2021-06-07-%E5%BF%85%E4%BF%AE%E4%BD%9C%E4%B8%9A1-D023-%E5%BC%A0%E4%BA%AE-%E5%8C%97%E4%BA%AC-hackdapp.pn + + + + + + + +
+ + + 如何提高防猝死的能力 + + https://www.hackdapp.com/archives/20210428-如何提高防猝死的能力.html + 2021-04-28T14:56:16.000Z + 2021-04-28T15:08:39.509Z + + 猝死就是平时身体健康、或貌似健康的患者,在出乎意料的短时间内,因自然疾病而突然死亡.

猝死,如此可怕,是哪些原因导致的呢?
85%是心血管问题,这其中,又有80%是给心脏供血的冠状动脉突发缺血了。

那么,猝死我们可以预防或控制吗?
好消息是,绝大部分情况可以,前提是你要有足够的心脏储备。而储备,是心血管健康里最容易被忽视的一个维度。所谓心力储备,就是心脏因身体的需要而增加射血的能力。所以,大部分情况下,猝死是由于心力储备坍塌导致的。

逻辑上有三种策略可以进行预防:

  1. 避免最后一根稻草策略。能引发猝死的事情,我们不要去做。比如: 大量喝酒或咖、心情抑郁、暴饮暴食等等。要注重先兆,要比发现最后一稻草更有效;
  2. 关注身体信号策略。我们要注意引发猝死的先兆,也就是去注意储备透支的信号。
  3. 拓展储备策略。这也是最重要的一种策略。既然储备是一种潜能,那我们就要努力去拓展它

原文链接: https://www.dedao.cn/article/w06eGYrQb1gzVxBryXPl73kZRqOaB8

]]>
+ + + + + + <p><strong>猝死就是平时身体健康、或貌似健康的患者,在出乎意料的短时间内,因自然疾病而突然死亡.</strong></p> +<p><strong>猝死,如此可怕,是哪些原因导致的呢?</strong><br>85%是心血管问题,这其中,又有80%是给心脏供血的冠状动脉突 + + + + + + + + + +
+ + + 如何用61分钟写出漂亮的推广文案 + + https://www.hackdapp.com/archives/how_to_write_ad_fast.html + 2021-04-07T10:09:14.000Z + 2021-04-07T12:28:02.909Z + + 最近,接触了不少通过推荐产品的联盟推广平台,只要你能通过自己的语言或文字,说服别人通过你的链接购买对应商品,那么你就能从中抽取一定的佣金。比如:将京东或淘宝联盟里的产品,通过知乎、蜜源、小红书等平台进行文案宣传。

在推广过程,你会很快发现,如何能够更好的说报用户,就往往就要考虑一个人的文案能力,当然不仅仅是文字功度,更重要的是你更懂得将适当的产品推送给最需要的人。这其中,就需要你多思考,如何挖掘产品卖点,如何通过数据了解客户需要什么等等。

对于一些专门写广告文案的高手来讲,往往都有一套自己的写作套路或者方法论,以提高自己的产出效率及效果。最终考验你的不是你写了多少字,而是到底转化多少用户进行付费。

今天,也是机缘巧合,刷推的时候发现一篇推文觉得写得挺不错的,所以也翻译过来与大家共同学习成长。

推主的整个写作框架,共拆分成11个小步骤,来实现“花最小的努力产出最好的效果”。

01/ 花10分钟, 收集广告主资料

了解你所要推广产品的广告主是谁,经营什么产品,产品解决什么问题,这一切只需要你从对方官网都可以快速了解。除了你从广告主直接获取的信息之外,你还需要通过Google检索与之相竞争的对手与产品是什么。

02/ 花5分钟,阅读广告主介绍

好好阅读上一步骤所收集到的广告主资料信息。想一想,如果广告主找你聊具体的推广信息,而你对自己的客户一无所知,是不是有点说不过去,所以要提前做好功课。

03/ 花5分钟,找到一个卖点

你要明白每一个产品往往都会有很多优点或者好处,你不可能使用有限的篇幅来顾及所有信息。所以,你需要依照自己的推广平台的文字限制,来选择性的介绍1个或多个产品卖点。

04/ 花1分钟,确定CTA

通过添加CTA(Call to action)链接或按钮,可以更容易说服用户采取下一步行动,有利于促进点击率或转化率。CTA要具备三个要素:要推广人们立即行动,而不是晚点再说;应该要求行动,而不是建议行动;引导人们行动的流程要足够简单。

比如:错误示例,“LearnMore”,“Download”,没有告诉用户所要获得的好处;好的示例,“Get My Free EBook”、“Get 50% Off My Ebook Now”

05/ 花10分钟,持续输出文字

通过之前对于广告主及产品的了解、选定的推广卖点以及CTA等多方面的了解,用自己的文字进行快速组织介绍,把所有能想到的文字尽量输出出来,不要担心写的好不好,通顺不通顺,你可以理解为列草稿。

06/ 花10分钟,将自己的头脑冷静一下

对于刚输出的内容,自己的思维可能一直处于一种惯性思维之中。试着将这种思维冷却下来,才可能更加理性的看待问题。

07/ 花6分钟,重新省视自己的文案

你可以通过大声朗读自己的文案,以及换位思考,假如你是读者,感受如何。另外,尽量使用客户有依据的数字来支撑你的表达,从而提升说服力。

08/ 花6分钟,检查自己的表达逻辑

检查自己方案的表达逻辑是否合理,以及学会在适当的位置进行段落,可以减轻用户的阅读障碍。如何不知道写符合逻辑的推广文案,可以学习一下aida(营销模式)_百度百科

09/ 花8分钟,优化文案

检查自己的文案,是否存在不通顺、措词不当以及存在错别字的情况,把自己的每一段文案当成一个产品进行精打细磨。

10/ All done

到这一步,你能做都已经做了,剩下的就只能看广告在市场中的具体表现效果了。

而你呢,接下来所要做的事情,就是继续写一篇文案,以此往复,不断提高自己“Writing-》Sell”的文案能力。

参考资料

]]>
+ + + + 如何用最少的时间写出最漂亮的广告推广文案呢?今天就向你推荐一个写作框架。,点击【ReadMore】,了解更多详情。 + + + + + + +
+ + + 交易者应掌握的能力 + + https://www.hackdapp.com/archives/Sun Feb 28 2021 00:00:00 GMT+0800 (China Standard Time).html + 2021-02-28T10:02:54.000Z + 2021-04-07T10:00:45.168Z + + 无论是在股市或是币市,我们都希望通过自己的一顿神操作,买到那些可以让自己瞬间反几倍甚至几十倍的股票或数字货币,但现实情况
会告诉你,即使是牛市你也能亏钱亏的要死。

为什么呢?这就不得不想想其中你想赚钱的行为,是一种投机还是投资?

投机呢,完全可能就是全凭着几个火热大群的fomo情绪,亦或是好巧不巧的几个自己认为重要的小道消息,就认为自己拿到了人生财富密码,知道自己输的底朝天;而投资往往是通过自己对标的物,花精力与时间去研究思考,挖机出它的长期价值,尤其是那些被低估的标的,即使是自己决策失误,也会总结教训,从错误中反思,改进自己的投资方法论,不错失提升自己大脑🧠成长的机会。

韭菜之所以是韭菜,就因为再每一次决策失误的时候不去学习反思,丧失了每一次成长的机会,慢慢就变成了一根老韭菜。

所以,在赚钱这条路上,我们慢慢培养总结自己的投资方法论,并在实践过程中不断反思复盘完善自己的投资逻辑。

思考带来决策,决策带来行动,行动改变命运,,行动改变命运!

]]>
+ + + + + + <p>无论是在股市或是币市,我们都希望通过自己的一顿神操作,买到那些可以让自己瞬间反几倍甚至几十倍的股票或数字货币,但现实情况<br>会告诉你,即使是牛市你也能亏钱亏的要死。</p> +<p>为什么呢?这就不得不想想其中你想赚钱的行为,是一种投机还是投资?</p> +<p>投机呢,完 + + + + + + + + + +
+ + + 如何提高收益风险比 + + https://www.hackdapp.com/archives/how-to-improve-return-risk-ratio.html + 2021-02-21T12:56:11.000Z + 2021-04-07T10:00:45.167Z + + 什么是收益风险比呢? 字面意思不难理解,就是: 收益风险比 = 可能的收益 / 未知的风险。

为什么需要认识并提升自己的收益风险比呢? 因为像我这样打工人,除了工资之外,就没有其他收入了,如果被辞职或家里出些什么事,无论是家庭生活质量还是自己的心理焦虑,都会受到极大的生存压力。而投资作为被动收入的一种手段,就可以提升我们在工作单一收入上的安全度,而提升收益风险比,就是在这一基础上能够获得更大的回报。

那么如何提高收益风险比呢?很简单:
一、提高分子值,即:让自己的可能收益的概率更高。那么如何做到呢?比如:筛选优质投资标的;选择合适的投资时机;长线持有,防止频繁操作,被甩下车的可能;
二、降低分母值,即:降低投资对自己生活的风险影响程度。如何做呢?比如:设置止损线,尽量让损失控制在自己可以接受的心理价位;按自己的风险承受能力,设置投资金额占总资产的百分比;增加场外赚钱能力,充沛的现金流在一定程序上可以降低自己的投资焦虑。

通过合理的收益风险比的控制,可以让我们在整个投资过程中,除了降低一些心理焦虑压力,还能获取更高的投资回报,并最终提升我们的家庭生活质量以及风险承受能力。

2021年,希望自己在数字货币投资领域,能够有个好的收获!

]]>
+ + + + + + <p>什么是收益风险比呢? 字面意思不难理解,就是: 收益风险比 = 可能的收益 / 未知的风险。</p> +<p>为什么需要认识并提升自己的收益风险比呢? 因为像我这样打工人,除了工资之外,就没有其他收入了,如果被辞职或家里出些什么事,无论是家庭生活质量还是自己的心理焦虑,都会 + + + + + + + + + +
+ + + C++简单程序入门 + + https://www.hackdapp.com/archives/simple_cpllus_code.html + 2019-04-04T04:00:00.000Z + 2021-04-07T09:31:42.557Z + +
/* filename: myapp.cpp
date: 2019-01-28 3:06 PM
auth: 55269778@qq.com */

#include <iostream>//定义头文件
#include <stdlib.h>

int main()
{
using namespace std;//命令空间, 简化后续变量或方法调用。e.g. std::string 等同于 string

string msg = "hi, my first dapp"; //定义变量

cout << msg <<endl;//打印字符串
}

//tryit: http://tpcg.io/Tulum1

以上代码便是C++最简单可运行的最小示例。基本包含了在程序结构中所必须的一些语言特性。

根据上述程序结构,我们可以大致将它拆分成五部分内容:

1. #include <iostream>

头文件定义主要用于引用第三方函数库,通过调用第三方函数可以减少开发代码量,提高开发效率,同时也避免了不必要的重复造轮子。

比如:通过引用\<cmath>库,可以帮助我们快速使用里面的函数进行一些数学运算。

所以,后续我们需要学会便是如何查阅C

2. int main()

main函数区别于其它普通函数之处在于: main函数默认被系统定义为应用入口调用方法。除此之外,与其他函数无任何区别。

#include <iostream>#include <stdlib.h>using namespace std;string sayHi(string username){    return string("hi, ").append(username).append("!");}int main(){    cout << sayHi("www.hackdapp.com") <<endl;}//tryit: http://tpcg.io/uHUkzy

函数定义,其实对于所有编程语言的定义方式大致相同, 都可以表现为以下形式

<返回类型|void> 方法名(参数定义1, 参数定义2,参数定义...){    //do some stuff    return <返回数据>}

如果你之前已经在使用其他编程语言,那么应该对于C++其实也可以很好的理解它的程序结构。

注: 后续我们会详细介绍函数的多种定义及使用方式,包括形参实参、重载以及虚函数等。

3. string message = "hi, my first app"

变量定义,在程序开发过程,往往需要定义一些临时变量,用于存储在数据逻辑处理过程所必须的临时存储。

而变量的类型,主要分为字符、整型,长/短整型、单精度、双精度、布尔类型以及字符串。
我们在实际应用场景中,需要明确了解与知道这些基础数据类型的定义及边界范围,比如,无符号整型、单精度。

尤其是对数字类型的字段,如果不了解其边界范围,很可能会导致运算溢出等问题,特别是在合约开发过程中,数字溢出很可能导致的便是相当大的经济损失。

换个角度讲,合理的使用变量类型,也可能在一定程序中节省资源的浪费。因为在EOS合约中存储数据是需要消耗资源的。

另外,对于变量的名称定义,其名称只能是由数字、字母以及下划线组成且不可能以数字开头,而且根据不同平台,对于名称的长度其实也是存在限制的。

4. cout << msg <<endl

coutiostream函数库中的一个流数据输出函数,一般用于在程序调用过程向控制台输入一些调试信息;与此对应的是cin, 用于接收输入数据流。

不过, 在EOS合约中无法调用此函数。举而代之的是,EOSLIB库自己封装的print函数.

5. //单行注解 or /*多行注解*/

在程序开发过程,往往需要通过语言描述某个代码文件所要实现的整体功能或者某个函数的功能、参数及约束说明。这时候就需要用到注解。

而注解同样也所有的编程语言中也大致相同,一般分为单行注释与多行注释。

单行注释适用于短小的描述某一行运行逻辑;而多行注释多用于描述函数说明以及文件功能说明。

]]>
+ + + + C++简单程序入门. 以最简单的示例代码,为你拆解其脉络结构。上手C++对你来说,那不是难事。 + + + + + + + + +
+ + + 零基础体验EOS入门合约开发 + + https://www.hackdapp.com/archives/try_eoscontract_dev.html + 2019-04-03T23:00:00.000Z + 2021-04-07T09:31:42.557Z + + 本教程主要面向初阶开发人员,目的在于带领大家以最简单的示例合约,通过简单但不失完整的流程,体验整个合约的编译、发布与调用过程,从而让大家从直观角度有个清晰的概念认识。


版本说明
测试网公链版本: v1.7.0-dirty
EOSjS-SDK版本:16.0.9
开发组件包(CDT): 1.5.0


一、帐户管理

1. Register EOS Account

生成公私钥

在进行帐户注册时,需要事先提供一对公私钥地址,以便在注册帐号时进行绑定使用。可通过EOS Key Generation网站进行公私钥地址生成。

注册帐户

通过Jungle2.0 - EOS Test Network Monitor (CryptoLions.io)网站进行EOS帐户的创建

点击图中标红create account, 在弹出界面中,填写事先生成的公钥地址


见上图中,需要填写三个信息,其中account name主要用于填写我们易于记忆的帐户名称,但其帐户名称长度只允许12位长度,且其组成字符也只能从a-z, 1-5以及一个点符号组成。
至于owner public key和 active public key分别对应该帐户owner权限和active权限。如果从安全角度讲,两个权限所对应的公钥地址应该设置成不一样的,这样当active private key丢失的时候,可以使用ower权限对active权限对应的公钥地址进行更换。因为ower和active权限是有层次关系的,只允许低级权限对下次权限进行操作。在不丢失ower私钥的情况下,也可以实现对ower权限地址的更换操作。

点击create, 创建成功后,会显示如下信息

2. Claim EOS


Jungle2.0 - EOS Test Network Monitor (CryptoLions.io)页面,点击菜单栏中的Faucet按钮,会弹出如下界面

3. Balance Query


Jungle2.0 - EOS Test Network Monitor (CryptoLions.io)页面,点击菜单栏中的account info按钮,弹出如下界面:

填写帐号名称后,点击get按钮, 便可以查到该用户的EOS余额及公钥地址信息。

4. Install Chrome Plugin: Scatter

安装scatter

在chrome浏览器中安装Chrome 网上应用店 - scatter插件。

注: 如果Chrome插件商店无法打开,则可以使用Start | Chrome Extension Downloader进行下载。scatter插件地址: https://chrome.google.com/webstore/detail/scatter/ammjpmhgckkpcamddpolhchgomcojkle?hl=zh-CN

插件安装完成后,可以chrome浏览器中看到如下高亮图标。

使用scatter

  • 初始化scatter帐户
    填写密码,然后点击创建按钮

    点击创建操作后,会显示如下界面,提示保存12个助记词

    大家需要保存好这12个助词词,以便于在忘记密码时用助记词进行恢复。注:丢失此助记词则意味着你将永远丢失该帐户。

  • 添加测试网络
    首先、打开主界面后,点击右上解系统设置

    然后,选择网络,新建网络

    填入测试网络的参数信息,比如: http://jungle2.cryptolions.io:80、chainid: e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473
    chaind的获取方式,可以直接通过http://jungle2.cryptolions.io/v1/chain/get_info进行查询

  • 导入公私钥
    回到主界面,选择Key Pairs, 然后导入之前创建的私钥
  • 绑定EOS帐户

5. Buy(RAM、CPU、NET )

访问内存交易 - 钱包 - EOSX - Fastest EOS Block Explorer网站,绑定scatter帐号

购买RAM

购买CPU与NET资源

二、合约开发

1. 编写示例合约

在本地创建一个工程目录

~> mkdir -p mycontract/{utils, contracts}
~> tree
.
├── contracts
└── utils

在工程目录contracts文件下,创建hello.cpp,

~> touch contracts/hello.cpp

打开hello.cpp, 填写以下内容

#include <eosiolib/eosio.hpp>

using namespace eosio;

class [[eosio::contract]] hello : public contract {
public:
using contract::contract;

[[eosio::action]]
void hi( name user ) {
print( "Hello, ", user);
}
};

EOSIO_DISPATCH(hello, (hi))

2. 编译合约

该步骤需要用到EOS合约开发所必需的cdt开发工具包, 来完成对示例合约的编译工作。

1)在本地安装eosio-cpp工具命令

brew tap eosio/eosio.cdt //增加仓库
brew install eosio.cdt //安装工具包

注: 可使用eosin-cpp –help命令来查看所有参数说明

2)进行合约编译,生成abi合约描述文件及wasm合约文件

eosio-cpp -abigen 'contracts/hello.cpp' -o 'contracts/hello.wasm' --contract 'hackdappcom1'

编译完成后,会在工程目录生成hello.abi、hello.wasm两个编译文件。hello.abi就好比webservice中的wsdl描述语言一样,主要用于对合约接口及数据结构进行结构性描述, wasm文件为合约编译后的二进制文件。

ABI文件详细说明: 剖析EOS合约编译ABI文件 | HackDApp

3. 发布合约

初始化项目工程,并安装eosjs-sdk

使用npm init命令对项目进行初始化

~> npm init
package name: (mycontract)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/nolan/Desktop/mycontract/package.json:

{
"name": "mycontract",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

然后,使用npm install eosjs@16.0.9命令进行eos sdk组件安装

~> npm install eosjs@16.0.9

安装完成后, 整个项目工程目录结构显示如下:

~> tree
.
├── contracts//合约文件
├── node_modules//依赖组件
├── package-lock.json
├── package.json//工程配置定义
└── utils//工具库

3 directories, 2 files

编辑合约发布文件: deploy.js

首先,在工程根目录下,创建deploy.js;
然后,打开该文件,并填下以下内容;

const eos = require('./utils/eossdk')({
chainId: "e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473",
httpEndpoint: "http://jungle2.cryptolions.io:80",
//更改处一: EOS合约Active权限权限
keyProvider: "5JxqGao9rzXWBUDnNzALyxaFdmZYXiZ46EzHL4sJkHkryzCFKxu",// 更改处二: 改为要发布的合约帐户名称
authorization: 'hackdappcom1@active',
broadcast: true,
sign: true
})
const {deployContract} = require('./utils/common')

//更改处三:改为要发布的合约帐户名称
deployContract(eos, { account: "hackdappcom1", contractDir: "./contracts" }).then((result) => {
console.log(`Deployment successful`, JSON.stringify(result, null , 4))
})
.catch(err => {
console.error(`Deployment failed`, err)
})

最后,根据自己的帐户信息进行参数更改。

注:deploy.js文件头引入的两个文件eossdkcommon.js可直接点击链接下载,并放入工程目录utils文件夹中。

执行合约发布

编辑完成deploy.js相关参数数据, 通过node命令进行合约发布。

node deploy.js

运行命令之后,如果发布成功,会显示以下日志信息:

Deployment successful
[
{
"broadcast": true,
"transaction": {
"compression": "none",
"transaction": {
"expiration": "2019-04-03T06:50:55",
"ref_block_num": 25564,
"ref_block_prefix": 1344811314,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
......
"account_ram_deltas": [
{
"account": "hackdappcom1",
"delta": -27
}
],
"except": null,
"inline_traces": []
}
],
"except": null
}
}
]

4. 合约调用

在确保合约发布成功之后,开始编写合约调用文件 invoke.js

~> touch invoke.js

打开invoke.js, 填入以下代码:

const eos = require('./utils/eossdk')({
chainId: "e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473",
httpEndpoint: "http://jungle2.cryptolions.io:80",
keyProvider: "5JxqGao9rzXWBUDnNzALyxaFdmZYXiZ46EzHL4sJkHkryzCFKxu",
authorization: 'hackdappcom1@active',
broadcast: true,
sign: true
})

const data = {
actions: [
{
account: 'hackdappcom1',
name: 'hi',
authorization: [{
actor: 'hackdappcom1',
permission: 'active'
}],
data: {"user": "222"}
}
]
}
eos.transaction(data).then((result)=>{
console.log(JSON.stringify(result.processed.action_traces[0].console, null, 4))
}).catch((err)=>{
console.log(err)
})

执行调用命令

node invoke.js

如果能够正常运行,则会显示以下内容信息

"Hello, 222"

另外,针对教程中出现的代码,我提供了完整的工程代码示例及文字稿教程。大家可点击链接或者直接克隆到本地进行查看。项目地址: https://github.com/hackdapp/learn_eos


可能出现的问题

  1. 如果你没有事先购买RAM资源,可以会提示以下错误信息
    {
    "code": 500,
    "message": "Internal Service Error",
    "error": {
    "code": 3080001,
    "name": "ram_usage_exceeded",
    "what": "Account using more than allotted RAM usage",
    "details": [
    {
    "message": "account hackdappcom1 has insufficient ram; needs 26318 bytes has 5471 bytes",
    "file": "resource_limits.cpp",
    "line_number": 213,
    "method": "verify_account_ram_usage"
    }
    ]
    }
    }

测试网帐号

帐户名公钥私钥
hackdappcom1EOS6LTWfM5ffbmjUhvwFnrU5QEBrmkzsRo2eXogr2h9oP8DUuzgAi5JxqGao9rzXWBUDnNzALyxaFdmZYXiZ46EzHL4sJkHkryzCFKxu
hackdappcom2EOS6qCqbFLuYK5rGK9LDPzcboLqy4phrUxLXLrhLgXxVBpzLzsJke5Jnw2anG8Zzy6MuCNxvwmaX5Hu4B6de1uzuae5QyRrUFtyfL2Wo
hackdappcom3EOS57B3rxRBBUiTyZf9iBxsWyQnvEhq2H95wbBbjdzcLbV1gfJ4zy5Ju2NNc24q3jQ2Yc2JcvwWjtGVeAyuWcNsaNVb37u7cmRW56zgc
hackdappcom4EOS7i5Diz2uqXSpvutmV4DftBRrL1XASzxsSdWBGrgzngPoXhT2dk5K6nyWMvpfYnQqLhS545dm53exduJgDBLHMYQ6SCNaPmeHjGZdr
hackdappcom5EOS6NcaFvvoekuBjhZLsBVywiMcN7VTVmgvAdA5srgTvQMeDmdiAH5JjN9efKokkgZYno2qjbE9C7WCGbVpPvgNArKDvcjbDic2pRGCS

参考资料

  1. https://nadejde.github.io/eos-token-sale/
  2. http://monitor.jungletestnet.io/#home
  3. https://jungle.eosx.io/tools/ram/buy?symbol=10
  4. https://github.com/hackdapp/learn_eos
  5. https://chrome-extension-downloader.com/f944f5bf7bc58292048aa5b9bf29dc48/scatter.crx.crx.crx

到此,整个EOS合约开发的流程就算介绍完毕。让我们再总结一下整体操作流程:

  1. 生成两对公私地址,并进行EOS帐户注册
  2. 通过jungle网站进行EOS币的领取,并对其进行余额查询
  3. 安装Scatter插件,导入私钥并绑定新身份
  4. 使用新注册的EOS帐户购买RAMCPUNET发布合约所需要的资源
  5. 创建合约测试示例并编译
  6. 编写发布合约脚本,替换合约帐户后进行合约发布
  7. 编写合约方法调用脚本,调用合约中的hi方法进行日志打印。
    通过七个步骤我们了解了整个EOS合约开发的最简化操作流程。

欢迎关注HackDApp博客或公众号, HackHook将持续为你分享IndieMaker成长路径、DAPP技术知识、高效Mac使用技巧、底层思维认知。

我的博客: https://www.hackdapp.com/
我的github: https://github.com/hackdapp
我的哔哩哔哩: https://space.bilibili.com/17360859
我的微信公众号: hackdapp

IndieMakers: https://www.indiemakers.cn

联系邮箱:55269778@qq.com

]]>
+ + + + 本教程主要面向初阶开发人员,目的在于带领大家以最简单的示例合约,通过简单但不失完整的流程,体验整个合约的编译、发布与调用过程,从而让大家从直观角度有个清晰的概念认识。 + + + + + + + + + + +
+ + + 巧用HistoryApiAction实现对链数据的存储与查询 + + https://www.hackdapp.com/archives/eosdev_datastorage_historyaction.html + 2019-03-13T08:36:13.000Z + 2021-04-07T09:31:42.556Z + + 在开发EOS DApp智能合约时,我们都知道可以使用multi_index来对合约数据的存储与查询,但合约的存储是需要消耗一定的资源的,而且随着用户的增长往往会导业务数据会越来越大,从而导致合约需要更多的资源来支撑其数据。

有时我们可以通过业务设计,让业务数据得到即时清理及资源释放。但大多数情况下,业务数据是不允许清理的,那么针对这种情况是否有其他办法来降低对合约存储资源的消耗呢?

那么,今天分享的方案就是:借用EOS链提供的history_api_action插件服务、内部合约Action调用来完成对业务数据的存储与查询。

举个🌰️:
在去中心化交易所中,往往搓合成功会产生大量的成交订单,那保存在合约数据库中肯定是不合适的,所以可以在搓合方法中通过调用内部日志方法的形式,通过交易日志来将订单数据写入区块中;然后通过EOS节点提供的查询历史action接口,查询合约日志数据并增量同步到中心化数据库。

下面,我们将通过具体的代码示例来帮助大家理解整个过程:


首先,我们新创建一个合约(dexchange.hpp/dexchange.cpp);

//dexchange.hpp
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>

using namespace eosio;

CONTRACT dexchange : public contract {
public:
using contract::contract;
dexchange(eosio::name receiver, eosio::name code, datastream<const char*> ds):contract(receiver, code, ds) {}

[[eosio::action]]
void executetrade(uint64_t pair_id, uint64_t sell_order_id, uint64_t buy_order_id);

[[eosio::action]]
void log(uint64_t deal_price, uint64_t quantity, uint64_t sell_order_id, uint64_t buy_order_id);

};

EOSIO_DISPATCH(dexchange, (executetrade)(log))

//https://gist.github.com/2b68242019242bdd12f174208e39e7d2

然后,定义并实现两个方法:executetrade、log。 executetrade合约方法负责搓合业务,当搓合业务处理完之后调用log方法,通过交易信息将参数调用数据写入区块中;

//filename: dexchange.cpp

#include "dexchange.hpp"

void dexchange::executetrade(uint64_t pair_id, uint64_t sell_order_id, uint64_t buy_order_id){
uint64_t deal_price = 1200;
uint64_t quantity = 10000;

action(
permission_level{ _self, "active"_n },
_self, "log"_n,
std::make_tuple(deal_price, pair_id, sell_order_id, buy_order_id)
).send();
}

void dexchange::log(uint64_t deal_price, uint64_t quantity, uint64_t sell_order_id, uint64_t buy_order_id){
require_auth( _self );
}

//https://gist.github.com/ea6ec431a57faee3a2823cfeee406efd

从以上示例可以看出,合约log日志方法其实并不需要做任何业务逻辑处理。只需要间接被调用,便可将我们需要的业务数据通过交易的形式记录在区块中,而不会浪费我们的合约存储空间,也不需要担心资源释放的问题。

下一步、发布智能合约,并调用一次executetrade合约方法

//发布合约至hackdappexch合约帐户
> cleos set contract hackdappexch contracts/ -p hackdappexch@active

//执行合约方法
> cleos push action hackdappexch executetrade '[1,2,3]' -p hackdappexch@active

最后,通过EOS链节点提供的RPC服务,进行历史action数据查询,通过数据过滤找到我们的日志方法及参数数据。

在确保之前的操作都成功之后,我们使用curl命令查询其对应服务:

curl --request POST \
--url https://localhost:8888/v1/history/get_actions \
--header 'content-type: application/x-www-form-urlencoded; charset=UTF-8' \
--data '{"pos":-1,"offset":-10,"account_name":"hackdappexch"}'

通过此接口查询出来的数据不仅仅是log合约方法数据,可能还会存在该合约的其他方法事件,需要根据情况再过滤一次数据。

补充说明

如果你在本地曾经搭建过EOS私链的化,那么或许看到过,EOS启动时是可以配置不同插件。而其中有一个插件history_api_plugin,就是用于监听并存储合约方法的调用信息;另外启动链节点时,是可以按规划自由指定所要监听的合约帐户及方法,如: --filter-on hackdappexch::log, 该参数配置表示只监听hackdappexch合约中的log方法。

nodeos -e -p eosio -d /mnt/dev/data \
--config-dir /mnt/dev/config \
--http-validate-host=false \
--plugin eosio::producer_plugin \
--plugin eosio::chain_api_plugin \
--plugin eosio::http_plugin \
--plugin eosio::history_api_plugin \
--http-server-address=0.0.0.0:8888 \
--access-control-allow-origin=* \
--contracts-console \
--filter-on hackdappexch:log: \
--max-transaction-time=1000 \
--verbose-http-errors &

如以上EOS节点启动命令,就展示了启动一个EOS节点的具体参数配置。其中,--filter-on参数便是指定只监听记录hackdappexch合约的log方法调用数据。

所以,当我们要通过链节点RPC服务查询合约方法历史调用数据时,需要先确认提供RPC服务的节点是否开启了history_api_plugin插件,以及自己所要查询的合约是否在其过滤规则之中。


小结

通过本篇文章,我们学会了利用内部合约方法调用 ➕️ 链节点历史Action查询的方式实现业务数据的另一种数据存储与查询方案。


在教程中如出现错误🐛或不易理解的知识点,欢迎加我微信指正!
Name: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org


changelog

2019-03-13 zhangliang

  • 初次发稿
]]>
+ + + + 在开发EOS DApp智能合约时,我们都知道可以使用`multi\\_index\_`来对合约数据的存储与查询,但合约的存储是需要消耗一定的资源的,而且随着用户的增长往往会导业务数据会越来越大,从而导致合约需要更多的资源来支撑其数据增长。那么是否有一种更好的方式来降低某些场景的资源消耗呢?那么,今天将为你分享一种数据存储方案: 借用EOS链提供的`history_api_action\_`插件、`内部合约Action调用`来完成对业务数据的存储与查询。HackDApp愿与你分享! + + + + + + + + + + + + + + +
+ + + 使用EOS.js发布EOS智能合约 + + https://www.hackdapp.com/archives/eosdev_deploycontract_eosjs.html + 2019-03-12T10:59:46.000Z + 2021-04-07T09:31:42.556Z + + 在之前的EOS合约开发文章,你可能学会了如何通过EOS系统命令cleos set contract的方式进行智能合约的发布与升级。

但在开发过程中,可能有的同学持续在命令容器与开发IDE间频繁切换,对开发效率有一定程序的影响,那是否有一种更好的方式帮助我们在一个窗口里快速发布合约呢?

那么本文将带你了解如何通过EOS.js进行智能合约的发布


如上图所示,在进行合约发布时,需要用到eos系统合约中的两个方法:setcode、setabi。而这两个方法分别会用到智能合约编译后的两个文件: *.wasm、*.abi。

注意 : 本文示例中使用的eosjs的版本为16.0.9

首先,需要初始化EOS-SDK实例。 事先准备好初始化SDK所必需的参数:

  • chainid
    所要发布的目标EOS链chainid. 例如:正式chainid: aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906; jungle测试网chainid: e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473等等
  • httpEndpoint
    EOS链环境http接口地址。 例如: http://localhost:8888
  • keyProvider
    合约帐户私钥,主要用于交易签名。
//config.js
const Eos = require('eosjs')

const eos = Eos({
chainId: "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f",
httpEndpoint: "http://localhost:8888",
keyProvider: "5K7mtrinTFrVTduSxizUc5hjXJEtTjVTsqSHeBHes1Viep86FP5",
broadcast: true,
sign: true
})

module.exports = {
eos,
}

//https://gist.github.com/hackdapp/2522411b98b1acdadc0d842f712ca6e0

下一步,需要代码实现对合约文件夹中的.wasm及.abi文件的读取;

function getDeployableFilesFromDir(dir) {
const dirCont = fs.readdirSync(dir)
const wasmFileName = dirCont.find(filePath => filePath.match(/.*\.(wasm)$/gi))
const abiFileName = dirCont.find(filePath => filePath.match(/.*\.(abi)$/gi))
if (!wasmFileName) throw new Error(`Cannot find a ".wasm file" in ${dir}`)
if (!abiFileName) throw new Error(`Cannot find an ".abi file" in ${dir}`)
return {
wasmPath: path.join(dir, wasmFileName),
abiPath: path.join(dir, abiFileName),
}
}

//https://gist.github.com/69b29103e5cc114f4478390076d8ad39

然后,通过调用eos实例,分别执行系统合约的setcode/setabi方法,从而达到智能合约的发布;

function deployContract({ account, contractDir }) {
const { wasmPath, abiPath } = getDeployableFilesFromDir(contractDir)

const wasm = fs.readFileSync(wasmPath)
const abi = fs.readFileSync(abiPath)

const codePromise = eos.setcode(account, 0, 0, wasm)
const abiPromise = eos.setabi(account, JSON.parse(abi))
return Promise.all([codePromise, abiPromise])
}

//https://gist.github.com/69b29103e5cc114f4478390076d8ad39

最后,调用deployContract方法,测试合约发布功能。

deployContract({ account: "eosio.token", contractDir: "./contract" }).then((result) => {
console.log(`Deployment successful`, JSON.stringify(result, null , 4))
})
.catch(err => {
console.error(`Deployment failed`, err)
})

//https://gist.github.com/69b29103e5cc114f4478390076d8ad39

小结

通过本文我们学习了如何通过eos实例的setcode/setabi方法将合约编译文件快速发布到指定链环境。

另外,如果为了提高发布合约效率,我们还可以在package.json中定义发布合约的运行脚本,并配合IDE工具中的快捷键,便可达到开发效率的进一步提升。


在教程中如出现错误🐛或不易理解的知识点,欢迎加我微信指正!
Name: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

注: 有想了解愿码全思维IT工程师加速器的朋友,可以扫码加群咨询。


changelog

2019-03-12 zhangliang

  • 初次发稿
]]>
+ + + + 之前我们曾经介绍过如何使用EOS的系统命令(cleos set contract)发布智能合约,那么今天将分享另外一种方式:使用eosjs-sdk发布合约。在此基础上,可以通过配置package.json脚本以及IDE快捷链,可以快速提升DApp开发效率。HackDApp愿与你分享! + + + + + + + + + + + + +
+ + + 剖析EOS合约编译ABI文件 + + https://www.hackdapp.com/archives/eosdev_contract_abi.html + 2019-03-07T11:33:14.000Z + 2021-04-07T09:31:42.555Z + + 相信不少开发者朋友在进行EOS合约开发时,都看到发布智能合约时的ABI文件。那ABI文件到底是什么东西?在EOS公链环境中到底发挥怎么样的作用呢以及如何解读ABI文件内容呢?

那么本章节将带你了解ABI文件与智能合约间的关系以及了解并学会ABI文件的编写。

ABI, 简称(Application Binary Interface), 是一个基于JSON语言的接口描述文档,用于描述EOS合约以及如何对合约方法进行调用。如果大家曾经接触过websocket、avro、hession、thrift等这类技术的化,那么是大体逻辑是相向的。比如websocket所提供的wsdl其实也是对websocket本身对外所提供服务的接口描述。

在EOS合约,ABI文件是由开发组件eosio.cdt工具包中的eosio-cpp命令执行所生成的文件。但在实际开发时,时常会碰到一些情况无法生成ABI文件。因为在合约开发,我们往往会根据业务自定义一些数据结构,或者使用一些第三方方法,而eosio.cdt本身对所有特隆并不是支持的很完善,所以时常导致编译失败,这时就需要我们理解ABI是如何定义智能合约的,以便于我们定制化修改自己的合约描述。

ABI文件结构是由什么组成的呢?让我们先看一个示例

{
"version": "eosio::abi/1.0",
"types": [],
"structs": [],
"actions": [],
"tables": [],
"ricardian_clauses": [],
"abi_extensions": [],
"___comment" : ""
}

上面json示例展示了一个标准智能合约所应具备的完整属性定义。

数据类型(type)
在项目开发过程,有时为了便于代码的理解,我们会将一些通用数据类型或数据结构进行别名定义,用一个在业务场景中更加贴合业务的名称代替。在types数组中便是对这种情况的定义描述。

比如:

{
"new_type_name": "age",
"type": "int"
}

或者

{
"new_type_name": "name",
"type": "string" //此处user为自定义数据结构
}

对于合约内嵌类型,是不会在此展示的。诸如: uint64_t、name、asset、symbol等。下图展示了EOS合约所支持的所有内置数据类型


结构体(struct)
在业务处理逻辑中,为了方便数据的传输与调用,往往我们会对针对业务数据进行建模并以结构体的形式展现。同样,它也需要在ABI文件中进行描述。

比如: eosio.token合约中的account结构体定义

  • ABI文件定义

    {
    "name": "account",
    "base": "",
    "fields": [
    {
    "name": "balance",
    "type": "asset"
    }
    ]
    }
  • eosio.token.hpp实现

    struct account {
    asset balance;

    uint64_t primary_key()const {
    return balance.symbol.code().raw();
    }
    };

另外,需要注意的就是除了以上这种结构体定义,其实还存在一种隐性结构体,即:合约方法参数
示例:

  • eosio.token.hpp中transfer方法定义

    void transfer( name    from,
    name to,
    asset quantity,
    string memo );
  • eosin.token合约中transfer方法在ABI文件中定义

    {
    "name": "transfer",
    "base": "",
    "fields": [
    {
    "name": "from",
    "type": "name"
    },
    {
    "name": "to",
    "type": "name"
    },
    {
    "name": "quantity",
    "type": "asset"
    },
    {
    "name": "memo",
    "type": "string"
    }
    ]
    }

可以看出,隐性结构体与前面所定义显性结构体定义是并没有什么不同,只是在智能合约业务逻辑中,我们仅用到显性结构体来存储我们的业务数据进行逻辑判断。


方法(Action)
Action数组主要用于描述外部可调用的方法列表以及具体的参数列表。在智能合约中,如果需要对外公开合约方法,往往会在合约头文件中进行如下定义:

[[eosio::action]]
void transfer(name from,name to, asset quantity, string memo);

而ABI的表现形式为:

{
"name": "transfer",
"type": "transfer",
"ricardian_contract": ""
}

从上述描述可以看出,在方法的类型定义关联了前面的隐性结构体类型。虽然在此处,方法名与隐性结构体类型命名一致,但实际情况并不一定非要相同。


表定义(Table)
关于表的ABI定义,相比其他几种定义要稍复杂一些。具体JSON定义如下

{
"name": "",
"type": "",
"index_type": "",
"key_names" : [],
"key_types" : []
}

JSON中字段说明如下:

  • name
    合约初始化表时所要使用的名称
  • type
    表对应的数据结构体。也就是前面所说的显性结构体类型
  • index _type
    此类型为表主键类型
  • key _names
    索引字段列表
  • key_types
    索引字段数据类型列表。数据长度与索引字段列表长度一致。需要说明的是索引字段类型,只支持uint64_t,uint128 _t,uint256 _t,double,long double五种类型
    示例:eosio.token合约中的accounts表
  • ABI表定义

    {
    "name": "accounts",
    "type": "account",
    "index_type": "i64",
    "key_names": ["primary_key"],
    "key_types": ["uint64"]
    }
  • 表合约代码

    struct [[eosio::table]] account {
    asset balance;

    uint64_t primary_key()const { return balance.symbol.code().raw(); }
    };

从表合约代码可以看来,只需要在数据结构体代码中添加eosio-table标签就可以完成对表的定义操作。

之所以提供多索引的实现,主要还是为了应对业务场景中不同维度的数据查询,而且支持按升序或降序的遍历方式处理业务。


ricardian条款(ricardian_clauses)
该数组主要用于定义一种基于文本的合约宪法。通过其与智能合约的整合,来解决一些无法通过程序来判定的情况。

示例如下:

"ricardian_clauses": [{
"id": "Warranty",
"body": "WARRANTY. The invoker of the contract action shall uphold its Obligations under this Contract in a timely and workmanlike manner, using knowledge and recommendations for performing the services which meet generally acceptable standards set forth by EOS.IO Blockchain Block Producers.\n\n"
},{
"id": "Default",
"body": "DEFAULT. The occurrence of any of the following shall constitute a material default under this Contract: \n\n"
},{
"id": "Remedies",
"body": "REMEDIES. In addition to any and all other rights a party may have available according to law, if a party defaults by failing to substantially perform any provision, term or condition of this Contract, the other party may terminate the Contract by providing written notice to the defaulting party. This notice shall describe with sufficient detail the nature of the default. The party receiving such notice shall promptly be removed from being a Block Producer and this Contract shall be automatically terminated. \n \n"
}
]

我们可以针对智能合约或者具体的合约方法,附加上对应的文本合约描述。比如针对方法的文本合约定义:

  • ABI定义

    "actions": [{
    "name": "hi",
    "type": "hi",
    "ricardian_contract": "# CONTRACT FOR hello::hi## ACTION NAME: hi\n### Parameters### Parameters\nInput parameters:Input parameters:\n\n* `user` (string to include in the output)* `user` (string to include in the output)\n\nImplied parameters: Implied parameters: \n\n* `account_name` (name of the party invoking and signing the contract)* `account_name` (name of the party invoking and signing the contract)\n\n### Intent### Intent\nINTENT. The intention of the author and the invoker of this contract is to print output. It shall have no other effect.INTENT. The intention of the author and the invoker of this contract is to print output. It shall have no other effect.\n\n### Term### Term\nTERM. This Contract expires at the conclusion of code execution.TERM. This Contract expires at the conclusion of code execution.\n"
    }]
  • 代码及文件定义(hello.hi_rc.md)

    # CONTRACT FOR hello::hi

    ## ACTION NAME: hi

    ### Parameters
    Input parameters:

    * `user` (string to include in the output)

    Implied parameters:

    * `account_name` (name of the party invoking and signing the contract)

    ### Intent
    INTENT. The intention of the author and the invoker of this contract is to print output. It shall have no other effect.

    ### Term
    TERM. This Contract expires at the conclusion of code execution.

ABI Extensions
该功能将允许用户进行自定义区块扩展, 包括对数据的签名、编码等。不过现在该属性暂未被应用支持。


到此,相信大家对于整个ABI文件的结构应该有了大体的认识与理解。这样大家可以在研究其他智能合约时,可以首先阅读对方的ABI文件,就可以熟悉对方的整体接口框架。


在教程中如出现错误🐛或不易理解的知识点,欢迎加我微信指正!
Name: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org


changelog
2019-03-07 zhangliang

  • 初次发稿
]]>
+ + + + 每个EOS合约开发者肯定都知道ABI文件,但却不一定都知道ABI内部属性是什么,具体作用。本文hackdapp将带你一探ABI究竟。HackDApp愿与你分享! + + + + + + + + + + + + + + +
+ + + 重塑思维:自律 VS 习惯 + + https://www.hackdapp.com/archives/rebuildbrain_habit.html + 2019-02-14T07:46:39.000Z + 2021-04-07T09:31:42.555Z + + 自律使我压抑,习惯助我成长。 自律与习惯,其实目标都是一致的,只是所产生的行动动力源是不相同的。

相信每个人都在不停的思考一个问题,“我如何才能使明天的自己比今天的自己更加优秀一些呢?”

为了让自己变得更好,我们去总结规律,改变自我认知,希望能从不断的思维升级过程中,锻造出属于自己的思维工具,培养及丰富问题症结的方案库。

为了让自己变得更好,我们需要靠意志去坚持去做一件让自己变得优秀的事情,但你发现一段时间之后,这件事不了了知,扔那儿放下了,因为这样的事在我的人生当中简直太熟悉不过了。

相反,有一些行为却长期固化下来了,比如我们的一些日常洗漱习惯,即使你中途有一段时间没去做,那你也不会放弃这件事。

当某一种行为已经成为你的习惯时,如果你有意识的去观察一下,会发现一些许规律。比如:刷牙,可能现在没有不早晚刷牙的童鞋吧。不妨想一想这个行为大家保持了多少年,到现在是否还需要各种精神动力去推着自己去做这个事吗?

明显不需要,可以说这已经是写入自己骨头里的一种惯性行为,你要是不注意都不发现它原来其实就是一个号的学习榜样。因为它太习以为常了,平常的都忘掉它的存在。

那既然刷牙可以养成习惯,那我们其他行为为啥就不能养成一种习惯呢?

首先,处于习惯性的行为执行过程并不会让你特别有心理负担;
其次,习惯中的行为并不会消耗自己稀缺的精力;
最后,行为关联及导向性。也就是习惯行为之间的联动开关。比如:洗漱的时候总能与刷牙这件事产生一定的链接,而这个链接往往就是我们通过意识去不断增强脑回路而形成的。

之所以总结这些,就是因为我身上的一件事,当时看李笑来的专栏里曾经提到一种感受,就是“不做这件事就难受”。 当时是在是无法理解这种状态,除了吃饭这件事,找不出天天不做就难受的事来,当你无法从自身找到可以参考的例子时,你总是无法理解其概念。

直到我发现身上这件事,刮胡子。对,你没看错,就是刮胡子。

为什么讲呢?因为之前总是用电动剃须刀,总是容易忘记用,时做时不做的,而且刮的也不是太干净。直到有一天看到京东做活动卖手动剃须刀,想着买来试一试,但当时也犹豫,每天早上用这个会不会特花时间啊。

但事实证明,相比电动剃须刀,手动的虽然要麻烦一些,时间也要多花费一些。但这件事我却坚持了一年,直至今日从心理感受来讲,自己并没有感觉每天要逼着自己去做这件事,而是很自觉的每天洗漱后自动进入刮胡子状态。

为什么会这样呢?因为每一次刮完胡子,对着镜子一照,感觉干净清爽,漂亮,帅气。让我从内心看到一个舒服的自己,这算不算是一种仪式感呢。

后来,我总结了一下习惯养成的一个关键因素:持续的心理反馈。反馈可以让我们感受到变化与进步,或是一种心理满足;而持续性一来可以增强行为的动力,二过可以慢慢促进脑回路的链接建立。

那么,如何建立自己的习惯养成路径呢?那就是

  1. 先制定一个你绝对认可其价值的目标;
  2. 在意识中建立诱导因子,也就是你需要在已形成的习惯之中,建立一个与新行动的触感连接;
  3. 持续反馈,每天都要总结,让自己内心见证成长,而后通过持续达到巩固行动的动力。

小结

好的习惯、应用技巧及思维方式是可以产生复利效应价值的,关键在于它不是形式上的应用,不是为技巧而技巧,一定是在我们的生活或工作实际场景中解决实际问题,并以此不断反馈价值收获,而持续的价值收益又会加强我们执行的动力,最终形成一个正向向上的良性循环♻️。

执行力其实是落实行动的第一要素,所以我们需要学会如何去补充这项能源。而最好的方式就是让自己认可这件事的价值。并且能够在做事的过程中,有深刻的反馈与心理感受,学会记录自己的心理变化。

最后,通过不断的执行与反馈,增强我们的脑回路链接。久而久之,就会成为我们的习惯。

]]>
+ + + + 本周最大的收获就是:搞清楚自律与习惯间的转换逻辑。明白靠自律去约束自己只能不断内耗意志力,相反如果通过打造系统逻辑,形成习惯便可从根本上提高效率。因为本身习惯不消耗意志力而是一种肌肉反应能力。HackDApp愿与你分享! + + + + + + + + + + + + +
+ + + C++基础语法(EOS完全开发指南) + + https://www.hackdapp.com/archives/eosdev_cplus_basic.html + 2019-01-28T10:16:50.000Z + 2021-04-07T09:31:42.554Z + + Author: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

/* filename: myapp.cpp
date: 2019-01-28 3:06 PM
auth: zhangliang<zhangliang@cldy.org> */

#include <iostream> //定义头文件
#include <stdlib.h>

int main()
{
using namespace std; //命令空间, 简化后续变量或方法调用。e.g. std::string 等同于 string

string msg = "hi, my first dapp"; //定义变量

cout << msg <<endl; //打印字符串
}

//tryit: http://tpcg.io/Tulum1

以上代码便是C++最简单可运行的最小示例。基本包含了在程序结构中所必须的一些语言特性。

根据上述程序结构,我们可以大致将它拆分成五部分内容:

1. #include <iostream>

头文件定义主要用于引用第三方函数库,通过调用第三方函数可以减少开发代码量,提高开发效率,同时也避免了不必要的重复造轮子。

比如:通过引用<cmath>库,可以帮助我们快速使用里面的函数进行一些数学运算。

函数列表

所以,后续我们需要学会便是如何查阅C++文档库,不断积累与完善对于第三方标准库的方法学习与理解。

2. int main()

main函数区别于其它普通函数之处在于: main函数默认被系统定义为应用入口调用方法。除此之外,与其他函数无任何区别。

#include <iostream>
#include <stdlib.h>

using namespace std;

string sayHi(string username)
{
return string("hi, ").append(username).append("!");
}

int main()
{
cout << sayHi("www.hackdapp.com") << endl;
}
//tryit: http://tpcg.io/uHUkzy

函数定义,其实对于所有编程语言的定义方式大致相同, 都可以表现为以下形式

<返回类型|void> 方法名(参数定义1, 参数定义2,参数定义...)
{
//do some stuff
return <返回数据>
}

如果你之前已经在使用其他编程语言,那么应该对于C++其实也可以很好的理解它的程序结构。

注: 在后续的第二部分,我们会详细介绍函数的多种定义及使用方式,包括形参实参、重载以及虚函数等。

3. string message = "hi, my first app"

变量定义,在程序开发过程,往往需要定义一些临时变量,用于存储在数据逻辑处理过程所必须的临时存储。

而变量的类型,主要分为字符、整型,长/短整型、单精度、双精度、布尔类型以及字符串。
我们在实际应用场景中,需要明确了解与知道这些基础数据类型的定义及边界范围,比如,无符号整型、单精度。

尤其是对数字类型的字段,如果不了解其边界范围,很可能会导致运算溢出等问题,特别是在合约开发过程中,数字溢出很可能导致的便是相当大的经济损失。

换个角度讲,合理的使用变量类型,也可能在一定程序中节省资源的浪费。因为在EOS合约中存储数据是需要消耗资源的。

另外,对于变量的名称定义,其名称只能是由数字、字母以及下划线组成且不可能以数字开头,而且根据不同平台,对于名称的长度其实也是存在限制的。

4. cout << msg <<endl

coutiostream函数库中的一个流数据输出函数,一般用于在程序调用过程向控制台输入一些调试信息;与此对应的是cin, 用于接收输入数据流。

不过, 在EOS合约中无法调用此函数。举而代之的是,EOSLIB库自己封装的print函数.

5. //单行注解 or /*多行注解*/

在程序开发过程,往往需要通过语言描述某个代码文件所要实现的整体功能或者某个函数的功能、参数及约束说明。这时候就需要用到注解。

而注解同样也所有的编程语言中也大致相同,一般分为单行注释与多行注释。

单行注释适用于短小的描述某一行运行逻辑;而多行注释多用于描述函数说明以及文件功能说明。


注: 在教程中如出现不易理解或存在错误的问题🐛,欢迎评论留言!

]]>
+ + + + <p><code>Author: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org</code></p> +<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="comment">/* filename: myapp.cpp</span></span><br><span class="line"><span class="comment"> date: 2019-01-28 3:06 PM</span></span><br><span class="line"><span class="comment"> auth: zhangliang&lt;zhangliang@cldy.org&gt; */</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt; //定义头文件</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>; <span class="comment">//命令空间, 简化后续变量或方法调用。e.g. std::string 等同于 string</span></span><br><span class="line"></span><br><span class="line"> <span class="built_in">string</span> msg = <span class="string">"hi, my first dapp"</span>; <span class="comment">//定义变量</span></span><br><span class="line"></span><br><span class="line"> <span class="built_in">cout</span> &lt;&lt; msg &lt;&lt;<span class="built_in">endl</span>; <span class="comment">//打印字符串</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//tryit: http://tpcg.io/Tulum1</span></span><br></pre></td></tr></table></figure> +<p>以上代码便是C++最简单可运行的最小示例。基本包含了在程序结构中所必须的一些语言特性。</p> +<p>根据上述程序结构,我们可以大致将它拆分成五部分内容:</p> + + + + + + + + + + + + +
+ + + C++导读(EOS完全开发指南) + + https://www.hackdapp.com/archives/eosdev_cplus_intro.html + 2019-01-28T10:08:35.000Z + 2021-04-07T09:31:42.555Z + + Author: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

本章节内容主要是带大家了解C++整个编程语言的体系架构,对C++编程语言有个整体的大致的认识与理解。另外,也是帮助大家在开发EOS智能合约之前做一下前期预习,易于对后面EOS合约的快速上手。

另外,需要说明的是,因为本身EOS智能合约是在一个沙箱机制中运行,所以它对一些标准函数库的方法进行了一些限制。所以可能导致大家可能在网上找的资料中的方法无法在合约中正常执行。

另一个角度讲,正是由于这种限制,也是减小了我们的学习范围,这样我们就不需要完全掌握的整个C++的语言体系,便可以开发智能合约。比如:文件操作读取,时间函数,随机数,这些在EOS合约里是都不可用的。 不过,有一个问题就是你无法明确知道哪些功能被禁用了,只能去试。或者官网有说明,可能我没有看到而已。

在整个开发过程,你只需要学会使用一些基础语法,简单数据类型、数据结构以及常用的一些工具库。比如:如何处理字符串,如何存储或操作数据结构。

除此之外,再掌握一些程序设计技巧,就可以实战开发自己的DApp应用了,而本身程序设计其实是与哪种程序语言不存在直接关系的,只是让你的程序有更好的应对扩展。

通过本章节内容你可以学会:

  • 对基础数据类型以及它们的数据边界有清晰的认识;
  • 学会如何使用不同数据结构处理业务场景中的问题;
  • 学会如何定义自己的函数;
  • 学会如何面对对象的思维设计自己的合约;
  • 学会如何通过模板封装形成自己的工具库;
  • 了解一些常用的标准库文件及常用的函数工具方法;
  • 学会如何通过手册查找工具函数

本章节,将会从以下八个部分进行分类介绍:

1.1 C++基础语法
1.2 基础数据类型及变量、常量定义
1.3 结构体及函数定义
1.4 数据结构
1.5 面向对象编程
1.6 高级应用(模板定义)
1.7 标准库及库函数
1.8 资源及经验分享


注: 在教程中如出现不易理解或存在错误的问题🐛,欢迎评论留言!

]]>
+ + + + <p><code>Author: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org</code></p> +<p>本章节内容主要是带大家了解C++整个编程语言的体系架构,对C++编程语言有个整体的大致的认识与理解。另外,也是帮助大家在开发EOS智能合约之前做一下前期预习,易于对后面EOS合约的快速上手。</p> +<p>另外,需要说明的是,因为本身EOS智能合约是在一个沙箱机制中运行,所以它对一些标准函数库的方法进行了一些限制。所以可能导致大家可能在网上找的资料中的方法无法在合约中正常执行。</p> + + + + + + + + + + + + +
+ + + 坚持的长性 + + https://www.hackdapp.com/archives/think_habit.html + 2019-01-21T01:31:24.000Z + 2021-04-07T09:31:42.554Z + +

今天早上算是被媳妇嘲笑了一番,为啥呢?

因为之前自己有一段时间,为了背英语单词,所以早起了一个月,而如今早一天晚一天,早起完全看心情。

媳妇给出的评价就是:用劲过猛,要么及早要么极迟,完全是一种过激行为。

同时她也给出建议:只要比上班的时间多出一小时其实就可以做很多事情。重要的是常态化。


2019开始了,自己确没开始。以前都早早给自己作出各种规划,对比现在,还不如之前的自己吗?不应该是每年比前一年好一些吗或者每天比昨天好一些吗?

哦,也可能是最近超忙,导致各种规划的推迟。但内心同时又会想起另外一种声音:不,你不是,你只是懒。事情没把你逼到一种绝境上,你是不会立即行动的。

2019要做的事

  1. 早起,不早起怎么做重要的事;而且希望能找到一些习惯思维方式;
  2. 持续写作,写一本自己的技术书籍,打造自己的硬核;
  3. 持续总结,不犯过去犯的错,少走弯路;
  4. 思考习惯养成路径,以便培养自己新习惯的有效成功率

注:事情不在多,夯实好这几点。

目前的状态

  • 时不时早起起来做一些事情,可能是工作上的,也可能是生活上的,但缺少对书的阅读;另外,感觉早上精力特别出奇的好,是否应该做一些最重要的事情,而读书的化放在晚上的时候。
  • 未达到持续写东西的地步,需要检讨;可能存在的原因: 对于第二天早上要写的东西,前一天没有大致规划;或者说并不需要规划,每天早上写的时候就按之前的套路写就可以了,不讲究一次写完写完美,而是持续写出自己的每个内容点,草稿结束后再修改,也是告诉自己好文章是持续修改出来的,不可能写完就扔那儿了,而是要持续完善。包括今天写的这篇,其实也是由之前早上写的卡片扩展而来的。
  • 总结之前过于重视形式化。总结对于我来讲,总感觉认可但又未给予足够的重视,因为总是断断续续的写一些自检清单。可能这个和习惯的养成也是一样,归根到底是没有成长的即视感,也就是没有反馈。比如:刮胡子,为什么要举这个例子呢?因为之前用电动剃须刀时,总是时不时刮一次;而用手动刮胡刀后,发现自己几乎每天都会坚持这件事。当时再想为什么这件事能坚持的如此之前呢?那其他事情怎么不能坚持下去呢?我是否能够从刮胡子这件事情中找到自己内心的那一份认识与感受呢。后来才发现,那是因为刮胡子这件事能让我内心出现一份好形象不邋遢的意识。洗漱的时候就是在潜意识里调动这份动力,而且在刮完胡子后更加让自己内心得以满足,这不正是一种仪式感吗?
  • 正在有意识,感受自己每天坚持做一件事情的内心是如何的?

所以,如果要让某个行为成为你的习惯,你就要从内心上提高对它的认可,以及最重要的一件事,你要寻找你的内心感受,是什么让你满足。如果这个不好理解的话,我给你的建议就是观察你已有的习惯中想想那是一种什么感觉,做个比较可能会更形象一些。

]]>
+ + + + + + <p><img src="https://ws1.sinaimg.cn/large/006tNc79gy1fzdyksu0ykj30qy0dw400.jpg" alt></p> +<p>今天早上算是被媳妇嘲笑了一番,为啥呢?</p> +<p>因为之前自己有一段时间,为了背英语单词,所 + + + + + + + + + + + + + + + +
+ + + 波场Tron-可快捷开发的实战工程模板 + + https://www.hackdapp.com/archives/tron_boilerplate.html + 2019-01-11T22:42:54.000Z + 2021-04-07T09:31:42.554Z + +
 _                         _           _ _                 _       _
| |_ _ __ ___ _ __ | |__ ___ (_) | ___ _ __ _ __ | | __ _| |_ ___
| __| '__/ _ \| '_ \ _____| '_ \ / _ \| | |/ _ \ '__| '_ \| |/ _` | __/ _ \
| |_| | | (_) | | | |_____| |_) | (_) | | | __/ | | |_) | | (_| | || __/
\__|_| \___/|_| |_| |_.__/ \___/|_|_|\___|_| | .__/|_|\__,_|\__\___|
|_|

Tron-Boilerplate, 是基于Tron公链的一套可快速搭建本地私链环境、发布合约以及配置完整的标准工程模板。

该工程模板旨在于帮助大家快速工程化本地开发环境,减少环境搭建以及调试开发流程过程中所需花费的大量时间,让大家将更多精力投入到产品设计与核心业务逻辑实现上。

使用提供的工程模板,可从以下四个方面提升开发效率:

  • 一键启动或暂停私链环境
  • 一键编译智能合约
  • 一键发布智能合约
  • 一键单元测试(jtest)

同时,本工程模板附带了一个完整的示例代码(Todolist),可供大家参考与学习。示例效果如下:

最后,开发人员只需按照项目工程结构,编写自己的智能合约、前端页面及与SDK交互逻辑即可。


前置依赖

1. 安装docker

Install Docker for Mac : https://docs.docker.com/docker-for-mac/
Install Docker for Windows: https://docs.docker.com/docker-for-windows/install/

更多资料可参考: https://docs.docker.com

2. 安装node

To install or update nvm, you can use the install script using cURL:

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

or wget

wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

The script clones the nvm repository to /.nvm and adds the source line to your profile (/.bash_profile, /.zshrc, /.profile, or /.bashrc)._

export NVM_DIR="${XDG_CONFIG_HOME/:-$HOME/.}nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

更多资料可参考: https://github.com/creationix/nvm#installation

3. 安装jdk8

JDK8: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

如果大家不使用tron提供的tron-studio开发合约的化,可以选择不安装此项。因为使用tronbox同样也可以编译以及发布合约。

4. 安装tronbox

npm install -g tronbox

注:对于最新的 Java-Tron Odyssey 3.2 版本,最小兼容的 TronBox 版本是 TronBox 2.2.1。请确保您已安装此版本。

更多资料:https://cn.developers.tron.network/docs/%E5%85%A5%E9%97%A8

5. 开发工具

开发工具可根据自己喜好自由选择,个人比较推荐VSCode

官网链接:https://code.visualstudio.com/

工程安装与使用

1. 克隆工程

git clone git@github.com:ChainDesk/tron_boilerplate.git

工程结构介绍

# 项目地址: https://github.com/ChainDesk/tron_boilerplate
# 注:待工程稳定后,可能会考虑做成插件,可使用yeoman快速构建,欢迎大家star.
.
├── README.md
├── bin
│   ├── libs
│   │   └── TronStudio.jar//TronStudio开发工具包
│   ├── start_docker.sh//启动私链
│   ├── start_tronstudio.sh//启动TronStudio
│   └── stop_docker.sh//停止私链
├── build//合约编译生成目录
│   └── contracts
│   ├── HelloWorld.json//示例合约ABI, HelloWorld
│   ├── Migrations.json
│   └── TodoList.json //示例合约ABI, TodoList
├── contracts//合约目录,大家合约都放在这儿
│   ├── HelloWorld.sol
│   ├── Migrations.sol
│   └── TodoList.sol
├── migrations//发布合约目录
│   ├── 1_initial_migration.js
│   └── 2_deploy_contracts.js //新添加的合约需要在此文件中定义,否则无法通过tronbox deploy命令发布
├── package-lock.json
├── package.json//前端App工程及依赖包定义,以及多个服务启动命令。
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
├── src//前端React代码目录
│   ├── TodoList.js
│   ├── contracts
│   │   └── TodoList.json //合约ABI文件
│   ├── index.js
│   ├── serviceWorker.js
│   └── tronweb.js //新启动的工程,需要根据私链生成的私钥以及新发布的合约地址在此重新修改。
├── test//jtest测试目录,方便大家编写测试用例
│   └── web.test.js
├── tronbox-config.js
└── tronbox.js//发布合约所依赖的配置,此文件定义了本地、测试以及正式网络的http访问地址

12 directories, 27 files

2. 工程初始化

npm install

这一步主要用于更新前端框架react所依赖的包文件,依赖包安装成功后,会在工程目录下看到一个node_modules文件夹。

如果你的前端选型不是react的化,也可根据自己需求进行依赖包配置修改。

3. 正式开发流程

3.1 启动链环境

执行cmd+shift+p,调用vscode的命令列表,选择run task从中选择start_docker任务_


同样,如果要停止当前docker环境,只需选择stop_docker脚本即可。_

所有的执行任务配置默认只存在两个地方:

  • tron_boilerplate/.vscode/tasks.json_
  • package.json中的scripts
    大家可根据自己需要进行添加或修改,而且也可以通过IDE本身的快捷键映射对应的任务。

3.2 发布合约

运行task任务,然后从中选择npm deploy, 即可发布当前所有合约至私链环境。

合约发布成功后,会显示如下:

Using network 'development'.

Running migration: 1_initial_migration.js
Replacing Migrations...
Migrations:
(base58) TBC7CqpjBxGUt9Z9hhM4QNRFF5osvG3j6r
(hex) 410d68b1bfd19d341bd0f772fad8697432d0d771be
Saving successful migration to network...
Saving artifacts...
Running migration: 2_deploy_contracts.js
Replacing TodoList...
TodoList:
(base58) TFyEw5qRRiZTJ5boLZJxZnv2hnhpBuvkjm
(hex) 4141d25df475fe0c053a9e2ed3a77faa10329185f0
Saving successful migration to network...
Saving artifacts...

3.3 修改配置参数

打开文件, tron_boilerplate/src/tronweb.js, 代码如下: _

...
const fullNode = new HttpProvider('http://127.0.0.1:8090');
const solidityNode = new HttpProvider('http://127.0.0.1:8091');
const eventServer = 'http://127.0.0.1:8092';

const privateKey = "<私钥地址>";
const contractAddr = "<合约地址>";
......

3.4 启动react服务

执行cmd+shift+p,调用vscode的命令列表,选择run task从中选择npm start即可启动前端服务。

打开浏览器,访问http://localhost:3000, 验证是否成功。


到此,整个工程的搭建及开发流程就介绍完毕,如中间出现任何问题欢迎加我个人微信咨询。

开发资料


在教程中如出现不易理解或存在错误的问题,欢迎加我微信指正!
Name: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

]]>
+ + + + 本教程通过以自己定制的工程模板为示例,讲解工程构建、快捷键部署私链及整体完整的开发注程,并配以操作动图帮助大家理解。hackdapp愿与你分享。 HackDApp愿与你分享! + + + + + + + + + + +
+ + + 2019MetaLife + + https://www.hackdapp.com/archives/2019metalife.html + 2019-01-07T16:28:42.000Z + 2021-04-07T09:31:42.553Z + + 新年愿意清单

  • 尝试每天500字,锻炼文字组织能力
  • 做一款自己的小众产品,用户达到100人
  • 尝试录制短视频
  • 出版一本书籍
]]>
+ + + + + + <p><strong>新年愿意清单</strong></p> +<ul> +<li>尝试每天500字,锻炼文字组织能力</li> +<li>做一款自己的小众产品,用户达到100人</li> +<li>尝试录制短视频</li> +<li>出版一本书籍</li> +</ul> + + + + + + + + +
+ +
diff --git a/baidu_verify_3oa53OCFMq.html b/baidu_verify_3oa53OCFMq.html index e69de29b..58faed05 100644 --- a/baidu_verify_3oa53OCFMq.html +++ b/baidu_verify_3oa53OCFMq.html @@ -0,0 +1,23 @@ + | HackDApp
\ No newline at end of file diff --git a/baidusitemap.xml b/baidusitemap.xml index e69de29b..2b2de7ff 100644 --- a/baidusitemap.xml +++ b/baidusitemap.xml @@ -0,0 +1,71 @@ + + + + https://www.hackdapp.com/archives/how-to-impl-nft-proj.html + 2021-06-28 + + + https://www.hackdapp.com/archives/how-to-make-goodnotes.html + 2021-06-07 + + + https://www.hackdapp.com/archives/20210428-%E5%A6%82%E4%BD%95%E6%8F%90%E9%AB%98%E9%98%B2%E7%8C%9D%E6%AD%BB%E7%9A%84%E8%83%BD%E5%8A%9B.html + 2021-04-28 + + + https://www.hackdapp.com/archives/how_to_write_ad_fast.html + 2021-04-07 + + + https://www.hackdapp.com/archives/Sun%20Feb%2028%202021%2000:00:00%20GMT+0800%20(China%20Standard%20Time).html + 2021-04-07 + + + https://www.hackdapp.com/archives/how-to-improve-return-risk-ratio.html + 2021-04-07 + + + https://www.hackdapp.com/archives/try_eoscontract_dev.html + 2021-04-07 + + + https://www.hackdapp.com/archives/simple_cpllus_code.html + 2021-04-07 + + + https://www.hackdapp.com/archives/eosdev_deploycontract_eosjs.html + 2021-04-07 + + + https://www.hackdapp.com/archives/eosdev_datastorage_historyaction.html + 2021-04-07 + + + https://www.hackdapp.com/archives/eosdev_cplus_intro.html + 2021-04-07 + + + https://www.hackdapp.com/archives/rebuildbrain_habit.html + 2021-04-07 + + + https://www.hackdapp.com/archives/eosdev_contract_abi.html + 2021-04-07 + + + https://www.hackdapp.com/archives/tron_boilerplate.html + 2021-04-07 + + + https://www.hackdapp.com/archives/think_habit.html + 2021-04-07 + + + https://www.hackdapp.com/archives/eosdev_cplus_basic.html + 2021-04-07 + + + https://www.hackdapp.com/archives/2019metalife.html + 2021-04-07 + + \ No newline at end of file diff --git "a/categories/EOS\345\256\214\345\205\250\345\274\200\345\217\221\346\214\207\345\215\227/index.html" "b/categories/EOS\345\256\214\345\205\250\345\274\200\345\217\221\346\214\207\345\215\227/index.html" index e69de29b..51c1cb89 100644 --- "a/categories/EOS\345\256\214\345\205\250\345\274\200\345\217\221\346\214\207\345\215\227/index.html" +++ "b/categories/EOS\345\256\214\345\205\250\345\274\200\345\217\221\346\214\207\345\215\227/index.html" @@ -0,0 +1,13 @@ +EOS完全开发指南 | HackDApp
\ No newline at end of file diff --git a/categories/Write/index.html b/categories/Write/index.html index e69de29b..f2f9a4be 100644 --- a/categories/Write/index.html +++ b/categories/Write/index.html @@ -0,0 +1,13 @@ +Write | HackDApp \ No newline at end of file diff --git "a/categories/\344\273\245\345\244\252\345\235\212\350\257\276\347\250\213/index.html" "b/categories/\344\273\245\345\244\252\345\235\212\350\257\276\347\250\213/index.html" new file mode 100644 index 00000000..635c48ca --- /dev/null +++ "b/categories/\344\273\245\345\244\252\345\235\212\350\257\276\347\250\213/index.html" @@ -0,0 +1,13 @@ +以太坊课程 | HackDApp \ No newline at end of file diff --git "a/categories/\345\214\272\345\235\227\351\223\276\346\212\200\346\234\257/index.html" "b/categories/\345\214\272\345\235\227\351\223\276\346\212\200\346\234\257/index.html" index e69de29b..de4fbeac 100644 --- "a/categories/\345\214\272\345\235\227\351\223\276\346\212\200\346\234\257/index.html" +++ "b/categories/\345\214\272\345\235\227\351\223\276\346\212\200\346\234\257/index.html" @@ -0,0 +1,13 @@ +区块链技术 | HackDApp \ No newline at end of file diff --git "a/categories/\345\277\203\350\204\217\345\214\273\345\255\246\350\257\276/index.html" "b/categories/\345\277\203\350\204\217\345\214\273\345\255\246\350\257\276/index.html" new file mode 100644 index 00000000..ccbfc177 --- /dev/null +++ "b/categories/\345\277\203\350\204\217\345\214\273\345\255\246\350\257\276/index.html" @@ -0,0 +1,13 @@ +心脏医学课 | HackDApp \ No newline at end of file diff --git "a/categories/\346\200\235\347\273\264\350\256\244\347\237\245/index.html" "b/categories/\346\200\235\347\273\264\350\256\244\347\237\245/index.html" index e69de29b..d3fb35c6 100644 --- "a/categories/\346\200\235\347\273\264\350\256\244\347\237\245/index.html" +++ "b/categories/\346\200\235\347\273\264\350\256\244\347\237\245/index.html" @@ -0,0 +1,13 @@ +思维认知 | HackDApp \ No newline at end of file diff --git "a/categories/\346\212\225\350\265\204/index.html" "b/categories/\346\212\225\350\265\204/index.html" index e69de29b..49027a11 100644 --- "a/categories/\346\212\225\350\265\204/index.html" +++ "b/categories/\346\212\225\350\265\204/index.html" @@ -0,0 +1,13 @@ +投资 | HackDApp \ No newline at end of file diff --git "a/categories/\346\226\260\345\271\264\350\256\241\345\210\222-2019/index.html" "b/categories/\346\226\260\345\271\264\350\256\241\345\210\222-2019/index.html" index e69de29b..7426c977 100644 --- "a/categories/\346\226\260\345\271\264\350\256\241\345\210\222-2019/index.html" +++ "b/categories/\346\226\260\345\271\264\350\256\241\345\210\222-2019/index.html" @@ -0,0 +1,13 @@ +新年计划(2019) | HackDApp \ No newline at end of file diff --git "a/categories/\347\237\245\350\257\206\345\215\241\347\211\207/index.html" "b/categories/\347\237\245\350\257\206\345\215\241\347\211\207/index.html" new file mode 100644 index 00000000..088e97b1 --- /dev/null +++ "b/categories/\347\237\245\350\257\206\345\215\241\347\211\207/index.html" @@ -0,0 +1,13 @@ +知识卡片 | HackDApp \ No newline at end of file diff --git "a/categories/\350\256\244\347\237\245/index.html" "b/categories/\350\256\244\347\237\245/index.html" index e69de29b..e3318432 100644 --- "a/categories/\350\256\244\347\237\245/index.html" +++ "b/categories/\350\256\244\347\237\245/index.html" @@ -0,0 +1,13 @@ +认知 | HackDApp \ No newline at end of file diff --git a/css/default.css b/css/default.css index e69de29b..123efd87 100644 --- a/css/default.css +++ b/css/default.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; +} diff --git a/css/donate.css b/css/donate.css index e69de29b..a2af08ce 100644 --- a/css/donate.css +++ b/css/donate.css @@ -0,0 +1,273 @@ +html, html>body { + margin: 0px !important; + padding: 0px !important; + height: 100%; + width: 100%; +} +body { + font-family: "Helvetica Neue", Ubuntu, "WenQuanYi Micro Hei", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", "Wenquanyi Micro Hei", "WenQuanYi Micro Hei Mono", "WenQuanYi Zen Hei", "WenQuanYi Zen Hei", "Apple LiGothic Medium", "SimHei", "ST Heiti", "WenQuanYi Zen Hei Sharp", Arial, sans-serif; + -webkit-font-smoothing:antialiased; + line-height: 1.8em; + text-shadow: 0 0 1px rgba(255,255,255,0.1); + background: #fff; +} +img {border-width: 0px;} +a{ + color: #000; + text-decoration: none; + outline:none; + border:none; +} +.list, .list li, .list-left li { + list-style: none; + list-style-type: none; + margin: 0px; + padding: 0px; +} +.pos-f { + position: fixed; +} +.left-100 { + width: 100%; + height: 100%; +} +.blur { + -webkit-filter: blur(3px); + filter: blur(3px); +} +.tr3 { + transition: all .3s; +} +#DonateText { + position: fixed; + font-size: 12px; + width: 70px; + height: 70px; + line-height: 70px; + color: #fff; + background: #ffd886 url(../img/like.svg) no-repeat center 10px; + background-size: 20px; + border-radius: 35px; + text-align: center; + left: calc(50% - 120px); + top: calc(50% - 60px); + z-index: -1; + transform: rotatez(-15deg ); +} +#donateBox { + left: calc(50% - 150px); + top: calc(50% - 15px); + background-color: #fff; + border: 1px solid #ddd; + border-radius: 6px; + width: 299px; + height: 28px; + float: left; + z-index: 1; +} +#donateBox li { + width: 74px; + /*float: left;*/ + float: right; + text-align: center; + border-left: 1px solid #ddd; + background: no-repeat center center; + background-color: rgba(204, 217, 220,0.1); + background-size: 45px; + transition: all .3s; + cursor: pointer; + overflow: hidden; + line-height: 600px; + height: 28px; + -webkit-filter: grayscale(1); + filter: grayscale(1); + opacity: 0.5; +} +#donateBox li:hover { + background-color: rgba(204, 217, 220,0.3); + -webkit-filter: grayscale(0); + filter: grayscale(0); + opacity: 1; +} +#donateBox>li:first-child { + border-width: 0; +} +#donateBox a { + display: block; +} +#donateBox #PayPal { + background-image: url(../img/paypal.svg); +} +#donateBox>#BTC { + background-image: url(../img/bitcoin.svg); + line-height: 28px; +} +#donateBox>#BTC:hover { + overflow: visible; +} +#BTC>button { + opacity: 0; + cursor: pointer; +} +#donateBox #AliPay { + background-image: url(../img/alipay.svg); +} +#donateBox #WeChat { + background-image: url(../img/wechat.svg); +} +#QRBox { + top: 0; + left: 0; + z-index: 1; + background-color: rgba(255,255,255,0.3); + display: none; + perspective: 400px; +} +#MainBox { + cursor: pointer; + position: absolute; + text-align: center; + width: 200px; + height: 200px; + left: calc(50% - 100px); + top: calc(50% - 100px); + background: #fff no-repeat center center; + background-size: 190px; + border-radius: 6px; + box-shadow: 0px 2px 7px rgba(0,0,0,0.3); + opacity: 0; + transition: all 1s ease-in-out; + transform-style: preserve-3d; + transform-origin: center center; + overflow: hidden; +} +#btc-key { + opacity: 0; + width: 2px; + height: 8px; + overflow: hidden; + left: -2px; + top: -8px; +} +#github { + width: 24px; + height: 24px; + left: calc(50% + 135px); + top: calc(50% - 30px); + background: no-repeat center center url(../img/github.svg); + background-size: contain; + opacity: 0.3; + transform: rotatez(15deg ); +} +[data-footnote] { + position: relative; + overflow: hidden; +} +[data-footnote]:hover { + overflow: visible; +} +[data-footnote]::before, [data-footnote]::after { + position: absolute; + transition: all .3s; + transform: translate3d(-50%,0,0); + opacity: 0; + left: 37px; + z-index: 10; +} +[data-footnote]::before { + content: attr(data-footnote); + border-radius: 6px; + background-color: rgba(100,100,100,0.8); + color: #fff; + height: 24px; + line-height: 24px; + padding: 0 6px; + font-size: 12px; + white-space: nowrap; + top: -24px; + left: 37px; +} +[data-footnote]::after { + content: ''; + border: 5px solid #333; + border-color: rgba(100,100,100,0.8) transparent transparent transparent; + top: 0; + left: 37px; +} +[data-footnote]:hover::before,[data-footnote]:hover::after { + opacity: 1; +} +[data-footnote]:hover::before,[data-footnote]:hover::after { + transform: translate3d(-50%,-7px,0); +} + +#MainBox.showQR { + opacity: 1; + animation-name:showQR; + animation-duration:3s; + animation-timing-function:ease-in-out; + animation-iteration-count:1; + animation-fill-mode:forwards; + -webkit-animation:showQR 3s ease-in-out 0s 1 normal forwards; +} +@keyframes showQR { + from { + transform: rotateX(90deg); + } + 8% { + opacity: 1; + transform: rotateX(-60deg); + } + 18% { + opacity: 1; + transform: rotateX(40deg); + } + 34% { + opacity: 1; + transform: rotateX(-28deg); + } + 44% { + opacity: 1; + transform: rotateX(18deg); + } + 58% { + opacity: 1; + transform: rotateX(-12deg); + } + 72% { + opacity: 1; + transform: rotateX(9deg); + } + 88% { + opacity: 1; + transform: rotateX(-5deg); + } + 96% { + opacity: 1; + transform: rotateX(2deg); + } + to { + opacity: 1; + } +} +#MainBox.hideQR { + opacity: 1; + animation-name:hideQR; + animation-duration:0.5s; + animation-timing-function:ease-in-out; + animation-iteration-count:1; + animation-fill-mode:forwards; + -webkit-animation:hideQR 0.5s ease-in-out 0s 1 normal forwards; +} +@keyframes hideQR { + from { + } + 20%,50% { + transform: scale(1.08,1.08); + opacity: 1; + } + to { + opacity: 0; + transform: rotateZ(40deg) scale(0.6,0.6); + } +} diff --git a/css/gitalk.css b/css/gitalk.css index e69de29b..3b1ef0a4 100644 --- a/css/gitalk.css +++ b/css/gitalk.css @@ -0,0 +1,1207 @@ +@font-face { + font-family: octicons-link; + src: url(data:font/woff;charset=utf-8;base64,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) format('woff'); +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + line-height: 1.5; + color: #24292e; + 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; +} + +.markdown-body .pl-c { + color: #6a737d; +} + +.markdown-body .pl-c1, +.markdown-body .pl-s .pl-v { + color: #005cc5; +} + +.markdown-body .pl-e, +.markdown-body .pl-en { + color: #6f42c1; +} + +.markdown-body .pl-smi, +.markdown-body .pl-s .pl-s1 { + color: #24292e; +} + +.markdown-body .pl-ent { + color: #22863a; +} + +.markdown-body .pl-k { + color: #d73a49; +} + +.markdown-body .pl-s, +.markdown-body .pl-pds, +.markdown-body .pl-s .pl-pse .pl-s1, +.markdown-body .pl-sr, +.markdown-body .pl-sr .pl-cce, +.markdown-body .pl-sr .pl-sre, +.markdown-body .pl-sr .pl-sra { + color: #032f62; +} + +.markdown-body .pl-v, +.markdown-body .pl-smw { + color: #e36209; +} + +.markdown-body .pl-bu { + color: #b31d28; +} + +.markdown-body .pl-ii { + color: #fafbfc; + background-color: #b31d28; +} + +.markdown-body .pl-c2 { + color: #fafbfc; + background-color: #d73a49; +} + +.markdown-body .pl-c2::before { + content: "^M"; +} + +.markdown-body .pl-sr .pl-cce { + font-weight: bold; + color: #22863a; +} + +.markdown-body .pl-ml { + color: #735c0f; +} + +.markdown-body .pl-mh, +.markdown-body .pl-mh .pl-en, +.markdown-body .pl-ms { + font-weight: bold; + color: #005cc5; +} + +.markdown-body .pl-mi { + font-style: italic; + color: #24292e; +} + +.markdown-body .pl-mb { + font-weight: bold; + color: #24292e; +} + +.markdown-body .pl-md { + color: #b31d28; + background-color: #ffeef0; +} + +.markdown-body .pl-mi1 { + color: #22863a; + background-color: #f0fff4; +} + +.markdown-body .pl-mc { + color: #e36209; + background-color: #ffebda; +} + +.markdown-body .pl-mi2 { + color: #f6f8fa; + background-color: #005cc5; +} + +.markdown-body .pl-mdr { + font-weight: bold; + color: #6f42c1; +} + +.markdown-body .pl-ba { + color: #586069; +} + +.markdown-body .pl-sg { + color: #959da5; +} + +.markdown-body .pl-corl { + text-decoration: underline; + color: #032f62; +} + +.markdown-body .octicon { + display: inline-block; + vertical-align: text-top; + fill: currentColor; +} + +.markdown-body a { + background-color: transparent; + -webkit-text-decoration-skip: objects; +} + +.markdown-body a:active, +.markdown-body a:hover { + outline-width: 0; +} + +.markdown-body strong { + font-weight: inherit; +} + +.markdown-body strong { + font-weight: bolder; +} + +.markdown-body h1 { + font-size: 2em; + margin: 0.67em 0; +} + +.markdown-body img { + border-style: none; +} + +.markdown-body svg:not(:root) { + overflow: hidden; +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre { + font-family: monospace, monospace; + font-size: 1em; +} + +.markdown-body hr { + -webkit-box-sizing: content-box; + box-sizing: content-box; + height: 0; + overflow: visible; +} + +.markdown-body input { + font: inherit; + margin: 0; +} + +.markdown-body input { + overflow: visible; +} + +.markdown-body [type="checkbox"] { + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +.markdown-body * { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body input { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +.markdown-body a { + color: #0366d6; + text-decoration: none; +} + +.markdown-body a:hover { + text-decoration: underline; +} + +.markdown-body strong { + font-weight: 600; +} + +.markdown-body hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #dfe2e5; +} + +.markdown-body hr::before { + display: table; + content: ""; +} + +.markdown-body hr::after { + display: table; + clear: both; + content: ""; +} + +.markdown-body table { + border-spacing: 0; + border-collapse: collapse; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body h1 { + font-size: 32px; + font-weight: 600; +} + +.markdown-body h2 { + font-size: 24px; + font-weight: 600; +} + +.markdown-body h3 { + font-size: 20px; + font-weight: 600; +} + +.markdown-body h4 { + font-size: 16px; + font-weight: 600; +} + +.markdown-body h5 { + font-size: 14px; + font-weight: 600; +} + +.markdown-body h6 { + font-size: 12px; + font-weight: 600; +} + +.markdown-body p { + margin-top: 0; + margin-bottom: 10px; +} + +.markdown-body blockquote { + margin: 0; +} + +.markdown-body ul, +.markdown-body ol { + padding-left: 0; + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body code { + font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 12px; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font: 12px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body .octicon { + vertical-align: text-bottom; +} + +.markdown-body .pl-0 { + padding-left: 0 !important; +} + +.markdown-body .pl-1 { + padding-left: 4px !important; +} + +.markdown-body .pl-2 { + padding-left: 8px !important; +} + +.markdown-body .pl-3 { + padding-left: 16px !important; +} + +.markdown-body .pl-4 { + padding-left: 24px !important; +} + +.markdown-body .pl-5 { + padding-left: 32px !important; +} + +.markdown-body .pl-6 { + padding-left: 40px !important; +} + +.markdown-body::before { + display: table; + content: ""; +} + +.markdown-body::after { + display: table; + clear: both; + content: ""; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body a:not([href]) { + color: inherit; + text-decoration: none; +} + +.markdown-body .anchor { + float: left; + padding-right: 4px; + margin-left: -20px; + line-height: 1; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body hr { + height: 0.25em; + padding: 0; + margin: 24px 0; + background-color: #e1e4e8; + border: 0; +} + +.markdown-body blockquote { + padding: 0 1em; + color: #6a737d; + border-left: 0.25em solid #dfe2e5; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body 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: 3px; + -webkit-box-shadow: inset 0 -1px 0 #959da5; + box-shadow: inset 0 -1px 0 #959da5; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 24px; + margin-bottom: 16px; + font-weight: 600; + line-height: 1.25; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + color: #1b1f23; + vertical-align: middle; + visibility: hidden; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + visibility: visible; +} + +.markdown-body h1 { + padding-bottom: 0.3em; + font-size: 2em; + border-bottom: 1px solid #eaecef; +} + +.markdown-body h2 { + padding-bottom: 0.3em; + font-size: 1.5em; + border-bottom: 1px solid #eaecef; +} + +.markdown-body h3 { + font-size: 1.25em; +} + +.markdown-body h4 { + font-size: 1em; +} + +.markdown-body h5 { + font-size: 0.875em; +} + +.markdown-body h6 { + font-size: 0.85em; + color: #6a737d; +} + +.markdown-body ul, +.markdown-body ol { + padding-left: 2em; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body li+li { + margin-top: 0.25em; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: 600; +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body table { + display: block; + width: 100%; + overflow: auto; +} + +.markdown-body table th { + font-weight: 600; +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid #dfe2e5; +} + +.markdown-body table tr { + background-color: #fff; + border-top: 1px solid #c6cbd1; +} + +.markdown-body table tr:nth-child(2n) { + background-color: #f6f8fa; +} + +.markdown-body img { + max-width: 100%; + -webkit-box-sizing: content-box; + box-sizing: content-box; + background-color: #fff; +} + +.markdown-body 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: 3px; +} + +.markdown-body code::before, +.markdown-body code::after { + letter-spacing: -0.2em; + content: "\A0"; +} + +.markdown-body pre { + word-wrap: normal; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f6f8fa; + border-radius: 3px; +} + +.markdown-body pre code { + display: inline; + max-width: auto; + padding: 0; + margin: 0; + overflow: visible; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body pre code::before, +.markdown-body pre code::after { + content: normal; +} + +.markdown-body .full-commit .btn-outline:not(:disabled):hover { + color: #005cc5; + border-color: #005cc5; +} + +.markdown-body 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: #fafbfc; + border: solid 1px #d1d5da; + border-bottom-color: #c6cbd1; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 #c6cbd1; + box-shadow: inset 0 -1px 0 #c6cbd1; +} + +.markdown-body :checked+.radio-label { + position: relative; + z-index: 1; + border-color: #0366d6; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 3px; +} + +.markdown-body .task-list-item input { + margin: 0 0.2em 0.25em -1.6em; + vertical-align: middle; +} + +.markdown-body hr { + border-bottom-color: #eee; +} +/* variables */ +/* functions & mixins */ +/* variables - calculated */ +/* styles */ +.gt-container { + -webkit-box-sizing: border-box; + box-sizing: border-box; + font-size: 16px; +/* loader */ +/* error */ +/* initing */ +/* no int */ +/* link */ +/* meta */ +/* popup */ +/* header */ +/* comments */ +/* comment */ +} +.gt-container * { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.gt-container a { + color: #6190e8; +} +.gt-container a:hover { + color: #81a6ed; + border-color: #81a6ed; +} +.gt-container a.is--active { + color: #333; + cursor: default !important; +} +.gt-container a.is--active:hover { + color: #333; +} +.gt-container .hide { + display: none !important; +} +.gt-container .gt-svg { + display: inline-block; + width: 1em; + height: 1em; + vertical-align: sub; +} +.gt-container .gt-svg svg { + width: 100%; + height: 100%; + fill: #6190e8; +} +.gt-container .gt-ico { + display: inline-block; +} +.gt-container .gt-ico-text { + margin-left: 0.3125em; +} +.gt-container .gt-ico-github .gt-svg { + width: 100%; + height: 100%; +} +.gt-container .gt-ico-github svg { + fill: inherit; +} +.gt-container .gt-spinner { + position: relative; +} +.gt-container .gt-spinner::before { + content: ''; + -webkit-box-sizing: border-box; + box-sizing: border-box; + position: absolute; + top: 3px; + width: 0.75em; + height: 0.75em; + margin-top: -0.1875em; + margin-left: -0.375em; + border-radius: 50%; + border: 1px solid #fff; + border-top-color: #6190e8; + -webkit-animation: gt-kf-rotate 0.6s linear infinite; + animation: gt-kf-rotate 0.6s linear infinite; +} +.gt-container .gt-loader { + position: relative; + border: 1px solid #999; + -webkit-animation: ease gt-kf-rotate 1.5s infinite; + animation: ease gt-kf-rotate 1.5s infinite; + display: inline-block; + font-style: normal; + width: 1.75em; + height: 1.75em; + line-height: 1.75em; + border-radius: 50%; +} +.gt-container .gt-loader:before { + content: ''; + position: absolute; + display: block; + top: 0; + left: 50%; + margin-top: -0.1875em; + margin-left: -0.1875em; + width: 0.375em; + height: 0.375em; + background-color: #999; + border-radius: 50%; +} +.gt-container .gt-avatar { + display: inline-block; + width: 3.125em; + height: 3.125em; +} +@media (max-width: 479px) { + .gt-container .gt-avatar { + width: 2em; + height: 2em; + } +} +.gt-container .gt-avatar img { + width: 100%; + height: auto; + border-radius: 3px; +} +.gt-container .gt-avatar-github { + width: 3em; + height: 3em; +} +@media (max-width: 479px) { + .gt-container .gt-avatar-github { + width: 1.875em; + height: 1.875em; + } +} +.gt-container .gt-btn { + padding: 0.75em 1.25em; + display: inline-block; + line-height: 1; + text-decoration: none; + white-space: nowrap; + cursor: pointer; + border: 1px solid #6190e8; + border-radius: 5px; + background-color: #6190e8; + color: #fff; + outline: none; + font-size: 0.75em; +} +.gt-container .gt-btn-text { + font-weight: 400; +} +.gt-container .gt-btn-loading { + position: relative; + margin-left: 0.5em; + display: inline-block; + width: 0.75em; + height: 1em; + vertical-align: top; +} +.gt-container .gt-btn.is--disable { + cursor: not-allowed; + opacity: 0.5; +} +.gt-container .gt-btn-login { + margin-right: 0; +} +.gt-container .gt-btn-preview { + background-color: #fff; + color: #6190e8; +} +.gt-container .gt-btn-preview:hover { + background-color: #f2f2f2; + border-color: #81a6ed; +} +.gt-container .gt-btn-public:hover { + background-color: #81a6ed; + border-color: #81a6ed; +} +.gt-container .gt-error { + text-align: center; + margin: 0.625em; + color: #ff3860; +} +.gt-container .gt-initing { + padding: 1.25em 0; + text-align: center; +} +.gt-container .gt-initing-text { + margin: 0.625em auto; + font-size: 92%; +} +.gt-container .gt-no-init { + padding: 1.25em 0; + text-align: center; +} +.gt-container .gt-link { + border-bottom: 1px dotted #6190e8; +} +.gt-container .gt-link-counts, +.gt-container .gt-link-project { + text-decoration: none; +} +.gt-container .gt-meta { + margin: 1.25em 0; + padding: 1em 0; + position: relative; + border-bottom: 1px solid #e9e9e9; + font-size: 1em; + position: relative; + z-index: 10; +} +.gt-container .gt-meta:before, +.gt-container .gt-meta:after { + content: " "; + display: table; +} +.gt-container .gt-meta:after { + clear: both; +} +.gt-container .gt-counts { + margin: 0 0.625em 0 0; +} +.gt-container .gt-user { + float: right; + margin: 0; + font-size: 92%; +} +.gt-container .gt-user-pic { + width: 16px; + height: 16px; + vertical-align: top; + margin-right: 0.5em; +} +.gt-container .gt-user-inner { + display: inline-block; + cursor: pointer; +} +.gt-container .gt-user .gt-ico { + margin: 0 0 0 0.3125em; +} +.gt-container .gt-user .gt-ico svg { + fill: inherit; +} +.gt-container .gt-user .is--poping .gt-ico svg { + fill: #6190e8; +} +.gt-container .gt-version { + color: #a1a1a1; + margin-left: 0.375em; +} +.gt-container .gt-copyright { + margin: 0 0.9375em 0.5em; + border-top: 1px solid #e9e9e9; + padding-top: 0.5em; +} +.gt-container .gt-popup { + position: absolute; + right: 0; + top: 2.375em; + background: #fff; + display: inline-block; + border: 1px solid #e9e9e9; + padding: 0.625em 0; + font-size: 0.875em; + letter-spacing: 0.5px; +} +.gt-container .gt-popup .gt-action { + cursor: pointer; + display: block; + margin: 0.5em 0; + padding: 0 1.125em; + position: relative; + text-decoration: none; +} +.gt-container .gt-popup .gt-action.is--active:before { + content: ''; + width: 0.25em; + height: 0.25em; + background: #6190e8; + position: absolute; + left: 0.5em; + top: 0.4375em; +} +.gt-container .gt-header { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} +.gt-container .gt-header-comment { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + margin-left: 1.25em; +} +@media (max-width: 479px) { + .gt-container .gt-header-comment { + margin-left: 0.875em; + } +} +.gt-container .gt-header-textarea { + padding: 0.75em; + display: block; + -webkit-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + min-height: 5.125em; + max-height: 15em; + border-radius: 5px; + border: 1px solid rgba(0,0,0,0.1); + font-size: 0.875em; + word-wrap: break-word; + resize: vertical; + background-color: #f6f6f6; + outline: none; + -webkit-transition: all 0.25s ease; + transition: all 0.25s ease; +} +.gt-container .gt-header-textarea:hover { + background-color: #fbfbfb; +} +.gt-container .gt-header-preview { + padding: 0.75em; + border-radius: 5px; + border: 1px solid rgba(0,0,0,0.1); + background-color: #f6f6f6; +} +.gt-container .gt-header-controls { + position: relative; + margin: 0.75em 0 0; +} +.gt-container .gt-header-controls:before, +.gt-container .gt-header-controls:after { + content: " "; + display: table; +} +.gt-container .gt-header-controls:after { + clear: both; +} +@media (max-width: 479px) { + .gt-container .gt-header-controls { + margin: 0; + } +} +.gt-container .gt-header-controls-tip { + font-size: 0.875em; + color: #6190e8; + text-decoration: none; + vertical-align: sub; +} +@media (max-width: 479px) { + .gt-container .gt-header-controls-tip { + display: none; + } +} +.gt-container .gt-header-controls .gt-btn { + float: right; + margin-left: 1.25em; +} +@media (max-width: 479px) { + .gt-container .gt-header-controls .gt-btn { + float: none; + width: 100%; + margin: 0.75em 0 0; + } +} +.gt-container:after { + content: ''; + position: fixed; + bottom: 100%; + left: 0; + right: 0; + top: 0; + opacity: 0; +} +.gt-container.gt-input-focused { + position: relative; +} +.gt-container.gt-input-focused:after { + content: ''; + position: fixed; + bottom: 0%; + left: 0; + right: 0; + top: 0; + background: #000; + opacity: 0.6; + -webkit-transition: opacity 0.3s, bottom 0s; + transition: opacity 0.3s, bottom 0s; + z-index: 9999; +} +.gt-container.gt-input-focused .gt-header-comment { + z-index: 10000; +} +.gt-container .gt-comments { + padding-top: 1.25em; +} +.gt-container .gt-comments-null { + text-align: center; +} +.gt-container .gt-comments-controls { + margin: 1.25em 0; + text-align: center; +} +.gt-container .gt-comment { + position: relative; + padding: 0.625em 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} +.gt-container .gt-comment-content { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; + margin-left: 1.25em; + padding: 0.75em 1em; + background-color: #f9f9f9; + overflow: auto; + -webkit-transition: all ease 0.25s; + transition: all ease 0.25s; +} +.gt-container .gt-comment-content:hover { + -webkit-box-shadow: 0 0.625em 3.75em 0 #f4f4f4; + box-shadow: 0 0.625em 3.75em 0 #f4f4f4; +} +@media (max-width: 479px) { + .gt-container .gt-comment-content { + margin-left: 0.875em; + padding: 0.625em 0.75em; + } +} +.gt-container .gt-comment-header { + margin-bottom: 0.5em; + font-size: 0.875em; + position: relative; +} +.gt-container .gt-comment-username { + font-weight: 500; + color: #6190e8; + text-decoration: none; +} +.gt-container .gt-comment-username:hover { + text-decoration: underline; +} +.gt-container .gt-comment-text { + margin-left: 0.5em; + color: #a1a1a1; +} +.gt-container .gt-comment-date { + margin-left: 0.5em; + color: #a1a1a1; +} +.gt-container .gt-comment-like, +.gt-container .gt-comment-edit, +.gt-container .gt-comment-reply { + position: absolute; + height: 1.375em; +} +.gt-container .gt-comment-like:hover, +.gt-container .gt-comment-edit:hover, +.gt-container .gt-comment-reply:hover { + cursor: pointer; +} +.gt-container .gt-comment-like { + top: 0; + right: 2em; +} +.gt-container .gt-comment-edit, +.gt-container .gt-comment-reply { + top: 0; + right: 0; +} +.gt-container .gt-comment-body { + color: #333 !important; +} +.gt-container .gt-comment-admin .gt-comment-content { + background-color: #f6f9fe; +} +@-webkit-keyframes gt-kf-rotate { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes gt-kf-rotate { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +/*# sourceMappingURL=gitalk.css.map*/ \ No newline at end of file diff --git a/css/my-gitalk.css b/css/my-gitalk.css index e69de29b..d58f9ca4 100644 --- a/css/my-gitalk.css +++ b/css/my-gitalk.css @@ -0,0 +1,249 @@ +.gitalk-card { + margin: 1.25rem auto; +} + +.gitalk-card .card-content { + padding: 1px 20px 20px 20px; +} + +#gitalk-container .gt-no-init a { + color: #42b983; + text-decoration: underline; +} + +#gitalk-container .gt-container .gt-btn, +#gitalk-container .gt-btn-login, +#gitalk-container .gt-container .gt-header-controls .gt-btn { + border: 1px solid #4caf50; + background-color: #4caf50; + box-shadow: 0 2px 2px 0 rgba(76, 175, 80, 0.14), 0 3px 1px -2px rgba(76, 175, 80, 0.2), 0 1px 5px 0 rgba(76, 175, 80, 0.12); +} + +#gitalk-container .gt-container .gt-link { + color: #42b983; + text-decoration: underline; +} + +#gitalk-container .gt-container .gt-btn-preview { + color: #4caf50; + background-color: #fff !important; + box-shadow: 0 2px 2px 0 rgba(76, 175, 80, 0.14), 0 3px 1px -2px rgba(76, 175, 80, 0.2), 0 1px 5px 0 rgba(76, 175, 80, 0.12); +} + +#gitalk-container .gt-container .gt-header-textarea { + background-color: #f6f9fc; + border: 1px solid rgba(0, 0, 0, 0.05); +} + +#gitalk-container .gt-container .gt-svg svg { + fill: #42b983; +} + +#gitalk-container .gt-container .gt-header-controls-tip, +#gitalk-container .gt-container a, +#gitalk-container .gt-container .gt-comment-username { + color: #42b983; +} + +#gitalk-container .gt-container .gt-ico-text { + margin-left: 0.08rem; +} + +#gitalk-container .gt-container .gt-comment-body { + color: #34495e !important; +} + +#gitalk-container .gt-container .gt-header-preview { + border: 1px solid rgba(0, 0, 0, 0.02); + background-color: #f9f9f9; +} + +.markdown-body p { + margin: 2px 2px 10px; + font-size: 1.05rem; + line-height: 1.78rem; +} + +.markdown-body blockquote p { + text-indent: 0.2rem; +} + +.markdown-body a { + padding: 0 2px; + color: #42b983; + font-weight: 500; + text-decoration: underline; +} + +.markdown-body img { + max-width: 100%; + height: auto; + cursor: pointer; +} + +.markdown-body ol li { + list-style-type: decimal; +} + +.markdown-body ol, +ul { + display: block; + padding-left: 2em; + word-spacing: 0.05rem; +} + +.markdown-body ul li, +ol li { + display: list-item; + line-height: 1.8rem; + font-size: 1rem; +} + +.markdown-body ul li { + list-style-type: disc; +} + +.markdown-body ul ul li { + list-style-type: circle; +} + +.markdown-body table, th, td { + padding: 12px 13px; + border: 1px solid #dfe2e5; +} + +.markdown-body table, th, td { + border: 0; +} + +table tr:nth-child(2n), thead { + background-color: #fafafa; +} + +.markdown-body table th { + background-color: #f2f2f2; + min-width: 80px; +} + +.markdown-body table td { + min-width: 80px; +} + +.markdown-body h1 { + font-size: 1.85rem; + font-weight: bold; + line-height: 2.2rem; +} + +.markdown-body h2 { + font-size: 1.65rem; + font-weight: bold; + line-height: 1.9rem; +} + +.markdown-body h3 { + font-size: 1.45rem; + font-weight: bold; + line-height: 1.7rem; +} + +.markdown-body h4 { + font-size: 1.25rem; + font-weight: bold; + line-height: 1.5rem; +} + +.markdown-body h5 { + font-size: 1.1rem; + font-weight: bold; + line-height: 1.4rem; +} + +.markdown-body h6 { + font-size: 1rem; + line-height: 1.3rem; +} + +.markdown-body p { + font-size: 1rem; + line-height: 1.5rem; +} + +.markdown-body hr { + margin: 12px 0; + border: 0; + border-top: 1px solid #ccc; +} + +.markdown-body blockquote { + margin: 15px 0; + border-left: 5px solid #42b983; + padding: 1rem 0.8rem 1rem 0.8rem; + color: #666; + background-color: rgba(66, 185, 131, .1); +} + +.markdown-body pre { + padding: 1.2em; + margin: .5em 0; + background: #272822; + overflow: auto; + border-radius: 0.3em; + tab-size: 4; +} + +.markdown-body code { + padding: 1px 1px; + font-size: 0.92rem; + color: #e96900; + background-color: #f8f8f8; + border-radius: 2px; +} + +.markdown-body pre code { + padding: 0; + color: #e8eaf6; + background-color: #272822; +} + +.markdown-body pre[class*="language-"] { + padding: 1.2em; + margin: .5em 0; +} + +.markdown-body code[class*="language-"], +pre[class*="language-"] { + color: #e8eaf6; +} + +.markdown-body [type="checkbox"]:not(:checked), [type="checkbox"]:checked { + position: inherit; + margin-left: -1.3rem; + margin-right: 0.4rem; + margin-top: -1px; + vertical-align: middle; + left: unset; + visibility: visible; +} + +.markdown-body b, +strong { + font-weight: bold; +} + +.markdown-body dfn { + font-style: italic; +} + +.markdown-body small { + font-size: 85%; +} + +.markdown-body cite { + font-style: normal; +} + +.markdown-body mark { + background-color: #fcf8e3; + padding: .2em; +} \ No newline at end of file diff --git a/css/style.css b/css/style.css index e69de29b..c9dd1bec 100644 --- a/css/style.css +++ b/css/style.css @@ -0,0 +1,1465 @@ +/** + * + * @package Maupassant + * @author cho + * @version 2.0 + * @link http://chopstack.com + */ +/* +pure css setting +When setting the primary font stack, apply it to the Pure grid units along +with `html`, `button`, `input`, `select`, and `textarea`. Pure Grids use +specific font stacks to ensure the greatest OS/browser compatibility. +*/ +html, button, input, select, textarea, +.MJXc-TeX-unknown-R, +.pure-g [class*="pure-u"] { + /* Set your content font stack here: */ + font-family: "PingFangSC-Regular", Helvetica, "Helvetica Neue", "Segoe UI", "Hiragino Sans GB", "Source Han Sans CN", "Microsoft YaHei", "STHeiti", "WenQuanYi Micro Hei", sans-serif !important; } + +body { + background-color: #FFF; + color: #444; + font-family: "TIBch", "Classic Grotesque W01", "Helvetica Neue", Arial, "Hiragino Sans GB", "STHeiti", "Microsoft YaHei", "WenQuanYi Micro Hei", SimSun, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-size: 14px; } + +.body_container { + padding: 0 60px; + max-width: 1150px; + margin: 0 auto; } + +.content_container { + padding-right: 50px; + padding-top: 20px; } + +a, button.submit { + color: #6E7173; + text-decoration: none; + -webkit-transition: all .1s ease-in; + -moz-transition: all .1s ease-in; + -o-transition: all .1s ease-in; + transition: all .1s ease-in; } + +a:hover, a:active { + color: #444; } + +a:focus { + outline: auto; } + +.clear { + clear: both; } + +div { + box-sizing: border-box; } + +#header { + padding: 58px 0 0; + text-align: left; + border-bottom: 1px solid #ddd; + position: relative; } + #header .site-name { + margin-bottom: 40px; } + #header .site-name h1 { + padding: 0; + margin: 0; + height: 0; + overflow: hidden; } + #header .site-name #logo { + font: bold 38px/1.12 "Times New Roman", Georgia, Times, sans-serif; + color: #555; } + #header .site-name #logo span, #header .site-name #logo:hover { + color: #777; } + #header .site-name .description { + margin: .2em 0 0; + color: #999; } + #header #nav-menu { + margin: 10px 0 -1px; + padding: 0; + position: absolute; + right: 0; + bottom: 0; } + #header #nav-menu a { + display: inline-block; + padding: 3px 20px 3px; + line-height: 30px; + color: #444; + font-size: 13px; + border: 1px solid transparent; } + #header #nav-menu a:hover { + border-bottom-color: #444; } + #header #nav-menu a.current { + border: 1px solid #ddd; + border-bottom-color: #fff; } + +#sidebar { + border-left: 1px solid #ddd; + padding-left: 35px; + margin-top: 40px; + padding-bottom: 20px; + word-wrap: break-word; } + #sidebar .widget { + margin-bottom: 30px; } + #sidebar .widget .widget-title { + color: #6E7173; + line-height: 2.7; + margin-top: 0; + font-size: 16px; + border-bottom: 1px solid #ddd; + display: block; + font-weight: normal; } + #sidebar .widget .comments-title { + color: #6E7173; + line-height: 2.7; + margin-top: 0; + font-size: 16px; + border-bottom: 0px solid #ddd; + display: block; + font-weight: normal; } + #sidebar .widget .tagcloud { + margin-top: 10px; } + #sidebar .widget .tagcloud a { + line-height: 1.5; + padding: 5px; } + #sidebar .widget ul { + list-style: none; + padding: 0; } + #sidebar .widget ul li { + margin: 5px 0; + line-height: 1.5; } + #sidebar .widget .category-list-count { + padding-left: 5px; + color: #6E7173; } + #sidebar .widget .category-list-count::before { + content: "("; } + #sidebar .widget .category-list-count::after { + content: ")"; } + #sidebar .widget .search-form { + position: relative; + overflow: hidden; } + #sidebar .widget .search-form input { + background: #fff 8px 8px no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6%2BR8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAG11AABzoAAA%2FN0AAINkAABw6AAA7GgAADA%2BAAAQkOTsmeoAAAESSURBVHjajNCxS9VRGMbxz71E4OwgoXPQxVEpXCI47%2BZqGP0LCoJO7UVD3QZzb3SwcHB7F3Uw3Zpd%2FAPCcJKG7Dj4u%2FK7Pwp94HDg5Xyf5z1Pr9YKImKANTzFXxzjU2ae6qhXaxURr%2FAFl9hHDy%2FwEK8z89sYVEp5gh84wMvMvGiSJ%2FEV85jNzLMR1McqfmN5BEBmnmMJFSvtpH7jdJiZv7q7Z%2BZPfMdcF6rN%2FT%2F1m2LGBkd4HhFT3dcRMY2FpskxaLNpayciHrWAGeziD7b%2BVfkithuTk8bkGa4wgWFmbrSTZOYeBvjc%2BucQj%2FEe6xHx4Taq1nrnKaW8K6XUUsrHWuvNevdRRLzFGwzvDbXAB9cDAHvhedDruuxSAAAAAElFTkSuQmCC); + padding: 7px 11px 7px 28px; + line-height: 16px; + border: 1px solid #bbb; + width: 65%; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + -ms-border-radius: 5px; + -o-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; } + +/* title for search result or tagged posts*/ +.label-title { + margin-top: 1.1em; + font-size: 20px; + font-weight: normal; + color: #888; } + +.post { + padding: 25px 0 15px; } + .post .post-title { + margin: 0; + color: #555; + text-align: left; + font: bold 25px/1.1 "ff-tisa-web-pro", Cambria, "Times New Roman", Georgia, Times, sans-serif; } + .post .post-title a { + color: #555; } + .post .post-meta { + padding: 0; + margin: 15px 0 0; + color: #6E7173; + float: left; + display: inline; + text-indent: .15em; } + .post .post-meta:before { + font-family: "FontAwesome"; + content: "\f073"; + padding-right: 0.3em; } + .post .post-meta .category:before { + font-family: "FontAwesome"; + content: "\f07c"; + padding-right: 0.3em; } + .post .post-meta #busuanzi_value_page_pv:before { + font-family: "FontAwesome"; + content: "\f024"; + padding-right: 0.3em; } + .post .ds-thread-count { + padding: 0; + margin: 15px 0 0; + color: #6E7173; + float: right; + display: inline; + text-indent: .15em; } + .post .ds-thread-count:before { + font-family: "FontAwesome"; + content: "\f0e5"; + padding-right: 0.3em; } + .post .ds-thread-count:hover { + color: #444; } + .post .disqus-comment-count { + padding: 0; + margin: 15px 0 0; + color: #6E7173; + float: right; + display: inline; + text-indent: .15em; } + .post .disqus-comment-count:before { + font-family: "FontAwesome"; + content: "\f0e5"; + padding-right: 0.3em; } + .post .disqus-comment-count:hover { + color: #444; } + .post .post-content { + clear: left; + font-size: 15px; + line-height: 1.77; + color: #444; + padding-top: 15px; + text-align: justify; + text-justify: distribute; + word-break: normal; } + .post .post-content h2 { + margin: 1.4em 0 1.1em; + border-bottom: 1px solid #eee; + overflow: hidden; } + .post .post-content h3 { + margin: 1.4em 0 1.1em; } + .post .post-content pre code { + padding: 0 2em; } + .post .post-content p { + margin: 0 0 1.234em; } + .post .post-content p code { + display: inline-block; + margin: 0 5px; + padding: 0 5px; + background: #f7f8f8; + font-family: Menlo, Consolas, monospace !important; } + .post .post-content p a { + color: #01579f; + padding-bottom: 2px; + word-break: normal; } + .post .post-content p a:hover { + text-decoration: underline; } + .post .post-content .caption { + color: #444; + display: block; + font-size: 0.9em; + margin-top: 0.1em; + position: relative; + text-align: center; } + .post .post-content hr { + margin: 2.4em auto; + border: none; + border-top: 1px solid #eee; + position: relative; } + .post .post-content img { + max-width: 100%; + padding: 0.5em 0; + margin: auto; + display: block; } + .post .post-content ul, .post .post-content ol { + border-radius: 3px; + margin: 1em 0; } + .post .post-content ul ul, .post .post-content ol ul { + margin: 0; } + .post .post-content ul code, .post .post-content ol code { + display: inline-block; + margin: 0 5px; + padding: 0px 5px; + background: #f7f8f8; + font-family: Menlo, Consolas, monospace !important; } + .post .post-content ul a, .post .post-content ol a { + color: #01579f; + padding-bottom: 2px; + word-break: normal; } + .post .post-content ul a:hover, .post .post-content ol a:hover { + text-decoration: underline; } + .post .tags { + padding-bottom: 1em; } + .post .tags a { + margin-right: .5em; } + .post .tags a:before { + font-family: "FontAwesome"; + content: "\f0c6"; + padding-right: 0.3em; } + +.page-navigator { + border-top: 1px solid #ddd; + list-style: none; + margin-top: 25px; + padding: 25px 0 0; + font-size: 14px; + text-align: center; } + .page-navigator .page-number { + display: inline-block; + margin: 0 5px 5px 0; } + .page-navigator a, .page-navigator span { + display: inline-block; + height: 25px; + line-height: 25px; + padding: 5px 9px; + border: 1px solid #DDD; + text-align: center; } + .page-navigator a:hover, .page-navigator span:hover { + background: #F8F8F8; + border-bottom-color: #D26911; } + .page-navigator a.prev, .page-navigator span.prev { + float: left; } + .page-navigator a.prev:before, .page-navigator span.prev:before { + font-family: "FontAwesome"; + content: "\f100"; + padding-right: 0.3em; } + .page-navigator a.next, .page-navigator span.next { + float: right; } + .page-navigator a.next:after, .page-navigator span.next:after { + font-family: "FontAwesome"; + content: "\f101"; + padding-left: 0.3em; } + .page-navigator .current { + background: #F8F8F8; + border-bottom-color: #D26911; } + .page-navigator .space { + border: none; + padding: 5px 5px; } + +#footer { + padding: .8em 0 3.6em; + margin-top: 1em; + line-height: 2.5; + color: #6E7173; + text-align: center; } + #footer span { + font-size: .9em; } + +/* for archive page starts*/ +.post-archive { + font-size: 15px; + line-height: 2; + padding-bottom: .8em; } + .post-archive h2 { + margin: 0; + font: bold 25px / 1.1 "ff-tisa-web-pro", Cambria, "Times New Roman", Georgia, Times, sans-serif; } + .post-archive .date { + padding-right: .7em; } + +/* for archive page ends*/ +/* middle*/ +@media print, screen and (max-width: 48em) { + .body_container { + padding: 0 30px; } + .content_container { + padding-right: 15px; } + .hidden_mid_and_down { + display: none !important; } + #sidebar { + border-left-width: 0px; } + #header .site-name { + margin-bottom: 20px; + text-align: center; } + #header #nav-menu { + position: relative; + text-align: center; } + #header #nav-menu a { + padding: 0 15px; + line-height: 27px; + height: 27px; + font-size: 13px; } } + +/* small*/ +@media print, screen and (max-width: 35.5em) { + .body_container { + padding: 0 20px; } + .content_container { + padding-right: 0; } } + +blockquote, .stressed { + -moz-box-sizing: border-box; + box-sizing: border-box; + margin: 2.5em 0; + padding: 0 0 0 50px; + color: #555; + border-left: none; } + +blockquote::before, .stressed-quote::before { + display: block; + font-family: times; + font-style: normal; + font-size: 48px; + color: #444; + font-weight: bold; + line-height: 30px; + margin-left: -50px; + position: absolute; } + +strong, b, em { + font-weight: bold; } + +pre { + margin: 2em 0; } + +.hidden1 { + display: none; } + +/* back-to-top rocket*/ +@media print, screen and (min-width: 48em) { + #rocket { + position: fixed; + right: 50px; + bottom: 50px; + display: block; + visibility: hidden; + width: 26px; + height: 48px; + background: url("data:image/png;base64,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") no-repeat 50% 0; + opacity: 0; + -webkit-transition: visibility 0.6s cubic-bezier(0.6, 0.04, 0.98, 0.335), opacity 0.6s cubic-bezier(0.6, 0.04, 0.98, 0.335), -webkit-transform 0.6s cubic-bezier(0.6, 0.04, 0.98, 0.335); + -moz-transition: visibility 0.6s cubic-bezier(0.6, 0.04, 0.98, 0.335), opacity 0.6s cubic-bezier(0.6, 0.04, 0.98, 0.335), -moz-transform 0.6s cubic-bezier(0.6, 0.04, 0.98, 0.335); + transition: visibility 0.6s cubic-bezier(0.6, 0.04, 0.98, 0.335), opacity 0.6s cubic-bezier(0.6, 0.04, 0.98, 0.335), transform 0.6s cubic-bezier(0.6, 0.04, 0.98, 0.335); } + #rocket i { + display: block; + margin-top: 48px; + height: 14px; + background: url("data:image/png;base64,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") no-repeat 50% -48px; + opacity: .5; + -webkit-transition: -webkit-transform .2s; + -moz-transition: -moz-transform .2s; + transition: transform .2s; + -webkit-transform-origin: 50% 0; + -moz-transform-origin: 50% 0; + transform-origin: 50% 0; } + #rocket:hover { + background-position: 50% -62px; } + #rocket:hover i { + background-position: 50% 100%; + -webkit-animation: flaming .7s infinite; + -moz-animation: flaming .7s infinite; + animation: flaming .7s infinite; } + #rocket.show { + visibility: visible; + opacity: 1; } + #rocket.launch { + background-position: 50% -62px; + opacity: 0; + -webkit-transform: translateY(-500px); + -moz-transform: translateY(-500px); + -ms-transform: translateY(-500px); + transform: translateY(-500px); + pointer-events: none; } + #rocket.launch i { + background-position: 50% 100%; + -webkit-transform: scale(1.4, 3.2); + -moz-transform: scale(1.4, 3.2); + transform: scale(1.4, 3.2); } } + +/* ******************************************************* +* Process timelime, (homepage) +******************************************************* */ +#process { + padding: 80px 0; + background-color: #fff; } + +#process .col-md-2 i { + font-size: 50px; + position: relative; + top: 10px; } + +#process .timeline-centered { + position: relative; + margin-bottom: 30px; } + +#process .timeline-centered::before, #process .timeline-centered::after, +#process .timeline-centered::before, #process .timeline-centered::after { + content: " "; + display: table; } + +#process .timeline-centered::after { + clear: both; } + +#process .timeline-centered::before { + content: ''; + position: absolute; + display: block; + width: 4px; + background: #f5f5f6; + /*left: 50%;*/ + top: 50px; + bottom: 50px; + margin-left: 10px; } + +#process .timeline-centered .timeline-entry { + position: relative; + /*width: 50%; + float: right;*/ + margin-top: 5px; + margin-left: 20px; + margin-bottom: 10px; + clear: both; } + +#process .timeline-centered .timeline-entry::before, +#process .timeline-centered .timeline-entry::after { + content: " "; + display: table; } + +#process .timeline-centered .timeline-entry::after { + clear: both; } + +#process .timeline-centered .timeline-entry.begin { + margin-bottom: 0; } + +#process .timeline-centered .timeline-entry.left-aligned { + float: left; } + +#process .timeline-centered .timeline-entry.left-aligned .timeline-entry-inner { + margin-left: 0; + margin-right: -18px; } + +#process .timeline-centered .timeline-entry.left-aligned .timeline-entry-inner .timeline-time { + left: auto; + right: -100px; + text-align: left; } + +#process span.number { + font-family: 'Georgia', serif, Helvetica, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans CN", "WenQuanYi Micro Hei", Arial, sans-serif; + font-style: italic; + font-size: 20px; + line-height: 0; + color: #E7E7E5; + position: relative; + top: -4px; } + +#process .timeline-centered .timeline-entry.left-aligned .timeline-entry-inner .timeline-icon { + float: right; } + +#process .timeline-centered .timeline-entry.left-aligned .timeline-entry-inner .timeline-label { + margin-left: 0; + margin-right: 70px; } + +#process .timeline-centered .timeline-entry.left-aligned .timeline-entry-inner .timeline-label::after { + left: auto; + right: 0; + margin-left: 0; + margin-right: -9px; + -moz-transform: rotate(180deg); + -o-transform: rotate(180deg); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); } + +.timeline-label p { + font-family: Helvetica, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans CN", "WenQuanYi Micro Hei", Arial, sans-serif; + margin-bottom: 3px; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner { + position: relative; + margin-left: -20px; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner::before, +#process .timeline-centered .timeline-entry .timeline-entry-inner::after { + content: " "; + display: table; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner::after { + clear: both; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner .timeline-time { + position: absolute; + left: -100px; + text-align: right; + padding: 10px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner .timeline-time > span { + display: block; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner .timeline-time > span:first-child { + font-size: 15px; + font-weight: bold; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner .timeline-time > span:last-child { + font-size: 12px; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner .timeline-icon { + background: #fff; + color: #737881; + display: block; + width: 40px; + height: 40px; + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + -webkit-border-radius: 20px; + -moz-border-radius: 20px; + border-radius: 20px; + text-align: center; + border: 4px solid #F5F5F6; + line-height: 40px; + font-size: 15px; + float: left; + position: absolute; + top: 50%; + margin-top: -20px; + margin-left: -9px; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner .timeline-icon.bg-primary { + background-color: #303641; + color: #fff; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner .timeline-label { + position: relative; + background: #eee; + padding: 30px; + margin-left: 60px; + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + +#process .timeline-centered .timeline-entry .timeline-entry-inner .timeline-label::after { + content: ''; + display: block; + position: absolute; + width: 0; + height: 0; + border-style: solid; + border-width: 9px 9px 9px 0; + border-color: transparent #eee transparent transparent; + left: 0; + top: 50%; + margin-top: -9px; + margin-left: -9px; } + +#process .line { + position: absolute; + display: block; + width: 4px; + background: #eee; + top: -3%; + right: -30px; + bottom: -3%; } + +#process .present, +#process .born { + font-size: 14px; + font-family: 'Georgia', serif, Helvetica, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans CN", "WenQuanYi Micro Hei", Arial, sans-serif; + font-style: italic; + color: #333; + padding: 10px; + background-color: #eee; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + +#process .present::after, +#process .born::after { + left: 100%; + top: 50%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + border-color: rgba(136, 183, 213, 0); + border-left-color: #eee; + border-width: 10px; + margin-top: -10px; } + +#process .present { + position: absolute; + top: -3%; + right: 0; + margin-top: -20px; + line-height: 100%; } + +#process .born { + position: absolute; + bottom: -3%; + right: 0; + margin-bottom: -20px; + line-height: 100%; } + +#process .dot_tp { + position: absolute; + top: -3%; + right: -35px; + background-color: transparent; + height: 15px; + width: 15px; + margin-top: -13px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + border: 3px solid #eee; } + +#process .dot_bt { + position: absolute; + bottom: -3%; + right: -35px; + background-color: transparent; + height: 15px; + width: 15px; + margin-bottom: -13px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + border: 3px solid #eee; } + +@media (max-width: 768px) { + #process .line { + right: 10px; } + #process .timeline-centered .timeline-entry .timeline-entry-inner .timeline-label { + margin-right: 30px; + margin-left: 45px; + padding: 20px; } + #process .timeline-centered .timeline-entry { + margin-right: 20px; } + #process .dot_tp, + #process .dot_bt { + right: 5px; } + #process .present, + #process .born { + right: 35px; } } + +/* read more*/ +.readmore a { + font-size: 14px; + color: #444; + margin: -10px 0; + padding: 5px 10px; + border: 1px solid #ddd; + border-radius: 5px; + float: right; } + .readmore a:after { + font-family: "FontAwesome"; + content: "\f101"; + padding-left: 0.3em; } + .readmore a:hover { + background: #F8F8F8; + border-bottom-color: #D26911; } + +/* syntax highlight*/ +figure.highlight, +.codeblock { + background: #f7f8f8; + margin: 10px 0; + line-height: 1.1em; + color: #333; + padding-top: 15px; + overflow: hidden; } + figure.highlight table, + .codeblock table { + display: block; + width: 100%; } + figure.highlight pre, + figure.highlight .gutter, + figure.highlight .code, + figure.highlight .tag, + .codeblock pre, + .codeblock .gutter, + .codeblock .code, + .codeblock .tag { + background-color: inherit; + font-family: Menlo, Consolas, monospace; + border: none; + padding: 0; + margin: 0; + cursor: text; } + figure.highlight .gutter, + figure.highlight .code, + .codeblock .gutter, + .codeblock .code { + vertical-align: top; } + figure.highlight.plain .gutter, + .codeblock.plain .gutter { + display: none; } + figure.highlight figcaption, + .codeblock figcaption { + font-size: 13px; + padding: 0 15px 20px; + margin: 0; + background: #f7f8f8; + color: #999999; } + figure.highlight figcaption a, + .codeblock figcaption a { + float: right; + color: #01579f; } + figure.highlight .gutter, + .codeblock .gutter { + background: #f7f8f8; + border-right: 1px solid #e6e6e6; + padding: 0.3em 15px; } + figure.highlight .code, + .codeblock .code { + padding: 0.3em 15px 0.3em 1em; + width: 100%; } + figure.highlight .code pre, + .codeblock .code pre { + max-width: 700px; + overflow-x: auto; + overflow-y: hidden; } + figure.highlight .line, + .codeblock .line { + height: 1.3em; + font-size: 13px; } + +.gist .line, +.gist .line-number { + font-family: Menlo, Consolas, monospace; + font-size: 1em; + margin: 0 0 5px 0; } + +.highlight .comment { + color: #969896; } + +.highlight .string { + color: #183691; } + +.highlight .keyword { + color: #a71d5d; } + +.highlight.apacheconf .code .common, +.highlight.apacheconf .code .nomarkup, +.highlight.apacheconf .code .attribute, +.highlight.apacheconf .code .variable, +.highlight.apacheconf .code .cbracket, +.highlight.apacheconf .code .keyword { + color: #0086b3; } + +.highlight.apacheconf .code .sqbracket { + color: #df5000; } + +.highlight.apacheconf .code .section, +.highlight.apacheconf .code .tag { + color: #63a35c; } + +.highlight.bash .code .shebang { + color: #969896; } + +.highlight.bash .code .literal, +.highlight.bash .code .built_in { + color: #0086b3; } + +.highlight.bash .code .variable { + color: #333; } + +.highlight.bash .code .title { + color: #795da3; } + +.highlight.coffeescript .code .title { + color: #795da3; } + +.highlight.coffeescript .code .literal, +.highlight.coffeescript .code .built_in, +.highlight.coffeescript .code .number { + color: #0086b3; } + +.highlight.coffeescript .code .reserved, +.highlight.coffeescript .code .attribute { + color: #1d3e81; } + +.highlight.coffeescript .code .subst, +.highlight.coffeescript .code .regexp, +.highlight.coffeescript .code .attribute { + color: #df5000; } + +.highlight.cpp .code .preprocessor, +.highlight.c .code .preprocessor { + color: #df5000; } + +.highlight.cpp .code .meta-keyword, +.highlight.c .code .meta-keyword { + color: #a71d5d; } + +.highlight.cpp .code .title, +.highlight.c .code .title { + color: #795da3; } + +.highlight.cpp .code .number, +.highlight.cpp .code .built_in, +.highlight.c .code .number, +.highlight.c .code .built_in { + color: #0086b3; } + +.highlight.cs .code .preprocessor, +.highlight.cs .code .preprocessor .keyword { + color: #333; } + +.highlight.cs .code .title { + color: #795da3; } + +.highlight.cs .code .number, +.highlight.cs .code .built_in { + color: #0086b3; } + +.highlight.cs .code .xmlDocTag, +.highlight.cs .code .doctag { + color: #63a35c; } + +.highlight.css .code .at_rule, +.highlight.css .code .important, +.highlight.css .code .meta { + color: #a71d5d; } + +.highlight.css .code .attribute, +.highlight.css .code .hexcolor, +.highlight.css .code .number, +.highlight.css .code .function { + color: #0086b3; } + +.highlight.css .code .attr_selector, +.highlight.css .code .value { + color: #333; } + +.highlight.css .code .id, +.highlight.css .code .class, +.highlight.css .code .pseudo, +.highlight.css .code .selector-pseudo { + color: #795da3; } + +.highlight.css .code .tag, +.highlight.css .code .selector-tag { + color: #63a35c; } + +.highlight.diff .code .chunk, +.highlight.diff .code .meta { + color: #795da3; + font-weight: bold; } + +.highlight.diff .code .addition { + color: #55a532; + background-color: #eaffea; } + +.highlight.diff .code .deletion { + color: #bd2c00; + background-color: #ffecec; } + +.highlight.http .code .attribute, +.highlight.http .code .attr { + color: #183691; } + +.highlight.http .code .literal { + color: #0086b3; } + +.highlight.http .code .request { + color: #a71d5d; } + +.highlight.ini .code .title, +.highlight.ini .code .section { + color: #795da3; } + +.highlight.ini .code .setting, +.highlight.ini .code .attr { + color: #a71d5d; } + +.highlight.ini .code .value, +.highlight.ini .code .keyword { + color: #333; } + +.highlight.java .code .title { + color: #795da3; } + +.highlight.java .code .javadoc { + color: #969896; } + +.highlight.java .code .meta, +.highlight.java .code .annotation, +.highlight.java .code .javadoctag { + color: #a71d5d; } + +.highlight.java .code .number { + color: #0086b3; } + +.highlight.java .code .params { + color: #1d3e81; } + +.highlight.js .code .built_in, +.highlight.js .code .title { + color: #795da3; } + +.highlight.js .code .javadoc { + color: #969896; } + +.highlight.js .code .tag, +.highlight.js .code .javadoctag { + color: #a71d5d; } + +.highlight.js .code .tag .title { + color: #333; } + +.highlight.js .code .regexp { + color: #df5000; } + +.highlight.js .code .literal, +.highlight.js .code .number { + color: #0086b3; } + +.highlight.json .code .attribute { + color: #183691; } + +.highlight.json .code .number, +.highlight.json .code .literal { + color: #0086b3; } + +.highlight.mak .code .constant { + color: #333; } + +.highlight.mak .code .title { + color: #795da3; } + +.highlight.mak .code .keyword, +.highlight.mak .code .meta-keyword { + color: #0086b3; } + +.highlight.md .code .value, +.highlight.md .code .link_label, +.highlight.md .code .strong, +.highlight.md .code .emphasis, +.highlight.md .code .blockquote, +.highlight.md .code .quote, +.highlight.md .code .section { + color: #183691; } + +.highlight.md .code .link_reference, +.highlight.md .code .symbol, +.highlight.md .code .code { + color: #0086b3; } + +.highlight.md .code .link_url, +.highlight.md .code .link { + text-decoration: underline; } + +.highlight.nginx .code .title, +.highlight.nginx .code .attribute { + color: #a71d5d; } + +.highlight.nginx .code .built_in, +.highlight.nginx .code .literal { + color: #0086b3; } + +.highlight.nginx .code .regexp { + color: #183691; } + +.highlight.nginx .code .variable { + color: #333; } + +.highlight.objectivec .code .preprocessor, +.highlight.objectivec .code .meta { + color: #a71d5d; } + .highlight.objectivec .code .preprocessor .title, + .highlight.objectivec .code .meta .title { + color: #df5000; } + +.highlight.objectivec .code .meta-string { + color: #183691; } + +.highlight.objectivec .code .title { + color: #795da3; } + +.highlight.objectivec .code .literal, +.highlight.objectivec .code .number, +.highlight.objectivec .code .built_in { + color: #0086b3; } + +.highlight.perl .code .sub { + color: #795da3; } + +.highlight.perl .code .title { + color: #795da3; } + +.highlight.perl .code .regexp { + color: #df5000; } + +.highlight.php .code .phpdoc, +.highlight.php .code .doctag { + color: #a71d5d; } + +.highlight.php .code .regexp { + color: #df5000; } + +.highlight.php .code .literal, +.highlight.php .code .number { + color: #0086b3; } + +.highlight.php .code .title { + color: #795da3; } + +.highlight.python .code .decorator, +.highlight.python .code .title, +.highlight.python .code .meta { + color: #795da3; } + +.highlight.python .code .number { + color: #0086b3; } + +.highlight.ruby .code .parent, +.highlight.ruby .code .title { + color: #795da3; } + +.highlight.ruby .code .prompt, +.highlight.ruby .code .constant, +.highlight.ruby .code .number, +.highlight.ruby .code .subst .keyword, +.highlight.ruby .code .symbol { + color: #0086b3; } + +.highlight.sql .built_in { + color: #a71d5d; } + +.highlight.sql .number { + color: #0086b3; } + +.highlight.xml .tag, .highlight.html .tag { + color: #333; } + +.highlight.xml .value, .highlight.html .value { + color: #183691; } + +.highlight.xml .attribute, +.highlight.xml .attr, .highlight.html .attribute, +.highlight.html .attr { + color: #795da3; } + +.highlight.xml .title, +.highlight.xml .name, .highlight.html .title, +.highlight.html .name { + color: #63a35c; } + +.highlight.puppet .title { + color: #795da3; } + +.highlight.puppet .function { + color: #0086b3; } + +.highlight.puppet .name { + color: #a71d5d; } + +.highlight.puppet .attr { + color: #0086b3; } + +.highlight.less .tag, +.highlight.less .at_rule { + color: #a71d5d; } + +.highlight.less .number, +.highlight.less .hexcolor, +.highlight.less .function, +.highlight.less .attribute { + color: #0086b3; } + +.highlight.less .built_in { + color: #df5000; } + +.highlight.less .id, +.highlight.less .pseudo, +.highlight.less .class, +.highlight.less .selector-id, +.highlight.less .selector-class, +.highlight.less .selector-tag { + color: #795da3; } + +.highlight.scss .tag, +.highlight.scss .at_rule, +.highlight.scss .important { + color: #a71d5d; } + +.highlight.scss .number, +.highlight.scss .hexcolor, +.highlight.scss .function, +.highlight.scss .attribute { + color: #0086b3; } + +.highlight.scss .variable { + color: #333; } + +.highlight.scss .built_in { + color: #df5000; } + +.highlight.scss .id, +.highlight.scss .pseudo, +.highlight.scss .class, +.highlight.scss .preprocessor, +.highlight.scss .selector-class, +.highlight.scss .selector-id { + color: #795da3; } + +.highlight.scss .tag, +.highlight.scss .selector-tag { + color: #63a35c; } + +.highlight.stylus .at_rule { + color: #a71d5d; } + +.highlight.stylus .tag, +.highlight.stylus .selector-tag { + color: #63a35c; } + +.highlight.stylus .number, +.highlight.stylus .hexcolor, +.highlight.stylus .attribute, +.highlight.stylus .params { + color: #0086b3; } + +.highlight.stylus .class, +.highlight.stylus .id, +.highlight.stylus .pseudo, +.highlight.stylus .title, +.highlight.stylus .selector-id, +.highlight.stylus .selector-pseudo, +.highlight.stylus .selector-class { + color: #795da3; } + +.highlight.go .typename { + color: #a71d5d; } + +.highlight.go .built_in, +.highlight.go .constant { + color: #0086b3; } + +.highlight.swift .preprocessor { + color: #a71d5d; } + +.highlight.swift .title { + color: #795da3; } + +.highlight.swift .built_in, +.highlight.swift .number, +.highlight.swift .type { + color: #0086b3; } + +.highlight.yml .line, +.highlight.yml .attr { + color: #63a35c; } + +.highlight.yml .line, +.highlight.yml .string, +.highlight.yml .type, +.highlight.yml .literal, +.highlight.yml .meta { + color: #183691; } + +.highlight.yml .number { + color: #0086b3; } + +/* post navigator*/ +.post-nav { + overflow: hidden; + margin-top: 15px; + margin-bottom: 20px; + padding: 10px; + white-space: nowrap; + border-top: 1px solid #eee; } + .post-nav a { + display: inline-block; + line-height: 25px; + font-size: 15px; + color: #555; + border-bottom: none; + float: left; } + .post-nav a.pre { + float: left; } + .post-nav a.pre:before { + font-family: "FontAwesome"; + content: "\f0d9"; + padding-right: 0.3em; } + .post-nav a.next { + float: right; } + .post-nav a.next:after { + font-family: "FontAwesome"; + content: "\f0da"; + padding-left: 0.3em; } + .post-nav a:hover { + border-bottom: none; + color: #222; } + +/* toc*/ +.toc-article { + border: 1px solid #bbb; + border-radius: 7px; + margin: 1.1em 0 0 2em; + padding: 0.7em 0.7em 0 0.7em; + max-width: 40%; } + +.toc-title { + font-size: 120%; } + +#toc { + line-height: 1em; + float: right; } + #toc .toc { + padding: 0; + margin: 0.5em; + line-height: 1.8em; } + #toc .toc li { + list-style-type: none; } + #toc .toc-child { + margin-left: 1em; + padding-left: 0; } + +/* table*/ +table { + margin: auto auto 15px; + width: 100%; + background: transparent; + border-collapse: collapse; + border-spacing: 0; + text-align: left; } + table th { + font-weight: bold; + padding: 5px 10px; + border-bottom: 2px solid #909ba2; } + table td { + padding: 5px 10px; } + table tr:nth-child(2n) { + background: #f7f8f8; } + +/* article-share*/ +.article-share-link { + cursor: pointer; + float: right; + margin-left: 20px; } + .article-share-link:before { + font-family: "FontAwesome"; + content: "\f064"; + padding-right: 6px; } + +.article-share-box { + position: absolute; + display: none; + background: #fff; + box-shadow: 1px 2px 10px rgba(0, 0, 0, 0.2); + border-radius: 3px; + margin-left: -145px; + overflow: hidden; + z-index: 1; } + .article-share-box.on { + display: block; } + +.article-share-input { + width: 100%; + background: none; + box-sizing: border-box; + font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif; + padding: 0 15px; + color: #555; + outline: none; + border: 1px solid #ddd; + border-radius: 3px 3px 0 0; + height: 36px; + line-height: 36px; } + +.article-share-links { + clearfix: none; + background: #eee; } + +.article-share-element, .article-share-twitter, .article-share-facebook, .article-share-weibo, .article-share-qrcode { + width: 50px; + height: 36px; + display: block; + float: left; + position: relative; + color: #999; + text-shadow: 0 1px #fff; } + .article-share-element:before, .article-share-twitter:before, .article-share-facebook:before, .article-share-weibo:before, .article-share-qrcode:before { + font-size: 20px; + font-family: "FontAwesome"; + width: 20px; + height: 20px; + position: absolute; + top: 50%; + left: 50%; + margin-top: -10px; + margin-left: -10px; + text-align: center; } + .article-share-element:hover, .article-share-twitter:hover, .article-share-facebook:hover, .article-share-weibo:hover, .article-share-qrcode:hover { + color: #fff; } + +.article-share-twitter:before { + content: "\f099"; } + +.article-share-twitter:hover { + background: #00aced; } + +.article-share-facebook:before { + content: "\f09a"; } + +.article-share-facebook:hover { + background: #3b5998; } + +.article-share-weibo:before { + content: "\f18a"; } + +.article-share-weibo:hover { + background: #d44137; } + +.article-share-qrcode:before { + content: "\f029"; } + +.article-share-qrcode:hover, .article-share-qrcode:active { + background: #38ad5a; } + .article-share-qrcode:hover ~ .qrcode, .article-share-qrcode:active ~ .qrcode { + display: block; + text-align: center; } + +.qrcode { + display: none; } + +/* search result*/ +ul.search-result-list { + padding-left: 10px; } + +a.search-result-title { + font-weight: bold; + font-size: 15px; + color: #555; } + +p.search-result { + color: #444; + text-align: justify; } + +em.search-keyword { + font-weight: bold; + font-style: normal; + color: #01579f; } + +/* Disqus Button */ +.disqus_click_btn { + line-height: 30px; + margin: 0; + min-width: 50px; + padding: 0 14px; + display: inline-block; + font-family: "Roboto", "Helvetica", "Arial", sans-serif; + font-size: 14px; + font-weight: 400; + letter-spacing: 0; + overflow: hidden; + will-change: box-shadow; + transition: box-shadow 0.2s cubic-bezier(0.4, 0, 1, 1), background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s cubic-bezier(0.4, 0, 0.2, 1); + outline: 0; + cursor: pointer; + text-decoration: none; + text-align: center; + vertical-align: middle; + border: 0; + background: rgba(158, 158, 158, 0.2); + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + color: #fff; + background-color: #999999; + text-shadow: 0; } + +.post-copyright { + margin: 2em 0 0; + padding: 0.5em 1em; + border-left: 3px solid #FF1700; + background-color: #F9F9F9; + list-style: none; } + .post-copyright li { + margin: 8px 0; } diff --git a/donate/index.html b/donate/index.html index e69de29b..c2b53d7f 100644 --- a/donate/index.html +++ b/donate/index.html @@ -0,0 +1,28 @@ + + + + + Donate-Page + + + + + + + + + +
Donate
+
    +
  • PayPal
  • +
  • +
  • AliPay
  • +
  • WeChat
  • +
+
+
+
+ + + + diff --git a/edusmart/index.html b/edusmart/index.html index e69de29b..9478d41c 100644 --- a/edusmart/index.html +++ b/edusmart/index.html @@ -0,0 +1,138 @@ +EOS完全开发指南 | HackDApp

EOS完全开发指南

为你提供最完整的EOS知识结构图谱,与EOS公链版本同步更新技术知识点。

+
+

🔗 文章阅读: http://learneos.hackdapp.com

+
+

第一部分、C++导读

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
1.0 简易程序入门1.1 C++基础语法1.2 基础数据类型及变量、常量定义1.3 结构体及函数定义
1.4 数据结构1.5 面向对象编程1.6 高级应用(模板定义)1.7 标准库及库函数
1.8 资料及经验分享
+

第二部分、EOS开发所必须掌握的基础概念与术语

+ + + + + + + + + + + + + + + + +
2.1 帐户及公私钥2.2 智能合约2.3 共识机制2.4 ABI/WASM
+

第三部分、深入理解智能合约

第四部分、高级应用技巧

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
5.1 存储合约数据5.2 多个合约间交互5.3 定制TOKEN合约、发行及转帐交互5.4 同步与异步调用合约方法
5.5 打包数据上链5.6 随机数生成5.7 预言机,与外部世界通讯5.8 合约内数据加密
5.9 合约编译5.10 合约发布与升级5.11 合约测试5.12 合约设计与实现
5.13 合约权限5.13 合约漏洞与安全防护
+

第五部分、剖析第三方合约

第六部分、实战开发—去中心化游戏

+ + + + + + + + + + + + + + + + + + + + + +
6.1 配置开发环境6.2 搭建项目工程6.3 合约开发6.4 UI及后端服务开发
6.5 服务部署与上线
+

更详细大纲请移步至🔗 : http://learneos.hackdapp.com

+
+

欢迎关注HackDApp博客或公众号, HackHook将持续为你分享IndieMaker成长路径、DAPP技术知识、高效Mac使用技巧、底层思维认知。

+
+

我的博客: https://www.hackdapp.com/
我的github: https://github.com/hackdapp
我的哔哩哔哩: https://space.bilibili.com/17360859
我的微信公众号: hackdapp

IndieMakers: https://www.indiemakers.cn

+
+

联系邮箱:55269778@qq.com

+
\ No newline at end of file diff --git a/favicon.ico b/favicon.ico index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b16faecf312192f7196e20bd3952959be6f5e464 100644 GIT binary patch literal 140513 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 literal 0 HcmV?d00001 diff --git a/google1031035202c817c5.html b/google1031035202c817c5.html index e69de29b..9dc73cbe 100644 --- a/google1031035202c817c5.html +++ b/google1031035202c817c5.html @@ -0,0 +1 @@ +google-site-verification: google1031035202c817c5.html \ No newline at end of file diff --git a/grownth/index.html b/grownth/index.html index e69de29b..a63e42bf 100644 --- a/grownth/index.html +++ b/grownth/index.html @@ -0,0 +1,34 @@ +EOS完全开发手册 | HackDApp

EOS完全开发手册

+
\ No newline at end of file diff --git a/history/index.html b/history/index.html index e69de29b..0fb32d99 100644 --- a/history/index.html +++ b/history/index.html @@ -0,0 +1,27 @@ + | HackDApp

Now
Past
1
2019-Now +转战更高价值的方向
2
2018 +充电一年
3
2017 +区块链之年
4
2016 +儿子降生
\ No newline at end of file diff --git a/img/AliPayQR.png b/img/AliPayQR.png index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e54760e35cca45e0a2ad40110c96f84d1a13be63 100644 GIT binary patch literal 28743 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 MMp@>elyTty0Zxy_m;e9( literal 0 HcmV?d00001 diff --git a/img/BTCQR.png b/img/BTCQR.png index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b7cd7d434b519c25562008b4a9cce30969afe892 100644 GIT binary patch literal 20129 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 R`EM1^oK}|3IBDeje*n|hOD6yT literal 0 HcmV?d00001 diff --git a/img/alipay.svg b/img/alipay.svg index e69de29b..2e789675 100644 --- a/img/alipay.svg +++ b/img/alipay.svg @@ -0,0 +1,46 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + diff --git a/img/bitcoin.svg b/img/bitcoin.svg index e69de29b..dc64d878 100644 --- a/img/bitcoin.svg +++ b/img/bitcoin.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/github.svg b/img/github.svg index e69de29b..7d9f99ff 100644 --- a/img/github.svg +++ b/img/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/like.svg b/img/like.svg index e69de29b..44adab30 100644 --- a/img/like.svg +++ b/img/like.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/paypal.svg b/img/paypal.svg index e69de29b..cdacb583 100644 --- a/img/paypal.svg +++ b/img/paypal.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + diff --git a/img/wechat.svg b/img/wechat.svg index e69de29b..c5d50af6 100644 --- a/img/wechat.svg +++ b/img/wechat.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html index e69de29b..81ce09d3 100644 --- a/index.html +++ b/index.html @@ -0,0 +1,18 @@ +HackDApp | Focus on DApp tutorials, Thinking growth, Mac skills, IndieMaker, etc.

基于以太坊的NFT开发实践

课程大纲

第一部分、项目总览

    Read More

    如何做好课堂笔记

    Read More

    如何提高防猝死的能力

    猝死就是平时身体健康、或貌似健康的患者,在出乎意料的短时间内,因自然疾病而突然死亡.

    +

    猝死,如此可怕,是哪些原因导致的呢?
    85%是心血管问题,这其中,又有80%是给心脏供血的冠状动脉突发缺血了。

    +

    那么,猝死我们可以预防或控制吗?
    好消息是,绝大部分情况可以,前提是你要有足够的心脏储备。而储备,是心血管健康里最容易被忽视的一个维度。所谓心力储备,就是心脏因身体的需要而增加射血的能力。所以,大部分情况下,猝死是由于心力储备坍塌导致的。

    Read More

    如何用61分钟写出漂亮的推广文案

    如何用最少的时间写出最漂亮的广告推广文案呢?今天就向你推荐一个写作框架。,点击【ReadMore】,了解更多详情。

    Read More

    交易者应掌握的能力

    无论是在股市或是币市,我们都希望通过自己的一顿神操作,买到那些可以让自己瞬间反几倍甚至几十倍的股票或数字货币,但现实情况
    会告诉你,即使是牛市你也能亏钱亏的要死。

    +

    为什么呢?这就不得不想想其中你想赚钱的行为,是一种投机还是投资?

    +

    投机呢,完全可能就是全凭着几个火热大群的fomo情绪,亦或是好巧不巧的几个自己认为重要的小道消息,就认为自己拿到了人生财富密码,知道自己输的底朝天;而投资往往是通过自己对标的物,花精力与时间去研究思考,挖机出它的长期价值,尤其是那些被低估的标的,即使是自己决策失误,也会总结教训,从错误中反思,改进自己的投资方法论,不错失提升自己大脑🧠成长的机会。

    Read More

    如何提高收益风险比

    什么是收益风险比呢? 字面意思不难理解,就是: 收益风险比 = 可能的收益 / 未知的风险。

    +

    为什么需要认识并提升自己的收益风险比呢? 因为像我这样打工人,除了工资之外,就没有其他收入了,如果被辞职或家里出些什么事,无论是家庭生活质量还是自己的心理焦虑,都会受到极大的生存压力。而投资作为被动收入的一种手段,就可以提升我们在工作单一收入上的安全度,而提升收益风险比,就是在这一基础上能够获得更大的回报。

    Read More

    C++简单程序入门

    C++简单程序入门. 以最简单的示例代码,为你拆解其脉络结构。上手C++对你来说,那不是难事。

    Read More

    \ No newline at end of file diff --git a/js/codeblock-resizer.js b/js/codeblock-resizer.js index e69de29b..96fd57fd 100644 --- a/js/codeblock-resizer.js +++ b/js/codeblock-resizer.js @@ -0,0 +1,51 @@ ++function($) { + 'use strict'; + + // Resize code blocks to fit the screen width + + var CodeBlockResizer = function(elem) { + this.$codeBlocks = $(elem); + }; + + CodeBlockResizer.prototype = { + /** + * Run main feature + */ + run: function() { + var self = this; + // resize all codeblocks + self.resize(); + // resize codeblocks when window is resized + $(window).smartresize(function() { + self.resize(); + }); + }, + + /** + * Resize codeblocks + */ + resize: function() { + var self = this; + self.$codeBlocks.each(function() { + var $gutter = $(this).find('.gutter'); + var $code = $(this).find('.code'); + // get padding of code div + var codePaddings = $code.width() - $code.innerWidth(); + // code block div width with padding - gutter div with padding + code div padding + var width = $(this).outerWidth() - $gutter.outerWidth() + codePaddings; + // apply new width + $code.css('width', width); + $code.children('pre').css('width', width); + }); + } + }; + + $(document).ready(function() { + // register jQuery function to check if an element has an horizontal scroll bar + $.fn.hasHorizontalScrollBar = function() { + return this.get(0).scrollWidth > this.innerWidth(); + }; + var resizer = new CodeBlockResizer('figure.highlight'); + resizer.run(); + }); +}(jQuery); diff --git a/js/donate.js b/js/donate.js index e69de29b..da3989bc 100644 --- a/js/donate.js +++ b/js/donate.js @@ -0,0 +1,78 @@ +(function($) { + $.getUrlParam = function(name) { + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); + var r = window.location.search.substr(1).match(reg); + if(r && r[2] && r[2] != 'null' && r[2] != 'undefined' && r[2] != '') { + return unescape(r[2]); + } else { + return null; + } + } +})(jQuery); +jQuery(document).ready(function() { + $("#github").attr('href', $.getUrlParam('GitHub') || "https://github.com/" + window.location.href.split(".github.io")[0].split("/").pop()) + var QRBox = $('#QRBox'); + var MainBox = $('#MainBox'); + var count = 0; + $("li").hide(); + if($.getUrlParam('BTCQR') && $.getUrlParam('BTCKEY')) { + var BTCQR = $.getUrlParam('BTCQR'); // 二维码路径 + var BTCKEY = $.getUrlParam('BTCKEY'); + count++; + $("#BTC").show(); + $("#BTC").addClass('yc') + $("#btc-key").attr("value",BTCKEY) + } + if($.getUrlParam('AliPayQR')) { + var AliPayQR = $.getUrlParam('AliPayQR'); + count++; + $("#AliPay").show(); + } + if($.getUrlParam('WeChatQR')) { + var WeChatQR = $.getUrlParam('WeChatQR'); + count++; + $("#WeChat").show(); + } + if($.getUrlParam('PayPal')) { + var PayPal = $.getUrlParam('PayPal'); + count++; + $("#PayPal a").attr("href",PayPal) + $("#PayPal").show(); + } + if(count == 0){ + $("#WeChat").after('
    没有开启任何Donate选项!
    '); + } + $("#donateBox li,#donateBox li a").css("width", Math.ceil(74+(74*(4-count)/count))+"px"); + function showQR(QR) { + if(QR) { + MainBox.css('background-image', 'url(' + QR + ')'); + } + $('#DonateText,#donateBox,#github').addClass('blur'); + QRBox.fadeIn(300, function(argument) { + MainBox.addClass('showQR'); + }); + } + + $('#donateBox>li').click(function(event) { + var thisID = $(this).attr('id'); + if(thisID === 'BTC') { + showQR(BTCQR); + new Clipboard('#BTCBn'); + } else if(thisID === 'AliPay') { + showQR(AliPayQR); + } else if(thisID === 'WeChat') { + showQR(WeChatQR); + } + }); + + MainBox.click(function(event) { + MainBox.removeClass('showQR').addClass('hideQR'); + setTimeout(function(a) { + QRBox.fadeOut(300, function(argument) { + MainBox.removeClass('hideQR'); + }); + $('#DonateText,#donateBox,#github').removeClass('blur'); + }, 600); + + }); +}); diff --git a/js/fancybox.js b/js/fancybox.js index e69de29b..3535a346 100644 --- a/js/fancybox.js +++ b/js/fancybox.js @@ -0,0 +1,19 @@ +$(document).ready(function() { + $('img').each(function() { + if ($(this).parent().hasClass('fancybox')) return; + if ($(this).hasClass('nofancybox')) return; + var alt = this.alt; + if (alt) $(this).after('' + alt + ''); + $(this).wrap(''); + }); + $(this).find('.fancybox').each(function(){ + $(this).attr('rel', 'article'); + }); +}); +$(document).ready(function() { + $("a[href$='.jpg'],a[href$='.png'],a[href$='.gif'],a[href$='.webp']").attr('rel', 'gallery').fancybox({ + helpers : { + title: { type: 'inside'} + } + }); +}); diff --git a/js/gitment.browser.js b/js/gitment.browser.js index e69de29b..06e13226 100644 --- a/js/gitment.browser.js +++ b/js/gitment.browser.js @@ -0,0 +1,3751 @@ +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
    \n
    \n \n ' + comment.user.login + '\n \n commented on\n ' + createDate.toDateString() + '\n ' + (createDate.toString() !== updateDate.toString() ? ' \u2022 edited' : '') + '\n
    ' + _icons.heart + ' ' + (comment.reactions.heart || '') + '
    \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 \n \n
    \n
    \n
    \n \n
    \n
    \n
    \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 Gitment\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/search.js b/js/search.js index e69de29b..bba51fb4 100644 --- a/js/search.js +++ b/js/search.js @@ -0,0 +1,86 @@ +var searchFunc = function(path, search_id, content_id) { + 'use strict'; + $.ajax({ + url: path, + dataType: "xml", + success: function( xmlResponse ) { + // get the contents from search data + var datas = $( "entry", xmlResponse ).map(function() { + return { + title: $( "title", this ).text(), + content: $("content",this).text(), + url: $( "url" , this).text() + }; + }).get(); + var $input = document.getElementById(search_id); + var $resultContent = document.getElementById(content_id); + $input.addEventListener('input', function(){ + var str='
      '; + var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/); + $resultContent.innerHTML = ""; + if (this.value.trim().length <= 0) { + return; + } + // perform local searching + datas.forEach(function(data) { + var isMatch = true; + var content_index = []; + var data_title = data.title.trim().toLowerCase(); + var data_content = data.content.trim().replace(/<[^>]+>/g,"").toLowerCase(); + var data_url = data.url; + var index_title = -1; + var index_content = -1; + var first_occur = -1; + // only match artiles with not empty titles and contents + if(data_title != '' && data_content != '') { + keywords.forEach(function(keyword, i) { + index_title = data_title.indexOf(keyword); + index_content = data_content.indexOf(keyword); + if( index_title < 0 && index_content < 0 ){ + isMatch = false; + } else { + if (index_content < 0) { + index_content = 0; + } + if (i == 0) { + first_occur = index_content; + } + } + }); + } + // show search results + if (isMatch) { + str += "
    • "+ data_title +""; + var content = data.content.trim().replace(/<[^>]+>/g,""); + if (first_occur >= 0) { + // cut out 100 characters + var start = first_occur - 30; + var outLength = 78; + if(start < 0){ + start = 0; + } + if (start + outLength > content.length){ + if(content.length < outLength){ + outLength = content.length - start; + }else{ + start = content.length - outLength; + } + } + var match_content = content.substr(start, outLength); + // highlight all keywords + keywords.forEach(function(keyword){ + var regS = new RegExp(keyword, "gi"); + match_content = match_content.replace(regS, ""+keyword+""); + }); + + str += "

      " + match_content +"...

      " + } + str += "
    • "; + } + }); + str += "
    "; + $resultContent.innerHTML = str; + }); + } + }); +} diff --git a/js/share.js b/js/share.js index e69de29b..f358213d 100644 --- a/js/share.js +++ b/js/share.js @@ -0,0 +1,60 @@ +(function($){ + + // article-share + $('body').on('click', function(){ + $('.article-share-box.on').removeClass('on'); + }).on('click', '.article-share-link', function(e){ + e.stopPropagation(); + + var $this = $(this), + url = $this.attr('data-url'), + qrcode_img = $this.attr('data-qrcode'), + encodedUrl = encodeURIComponent(url), + id = 'article-share-box-' + $this.attr('data-id'), + title = document.title, + offset = $this.offset(); + + if ($('#' + id).length){ + var box = $('#' + id); + + if (box.hasClass('on')){ + box.removeClass('on'); + return; + } + } else { + var html = [ + '
    ', + '', + '
    ', + '', + '', + '', + '', + '
    ', + '
    ', + '
    ' + ].join(''); + + var box = $(html); + + $('body').append(box); + } + + $('.article-share-box.on').hide(); + + box.css({ + top: offset.top + 25, + left: offset.left + }).addClass('on'); + }).on('click', '.article-share-box', function(e){ + e.stopPropagation(); + }).on('click', '.article-share-box-input', function(){ + $(this).select(); + }).on('click', '.article-share-box-link', function(e){ + e.preventDefault(); + e.stopPropagation(); + + window.open(this.href, 'article-share-box-window-' + Date.now(), 'width=500,height=450'); + }); + +})(jQuery); diff --git a/js/smartresize.js b/js/smartresize.js index e69de29b..7def5e71 100644 --- a/js/smartresize.js +++ b/js/smartresize.js @@ -0,0 +1,32 @@ ++(function($, sr) { + // debouncing function from John Hann + // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ + var debounce = function(func, threshold, execAsap) { + var timeout; + + return function debounced() { + var obj = this, args = arguments; + + function delayed() { + if (!execAsap) { + func.apply(obj, args); + } + + timeout = null; + }; + + if (timeout) { + clearTimeout(timeout); + } + else if (execAsap) { + func.apply(obj, args); + } + + timeout = setTimeout(delayed, threshold || 100); + }; + }; + + jQuery.fn[sr] = function(fn) { + return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); + }; +})(jQuery, 'smartresize'); diff --git a/js/totop.js b/js/totop.js index e69de29b..afa66d9a 100644 --- a/js/totop.js +++ b/js/totop.js @@ -0,0 +1,12 @@ +$(window).scroll(function() { + $(window).scrollTop() > 500 ? $("#rocket").addClass("show") : $("#rocket").removeClass("show"); +}); +$("#rocket").click(function() { + $("#rocket").addClass("launch"); + $("html, body").animate({ + scrollTop: 0 + }, 500, function() { + $("#rocket").removeClass("show launch"); + }); + return false; +}); diff --git a/page/2/index.html b/page/2/index.html index e69de29b..87e580eb 100644 --- a/page/2/index.html +++ b/page/2/index.html @@ -0,0 +1,18 @@ +HackDApp | Focus on DApp tutorials, Thinking growth, Mac skills, IndieMaker, etc.

    零基础体验EOS入门合约开发

    本教程主要面向初阶开发人员,目的在于带领大家以最简单的示例合约,通过简单但不失完整的流程,体验整个合约的编译、发布与调用过程,从而让大家从直观角度有个清晰的概念认识。

    Read More

    巧用HistoryApiAction实现对链数据的存储与查询

    在开发EOS DApp智能合约时,我们都知道可以使用`multi\\_index\_`来对合约数据的存储与查询,但合约的存储是需要消耗一定的资源的,而且随着用户的增长往往会导业务数据会越来越大,从而导致合约需要更多的资源来支撑其数据增长。那么是否有一种更好的方式来降低某些场景的资源消耗呢?那么,今天将为你分享一种数据存储方案: 借用EOS链提供的`history_api_action\_`插件、`内部合约Action调用`来完成对业务数据的存储与查询。HackDApp愿与你分享!

    Read More

    使用EOS.js发布EOS智能合约

    之前我们曾经介绍过如何使用EOS的系统命令(cleos set contract)发布智能合约,那么今天将分享另外一种方式:使用eosjs-sdk发布合约。在此基础上,可以通过配置package.json脚本以及IDE快捷链,可以快速提升DApp开发效率。HackDApp愿与你分享!

    Read More

    剖析EOS合约编译ABI文件

    每个EOS合约开发者肯定都知道ABI文件,但却不一定都知道ABI内部属性是什么,具体作用。本文hackdapp将带你一探ABI究竟。HackDApp愿与你分享!

    Read More

    重塑思维:自律 VS 习惯

    本周最大的收获就是:搞清楚自律与习惯间的转换逻辑。明白靠自律去约束自己只能不断内耗意志力,相反如果通过打造系统逻辑,形成习惯便可从根本上提高效率。因为本身习惯不消耗意志力而是一种肌肉反应能力。HackDApp愿与你分享!

    Read More

    C++基础语法(EOS完全开发指南)

    Author: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

    +
    /* filename: myapp.cpp
    date: 2019-01-28 3:06 PM
    auth: zhangliang<zhangliang@cldy.org> */

    #include <iostream> //定义头文件
    #include <stdlib.h>

    int main()
    {
    using namespace std; //命令空间, 简化后续变量或方法调用。e.g. std::string 等同于 string

    string msg = "hi, my first dapp"; //定义变量

    cout << msg <<endl; //打印字符串
    }

    //tryit: http://tpcg.io/Tulum1
    +

    以上代码便是C++最简单可运行的最小示例。基本包含了在程序结构中所必须的一些语言特性。

    +

    根据上述程序结构,我们可以大致将它拆分成五部分内容:

    Read More

    C++导读(EOS完全开发指南)

    Author: zhangliang | WeChat: rushking2009 | Mail: zhangliang@cldy.org

    +

    本章节内容主要是带大家了解C++整个编程语言的体系架构,对C++编程语言有个整体的大致的认识与理解。另外,也是帮助大家在开发EOS智能合约之前做一下前期预习,易于对后面EOS合约的快速上手。

    +

    另外,需要说明的是,因为本身EOS智能合约是在一个沙箱机制中运行,所以它对一些标准函数库的方法进行了一些限制。所以可能导致大家可能在网上找的资料中的方法无法在合约中正常执行。

    Read More

    \ No newline at end of file diff --git a/page/3/index.html b/page/3/index.html new file mode 100644 index 00000000..0e2a2197 --- /dev/null +++ b/page/3/index.html @@ -0,0 +1,19 @@ +HackDApp | Focus on DApp tutorials, Thinking growth, Mac skills, IndieMaker, etc.

    坚持的长性

    +

    今天早上算是被媳妇嘲笑了一番,为啥呢?

    +

    因为之前自己有一段时间,为了背英语单词,所以早起了一个月,而如今早一天晚一天,早起完全看心情。

    Read More

    波场Tron-可快捷开发的实战工程模板

    本教程通过以自己定制的工程模板为示例,讲解工程构建、快捷键部署私链及整体完整的开发注程,并配以操作动图帮助大家理解。hackdapp愿与你分享。 HackDApp愿与你分享!

    Read More

    2019MetaLife

    新年愿意清单

    +
      +
    • 尝试每天500字,锻炼文字组织能力
    • +
    • 做一款自己的小众产品,用户达到100人
    • +
    • 尝试录制短视频

    Read More

    \ No newline at end of file diff --git a/robots.txt b/robots.txt index e69de29b..ec15686a 100644 --- a/robots.txt +++ b/robots.txt @@ -0,0 +1,15 @@ +User-agent: * +Allow: /*.html$ +Allow: /archives/*.html$ +Allow: /weekly/*.html$ +Allow: /things/*.html$ +Allow: /wiki/*.html$ +Allow: /categories/*/*.html$ +Allow: /about/*.html$ + +Disallow: /page/ +Disallow: /tags/ +Disallow: /vendors/ +Disallow: /fonts/ +Disallow: /vendors/ +Disallow: /fancybox/ diff --git a/sitemap.xml b/sitemap.xml index e69de29b..0b6cd16c 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -0,0 +1,193 @@ + + + + + https://www.hackdapp.com/archives/how-to-impl-nft-proj.html + + 2021-06-28T15:33:38.116Z + + + + + https://www.hackdapp.com/archives/how-to-make-goodnotes.html + + 2021-06-07T09:29:04.609Z + + + + + https://www.hackdapp.com/archives/20210428-%E5%A6%82%E4%BD%95%E6%8F%90%E9%AB%98%E9%98%B2%E7%8C%9D%E6%AD%BB%E7%9A%84%E8%83%BD%E5%8A%9B.html + + 2021-04-28T15:08:39.509Z + + + + + https://www.hackdapp.com/archives/how_to_write_ad_fast.html + + 2021-04-07T12:28:02.909Z + + + + + https://www.hackdapp.com/archives/Sun%20Feb%2028%202021%2000:00:00%20GMT+0800%20(China%20Standard%20Time).html + + 2021-04-07T10:00:45.168Z + + + + + https://www.hackdapp.com/archives/how-to-improve-return-risk-ratio.html + + 2021-04-07T10:00:45.167Z + + + + + https://www.hackdapp.com/wiki/index.html + + 2021-04-07T09:31:42.563Z + + + + + https://www.hackdapp.com/weekly/index.html + + 2021-04-07T09:31:42.562Z + + + + + https://www.hackdapp.com/history/index.html + + 2021-04-07T09:31:42.561Z + + + + + https://www.hackdapp.com/things/index.html + + 2021-04-07T09:31:42.561Z + + + + + https://www.hackdapp.com/tools/index.html + + 2021-04-07T09:31:42.561Z + + + + + https://www.hackdapp.com/google1031035202c817c5.html + + 2021-04-07T09:31:42.560Z + + + + + https://www.hackdapp.com/grownth/index.html + + 2021-04-07T09:31:42.560Z + + + + + https://www.hackdapp.com/baidu_verify_3oa53OCFMq.html + + 2021-04-07T09:31:42.558Z + + + + + https://www.hackdapp.com/about/index.html + + 2021-04-07T09:31:42.558Z + + + + + https://www.hackdapp.com/edusmart/index.html + + 2021-04-07T09:31:42.558Z + + + + + https://www.hackdapp.com/archives/try_eoscontract_dev.html + + 2021-04-07T09:31:42.557Z + + + + + https://www.hackdapp.com/archives/simple_cpllus_code.html + + 2021-04-07T09:31:42.557Z + + + + + https://www.hackdapp.com/archives/eosdev_deploycontract_eosjs.html + + 2021-04-07T09:31:42.556Z + + + + + https://www.hackdapp.com/archives/eosdev_datastorage_historyaction.html + + 2021-04-07T09:31:42.556Z + + + + + https://www.hackdapp.com/archives/eosdev_cplus_intro.html + + 2021-04-07T09:31:42.555Z + + + + + https://www.hackdapp.com/archives/rebuildbrain_habit.html + + 2021-04-07T09:31:42.555Z + + + + + https://www.hackdapp.com/archives/eosdev_contract_abi.html + + 2021-04-07T09:31:42.555Z + + + + + https://www.hackdapp.com/archives/tron_boilerplate.html + + 2021-04-07T09:31:42.554Z + + + + + https://www.hackdapp.com/archives/think_habit.html + + 2021-04-07T09:31:42.554Z + + + + + https://www.hackdapp.com/archives/eosdev_cplus_basic.html + + 2021-04-07T09:31:42.554Z + + + + + https://www.hackdapp.com/archives/2019metalife.html + + 2021-04-07T09:31:42.553Z + + + + diff --git a/things/index.html b/things/index.html index e69de29b..1627cae0 100644 --- a/things/index.html +++ b/things/index.html @@ -0,0 +1,36 @@ +好物推荐☂ | HackDApp

    好物推荐☂

    与你分享我自己常年在用的效率工具与workflow,会根据自己的周报收获持续更新。HackDApp愿与你分享!

    +
    +

    输入法

    鼠须管配置方案(五笔方案): https://github.com/hackdapp/Rime
    效果图
    注:时隔多年鼠须管终于来了一次升级,后果就是本地原有方案报错无法使用,所以自己又重新折腾了一番。

    +

    桌面控件

    效果图

    +
      +
    1. 歐陽娜娜Nana OuYang
    2. +
    + + +
    +

    工具网站

      +
    1. 简历制作
      https://www.kickresume.com
    2. +
    +

    2.

    +
    \ No newline at end of file diff --git a/tools/index.html b/tools/index.html index e69de29b..76daf1bc 100644 --- a/tools/index.html +++ b/tools/index.html @@ -0,0 +1,24 @@ + | HackDApp

    http://joinwee.com/lesson/20/#4

    +

    https://www.damengxiang.me/categories/all.html

    +
    \ No newline at end of file diff --git a/weekly/index.html b/weekly/index.html index e69de29b..ff0fa9cf 100644 --- a/weekly/index.html +++ b/weekly/index.html @@ -0,0 +1,26 @@ +学习周报⏳ | HackDApp

    学习周报⏳

    +

    与你分享与当周所收集的各种价值信息资源,当然不仅限于高质量知识、工具技巧,还包括书籍推荐📘️、技术教程、VLOG🎬️、⌨️DIY硬件。

    +
    +

    wiki.hackdapp.com

    +
    \ No newline at end of file diff --git a/wiki/index.html b/wiki/index.html index e69de29b..2282d8c0 100644 --- a/wiki/index.html +++ b/wiki/index.html @@ -0,0 +1,22 @@ + | HackDApp

    \ No newline at end of file