diff --git a/.gitignore b/.gitignore index c155d50356..25966ed913 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,11 @@ image/*.TXT !extension/cardpile !extension/coin !extension/wuxing +!extension/3D精选 +!extension/杀海拾遗 +!extension/欢乐卡牌 +!extension/玩点论杀 +!extension/英雄杀 !node_modules/@types !node_modules/noname-typings !node_modules/options diff --git a/audio/background/aozhan_shousha.mp3 b/audio/background/aozhan_shousha.mp3 new file mode 100644 index 0000000000..745180daa0 Binary files /dev/null and b/audio/background/aozhan_shousha.mp3 differ diff --git a/audio/background/effect_tuishouBGM.mp3 b/audio/background/effect_tuishouBGM.mp3 new file mode 100644 index 0000000000..56f4b302ce Binary files /dev/null and b/audio/background/effect_tuishouBGM.mp3 differ diff --git a/audio/background/effect_yinzhanBGM.mp3 b/audio/background/effect_yinzhanBGM.mp3 new file mode 100644 index 0000000000..a897c8ef87 Binary files /dev/null and b/audio/background/effect_yinzhanBGM.mp3 differ diff --git a/audio/card/female/shuiyanqijun.mp3 b/audio/card/female/shuiyanqijunx.mp3 similarity index 100% rename from audio/card/female/shuiyanqijun.mp3 rename to audio/card/female/shuiyanqijunx.mp3 diff --git a/audio/card/male/shuiyanqijun.mp3 b/audio/card/male/shuiyanqijunx.mp3 similarity index 100% rename from audio/card/male/shuiyanqijun.mp3 rename to audio/card/male/shuiyanqijunx.mp3 diff --git a/audio/die/chezhou.mp3 b/audio/die/chezhou.mp3 new file mode 100644 index 0000000000..37407f46e0 Binary files /dev/null and b/audio/die/chezhou.mp3 differ diff --git a/audio/die/clan_luji.mp3 b/audio/die/clan_luji.mp3 new file mode 100644 index 0000000000..56f61717e5 Binary files /dev/null and b/audio/die/clan_luji.mp3 differ diff --git a/audio/die/dc_xiahouhui.mp3 b/audio/die/dc_xiahouhui.mp3 new file mode 100644 index 0000000000..e62ac76cac Binary files /dev/null and b/audio/die/dc_xiahouhui.mp3 differ diff --git a/audio/die/dc_zhongyu.mp3 b/audio/die/dc_zhongyu.mp3 new file mode 100644 index 0000000000..5d67e6aa68 Binary files /dev/null and b/audio/die/dc_zhongyu.mp3 differ diff --git a/audio/die/dc_zhushuo.mp3 b/audio/die/dc_zhushuo.mp3 new file mode 100644 index 0000000000..f738d29371 Binary files /dev/null and b/audio/die/dc_zhushuo.mp3 differ diff --git a/audio/die/dm_diaochan.mp3 b/audio/die/dm_diaochan.mp3 new file mode 100644 index 0000000000..ad89f24c8c Binary files /dev/null and b/audio/die/dm_diaochan.mp3 differ diff --git a/audio/die/dm_lvbu.mp3 b/audio/die/dm_lvbu.mp3 new file mode 100644 index 0000000000..77d4bb762d Binary files /dev/null and b/audio/die/dm_lvbu.mp3 differ diff --git a/audio/die/gz_dongzhao.mp3 b/audio/die/gz_dongzhao.mp3 new file mode 100644 index 0000000000..3961fa536e Binary files /dev/null and b/audio/die/gz_dongzhao.mp3 differ diff --git a/audio/die/gz_mifangfushiren.mp3 b/audio/die/gz_mifangfushiren.mp3 new file mode 100644 index 0000000000..377f9d2dd8 Binary files /dev/null and b/audio/die/gz_mifangfushiren.mp3 differ diff --git a/audio/die/mb_sunjun.mp3 b/audio/die/mb_sunjun.mp3 new file mode 100644 index 0000000000..7a785026cc Binary files /dev/null and b/audio/die/mb_sunjun.mp3 differ diff --git a/audio/die/mb_zerong.mp3 b/audio/die/mb_zerong.mp3 new file mode 100644 index 0000000000..f046fe62e6 Binary files /dev/null and b/audio/die/mb_zerong.mp3 differ diff --git a/audio/die/ol_guanhai.mp3 b/audio/die/ol_guanhai.mp3 new file mode 100644 index 0000000000..37eef321a7 Binary files /dev/null and b/audio/die/ol_guanhai.mp3 differ diff --git a/audio/die/ol_guanzhang.mp3 b/audio/die/ol_guanzhang.mp3 new file mode 100644 index 0000000000..2bb24d9256 Binary files /dev/null and b/audio/die/ol_guanzhang.mp3 differ diff --git a/audio/die/ol_wangyi.mp3 b/audio/die/ol_wangyi.mp3 new file mode 100644 index 0000000000..dba2d980d9 Binary files /dev/null and b/audio/die/ol_wangyi.mp3 differ diff --git a/audio/die/ol_zhaozhong.mp3 b/audio/die/ol_zhaozhong.mp3 new file mode 100644 index 0000000000..0104785ddc Binary files /dev/null and b/audio/die/ol_zhaozhong.mp3 differ diff --git a/audio/die/pot_lusu.mp3 b/audio/die/pot_lusu.mp3 new file mode 100644 index 0000000000..70768cf492 Binary files /dev/null and b/audio/die/pot_lusu.mp3 differ diff --git a/audio/die/renwan.mp3 b/audio/die/renwan.mp3 new file mode 100644 index 0000000000..e60b92b3f9 Binary files /dev/null and b/audio/die/renwan.mp3 differ diff --git a/audio/die/shen_zhonghui.mp3 b/audio/die/shen_zhonghui.mp3 new file mode 100644 index 0000000000..00be983af8 Binary files /dev/null and b/audio/die/shen_zhonghui.mp3 differ diff --git a/audio/die/v_caopi.mp3 b/audio/die/v_caopi.mp3 new file mode 100644 index 0000000000..4d74493ded Binary files /dev/null and b/audio/die/v_caopi.mp3 differ diff --git a/audio/die/wild_liru.mp3 b/audio/die/wild_liru.mp3 new file mode 100644 index 0000000000..1dd988bfad Binary files /dev/null and b/audio/die/wild_liru.mp3 differ diff --git a/audio/die/yj_zhanghuan.mp3 b/audio/die/yj_zhanghuan.mp3 new file mode 100644 index 0000000000..daedd368ac Binary files /dev/null and b/audio/die/yj_zhanghuan.mp3 differ diff --git a/audio/skill/boss_heisheng.mp3 b/audio/skill/boss_heisheng.mp3 index 65de185868..19c8dcfbe1 100644 Binary files a/audio/skill/boss_heisheng.mp3 and b/audio/skill/boss_heisheng.mp3 differ diff --git a/audio/skill/boss_shengfu.mp3 b/audio/skill/boss_shengfu.mp3 index 19c8dcfbe1..65de185868 100644 Binary files a/audio/skill/boss_shengfu.mp3 and b/audio/skill/boss_shengfu.mp3 differ diff --git a/audio/skill/clanfennu1.mp3 b/audio/skill/clanfennu1.mp3 new file mode 100644 index 0000000000..dbdd281ba0 Binary files /dev/null and b/audio/skill/clanfennu1.mp3 differ diff --git a/audio/skill/clanfennu2.mp3 b/audio/skill/clanfennu2.mp3 new file mode 100644 index 0000000000..d6bc78e3db Binary files /dev/null and b/audio/skill/clanfennu2.mp3 differ diff --git a/audio/skill/clangailan1.mp3 b/audio/skill/clangailan1.mp3 new file mode 100644 index 0000000000..857e08b87f Binary files /dev/null and b/audio/skill/clangailan1.mp3 differ diff --git a/audio/skill/clangailan2.mp3 b/audio/skill/clangailan2.mp3 new file mode 100644 index 0000000000..5a26d206e0 Binary files /dev/null and b/audio/skill/clangailan2.mp3 differ diff --git a/audio/skill/clanzelie1.mp3 b/audio/skill/clanzelie1.mp3 new file mode 100644 index 0000000000..6fa29e33f8 Binary files /dev/null and b/audio/skill/clanzelie1.mp3 differ diff --git a/audio/skill/clanzelie2.mp3 b/audio/skill/clanzelie2.mp3 new file mode 100644 index 0000000000..8c9b4b628a Binary files /dev/null and b/audio/skill/clanzelie2.mp3 differ diff --git a/audio/skill/dcdianlun1.mp3 b/audio/skill/dcdianlun1.mp3 new file mode 100644 index 0000000000..791e39894d Binary files /dev/null and b/audio/skill/dcdianlun1.mp3 differ diff --git a/audio/skill/dcdianlun2.mp3 b/audio/skill/dcdianlun2.mp3 new file mode 100644 index 0000000000..c342b3ea08 Binary files /dev/null and b/audio/skill/dcdianlun2.mp3 differ diff --git a/audio/skill/dcdujun1.mp3 b/audio/skill/dcdujun1.mp3 new file mode 100644 index 0000000000..16044f9192 Binary files /dev/null and b/audio/skill/dcdujun1.mp3 differ diff --git a/audio/skill/dcdujun2.mp3 b/audio/skill/dcdujun2.mp3 new file mode 100644 index 0000000000..68f813e0ba Binary files /dev/null and b/audio/skill/dcdujun2.mp3 differ diff --git a/audio/skill/dcduzhang1.mp3 b/audio/skill/dcduzhang1.mp3 new file mode 100644 index 0000000000..07124d1489 Binary files /dev/null and b/audio/skill/dcduzhang1.mp3 differ diff --git a/audio/skill/dcduzhang2.mp3 b/audio/skill/dcduzhang2.mp3 new file mode 100644 index 0000000000..d66a9afacf Binary files /dev/null and b/audio/skill/dcduzhang2.mp3 differ diff --git a/audio/skill/dcjianghuo1.mp3 b/audio/skill/dcjianghuo1.mp3 new file mode 100644 index 0000000000..275aafc1e1 Binary files /dev/null and b/audio/skill/dcjianghuo1.mp3 differ diff --git a/audio/skill/dcjianghuo2.mp3 b/audio/skill/dcjianghuo2.mp3 new file mode 100644 index 0000000000..beecca9c41 Binary files /dev/null and b/audio/skill/dcjianghuo2.mp3 differ diff --git a/audio/skill/dcjiesi1.mp3 b/audio/skill/dcjiesi1.mp3 new file mode 100644 index 0000000000..470d479cc6 Binary files /dev/null and b/audio/skill/dcjiesi1.mp3 differ diff --git a/audio/skill/dcjiesi2.mp3 b/audio/skill/dcjiesi2.mp3 new file mode 100644 index 0000000000..95ba86794a Binary files /dev/null and b/audio/skill/dcjiesi2.mp3 differ diff --git a/audio/skill/dcjikun1.mp3 b/audio/skill/dcjikun1.mp3 new file mode 100644 index 0000000000..6274ceccac Binary files /dev/null and b/audio/skill/dcjikun1.mp3 differ diff --git a/audio/skill/dcjikun2.mp3 b/audio/skill/dcjikun2.mp3 new file mode 100644 index 0000000000..573f8ad5e1 Binary files /dev/null and b/audio/skill/dcjikun2.mp3 differ diff --git a/audio/skill/dcjilie1.mp3 b/audio/skill/dcjilie1.mp3 new file mode 100644 index 0000000000..7d1bad5c3c Binary files /dev/null and b/audio/skill/dcjilie1.mp3 differ diff --git a/audio/skill/dcjilie2.mp3 b/audio/skill/dcjilie2.mp3 new file mode 100644 index 0000000000..91fa6519b9 Binary files /dev/null and b/audio/skill/dcjilie2.mp3 differ diff --git a/audio/skill/dcjiwei1.mp3 b/audio/skill/dcjiwei1.mp3 new file mode 100644 index 0000000000..d819b98e85 Binary files /dev/null and b/audio/skill/dcjiwei1.mp3 differ diff --git a/audio/skill/dcjiwei2.mp3 b/audio/skill/dcjiwei2.mp3 new file mode 100644 index 0000000000..9098c5c662 Binary files /dev/null and b/audio/skill/dcjiwei2.mp3 differ diff --git a/audio/skill/dcjuanji1.mp3 b/audio/skill/dcjuanji1.mp3 new file mode 100644 index 0000000000..fb2973ff8e Binary files /dev/null and b/audio/skill/dcjuanji1.mp3 differ diff --git a/audio/skill/dcjuanji2.mp3 b/audio/skill/dcjuanji2.mp3 new file mode 100644 index 0000000000..bcddf2daf6 Binary files /dev/null and b/audio/skill/dcjuanji2.mp3 differ diff --git a/audio/skill/dclinjie1.mp3 b/audio/skill/dclinjie1.mp3 new file mode 100644 index 0000000000..573238f668 Binary files /dev/null and b/audio/skill/dclinjie1.mp3 differ diff --git a/audio/skill/dclinjie2.mp3 b/audio/skill/dclinjie2.mp3 new file mode 100644 index 0000000000..3e68556c49 Binary files /dev/null and b/audio/skill/dclinjie2.mp3 differ diff --git a/audio/skill/dclishi1.mp3 b/audio/skill/dclishi1.mp3 new file mode 100644 index 0000000000..b7f6491b26 Binary files /dev/null and b/audio/skill/dclishi1.mp3 differ diff --git a/audio/skill/dclishi2.mp3 b/audio/skill/dclishi2.mp3 new file mode 100644 index 0000000000..57e109946f Binary files /dev/null and b/audio/skill/dclishi2.mp3 differ diff --git a/audio/skill/dcpigua1.mp3 b/audio/skill/dcpigua1.mp3 new file mode 100644 index 0000000000..4c06cb7a85 Binary files /dev/null and b/audio/skill/dcpigua1.mp3 differ diff --git a/audio/skill/dcpigua2.mp3 b/audio/skill/dcpigua2.mp3 new file mode 100644 index 0000000000..a5af8efcb5 Binary files /dev/null and b/audio/skill/dcpigua2.mp3 differ diff --git a/audio/skill/dcrenshuang1.mp3 b/audio/skill/dcrenshuang1.mp3 new file mode 100644 index 0000000000..682df82493 Binary files /dev/null and b/audio/skill/dcrenshuang1.mp3 differ diff --git a/audio/skill/dcrenshuang2.mp3 b/audio/skill/dcrenshuang2.mp3 new file mode 100644 index 0000000000..3a920e6faa Binary files /dev/null and b/audio/skill/dcrenshuang2.mp3 differ diff --git a/audio/skill/dcshefu1.mp3 b/audio/skill/dcshefu1.mp3 new file mode 100644 index 0000000000..351e6627bd Binary files /dev/null and b/audio/skill/dcshefu1.mp3 differ diff --git a/audio/skill/dcshefu2.mp3 b/audio/skill/dcshefu2.mp3 new file mode 100644 index 0000000000..c41f2e092f Binary files /dev/null and b/audio/skill/dcshefu2.mp3 differ diff --git a/audio/skill/dcshuguo1.mp3 b/audio/skill/dcshuguo1.mp3 new file mode 100644 index 0000000000..6ff5eb5d84 Binary files /dev/null and b/audio/skill/dcshuguo1.mp3 differ diff --git a/audio/skill/dcshuguo2.mp3 b/audio/skill/dcshuguo2.mp3 new file mode 100644 index 0000000000..c33990de5a Binary files /dev/null and b/audio/skill/dcshuguo2.mp3 differ diff --git a/audio/skill/dcsugang1.mp3 b/audio/skill/dcsugang1.mp3 new file mode 100644 index 0000000000..2f5942efe7 Binary files /dev/null and b/audio/skill/dcsugang1.mp3 differ diff --git a/audio/skill/dcsugang2.mp3 b/audio/skill/dcsugang2.mp3 new file mode 100644 index 0000000000..e683f5955c Binary files /dev/null and b/audio/skill/dcsugang2.mp3 differ diff --git a/audio/skill/dcyiju1.mp3 b/audio/skill/dcyiju1.mp3 new file mode 100644 index 0000000000..50e2901d78 Binary files /dev/null and b/audio/skill/dcyiju1.mp3 differ diff --git a/audio/skill/dcyiju2.mp3 b/audio/skill/dcyiju2.mp3 new file mode 100644 index 0000000000..25be06ff6e Binary files /dev/null and b/audio/skill/dcyiju2.mp3 differ diff --git a/audio/skill/dczhidui1.mp3 b/audio/skill/dczhidui1.mp3 new file mode 100644 index 0000000000..a475e298f8 Binary files /dev/null and b/audio/skill/dczhidui1.mp3 differ diff --git a/audio/skill/dczhidui2.mp3 b/audio/skill/dczhidui2.mp3 new file mode 100644 index 0000000000..c9a1758e3a Binary files /dev/null and b/audio/skill/dczhidui2.mp3 differ diff --git a/audio/skill/dczsshuhe1.mp3 b/audio/skill/dczsshuhe1.mp3 new file mode 100644 index 0000000000..d3ea220588 Binary files /dev/null and b/audio/skill/dczsshuhe1.mp3 differ diff --git a/audio/skill/dczsshuhe2.mp3 b/audio/skill/dczsshuhe2.mp3 new file mode 100644 index 0000000000..5f7f259a1e Binary files /dev/null and b/audio/skill/dczsshuhe2.mp3 differ diff --git a/audio/skill/lingbo1.mp3 b/audio/skill/lingbo1.mp3 deleted file mode 100755 index d1c0212737..0000000000 Binary files a/audio/skill/lingbo1.mp3 and /dev/null differ diff --git a/audio/skill/lingbo2.mp3 b/audio/skill/lingbo2.mp3 deleted file mode 100755 index 4f1b9d9286..0000000000 Binary files a/audio/skill/lingbo2.mp3 and /dev/null differ diff --git a/audio/skill/mbfozong1.mp3 b/audio/skill/mbfozong1.mp3 new file mode 100644 index 0000000000..40d5d2a1e6 Binary files /dev/null and b/audio/skill/mbfozong1.mp3 differ diff --git a/audio/skill/mbfozong2.mp3 b/audio/skill/mbfozong2.mp3 new file mode 100644 index 0000000000..cd76d1f83a Binary files /dev/null and b/audio/skill/mbfozong2.mp3 differ diff --git a/audio/skill/mbfozong3.mp3 b/audio/skill/mbfozong3.mp3 new file mode 100644 index 0000000000..606bae917d Binary files /dev/null and b/audio/skill/mbfozong3.mp3 differ diff --git a/audio/skill/mbfozong4.mp3 b/audio/skill/mbfozong4.mp3 new file mode 100644 index 0000000000..b82a3d3f1c Binary files /dev/null and b/audio/skill/mbfozong4.mp3 differ diff --git a/audio/skill/mbfozong5.mp3 b/audio/skill/mbfozong5.mp3 new file mode 100644 index 0000000000..e1632c3771 Binary files /dev/null and b/audio/skill/mbfozong5.mp3 differ diff --git a/audio/skill/mbfozong6.mp3 b/audio/skill/mbfozong6.mp3 new file mode 100644 index 0000000000..ced188fd7e Binary files /dev/null and b/audio/skill/mbfozong6.mp3 differ diff --git a/audio/skill/mbfutu1.mp3 b/audio/skill/mbfutu1.mp3 new file mode 100644 index 0000000000..671dc08c8b Binary files /dev/null and b/audio/skill/mbfutu1.mp3 differ diff --git a/audio/skill/mbfutu2.mp3 b/audio/skill/mbfutu2.mp3 new file mode 100644 index 0000000000..01f7b132e5 Binary files /dev/null and b/audio/skill/mbfutu2.mp3 differ diff --git a/audio/skill/mbfutu3.mp3 b/audio/skill/mbfutu3.mp3 new file mode 100644 index 0000000000..fd25de235f Binary files /dev/null and b/audio/skill/mbfutu3.mp3 differ diff --git a/audio/skill/mbfutu4.mp3 b/audio/skill/mbfutu4.mp3 new file mode 100644 index 0000000000..6acd946dd8 Binary files /dev/null and b/audio/skill/mbfutu4.mp3 differ diff --git a/audio/skill/mbfutu5.mp3 b/audio/skill/mbfutu5.mp3 new file mode 100644 index 0000000000..0b8159be7f Binary files /dev/null and b/audio/skill/mbfutu5.mp3 differ diff --git a/audio/skill/mbfutu6.mp3 b/audio/skill/mbfutu6.mp3 new file mode 100644 index 0000000000..655194f9c6 Binary files /dev/null and b/audio/skill/mbfutu6.mp3 differ diff --git a/audio/skill/mbfutu7.mp3 b/audio/skill/mbfutu7.mp3 new file mode 100644 index 0000000000..c3f9b73a80 Binary files /dev/null and b/audio/skill/mbfutu7.mp3 differ diff --git a/audio/skill/mbfutu8.mp3 b/audio/skill/mbfutu8.mp3 new file mode 100644 index 0000000000..2223374cc0 Binary files /dev/null and b/audio/skill/mbfutu8.mp3 differ diff --git a/audio/skill/mbjiebian1.mp3 b/audio/skill/mbjiebian1.mp3 new file mode 100644 index 0000000000..ec2f86400b Binary files /dev/null and b/audio/skill/mbjiebian1.mp3 differ diff --git a/audio/skill/mbjiebian2.mp3 b/audio/skill/mbjiebian2.mp3 new file mode 100644 index 0000000000..2a94196408 Binary files /dev/null and b/audio/skill/mbjiebian2.mp3 differ diff --git a/audio/skill/mbjingtu1.mp3 b/audio/skill/mbjingtu1.mp3 new file mode 100644 index 0000000000..fffa6683e8 Binary files /dev/null and b/audio/skill/mbjingtu1.mp3 differ diff --git a/audio/skill/mbjingtu2.mp3 b/audio/skill/mbjingtu2.mp3 new file mode 100644 index 0000000000..9f0d06d4a5 Binary files /dev/null and b/audio/skill/mbjingtu2.mp3 differ diff --git a/audio/skill/mbjingtu3.mp3 b/audio/skill/mbjingtu3.mp3 new file mode 100644 index 0000000000..1eb9473bff Binary files /dev/null and b/audio/skill/mbjingtu3.mp3 differ diff --git a/audio/skill/mbjingtu4.mp3 b/audio/skill/mbjingtu4.mp3 new file mode 100644 index 0000000000..7808142c79 Binary files /dev/null and b/audio/skill/mbjingtu4.mp3 differ diff --git a/audio/skill/mbjingtu5.mp3 b/audio/skill/mbjingtu5.mp3 new file mode 100644 index 0000000000..16d7d426b7 Binary files /dev/null and b/audio/skill/mbjingtu5.mp3 differ diff --git a/audio/skill/mbjingtu6.mp3 b/audio/skill/mbjingtu6.mp3 new file mode 100644 index 0000000000..635d1b878c Binary files /dev/null and b/audio/skill/mbjingtu6.mp3 differ diff --git a/audio/skill/mbxianshuai1.mp3 b/audio/skill/mbxianshuai1.mp3 new file mode 100644 index 0000000000..dd70fbb074 Binary files /dev/null and b/audio/skill/mbxianshuai1.mp3 differ diff --git a/audio/skill/mbxianshuai2.mp3 b/audio/skill/mbxianshuai2.mp3 new file mode 100644 index 0000000000..130b37410a Binary files /dev/null and b/audio/skill/mbxianshuai2.mp3 differ diff --git a/audio/skill/mbxiongtu1.mp3 b/audio/skill/mbxiongtu1.mp3 new file mode 100644 index 0000000000..b2344fa41d Binary files /dev/null and b/audio/skill/mbxiongtu1.mp3 differ diff --git a/audio/skill/mbxiongtu2.mp3 b/audio/skill/mbxiongtu2.mp3 new file mode 100644 index 0000000000..f7dbe8e11d Binary files /dev/null and b/audio/skill/mbxiongtu2.mp3 differ diff --git a/audio/skill/mbxiongtu3.mp3 b/audio/skill/mbxiongtu3.mp3 new file mode 100644 index 0000000000..63411ca5c2 Binary files /dev/null and b/audio/skill/mbxiongtu3.mp3 differ diff --git a/audio/skill/mbxiongtu4.mp3 b/audio/skill/mbxiongtu4.mp3 new file mode 100644 index 0000000000..027472e380 Binary files /dev/null and b/audio/skill/mbxiongtu4.mp3 differ diff --git a/audio/skill/olbiri1.mp3 b/audio/skill/olbiri1.mp3 new file mode 100644 index 0000000000..35033c6e85 Binary files /dev/null and b/audio/skill/olbiri1.mp3 differ diff --git a/audio/skill/oldici1.mp3 b/audio/skill/oldici1.mp3 new file mode 100644 index 0000000000..7e2456278b Binary files /dev/null and b/audio/skill/oldici1.mp3 differ diff --git a/audio/skill/oldici2.mp3 b/audio/skill/oldici2.mp3 new file mode 100644 index 0000000000..dcaa5677e7 Binary files /dev/null and b/audio/skill/oldici2.mp3 differ diff --git a/audio/skill/olduoqi1.mp3 b/audio/skill/olduoqi1.mp3 new file mode 100644 index 0000000000..727473b4af Binary files /dev/null and b/audio/skill/olduoqi1.mp3 differ diff --git a/audio/skill/olduoqi2.mp3 b/audio/skill/olduoqi2.mp3 new file mode 100644 index 0000000000..4d72f3005e Binary files /dev/null and b/audio/skill/olduoqi2.mp3 differ diff --git a/audio/skill/olfuhun1.mp3 b/audio/skill/olfuhun1.mp3 new file mode 100644 index 0000000000..2220105ccf Binary files /dev/null and b/audio/skill/olfuhun1.mp3 differ diff --git a/audio/skill/olfuhun2.mp3 b/audio/skill/olfuhun2.mp3 new file mode 100644 index 0000000000..d9ad41cff0 Binary files /dev/null and b/audio/skill/olfuhun2.mp3 differ diff --git a/audio/skill/olgangquan1.mp3 b/audio/skill/olgangquan1.mp3 new file mode 100644 index 0000000000..6732e0a377 Binary files /dev/null and b/audio/skill/olgangquan1.mp3 differ diff --git a/audio/skill/olgangquan2.mp3 b/audio/skill/olgangquan2.mp3 new file mode 100644 index 0000000000..44179c93b0 Binary files /dev/null and b/audio/skill/olgangquan2.mp3 differ diff --git a/audio/skill/olhuanhuo1.mp3 b/audio/skill/olhuanhuo1.mp3 new file mode 100644 index 0000000000..6526cba21e Binary files /dev/null and b/audio/skill/olhuanhuo1.mp3 differ diff --git a/audio/skill/olhuanhuo2.mp3 b/audio/skill/olhuanhuo2.mp3 new file mode 100644 index 0000000000..23774c0f21 Binary files /dev/null and b/audio/skill/olhuanhuo2.mp3 differ diff --git a/audio/skill/olhuaquan1.mp3 b/audio/skill/olhuaquan1.mp3 new file mode 100644 index 0000000000..c47835c59c Binary files /dev/null and b/audio/skill/olhuaquan1.mp3 differ diff --git a/audio/skill/olhuaquan2.mp3 b/audio/skill/olhuaquan2.mp3 new file mode 100644 index 0000000000..3c04482777 Binary files /dev/null and b/audio/skill/olhuaquan2.mp3 differ diff --git a/audio/skill/olkuangmo1.mp3 b/audio/skill/olkuangmo1.mp3 new file mode 100644 index 0000000000..cf240268c9 Binary files /dev/null and b/audio/skill/olkuangmo1.mp3 differ diff --git a/audio/skill/olkuangmo2.mp3 b/audio/skill/olkuangmo2.mp3 new file mode 100644 index 0000000000..e2ce45257b Binary files /dev/null and b/audio/skill/olkuangmo2.mp3 differ diff --git a/audio/skill/olkuangmo3.mp3 b/audio/skill/olkuangmo3.mp3 new file mode 100644 index 0000000000..6b18d69784 Binary files /dev/null and b/audio/skill/olkuangmo3.mp3 differ diff --git a/audio/skill/olmiji1.mp3 b/audio/skill/olmiji1.mp3 new file mode 100644 index 0000000000..1b8e55ab6f Binary files /dev/null and b/audio/skill/olmiji1.mp3 differ diff --git a/audio/skill/olmiji2.mp3 b/audio/skill/olmiji2.mp3 new file mode 100644 index 0000000000..6ccbabd1da Binary files /dev/null and b/audio/skill/olmiji2.mp3 differ diff --git a/audio/skill/olpengbi1.mp3 b/audio/skill/olpengbi1.mp3 new file mode 100644 index 0000000000..bbf001864e Binary files /dev/null and b/audio/skill/olpengbi1.mp3 differ diff --git a/audio/skill/olpengbi2.mp3 b/audio/skill/olpengbi2.mp3 new file mode 100644 index 0000000000..b5383510a9 Binary files /dev/null and b/audio/skill/olpengbi2.mp3 differ diff --git a/audio/skill/olqingshi1.mp3 b/audio/skill/olqingshi1.mp3 new file mode 100644 index 0000000000..ac977fe288 Binary files /dev/null and b/audio/skill/olqingshi1.mp3 differ diff --git a/audio/skill/olqingshi2.mp3 b/audio/skill/olqingshi2.mp3 new file mode 100644 index 0000000000..b5af0d80f0 Binary files /dev/null and b/audio/skill/olqingshi2.mp3 differ diff --git a/audio/skill/olsanou1.mp3 b/audio/skill/olsanou1.mp3 new file mode 100644 index 0000000000..165f30c795 Binary files /dev/null and b/audio/skill/olsanou1.mp3 differ diff --git a/audio/skill/olsanou2.mp3 b/audio/skill/olsanou2.mp3 new file mode 100644 index 0000000000..987c34e5fb Binary files /dev/null and b/audio/skill/olsanou2.mp3 differ diff --git a/audio/skill/olxiewei1.mp3 b/audio/skill/olxiewei1.mp3 new file mode 100644 index 0000000000..8e88ceb920 Binary files /dev/null and b/audio/skill/olxiewei1.mp3 differ diff --git a/audio/skill/olxiewei2.mp3 b/audio/skill/olxiewei2.mp3 new file mode 100644 index 0000000000..60f2f4f63e Binary files /dev/null and b/audio/skill/olxiewei2.mp3 differ diff --git a/audio/skill/olyintian1.mp3 b/audio/skill/olyintian1.mp3 new file mode 100644 index 0000000000..1f311adc0a Binary files /dev/null and b/audio/skill/olyintian1.mp3 differ diff --git a/audio/skill/olyouque1.mp3 b/audio/skill/olyouque1.mp3 new file mode 100644 index 0000000000..6aa107d15a Binary files /dev/null and b/audio/skill/olyouque1.mp3 differ diff --git a/audio/skill/olyouque2.mp3 b/audio/skill/olyouque2.mp3 new file mode 100644 index 0000000000..965d676aea Binary files /dev/null and b/audio/skill/olyouque2.mp3 differ diff --git a/audio/skill/olzhenlie1.mp3 b/audio/skill/olzhenlie1.mp3 new file mode 100644 index 0000000000..5c4b10e7ec Binary files /dev/null and b/audio/skill/olzhenlie1.mp3 differ diff --git a/audio/skill/olzhenlie2.mp3 b/audio/skill/olzhenlie2.mp3 new file mode 100644 index 0000000000..e7747feb82 Binary files /dev/null and b/audio/skill/olzhenlie2.mp3 differ diff --git a/audio/skill/paoxiao_guanzhang2.mp3 b/audio/skill/paoxiao_guanzhang2.mp3 new file mode 100644 index 0000000000..f9ca565c41 Binary files /dev/null and b/audio/skill/paoxiao_guanzhang2.mp3 differ diff --git a/audio/skill/paoxiao_ol_guanzhang1.mp3 b/audio/skill/paoxiao_ol_guanzhang1.mp3 new file mode 100644 index 0000000000..efc3e45ab5 Binary files /dev/null and b/audio/skill/paoxiao_ol_guanzhang1.mp3 differ diff --git a/audio/skill/potdimeng1.mp3 b/audio/skill/potdimeng1.mp3 new file mode 100644 index 0000000000..0fc108b3f5 Binary files /dev/null and b/audio/skill/potdimeng1.mp3 differ diff --git a/audio/skill/potdimeng2.mp3 b/audio/skill/potdimeng2.mp3 new file mode 100644 index 0000000000..5e3c9fa562 Binary files /dev/null and b/audio/skill/potdimeng2.mp3 differ diff --git a/audio/skill/pothaoshi1.mp3 b/audio/skill/pothaoshi1.mp3 new file mode 100644 index 0000000000..adba6014f8 Binary files /dev/null and b/audio/skill/pothaoshi1.mp3 differ diff --git a/audio/skill/pothaoshi2.mp3 b/audio/skill/pothaoshi2.mp3 new file mode 100644 index 0000000000..8d6ca8db11 Binary files /dev/null and b/audio/skill/pothaoshi2.mp3 differ diff --git a/audio/skill/pothaoshi3.mp3 b/audio/skill/pothaoshi3.mp3 new file mode 100644 index 0000000000..c6f121543d Binary files /dev/null and b/audio/skill/pothaoshi3.mp3 differ diff --git a/audio/skill/xinfu_qiaosi1.mp3 b/audio/skill/qiaosi1.mp3 similarity index 100% rename from audio/skill/xinfu_qiaosi1.mp3 rename to audio/skill/qiaosi1.mp3 diff --git a/audio/skill/xinfu_qiaosi2.mp3 b/audio/skill/qiaosi2.mp3 similarity index 100% rename from audio/skill/xinfu_qiaosi2.mp3 rename to audio/skill/qiaosi2.mp3 diff --git a/audio/skill/qingguo1.mp3 b/audio/skill/qingguo1.mp3 index 1d3a73ce66..d1c0212737 100755 Binary files a/audio/skill/qingguo1.mp3 and b/audio/skill/qingguo1.mp3 differ diff --git a/audio/skill/qingguo2.mp3 b/audio/skill/qingguo2.mp3 index dcf4e32944..4f1b9d9286 100755 Binary files a/audio/skill/qingguo2.mp3 and b/audio/skill/qingguo2.mp3 differ diff --git a/audio/skill/yingbing1.mp3 b/audio/skill/reyingbing1.mp3 similarity index 100% rename from audio/skill/yingbing1.mp3 rename to audio/skill/reyingbing1.mp3 diff --git a/audio/skill/yingbing2.mp3 b/audio/skill/reyingbing2.mp3 similarity index 100% rename from audio/skill/yingbing2.mp3 rename to audio/skill/reyingbing2.mp3 diff --git a/audio/skill/zhoufu1.mp3 b/audio/skill/rezhoufu1.mp3 similarity index 100% rename from audio/skill/zhoufu1.mp3 rename to audio/skill/rezhoufu1.mp3 diff --git a/audio/skill/zhoufu2.mp3 b/audio/skill/rezhoufu2.mp3 similarity index 100% rename from audio/skill/zhoufu2.mp3 rename to audio/skill/rezhoufu2.mp3 diff --git a/audio/skill/sbbeifa1.mp3 b/audio/skill/sbbeifa1.mp3 new file mode 100644 index 0000000000..840e0e477f Binary files /dev/null and b/audio/skill/sbbeifa1.mp3 differ diff --git a/audio/skill/sbbeifa2.mp3 b/audio/skill/sbbeifa2.mp3 new file mode 100644 index 0000000000..4493203749 Binary files /dev/null and b/audio/skill/sbbeifa2.mp3 differ diff --git a/audio/skill/sbbeifa3.mp3 b/audio/skill/sbbeifa3.mp3 new file mode 100644 index 0000000000..27301a469c Binary files /dev/null and b/audio/skill/sbbeifa3.mp3 differ diff --git a/audio/skill/sbbeifa4.mp3 b/audio/skill/sbbeifa4.mp3 new file mode 100644 index 0000000000..f95ac1f8ba Binary files /dev/null and b/audio/skill/sbbeifa4.mp3 differ diff --git a/audio/skill/sbbeifa5.mp3 b/audio/skill/sbbeifa5.mp3 new file mode 100644 index 0000000000..0cf790696b Binary files /dev/null and b/audio/skill/sbbeifa5.mp3 differ diff --git a/audio/skill/sbtiaoxin3.mp3 b/audio/skill/sbtiaoxin3.mp3 new file mode 100644 index 0000000000..281105ca9e Binary files /dev/null and b/audio/skill/sbtiaoxin3.mp3 differ diff --git a/audio/skill/sbtiaoxin4.mp3 b/audio/skill/sbtiaoxin4.mp3 new file mode 100644 index 0000000000..fa4ba154ee Binary files /dev/null and b/audio/skill/sbtiaoxin4.mp3 differ diff --git a/audio/skill/wusheng_guanzhang2.mp3 b/audio/skill/wusheng_guanzhang2.mp3 new file mode 100644 index 0000000000..f97b7d6bac Binary files /dev/null and b/audio/skill/wusheng_guanzhang2.mp3 differ diff --git a/audio/skill/wusheng_ol_guanzhang1.mp3 b/audio/skill/wusheng_ol_guanzhang1.mp3 new file mode 100644 index 0000000000..69fe1dacd3 Binary files /dev/null and b/audio/skill/wusheng_ol_guanzhang1.mp3 differ diff --git a/card/gujian.js b/card/gujian.js deleted file mode 100644 index a336ae3543..0000000000 --- a/card/gujian.js +++ /dev/null @@ -1,1999 +0,0 @@ -import { lib, game, ui, get, ai, _status } from "../noname.js"; -game.import("card", function () { - return { - name: "gujian", - card: { - luyugeng: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("luyugeng"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.luyugeng = card; - target.storage.luyugeng_markcount = 3; - target.addSkill("luyugeng"); - }, - ai: { - order: 2, - value: 4, - result: { - target: 1, - }, - }, - }, - jinlianzhu: { - type: "trick", - fullskin: true, - filterTarget: true, - global: "g_jinlianzhu", - content() { - var evt = event.getParent(3)._trigger; - evt.cancel(); - if (evt.source) { - evt.source.draw(); - } - }, - ai: { - order: 1, - value: [5, 1], - useful: [6, 1], - result: { - target(player, target) { - var evt = _status.event.getTrigger(); - var eff = get.damageEffect(target, evt.source, target, evt.nature); - if (eff > 0) { - return -1; - } - if (eff < 0) { - return 2; - } - return 0; - }, - }, - }, - }, - chunbing: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("chunbing"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.chunbing = card; - target.storage.chunbing_markcount = 5; - target.addSkill("chunbing"); - }, - ai: { - order: 2, - value: 4, - result: { - target(player, target) { - var num = target.needsToDiscard(); - if (num) { - if (target == player && num > 1) { - return num; - } - return Math.sqrt(num); - } - return 0; - }, - }, - }, - }, - gudonggeng: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("gudonggeng"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.gudonggeng = card; - target.storage.gudonggeng_markcount = 3; - target.addSkill("gudonggeng"); - }, - ai: { - order: 2, - value: 4, - result: { - target(player, target) { - if (player == target && !player.hasShan()) { - return 2; - } - return 1 / Math.max(1, target.hp); - }, - }, - }, - }, - liyutang: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("liyutang"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.liyutang = card; - target.storage.liyutang_markcount = 2; - target.addSkill("liyutang"); - }, - ai: { - order: 2, - value: 4, - result: { - target(player, target) { - if (player == target && target.isMinHp()) { - return 2; - } - if (target.isMinHp()) { - return 1.5; - } - return 1 / Math.max(1, target.hp); - }, - }, - }, - }, - mizhilianou: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("mizhilianou"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.mizhilianou = card; - target.storage.mizhilianou_markcount = 4; - target.addSkill("mizhilianou"); - }, - ai: { - order: 2, - value: 4, - result: { - target(player, target) { - if (target == player) { - if (target.countCards("he", { suit: "heart" })) { - if (target.isDamaged()) { - return 1.5; - } - } else { - return 0.2; - } - } else if (target.isDamaged()) { - return 1; - } - return 0.5; - }, - }, - }, - }, - xiajiao: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("xiajiao"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.xiajiao = card; - target.storage.xiajiao_markcount = 3; - target.addSkill("xiajiao"); - target.addTempSkill("xiajiao3"); - }, - ai: { - order: 2, - value: 5, - result: { - target: 1, - }, - }, - }, - tanhuadong: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("tanhuadong"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.tanhuadong = card; - target.storage.tanhuadong_markcount = 3; - target.addSkill("tanhuadong"); - }, - ai: { - order: 2, - value: 5, - result: { - target: 1, - }, - }, - }, - mapodoufu: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("mapodoufu"); - }, - //range:{global:1}, - content() { - if (target == targets[0] && cards.length) { - target.$gain2(cards); - } - target.storage.mapodoufu = card; - target.storage.mapodoufu_markcount = 2; - target.addSkill("mapodoufu"); - }, - ai: { - order: 1, - value: 5, - result: { - target(player, target) { - return player == target ? 2 : 1; - }, - }, - }, - }, - qingtuan: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("qingtuan"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.qingtuan = card; - target.storage.qingtuan_markcount = 2; - target.addSkill("qingtuan"); - }, - ai: { - order: 4, - value: 4, - result: { - target(player, target) { - if (target == player) { - if (target.hasSha()) { - return 2; - } - } else { - var nh = target.countCards("h"); - if (nh >= 3) { - return 1; - } - if (target.hasSha()) { - return 1; - } - if (nh && Math.random() < 0.5) { - return 1; - } - } - return player.needsToDiscard() ? 0.2 : 0; - }, - }, - }, - }, - yougeng: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("yougeng"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.yougeng = card; - target.storage.yougeng_markcount = 2; - target.addSkill("yougeng"); - }, - ai: { - order: 2, - value: 4, - result: { - target(player, target) { - if (target.isHealthy()) { - return player.needsToDiscard() ? 0.1 : 0; - } - if (target.isMinHp()) { - return 1.5; - } - return 1 / Math.max(1, target.hp); - }, - }, - }, - }, - molicha: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("molicha"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.molicha = card; - target.storage.molicha_markcount = 4; - target.addSkill("molicha"); - }, - ai: { - order: 2, - value: 4, - result: { - target: 1, - }, - }, - }, - yuanbaorou: { - fullskin: true, - type: "food", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("yuanbaorou"); - }, - //range:{global:1}, - content() { - target.$gain2(cards); - target.storage.yuanbaorou = card; - target.storage.yuanbaorou_markcount = 4; - target.addSkill("yuanbaorou"); - }, - ai: { - order: 2, - value: 4, - result: { - target(player, target) { - if (target == player) { - if (target.hasSha()) { - return 2; - } - } else { - var nh = target.countCards("h"); - if (nh >= 3) { - return 1; - } - if (target.hasSha()) { - return 1; - } - if (nh && Math.random() < 0.5) { - return 1; - } - } - return player.needsToDiscard() ? 0.2 : 0; - }, - }, - }, - }, - heilonglinpian: { - fullskin: true, - type: "trick", - enable: true, - toself: true, - filterTarget(card, player, target) { - return target == player; - }, - selectTarget: -1, - modTarget: true, - content() { - target.changeHujia(); - target.addTempSkill("heilonglinpian", { player: "phaseBegin" }); - }, - ai: { - value: [6, 1], - useful: 1, - order: 2, - result: { - target: 1, - }, - }, - }, - mutoumianju: { - fullskin: true, - type: "equip", - subtype: "equip2", - skills: ["mutoumianju_skill"], - ai: { equipValue: 4 }, - onLose() { - if (player.getStat().skill.mutoumianju_skill) { - delete player.getStat().skill.mutoumianju_skill; - } - }, - }, - yuheng: { fullskin: true }, - gjyuheng: { - fullskin: true, - cardimage: "yuheng", - type: "equip", - subtype: "equip5", - nopower: true, - nomod: true, - unique: true, - skills: ["gjyuheng_skill"], - ai: { equipValue: 6 }, - onLose() { - if (player.getStat().skill.gjyuheng_skill) { - delete player.getStat().skill.gjyuheng_skill; - } - }, - }, - gjyuheng_plus: { - fullskin: true, - type: "equip", - subtype: "equip5", - nopower: true, - unique: true, - nomod: true, - epic: true, - cardimage: "yuheng", - skills: ["gjyuheng_plus_skill"], - ai: { equipValue: 7 }, - onLose() { - if (player.getStat().skill.gjyuheng_plus_skill) { - delete player.getStat().skill.gjyuheng_plus_skill; - } - }, - }, - gjyuheng_pro: { - fullskin: true, - type: "equip", - subtype: "equip5", - nopower: true, - unique: true, - nomod: true, - legend: true, - cardimage: "yuheng", - skills: ["gjyuheng_pro_skill"], - ai: { - equipValue: 8, - }, - }, - shatang: { - fullskin: true, - type: "trick", - enable: true, - filterTarget: true, - cardcolor: "red", - cardnature: "fire", - content() { - "step 0"; - target.damage("fire"); - "step 1"; - target.changeHujia(); - }, - ai: { - value: [4, 1], - useful: 2, - order: 2, - result: { - target(player, target) { - if (target.hasSkillTag("nofire")) { - return 1.5; - } - if (target.hasSkillTag("maixie_hp")) { - return 0; - } - if (target.hp == 1) { - return -1; - } - return -1 / Math.sqrt(target.hp + 1); - }, - }, - tag: { - damage: 1, - fireDamage: 1, - natureDamage: 1, - }, - }, - }, - shujinsan: { - fullskin: true, - type: "trick", - enable: true, - filterTarget(card, player, target) { - return target.countCards("he") > 0; - }, - content() { - "step 0"; - target.chooseToDiscard("he", [1, target.countCards("he")], "弃置任意张牌并摸等量的牌").ai = function (card) { - return 6 - get.value(card); - }; - "step 1"; - if (result.bool) { - target.draw(result.cards.length); - } - }, - ai: { - order: 1.5, - value: [4, 1], - tag: { - norepeat: 1, - }, - result: { - target(player, target) { - if (target == player) { - var cards = player.getCards("he"); - var num = -1; - for (var i = 0; i < cards.length; i++) { - if (get.value(cards[i]) < 6) { - num++; - } - } - if (player.needsToDiscard() && num < 1) { - num = 1; - } - return Math.max(0, num); - } else { - if (!player.needsToDiscard() && target.countCards("he") <= 3) { - return 0; - } - return target.countCards("he") / 2; - } - }, - }, - }, - }, - dinvxuanshuang: { - fullskin: true, - type: "basic", - savable: true, - selectTarget: -1, - content() { - "step 0"; - target.recover(); - "step 1"; - if (target.isIn()) { - target.chooseToDiscard([1, Infinity], "he", "弃置任意张牌并摸等量的牌"); - } else { - event.finish(); - } - "step 2"; - if (result.bool) { - target.draw(result.cards.length); - } - }, - ai: { - basic: { - order: 6, - useful: 10, - value: [8, 6.5, 5, 4], - }, - result: { - target: 2, - }, - tag: { - recover: 1, - save: 1, - }, - }, - }, - ziyangdan: { - fullskin: true, - type: "basic", - enable: true, - filterTarget: true, - content() { - target.changeHujia(3); - if (target.hasSkill("ziyangdan")) { - target.storage.ziyangdan += 3; - } else { - target.addSkill("ziyangdan"); - } - }, - ai: { - order: 1.6, - value: [7, 1], - useful: 3, - tag: { - norepeat: 1, - }, - result: { - target(player, target) { - if (target.hp > 2) { - if (player.needsToDiscard()) { - return 1 / target.hp; - } - return 0; - } - if (target.hp > 0) { - return 2 / target.hp; - } - return 0; - }, - }, - }, - }, - yunvyuanshen: { - fullskin: true, - type: "basic", - enable: true, - logv: false, - filterTarget(card, player, target) { - return !target.hasSkill("yunvyuanshen_skill"); - }, - content() { - target.storage.yunvyuanshen_skill = game.createCard("yunvyuanshen"); - target.addSkill("yunvyuanshen_skill"); - if (cards && cards.length) { - card = cards[0]; - } - if (target == targets[0] && card.clone && (card.clone.parentNode == player.parentNode || card.clone.parentNode == ui.arena)) { - card.clone.moveDelete(target); - game.addVideo("gain2", target, get.cardsInfo([card])); - } - }, - ai: { - basic: { - // value: 9, - useful: 4, - value: 7, - }, - order: 2, - result: { - target(player, target) { - return 1 / Math.sqrt(1 + target.hp); - }, - }, - }, - }, - bingpotong: { - fullskin: true, - type: "jiguan", - enable: true, - wuxieable: true, - filterTarget(card, player, target) { - return target.countCards("h") > 0; - }, - selectTarget: [1, 3], - content() { - "step 0"; - if (target.countCards("h") == 0 || player.countCards("h") == 0) { - event.finish(); - return; - } - player - .chooseCard("请展示一张手牌", true) - .set("ai", function () { - var num = 0; - var rand = _status.event.rand; - if (get.color(card) == "red") { - if (rand) { - num -= 6; - } - } else { - if (!rand) { - num -= 6; - } - } - var value = get.value(card); - if (value >= 8) { - return -100; - } - return num - value; - }) - .set("rand", Math.random() < 0.5).prompt2 = "若与" + get.translation(target) + "展示的牌相同,你弃置展示的牌," + get.translation(target) + "失去1点体力"; - "step 1"; - event.card1 = result.cards[0]; - target - .chooseCard("请展示一张手牌", true) - .set("ai", function (card) { - var num = 0; - var rand = _status.event.rand; - if (get.color(card) == "red") { - if (rand) { - num -= 6; - } - } else { - if (!rand) { - num -= 6; - } - } - var value = get.value(card); - if (value >= 8) { - return -100; - } - return num - value; - }) - .set("rand", Math.random() < 0.5).prompt2 = "若与" + get.translation(player) + "展示的牌相同," + get.translation(player) + "弃置展示的牌,你失去1点体力"; - "step 2"; - event.card2 = result.cards[0]; - ui.arena.classList.add("thrownhighlight"); - game.addVideo("thrownhighlight1"); - player.$compare(event.card1, target, event.card2); - game.delay(4); - "step 3"; - game.log(player, "展示了", event.card1); - game.log(target, "展示了", event.card2); - if (get.color(event.card2) == get.color(event.card1)) { - player.discard(event.card1).animate = false; - target.$gain2(event.card2); - var clone = event.card1.clone; - if (clone) { - clone.style.transition = "all 0.5s"; - clone.style.transform = "scale(1.2)"; - clone.delete(); - game.addVideo("deletenode", player, get.cardsInfo([clone])); - } - target.loseHp(); - event.finish(); - event.parent.cancelled = true; - } else { - player.$gain2(event.card1); - target.$gain2(event.card2); - game.delay(); - } - ui.arena.classList.remove("thrownhighlight"); - game.addVideo("thrownhighlight2"); - }, - ai: { - basic: { - order: 2, - value: [5, 1], - useful: 1, - }, - result: { - player(player, target) { - if (player.countCards("h") <= Math.min(5, Math.max(2, player.hp)) && _status.event.name == "chooseToUse") { - if (typeof _status.event.filterCard == "function" && _status.event.filterCard(new lib.element.VCard({ name: "bingpotong" }))) { - return -10; - } - if (_status.event.skill) { - var viewAs = get.info(_status.event.skill).viewAs; - if (viewAs == "bingpotong") { - return -10; - } - if (viewAs && viewAs.name == "bingpotong") { - return -10; - } - } - } - return 0; - }, - target(player, target) { - if (player.countCards("h") <= 1) { - return 0; - } - return -1.5; - }, - }, - tag: { - loseHp: 1, - }, - }, - }, - feibiao: { - type: "jiguan", - enable: true, - fullskin: true, - wuxieable: true, - outrange: { globalFrom: 2 }, - filterTarget(card, player, target) { - return target != player; - }, - content() { - "step 0"; - if (!target.countCards("h", { color: "black" })) { - target.loseHp(); - event.finish(); - } else { - target.chooseToDiscard({ color: "black" }, "弃置一张黑色手牌或受失去1点体力").ai = function (card) { - return 8 - get.value(card); - }; - } - "step 1"; - if (!result.bool) { - target.loseHp(); - } - }, - ai: { - basic: { - order: 9, - value: 3, - useful: 1, - }, - result: { - target: -2, - }, - tag: { - discard: 1, - loseHp: 1, - }, - }, - }, - longxugou: { - type: "jiguan", - enable: true, - fullskin: true, - wuxieable: true, - filterTarget(card, player, target) { - return target != player && target.countGainableCards(player, "e"); - }, - content() { - "step 0"; - var es = target.getGainableCards(player, "e"); - if (es.length) { - player - .choosePlayerCard("e", target, true) - .set("es", es) - .set("filterButton", function (button) { - return _status.event.es.includes(button.link); - }); - } else { - event.finish(); - } - "step 1"; - if (result.bool) { - target.$give(result.links[0], player); - target.lose(result.links[0], ui.special); - event.card = result.links[0]; - game.delay(); - } else { - event.finish(); - } - "step 2"; - if (event.card && get.position(event.card) == "s") { - player.equip(event.card); - } - }, - ai: { - basic: { - order: 9, - value: 6, - useful: 4, - }, - result: { - target: -1, - }, - tag: { - loseCard: 1, - gain: 1, - }, - }, - }, - qiankunbiao: { - type: "jiguan", - enable: true, - fullskin: true, - wuxieable: true, - filterTarget(card, player, target) { - return target != player && target.countCards("he") > 0; - }, - changeTarget(player, targets) { - game.filterPlayer(function (current) { - return get.distance(targets[0], current, "pure") == 1 && current.countCards("he"); - }, targets); - }, - content() { - var he = target.getCards("he"); - if (he.length) { - target.discard(he.randomGet()).delay = false; - } - }, - contentAfter() { - game.delay(0.5); - }, - ai: { - order: 7, - tag: { - loseCard: 1, - discard: 1, - }, - wuxie() { - return 0; - }, - result: { - target: -1, - }, - }, - }, - shenhuofeiya: { - type: "jiguan", - enable: true, - fullskin: true, - wuxieable: true, - filterTarget(card, player, target) { - return target != player; - }, - changeTarget(player, targets) { - game.filterPlayer(function (current) { - return get.distance(targets[0], current, "pure") == 1; - }, targets); - }, - cardcolor: "red", - cardnature: "fire", - content() { - "step 0"; - var next = target.chooseToRespond({ name: "shan" }); - next.ai = function (card) { - if (get.damageEffect(target, player, target, "fire") >= 0) { - return 0; - } - if (player.hasSkillTag("notricksource")) { - return 0; - } - if (target.hasSkillTag("notrick")) { - return 0; - } - if (target.hasSkillTag("noShan")) { - return -1; - } - return 11 - get.value(card); - }; - next.set("respondTo", [player, card]); - next.autochoose = lib.filter.autoRespondShan; - "step 1"; - if (result.bool == false) { - target.damage("fire"); - } - }, - ai: { - wuxie(target, card, player, viewer) { - if (get.attitude(viewer, target) > 0 && target.countCards("h", "shan")) { - if (!target.countCards("h") || target.hp == 1 || Math.random() < 0.7) { - return 0; - } - } - if (get.attitude(viewer, target) <= 0) { - return 0; - } - }, - order: 7, - tag: { - respond: 1, - respondShan: 1, - damage: 1, - natureDamage: 1, - fireDamage: 1, - multitarget: 1, - multineg: 1, - }, - result: { - target(player, target) { - if (target.hasSkillTag("nofire")) { - return 0; - } - if (player.hasUnknown(2)) { - return 0; - } - var nh = target.countCards("h"); - if (lib.config.mode == "identity") { - if (target.isZhu && nh <= 2 && target.hp <= 1) { - return -100; - } - } - if (nh == 0) { - return -2; - } - if (nh == 1) { - return -1.7; - } - return -1.5; - }, - }, - }, - }, - mianlijinzhen: { - type: "jiguan", - enable: true, - fullskin: true, - filterTarget(card, player, target) { - return target.hp >= player.hp; - }, - content() { - "step 0"; - target.draw(); - "step 1"; - target.loseHp(); - }, - ai: { - order: 2, - value: [5, 1], - useful: [4, 1], - result: { - target: -1.5, - }, - tag: { - // damage:1 - }, - }, - }, - // longxugou:{ - // type:'jiguan', - // enable:true, - // fullskin:true, - // }, - liutouge: { - type: "jiguan", - enable: true, - fullskin: true, - filterTarget: true, - wuxieable: true, - content() { - if (player.getEnemies().includes(target)) { - target.getDebuff(); - } else { - target.getBuff(); - } - }, - ai: { - order: 4, - value: 5, - result: { - player(player, target) { - if (get.attitude(player, target) == 0) { - return 0; - } - return 1; - }, - }, - }, - }, - liufengsan: { - type: "trick", - enable: true, - fullskin: true, - filterTarget: true, - content() { - var list = []; - for (var i = 0; i < 2; i++) { - list.push(game.createCard("shan")); - } - target.gain(list, "gain2"); - }, - ai: { - order: 4.5, - value: [5, 1], - tag: { - gain: 1, - norepeat: 1, - }, - result: { - target(player, target) { - if (target == player) { - if (!target.hasShan("all")) { - return 2; - } - var num = target.needsToDiscard(2); - if (num == 0) { - return 1.5; - } - if (num == 1) { - return 1; - } - return 0.5; - } else { - switch (target.countCards("h")) { - case 0: - return 2; - case 1: - return 1.5; - case 2: - return 1; - default: - return 0.5; - } - } - }, - }, - }, - }, - shihuifen: { - type: "trick", - fullskin: true, - filterTarget: true, - global: "g_shihuifen", - content() { - "step 0"; - if (!_status.currentPhase?.isIn()) { - return; - } - var next = _status.currentPhase.chooseToRespond({ name: "shan" }); - next.set("respondTo", [player, card]); - next.set("prompt2", "否则本回合无法对其他角色使用卡牌"); - "step 1"; - if (!result.bool) { - _status.currentPhase.addTempSkill("shihuifen", "phaseUseAfter"); - } - }, - ai: { - order: 1, - value: [5, 1], - useful: [5, 1], - tag: { - respond: 1, - respondShan: 1, - }, - result: { - target(player, target) { - if (target.countCards("h") >= 3 || target.needsToDiscard()) { - return -1.5; - } - return 0; - }, - }, - }, - }, - }, - skill: { - ziyangdan: { - trigger: { player: "phaseBegin" }, - silent: true, - init(player) { - player.storage.ziyangdan = 3; - }, - onremove: true, - content() { - if (player.hujia > 0) { - player.changeHujia(-1); - } - player.storage.ziyangdan--; - if (player.hujia == 0 || player.storage.ziyangdan == 0) { - player.removeSkill("ziyangdan"); - } - }, - ai: { - threaten: 0.8, - }, - }, - luyugeng: { - mark: "card", - enable: "phaseUse", - usable: 1, - nopop: true, - filterCard: { type: "basic" }, - filter(event, player) { - return player.countCards("h", { type: "basic" }); - }, - intro: { - content(storage, player) { - return "出牌阶段限一次,你可以弃置一张基本牌并发现一张牌,持续三回合(剩余" + player.storage.luyugeng_markcount + "回合)"; - }, - }, - content() { - player.discoverCard(); - }, - group: "luyugeng_count", - subSkill: { - count: { - trigger: { player: "phaseAfter" }, - forced: true, - popup: false, - content() { - player.storage.luyugeng_markcount--; - if (player.storage.luyugeng_markcount == 0) { - delete player.storage.luyugeng; - delete player.storage.luyugeng_markcount; - player.removeSkill("luyugeng"); - } else { - player.updateMarks(); - } - }, - }, - }, - }, - xiajiao: { - mark: "card", - trigger: { player: ["phaseUseBefore", "phaseEnd"] }, - forced: true, - popup: false, - nopop: true, - filter(event, player) { - return !player.hasSkill("xiajiao3"); - }, - intro: { - content(storage, player) { - return "你在摸牌阶段额外摸一张牌,然后弃置一张牌(剩余" + player.storage.xiajiao_markcount + "回合)"; - }, - }, - content() { - player.storage.xiajiao_markcount--; - if (player.storage.xiajiao_markcount == 0) { - delete player.storage.xiajiao; - delete player.storage.xiajiao_markcount; - player.removeSkill("xiajiao"); - } else { - player.updateMarks(); - } - player.addTempSkill("xiajiao3"); - }, - group: "xiajiao_draw", - subSkill: { - draw: { - trigger: { player: "phaseDrawBegin" }, - forced: true, - content() { - trigger.num++; - player.addTempSkill("xiajiao2"); - }, - }, - }, - }, - xiajiao2: { - trigger: { player: "phaseDrawAfter" }, - silent: true, - content() { - player.chooseToDiscard("he", true); - }, - }, - xiajiao3: {}, - mizhilianou: { - mark: "card", - trigger: { player: "phaseAfter" }, - forced: true, - popup: false, - nopop: true, - intro: { - content(storage, player) { - return "你可以将一张红桃牌当作桃使用(剩余" + player.storage.mizhilianou_markcount + "回合)"; - }, - }, - content() { - player.storage.mizhilianou_markcount--; - if (player.storage.mizhilianou_markcount == 0) { - delete player.storage.mizhilianou; - delete player.storage.mizhilianou_markcount; - player.removeSkill("mizhilianou"); - } else { - player.updateMarks(); - } - }, - group: "mizhilianou_use", - subSkill: { - use: { - enable: "chooseToUse", - filterCard: { suit: "heart" }, - position: "he", - viewAs: { name: "tao" }, - viewAsFilter(player) { - return player.countCards("he", { suit: "heart" }) > 0; - }, - prompt: "将一张红桃牌当桃使用", - check(card) { - return 10 - get.value(card); - }, - ai: { - skillTagFilter(player) { - return player.countCards("he", { suit: "heart" }) > 0; - }, - save: true, - respondTao: true, - }, - }, - }, - }, - chunbing: { - mark: "card", - trigger: { player: "phaseAfter" }, - forced: true, - popup: false, - nopop: true, - intro: { - content(storage, player) { - return "你的手牌上限+1(剩余" + player.storage.chunbing_markcount + "回合)"; - }, - }, - mod: { - maxHandcard(player, num) { - return num + 1; - }, - }, - content() { - player.storage.chunbing_markcount--; - if (player.storage.chunbing_markcount == 0) { - delete player.storage.chunbing; - delete player.storage.chunbing_markcount; - player.removeSkill("chunbing"); - } else { - player.updateMarks(); - } - }, - }, - gudonggeng: { - mark: "card", - trigger: { player: "phaseBegin" }, - forced: true, - popup: false, - nopop: true, - intro: { - content(storage, player) { - return "当你下一次受到杀造成的伤害时,令伤害-1(剩余" + player.storage.gudonggeng_markcount + "回合)"; - }, - }, - content() { - player.storage.gudonggeng_markcount--; - if (player.storage.gudonggeng_markcount == 0) { - delete player.storage.gudonggeng; - delete player.storage.gudonggeng_markcount; - player.removeSkill("gudonggeng"); - } else { - player.updateMarks(); - } - }, - group: "gudonggeng_damage", - subSkill: { - damage: { - trigger: { player: "damageBegin" }, - filter(event, player) { - return event.card && event.card.name == "sha" && event.num > 0; - }, - forced: true, - content() { - trigger.num--; - delete player.storage.gudonggeng; - delete player.storage.gudonggeng_markcount; - player.removeSkill("gudonggeng"); - }, - }, - }, - ai: { - effect: { - target(card, player, target) { - if (card.name == "sha" && get.attitude(player, target) < 0) { - return 0.5; - } - }, - }, - }, - }, - qingtuan: { - mark: "card", - trigger: { player: "phaseAfter" }, - forced: true, - popup: false, - nopop: true, - intro: { - content(storage, player) { - return "你在回合内使用首张杀时摸一张牌(剩余" + player.storage.qingtuan_markcount + "回合)"; - }, - }, - content() { - player.storage.qingtuan_markcount--; - if (player.storage.qingtuan_markcount == 0) { - delete player.storage.qingtuan; - delete player.storage.qingtuan_markcount; - player.removeSkill("qingtuan"); - } else { - player.updateMarks(); - } - }, - group: "qingtuan_draw", - subSkill: { - draw: { - trigger: { player: "useCard" }, - filter(event, player) { - return event.card.name == "sha" && _status.currentPhase == player; - }, - usable: 1, - forced: true, - content() { - player.draw(); - }, - }, - }, - }, - liyutang: { - mark: "card", - trigger: { player: "phaseEnd" }, - forced: true, - popup: false, - nopop: true, - intro: { - content(storage, player) { - return "结束阶段,若你的体力值为全场最少或之一,你获得1点护甲(剩余" + player.storage.liyutang_markcount + "回合)"; - }, - }, - content() { - if (player.isMinHp()) { - player.logSkill("liyutang"); - player.changeHujia(); - } - player.storage.liyutang_markcount--; - if (player.storage.liyutang_markcount == 0) { - delete player.storage.liyutang; - delete player.storage.liyutang_markcount; - player.removeSkill("liyutang"); - } else { - player.updateMarks(); - } - }, - }, - yougeng: { - mark: "card", - trigger: { player: "phaseBegin" }, - forced: true, - popup: false, - nopop: true, - intro: { - content(storage, player) { - return "准备阶段,若你的体力值为全场最少或之一,你回复1点体力(剩余" + player.storage.yougeng_markcount + "回合)"; - }, - }, - content() { - if (player.isDamaged() && player.isMinHp()) { - player.logSkill("yougeng"); - player.recover(); - } - player.storage.yougeng_markcount--; - if (player.storage.yougeng_markcount == 0) { - delete player.storage.yougeng; - delete player.storage.yougeng_markcount; - player.removeSkill("yougeng"); - } else { - player.updateMarks(); - } - }, - }, - molicha: { - mark: "card", - trigger: { player: "phaseAfter" }, - forced: true, - popup: false, - nopop: true, - intro: { - content(storage, player) { - return "你不能成为其他角色的黑色牌的目标(剩余" + player.storage.molicha_markcount + "回合)"; - }, - }, - mod: { - targetEnabled(card, player, target) { - if (player != target && get.color(card) == "black") { - return false; - } - }, - }, - content() { - player.storage.molicha_markcount--; - if (player.storage.molicha_markcount == 0) { - delete player.storage.molicha; - delete player.storage.molicha_markcount; - player.removeSkill("molicha"); - player.logSkill("molicha"); - } else { - player.updateMarks(); - } - }, - }, - yuanbaorou: { - mark: "card", - trigger: { player: "phaseAfter" }, - forced: true, - popup: false, - nopop: true, - intro: { - content(storage, player) { - return "你在出牌阶段可以额外使用一张杀(剩余" + player.storage.yuanbaorou_markcount + "回合)"; - }, - }, - mod: { - cardUsable(card, player, num) { - if (card.name == "sha") { - return num + 1; - } - }, - }, - content() { - player.storage.yuanbaorou_markcount--; - if (player.storage.yuanbaorou_markcount == 0) { - delete player.storage.yuanbaorou; - delete player.storage.yuanbaorou_markcount; - player.removeSkill("yuanbaorou"); - } else { - player.updateMarks(); - } - }, - }, - tanhuadong: { - mark: "card", - trigger: { player: "phaseEnd" }, - forced: true, - popup: false, - nopop: true, - intro: { - content(storage, player) { - return "出牌阶段结束时,你摸一张牌(剩余" + player.storage.tanhuadong_markcount + "回合)"; - }, - }, - content() { - player.storage.tanhuadong_markcount--; - if (player.storage.tanhuadong_markcount == 0) { - delete player.storage.tanhuadong; - delete player.storage.tanhuadong_markcount; - player.removeSkill("tanhuadong"); - } else { - player.updateMarks(); - } - }, - group: "tanhuadong_draw", - subSkill: { - draw: { - trigger: { player: "phaseUseEnd" }, - forced: true, - content() { - player.draw(); - }, - }, - }, - }, - mapodoufu: { - mark: "card", - trigger: { player: "phaseJieshuBegin" }, - forced: true, - popup: false, - nopop: true, - forceLoad: true, - intro: { - content(storage, player) { - return "结束阶段,你随机弃置一名随机敌人的一张随机牌(剩余" + player.storage.mapodoufu_markcount + "回合)"; - }, - }, - content() { - var list = player.getEnemies(); - for (var i = 0; i < list.length; i++) { - if (!list[i].countCards("he")) { - list.splice(i--, 1); - } - } - var target = list.randomGet(); - if (target) { - player.logSkill("mapodoufu", target); - target.discard(target.getCards("he").randomGet()); - target.addExpose(0.2); - } - player.storage.mapodoufu_markcount--; - if (player.storage.mapodoufu_markcount == 0) { - delete player.storage.mapodoufu; - delete player.storage.mapodoufu_markcount; - player.removeSkill("mapodoufu"); - } else { - player.updateMarks(); - } - }, - }, - yunvyuanshen_skill: { - mark: "card", - intro: { - content: "下一进入濒死状态时回复1点体力", - }, - trigger: { player: "dying" }, - forced: true, - priority: 6.1, - onremove: true, - filter(event, player) { - return player.hp <= 0; - }, - content() { - player.recover(); - player.removeSkill("yunvyuanshen_skill"); - }, - }, - heilonglinpian: { - mark: true, - marktext: "鳞", - intro: { - content: "防御距离+1", - }, - mod: { - globalTo(from, to, distance) { - return distance + 1; - }, - }, - }, - mutoumianju_skill: { - equipSkill: true, - enable: "chooseToUse", - filterCard: true, - usable: 1, - viewAs: { name: "sha" }, - viewAsFilter(player) { - if (!player.countCards("h")) { - return false; - } - }, - prompt: "将一张手牌当杀使用", - check(card) { - return 5 - get.value(card); - }, - ai: { - respondSha: true, - order() { - return get.order({ name: "sha" }) + 0.1; - }, - skillTagFilter(player, tag, arg) { - if (arg != "use") { - return false; - } - if (!player.countCards("h")) { - return false; - } - }, - }, - }, - gjyuheng_skill: { - equipSkill: true, - enable: "phaseUse", - usable: 1, - filterCard: { suit: "spade" }, - check(card) { - return 8 - get.value(card); - }, - filter(event, player) { - if (!player.countCards("h", { suit: "spade" })) { - return false; - } - var enemies = player.getEnemies(); - for (var i = 0; i < enemies.length; i++) { - if (enemies[i].countCards("h", { suit: "spade" })) { - return true; - } - } - return false; - }, - content() { - var enemies = player.getEnemies(); - var list = []; - for (var i = 0; i < enemies.length; i++) { - var hs = enemies[i].getCards("h", { suit: "spade" }); - if (hs.length) { - list.push([enemies[i], hs]); - } - } - if (list.length) { - var current = list.randomGet(); - player.line(current[0]); - current[0].give(current[1].randomGet(), player, true); - } - "step 1"; - var card = player.getEquip("gjyuheng"); - if (card) { - if (typeof card.storage.gjyuheng != "number") { - card.storage.gjyuheng = 1; - } else { - card.storage.gjyuheng++; - } - if (card.storage.gjyuheng >= 3) { - card.init([card.suit, card.number, "gjyuheng_plus", card.nature]); - player.addTempSkill("gjyuheng_plus_temp"); - } - } - }, - ai: { - order: 9, - result: { - player: 1, - }, - }, - }, - gjyuheng_plus_temp: {}, - gjyuheng_plus_skill: { - equipSkill: true, - enable: "phaseUse", - usable: 1, - filterCard: { color: "black" }, - check(card) { - return 8 - get.value(card); - }, - filter(event, player) { - // if(player.hasSkill('gjyuheng_plus_temp')) return false; - if (!player.countCards("h", { color: "black" })) { - return false; - } - var enemies = player.getEnemies(); - for (var i = 0; i < enemies.length; i++) { - if (enemies[i].countCards("h", { suit: "spade" })) { - return true; - } - } - return false; - }, - content() { - var enemies = player.getEnemies(); - var list = []; - for (var i = 0; i < enemies.length; i++) { - var hs = enemies[i].getCards("h", { suit: "spade" }); - if (hs.length) { - list.push([enemies[i], hs]); - } - } - if (list.length) { - var current = list.randomGet(); - player.line(current[0]); - current[0].give(current[1].randomGet(), player, true); - } - "step 1"; - var card = player.getEquip("gjyuheng_plus"); - if (card) { - if (typeof card.storage.gjyuheng != "number") { - card.storage.gjyuheng = 1; - } else { - card.storage.gjyuheng++; - } - if (card.storage.gjyuheng >= 7) { - card.init([card.suit, card.number, "gjyuheng_pro", card.nature]); - } - } - }, - ai: { - order: 9, - result: { - player: 1, - }, - }, - }, - gjyuheng_pro_skill: { - equipSkill: true, - enable: "phaseUse", - filterCard: { color: "black" }, - check(card) { - return 8 - get.value(card); - }, - filter(event, player) { - if (!player.countCards("h", { color: "black" })) { - return false; - } - var enemies = player.getEnemies(); - for (var i = 0; i < enemies.length; i++) { - if (enemies[i].countCards("h", { suit: "spade" })) { - return true; - } - } - return false; - }, - content() { - var enemies = player.getEnemies(); - var list = []; - for (var i = 0; i < enemies.length; i++) { - var hs = enemies[i].getCards("h", { suit: "spade" }); - if (hs.length) { - list.push([enemies[i], hs]); - } - } - if (list.length) { - var current = list.randomGet(); - player.line(current[0]); - current[0].give(current[1].randomGet(), player, true); - } - "step 1"; - var card = player.getEquip("gjyuheng"); - if (card) { - if (typeof card.storage.gjyuheng != "number") { - card.storage.gjyuheng = 1; - } else { - card.storage.gjyuheng++; - } - if (card.storage.gjyuheng >= 3) { - card.init([card.suit, card.number, "gjyuheng_plus", card.nature]); - player.addTempSkill("gjyuheng_plus_temp"); - } - } - }, - ai: { - order: 9, - result: { - player: 1, - }, - }, - }, - shihuifen: { - mark: true, - intro: { - content: "使用卡牌无法指定其他角色为目标", - }, - mod: { - playerEnabled(card, player, target) { - if (player != target) { - return false; - } - }, - }, - }, - g_shihuifen: { - trigger: { global: "phaseUseBegin" }, - direct: true, - filter(event, player) { - if (event.player.hasSkill("shihuifen")) { - return false; - } - if (event.player == player) { - return false; - } - if (!lib.filter.targetEnabled({ name: "shihuifen" }, player, event.player)) { - return false; - } - return player.hasCard("shihuifen") || player.hasSkillTag("shihuifen"); - }, - content() { - player.chooseToUse( - get.prompt("shihuifen", trigger.player).replace(/发动/, "使用"), - function (card, player) { - if (card.name != "shihuifen") { - return false; - } - return lib.filter.cardEnabled(card, player, "forceEnable"); - }, - trigger.player, - -1 - ).targetRequired = true; - }, - }, - g_jinlianzhu: { - trigger: { global: "damageBefore" }, - direct: true, - filter(event, player) { - if (!lib.filter.targetEnabled({ name: "jinlianzhu" }, player, event.player)) { - return false; - } - return player.hasCard("jinlianzhu"); - }, - content() { - player.chooseToUse( - get.prompt("jinlianzhu", trigger.player).replace(/发动/, "使用"), - function (card, player) { - if (card.name != "jinlianzhu") { - return false; - } - return lib.filter.cardEnabled(card, player, "forceEnable"); - }, - trigger.player, - -1 - ).targetRequired = true; - }, - }, - }, - cardType: { - food: 0.3, - }, - translate: { - jinlianzhu: "金莲珠", - jinlianzhu_info: "对一名即将受到伤害的角色使用,防止此伤害,并令伤害来源摸一张牌。", - shihuifen: "石灰粉", - shihuifen_info: "在一名其他角色的出牌阶段开始时对其使用,目标需打出一张【闪】,否则此阶段使用卡牌无法指定其他角色为目标。", - liufengsan: "流风散", - liufengsan_info: "出牌阶段对一名角色使用,目标获得两张闪。", - liutouge: "六骰格", - liutouge_info: "出牌阶段对一名角色使用,若目标是敌人,对目标施加一个随机的负面效果;否则对目标施加一个随机的正面效果。", - longxugou: "龙须钩", - longxugou_info: "出牌阶段对一名装备区内有牌的其他角色使用,获得其装备区内的一张牌并装备之。", - mianlijinzhen: "棉里针", - mianlijinzhen_info: "出牌阶段对一名体力值不小于你的角色使用,目标摸一张牌然后失去1点体力。", - shenhuofeiya: "神火飞鸦", - shenhuofeiya_info: "出牌阶段对一名其他角色和其相邻角色使用,目标需打出一张【闪】,否则受到1点火属性伤害。", - qiankunbiao: "乾坤镖", - qiankunbiao_info: "随机弃置一名其他角色和其相邻角色的一张牌。", - - bingpotong: "天女散花", - bingpotong_ab: "散花", - bingpotong_info: "出牌阶段对至多3名角色使用,你与每个目标依次同时展示一张手牌,若颜色相同,你弃置展示的手牌,目标失去1点体力并终止结算。", - feibiao: "飞镖", - feibiao_info: "出牌阶段,对一名距离1以外的角色使用,令其弃置一张黑色手牌或失去1点体力。", - - dinvxuanshuang: "帝女玄霜", - dinvxuanshuang_info: "对一名濒死状态的角色使用,目标回复1点体力,然后可以弃置任意张牌并摸等量的牌。", - yunvyuanshen: "玉女元参", - yunvyuanshen_skill: "玉女元参", - yunvyuanshen_info: "出牌阶段对一名角色使用,目标在下一次进入濒死状态时回复1点体力。", - ziyangdan: "紫阳丹", - ziyangdan_info: "出牌阶段对一名角色使用,目标获得3点护甲,此后每个准备阶段失去1点护甲,直到首次失去所有护甲或累计以此法失去3点护甲。", - gjyuheng: "玉衡", - gjyuheng_plus: "玉衡", - gjyuheng_pro: "玉衡", - gjyuheng_skill: "玉衡", - gjyuheng_plus_skill: "玉衡", - gjyuheng_pro_skill: "玉衡", - gjyuheng_info: "出牌阶段限一次,若敌方角色有黑桃手牌,你可以弃置一张黑桃手牌,然后获得一名随机敌方角色的一张随机黑桃手牌(此牌在本局游戏中第三次和第七次发动效果后,分别自动获得一次强化)。", - gjyuheng_plus_info: "由普通玉衡强化得到,将玉衡技能描述中的“弃置一张黑桃手牌”改为“弃置一张黑色手牌”。", - gjyuheng_pro_info: "由普通玉衡二次强化得到,将玉横技能描述中的“弃置一张黑桃手牌”改为“弃置一张黑色手牌”,并去掉使用次数限制。", - gjyuheng_skill_info: "出牌阶段限一次,若敌方角色有黑桃手牌,你可以弃置一张黑桃手牌,然后获得一名随机敌方角色的一张随机黑桃手牌。", - gjyuheng_plus_skill_info: "出牌阶段限一次,若敌方角色有黑桃手牌,你可以弃置一张黑色手牌,然后获得一名随机敌方角色的一张随机黑桃手牌。", - gjyuheng_pro_skill_info: "出牌阶段,若敌方角色有黑桃手牌,你可以弃置一张黑色手牌,然后获得一名随机敌方角色的一张随机黑桃手牌。", - shujinsan: "舒筋散", - shujinsan_info: "出牌阶段对任意角色使用,目标可弃置任意张牌,并摸等量的牌。", - mutoumianju: "木头面具", - mutoumianju_info: "出牌阶段限一次,你可以将一张手牌当作杀使用。", - mutoumianju_skill: "木杀", - mutoumianju_skill_info: "出牌阶段限一次,你可以将一张手牌当作杀使用。", - heilonglinpian: "黑龙鳞片", - heilonglinpian_info: "出牌阶段对自己使用,获得1点护甲,直到下一回合开始,你的防御距离+1。", - shatang: "沙棠", - shatang_info: "出牌阶段对一名角色使用,对目标造成1点火焰伤害,然后目标获得1点护甲。", - - food: "食物", - chunbing: "春饼", - chunbing_info: "你的手牌上限+1,持续五回合。", - gudonggeng: "骨董羹", - gudonggeng_info: "当你下一次受到杀造成的伤害时,令伤害-1,持续三回合。", - yougeng: "酉羹", - yougeng_info: "准备阶段,若你的体力值为全场最少或之一,你回复1点体力,持续两回合。", - liyutang: "鲤鱼汤", - liyutang_info: "结束阶段,若你的体力值为全场最少或之一,你获得1点护甲,持续两回合。", - mizhilianou: "蜜汁藕", - mizhilianou_info: "你可以将一张红桃牌当作桃使用,持续四回合。", - xiajiao: "虾饺", - xiajiao_info: "你在摸牌阶段额外摸一张牌,然后弃置一张牌,持续三回合。", - tanhuadong: "昙花冻", - tanhuadong_info: "出牌阶段结束时,你摸一张牌,持续三回合。", - qingtuan: "青团", - qingtuan_info: "你在回合内使用首张杀时摸一张牌,持续两回合。", - luyugeng: "鲈鱼羹", - luyugeng_info: "出牌阶段限一次,你可以弃置一张基本牌并发现一张牌,持续三回合。", - yuanbaorou: "元宝肉", - yuanbaorou_info: "你在出牌阶段可以额外使用一张杀,持续四回合。", - molicha: "茉莉茶", - molicha_info: "你不能成为其他角色的黑色牌的目标,持续四回合。", - mapodoufu: "麻婆豆腐", - mapodoufu_info: "结束阶段,你弃置一名随机敌人的一张随机牌,持续两回合。", - }, - list: [ - ["spade", 2, "tanhuadong"], - ["club", 1, "molicha"], - ["club", 3, "chunbing"], - ["heart", 12, "yougeng"], - ["heart", 8, "gudonggeng"], - ["heart", 1, "liyutang"], - ["diamond", 4, "mizhilianou"], - ["diamond", 6, "xiajiao"], - ["spade", 3, "qingtuan"], - ["club", 11, "luyugeng"], - ["heart", 4, "mapodoufu"], - ["spade", 8, "yuanbaorou"], - - ["spade", 7, "gjyuheng"], - ["club", 4, "mutoumianju"], - ["spade", 2, "heilonglinpian"], - ["spade", 1, "mianlijinzhen"], - ["heart", 13, "yunvyuanshen"], - - ["club", 8, "feibiao", "poison"], - ["diamond", 9, "feibiao", "poison"], - - ["spade", 3, "bingpotong", "poison"], - ["club", 12, "bingpotong", "poison"], - - ["club", 5, "shihuifen"], - ["club", 1, "shihuifen"], - ["spade", 13, "shihuifen"], - - ["diamond", 6, "shujinsan"], - ["spade", 2, "shujinsan"], - - ["diamond", 6, "ziyangdan"], - ["heart", 1, "ziyangdan"], - - // ['diamond',7,'dinvxuanshuang'], - ["heart", 9, "dinvxuanshuang"], - - ["spade", 9, "qiankunbiao"], - ["club", 13, "qiankunbiao"], - - ["diamond", 9, "shenhuofeiya"], - ["spade", 7, "longxugou"], - - ["heart", 9, "jinlianzhu"], - ["spade", 7, "jinlianzhu"], - - ["heart", 6, "liutouge"], - ["club", 6, "liutouge"], - - ["club", 6, "liufengsan"], - ["club", 3, "liufengsan"], - - ["heart", 13, "shatang", "fire"], - ], - }; -}); diff --git a/card/guozhan.js b/card/guozhan.js index aad3792421..54f3714b34 100644 --- a/card/guozhan.js +++ b/card/guozhan.js @@ -671,7 +671,7 @@ game.import("card", function () { }, }, shuiyanqijunx: { - audio: "shuiyanqijun", + audio: true, fullskin: true, type: "trick", cardnature: "thunder", diff --git a/card/gwent.js b/card/gwent.js deleted file mode 100644 index 89281d9268..0000000000 --- a/card/gwent.js +++ /dev/null @@ -1,2439 +0,0 @@ -import { lib, game, ui, get, ai, _status } from "../noname.js"; -game.import("card", function () { - return { - name: "gwent", - card: { - gw_dieyi: { - fullskin: true, - }, - gw_dieyi_equip1: { - fullskin: true, - vanish: true, - hidden: true, - cardimage: "gw_dieyi", - type: "equip", - subtype: "equip1", - //TODO: 维护所有水乎武将的onLose事件 - onLose() { - lib.skill.gw_dieyi.process(player); - }, - loseDelay: false, - skills: [], - ai: { - equipValue: 0, - }, - }, - gw_dieyi_equip2: { - fullskin: true, - vanish: true, - hidden: true, - cardimage: "gw_dieyi", - type: "equip", - subtype: "equip2", - onLose() { - lib.skill.gw_dieyi.process(player); - }, - loseDelay: false, - skills: [], - ai: { - equipValue: 0, - }, - }, - gw_dieyi_equip3: { - fullskin: true, - vanish: true, - hidden: true, - cardimage: "gw_dieyi", - type: "equip", - subtype: "equip3", - onLose() { - lib.skill.gw_dieyi.process(player); - }, - loseDelay: false, - skills: [], - ai: { - equipValue: 0, - }, - }, - gw_dieyi_equip4: { - fullskin: true, - vanish: true, - hidden: true, - cardimage: "gw_dieyi", - type: "equip", - subtype: "equip4", - onLose() { - lib.skill.gw_dieyi.process(player); - }, - loseDelay: false, - skills: [], - ai: { - equipValue: 0, - }, - }, - gw_dieyi_equip5: { - fullskin: true, - vanish: true, - hidden: true, - cardimage: "gw_dieyi", - type: "equip", - subtype: "equip5", - onLose() { - lib.skill.gw_dieyi.process(player); - }, - loseDelay: false, - skills: [], - ai: { - equipValue: 0, - }, - }, - gw_dieyi_judge: { - fullskin: true, - vanish: true, - hidden: true, - cardimage: "gw_dieyi", - enable: true, - type: "delay", - filterTarget: true, - effect() { - lib.skill.gw_dieyi.process(player); - }, - }, - gw_hudiewu: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable(card, player) { - return game.hasPlayer(function (current) { - return current != player && current.countCards("ej"); - }); - }, - notarget: true, - contentBefore() { - player.$skill("蝴蝶舞", "legend", "metal"); - game.delay(2); - }, - content() { - "step 0"; - event.targets = game - .filterPlayer(function (current) { - return current.countCards("ej"); - }) - .sortBySeat(); - event.targets.remove(player); - "step 1"; - if (event.targets.length) { - var target = event.targets.shift(); - var ej = target.getCards("ej"); - player.line(target); - target.removeEquipTrigger(); - for (var i = 0; i < ej.length; i++) { - game.createCard(ej[i]).discard(); - ej[i].init([ej[i].suit, ej[i].number, "gw_dieyi_" + (get.subtype(ej[i]) || "judge")]); - } - event.redo(); - } - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 6, - useful: [6, 1], - result: { - player(player) { - return game.countPlayer(function (current) { - if (current == player) { - return; - } - return -(current.countCards("e") - current.countCards("j") / 3) * get.sgn(get.attitude(player, current)); - }); - }, - }, - order: 0.7, - }, - }, - gw_yigeniyin: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable: true, - notarget: true, - contentBefore() { - player.$skill("伊格尼印", "legend", "metal"); - game.delay(2); - }, - content() { - "step 0"; - var enemies = player.getEnemies(); - var target = get.max(enemies, "hp", "list").randomGet(); - if (target) { - player.line(target, "fire"); - target.damage("fire"); - game.delay(); - } - "step 1"; - event.targets = game - .filterPlayer(function (current) { - return current.isMaxHp(); - }) - .sortBySeat(); - player.line(event.targets, "fire"); - "step 2"; - if (event.targets.length) { - var target = event.targets.shift(); - player.line(target, "fire"); - target.damage("fire"); - event.redo(); - } - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player(player) { - var enemies = player.getEnemies(); - var players = game.filterPlayer(); - var func = function (current) { - if (current) { - return current.hp; - } - return 0; - }; - var max1 = get.max(enemies, func); - for (var i = 0; i < players.length; i++) { - if (players[i].hp == max1) { - players.splice(i, 1); - break; - } - } - var max2 = get.max(players, func); - if (max1 - 1 > max2) { - return get.damageEffect(get.max(enemies, func, "item"), player, player, "fire"); - } else { - var num; - if (max1 > max2) { - num = get.sgn(get.damageEffect(get.max(enemies, func, "item"), player, player, "fire")); - } else if (max1 == max2) { - num = 0; - } else { - num = 1; - } - return ( - num + - game.countPlayer(function (current) { - if (current.hp >= max2) { - return get.sgn(get.damageEffect(current, player, player, "fire")); - } - }) - ); - } - }, - }, - order: 0.7, - }, - }, - gw_leizhoushu: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable: true, - notarget: true, - contentBefore() { - player.$skill("雷咒术", "legend", "metal"); - game.delay(2); - }, - content() { - if (player.hasSkill("gw_leizhoushu")) { - if (typeof player.storage.gw_leizhoushu != "number") { - player.storage.gw_leizhoushu = 2; - } else { - player.storage.gw_leizhoushu++; - } - player.syncStorage("gw_leizhoushu"); - player.updateMarks(); - } else { - player.addSkill("gw_leizhoushu"); - } - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player(player) { - return ( - 1 + - game.countPlayer(function (current) { - if (current != player && current.isMaxHandcard()) { - return -get.sgn(get.attitude(player, current)); - } - }) - ); - }, - }, - order: 0.5, - }, - }, - gw_aerdeyin: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable(card, player) { - var enemies = player.getEnemies(); - return enemies.length > 0; - }, - notarget: true, - contentBefore() { - player.$skill("阿尔德印", "legend", "metal"); - game.delay(2); - }, - content() { - "step 0"; - var enemies = player.getEnemies(); - event.list = [enemies.randomGet()]; - "step 1"; - if (event.list.length) { - var target = event.list.shift(); - event.target = target; - player.line(target, "green"); - target.damage(); - } else { - delete event.target; - } - "step 2"; - if (event.target) { - if (!event.target.isTurnedOver()) { - event.target.turnOver(); - event.target.addSkill("gw_aerdeyin"); - } - event.goto(1); - } - "step 3"; - game.delay(); - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player(player) { - return game.countPlayer(function (current) { - if (get.distance(player, current, "pure") == 1) { - var att = get.sgn(get.attitude(player, current)); - if (current == player.next) { - return -att * 1.5; - } - return -att; - } - }); - }, - }, - order: 0.5, - }, - }, - gw_ansha: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable(card, player) { - var enemies = player.getEnemies(); - return game.hasPlayer(function (current) { - return current.hp == 1 && enemies.includes(current); - }); - }, - notarget: true, - contentBefore() { - player.$skill("暗杀", "legend", "metal"); - game.delay(2); - }, - content() { - var enemies = player.getEnemies(); - var list = game.filterPlayer(function (current) { - return current.hp == 1 && enemies.includes(current); - }); - if (list.length) { - var target = list.randomGet(); - player.line(target); - target.die(); - } - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player: 1, - }, - order: 0.6, - }, - }, - gw_xinsheng: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable(card, player) { - return game.hasPlayer(function (current) { - return !current.isUnseen(); - }); - }, - notarget: true, - contentBefore() { - player.$skill("新生", "legend", "metal"); - game.delay(2); - }, - content() { - "step 0"; - var target = get.max( - game - .filterPlayer(function (current) { - return !current.isUnseen(); - }, "list") - .randomSort(), - function (current) { - var att = get.attitude(player, current); - if (att < 0 && current.isDamaged() && current.hp <= 3) { - return -10; - } - var rank = get.rank(current, true); - if (current.maxHp >= 3) { - if (current.hp <= 1) { - if (att > 0) { - return att * 3 + 2; - } - return att * 3; - } else if (current.hp == 2) { - if (att > 0) { - att *= 1.5; - } else { - att /= 1.5; - } - } - } - if (rank >= 7) { - if (att > 0) { - return att / 10; - } - return -att / 5; - } else if (rank <= 4) { - if (att < 0) { - return -att / 10; - } - return att; - } - return Math.abs(att / 2); - }, - "item" - ); - event.aitarget = target; - var list = []; - for (var i in lib.character) { - if (!lib.filter.characterDisabled(i) && !lib.filter.characterDisabled2(i)) { - list.push(i); - } - } - var players = game.players.concat(game.dead); - for (var i = 0; i < players.length; i++) { - list.remove(players[i].name); - list.remove(players[i].name1); - list.remove(players[i].name2); - } - var dialog = ui.create.dialog("选择一张武将牌", "hidden"); - dialog.add([list.randomGets(12), "character"]); - player.chooseButton(dialog, true).ai = function (button) { - if (get.attitude(player, event.aitarget) > 0) { - return get.rank(button.link, true); - } else { - return -get.rank(button.link, true); - } - }; - "step 1"; - event.nametarget = result.links[0]; - player.chooseTarget(true, "使用" + get.translation(event.nametarget) + "替换一名角色的武将牌", function (card, player, target) { - return !target.isUnseen() && !target.isMin(); - }).ai = function (target) { - if (target == event.aitarget) { - return 1; - } else { - return 0; - } - }; - "step 2"; - var target = result.targets[0]; - var hp = target.hp; - target.reinit(target.name, event.nametarget); - target.hp = Math.min(hp + 1, target.maxHp); - target.update(); - player.line(target, "green"); - "step 3"; - game.triggerEnter(target); - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player: 1, - }, - order: 0.5, - }, - }, - gw_niuquzhijing: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable(card, player) { - return game.hasPlayer(function (current) { - return current.hp != player.hp; - }); - }, - notarget: true, - contentBefore() { - var list1 = game.filterPlayer(function (current) { - return current.isMaxHp(); - }); - var list2 = game.filterPlayer(function (current) { - return current.isMinHp(); - }); - player.line(list1); - for (var i = 0; i < list1.length; i++) { - list1[i].addTempClass("target"); - } - setTimeout(function () { - var list11 = list1.slice(0); - var list22 = list2.slice(0); - while (list22.length > list11.length) { - list11.push(list1.randomGet()); - } - while (list22.length < list11.length) { - list22.push(list2.randomGet()); - } - list11.sortBySeat(); - list22.sortBySeat(); - while (list11.length) { - list11.shift().line(list22.shift(), "green"); - } - }, 500); - player.$skill("纽曲之镜", "legend", "metal"); - game.delay(2); - }, - content() { - var max = null, - min = null; - for (var i = 0; i < game.players.length; i++) { - if (game.players[i].isMaxHp()) { - max = game.players[i].hp; - break; - } - } - for (var i = 0; i < game.players.length; i++) { - if (game.players[i].isMinHp()) { - min = game.players[i].hp; - break; - } - } - var targets = game.filterPlayer(); - if (max != min && max != null && min != null) { - for (var i = 0; i < targets.length; i++) { - if (targets[i].hp == max) { - targets[i].hp--; - targets[i].maxHp--; - targets[i].$damagepop(-1); - } else if (targets[i].hp == min) { - targets[i].hp++; - targets[i].maxHp++; - targets[i].$damagepop(1, "wood"); - } - targets[i].update(); - } - } - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player(player, target) { - return game.countPlayer(function (current) { - if (current.isMaxHp()) { - return -get.sgn(get.attitude(player, current)); - } - if (current.isMinHp()) { - return get.sgn(get.attitude(player, current)); - } - }); - }, - }, - order: 3.5, - }, - }, - gw_zhongmozhizhan: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable: true, - notarget: true, - contentBefore() { - player.line(game.filterPlayer()); - player.$skill("终末之战", "legend", "metal"); - game.delay(2); - }, - content() { - "step 0"; - event.num = 0; - event.targets = game.filterPlayer().sortBySeat(); - "step 1"; - if (event.num < targets.length) { - ui.clear(); - var target = targets[event.num]; - var cards = target.getCards("hej"); - target.lose(cards)._triggered = null; - target.$throw(cards); - event.num++; - event.redo(); - game.delay(0.7); - } - "step 2"; - ui.clear(); - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player(player, target) { - if (player.hasUnknown()) { - return 0; - } - return -game.countPlayer(function (current) { - return current.countCards("he") * get.sgn(get.attitude(player, current)); - }); - }, - }, - order: 0.5, - }, - }, - gw_ganhan: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable: true, - notarget: true, - contentBefore() { - player.line(game.filterPlayer()); - player.$skill("干旱", "legend", "metal"); - game.delay(2); - }, - content() { - "step 0"; - event.num = 0; - event.targets = game.filterPlayer().sortBySeat(); - "step 1"; - if (event.num < targets.length) { - ui.clear(); - var target = targets[event.num]; - target.loseMaxHp(true); - event.num++; - event.redo(); - } - "step 2"; - ui.clear(); - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 7, - useful: [5, 1], - result: { - player(player, target) { - if (player.hasUnknown()) { - return 0; - } - return game.countPlayer(function (current) { - var att = -get.sgn(get.attitude(player, current)); - if (current.isHealthy()) { - switch (current.hp) { - case 1: - return att * 3; - case 2: - return att * 2; - case 3: - return att * 1.5; - case 4: - return att; - default: - return att * 0.5; - } - } else if (current.maxHp - current.hp == 1) { - switch (current.hp) { - case 1: - return att * 0.5; - case 2: - return att * 0.3; - case 3: - return att * 0.2; - default: - return att * 0.15; - } - } else { - return att * 0.1; - } - }); - }, - }, - order: 0.5, - }, - }, - gw_huangjiashenpan: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable: true, - notarget: true, - contentBefore() { - player.$skill("皇家审判", "legend", "metal"); - game.delay(2); - }, - content() { - "step 0"; - var list = get.libCard(function (info) { - return info.subtype == "spell_gold"; - }); - list.remove("gw_huangjiashenpan"); - if (list.length) { - player.chooseVCardButton(list, true, "notype").ai = function () { - return Math.random(); - }; - } - "step 1"; - if (result.bool) { - player.gain(game.createCard(result.links[0][2]), "draw"); - } - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player: 1, - }, - order: 0.1, - }, - }, - gw_tunshi: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable(event, player) { - if (player.maxHp == 1) { - return false; - } - var list = player.getEnemies(); - for (var i = 0; i < list.length; i++) { - if (list[i].isMin()) { - continue; - } - if (list[i].getStockSkills().length) { - return true; - } - } - }, - notarget: true, - contentBefore() { - player.$skill("吞噬", "legend", "metal"); - game.delay(2); - }, - content() { - var list = player.getEnemies(); - for (var i = 0; i < list.length; i++) { - if (list[i].isMin() || !list[i].getStockSkills().length) { - list.splice(i--, 1); - } - } - if (list.length) { - var target = list.randomGet(); - target.addExpose(0.1); - player.line(target); - var skill = target.getStockSkills().randomGet(); - target.popup(skill); - player.addSkill(skill); - target.removeSkill(skill); - player.loseHp(); - player.loseMaxHp(true); - target.gainMaxHp(true); - target.recover(); - } - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player(player) { - if (player.hp <= 2) { - return 0; - } - return 1; - }, - }, - order: 0.4, - }, - }, - gw_chongci: { - fullborder: "gold", - type: "spell", - subtype: "spell_gold", - vanish: true, - enable: true, - notarget: true, - contentBefore() { - player.$skill("冲刺", "legend", "metal"); - game.delay(2); - }, - content() { - "step 0"; - event.hs = player.getCards("h"); - event.es = player.getCards("e"); - player.discard(event.hs.concat(event.es)); - "step 1"; - var hs2 = []; - for (var i = 0; i < event.hs.length; i++) { - var type = get.type(event.hs[i], "trick"); - var cardname = event.hs[i].name; - var list = game.findCards(function (name) { - if (cardname == name) { - return; - } - if (get.type({ name: name }, "trick") == type) { - return true; - } - }); - if (!list.length) { - list = [cardname]; - } - hs2.push(game.createCard(list.randomGet())); - } - var list = get.libCard(function (info) { - return info.type == "spell" && info.subtype != "spell_gold"; - }); - if (list.length) { - hs2.push(game.createCard(list.randomGet())); - } - if (hs2.length) { - player.gain(hs2, "draw"); - } - "step 2"; - var es2 = []; - for (var i = 0; i < event.es.length; i++) { - var subtype = get.subtype(event.es[i]); - var cardname = event.es[i].name; - var list = game.findCards(function (name) { - if (cardname == name) { - return; - } - if (get.subtype({ name: name }) == subtype) { - return true; - } - }); - if (!list.length) { - list = [cardname]; - } - es2.push(game.createCard(list.randomGet())); - } - if (es2.length) { - game.delay(); - player.$draw(es2); - for (var i = 0; i < es2.length; i++) { - player.equip(es2[i]); - } - } - "step 3"; - player.tempHide(); - }, - contentAfter() { - var evt = _status.event.getParent("phaseUse"); - if (evt && evt.name == "phaseUse") { - evt.skipped = true; - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player: 1, - }, - order: 0.2, - }, - }, - gw_youer: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - vanish: true, - enable: true, - filterTarget(card, player, target) { - return target != player && target.countCards("h") > 0; - }, - content() { - "step 0"; - var cards = target.getCards("h"); - target.lose(cards, ui.special); - target.storage.gw_youer = cards; - target.addSkill("gw_youer"); - "step 1"; - player.draw(); - }, - ai: { - basic: { - order: 10, - value: 7, - useful: [3, 1], - }, - result: { - target(player, target) { - if (target.hasSkillTag("noh")) { - return 3; - } - var num = -Math.sqrt(target.countCards("h")); - if (player.hasSha() && player.canUse("sha", target)) { - num -= 2; - } - return num; - }, - }, - }, - }, - gw_tongdi: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - vanish: true, - enable: true, - filterTarget(card, player, target) { - return target != player && target.countCards("h"); - }, - content() { - "step 0"; - player.gainPlayerCard(target, "h", true, "visible").set("ai", function (button) { - return get.value(button.link); - }); - "step 1"; - target.gain(game.createCard("sha"), "gain2"); - }, - ai: { - basic: { - order: 8, - value: 9.5, - useful: [5, 1], - }, - result: { - target(player, target) { - if (target.getEquip(4)) { - return -2; - } - return -1; - }, - }, - }, - }, - gw_fuyuan: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - vanish: true, - savable: true, - selectTarget: -1, - content() { - target.recover(); - target.draw(); - }, - ai: { - basic: { - order: 6, - useful: 10, - value: [8, 6.5, 5, 4], - }, - result: { - target: 2, - }, - tag: { - recover: 1, - save: 1, - }, - }, - }, - gw_zhuoshao: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - vanish: true, - enable: true, - filterTarget(card, player, target) { - return target.isMaxHp(); - }, - cardnature: "fire", - selectTarget: [1, Infinity], - content() { - target.damage("fire"); - }, - ai: { - basic: { - order: 8.5, - value: 7.5, - useful: [4, 1], - }, - result: { - target: -1, - }, - tag: { - damage: 1, - fireDamage: 1, - natureDamage: 1, - }, - }, - }, - gw_butianshu: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - vanish: true, - enable: true, - filterTarget: true, - async content(event, trigger, player) { - var list = []; - for (var i in lib.card) { - if (!lib.card[i].content) { - continue; - } - if (lib.card[i].mode && lib.card[i].mode.includes(lib.config.mode) == false) { - continue; - } - if (lib.card[i].vanish) { - continue; - } - if (lib.card[i].type == "delay") { - list.push([event.card.suit, event.card.number, i]); - } - } - if (list.length) { - var dialog = ui.create.dialog("卜天术", [list, "vcard"]); - var bing = event.target.countCards("h") <= 1; - const { result } = await player - .chooseButton(dialog, true, function (button) { - if (get.effect(event.target, { name: button.link[2] }, player, player) > 0) { - if (button.link[2] == "bingliang") { - if (bing) { - return 2; - } - return 0.7; - } - if (button.link[2] == "lebu") { - return 1; - } - if (button.link[2] == "guiyoujie") { - return 0.5; - } - if (button.link[2] == "caomu") { - return 0.3; - } - return 0.2; - } - return 0; - }) - .set("filterButton", function (button) { - return !event.target.hasJudge(button.link[2]); - }); - if (result.links && result.links[0]) { - var card = game.createCard(result.links[0][2]); - event.judgecard = card; - event.target.$draw(card); - event.target.addJudge(event.judgecard); - } - } - }, - ai: { - value: 8, - useful: [5, 1], - result: { - player(player, target) { - var eff = 0; - for (var i in lib.card) { - if (lib.card[i].type == "delay") { - var current = get.effect(target, { name: i }, player, player); - if (current > eff) { - eff = current; - } - } - } - return eff; - }, - }, - order: 6, - }, - }, - gw_shizizhaohuan: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - vanish: true, - enable: true, - filterTarget(card, player, target) { - return target == player; - }, - selectTarget: -1, - // contentBefore:function(){ - // player.$skill('十字召唤','legend','water'); - // game.delay(2); - // }, - content() { - var list = []; - list.push(get.cardPile2("juedou")); - list.push(get.cardPile2("huogong")); - list.push(get.cardPile2("nanman")); - list.push(get.cardPile2("huoshaolianying")); - for (var i = 0; i < list.length; i++) { - if (!list[i]) { - list.splice(i--, 1); - } - } - list = [list.randomGet()]; - var sha = get.cardPile2("sha"); - if (sha) { - if (list.length) { - list.push(sha); - } else { - sha.remove(); - list.push(sha); - var sha2 = get.cardPile2("sha"); - if (sha2) { - list.push(sha2); - } - } - } - if (list.length) { - target.gain(list, "gain2", "log"); - } - }, - ai: { - value: 8, - useful: [6, 1], - result: { - player: 1, - }, - order: 6, - }, - }, - gw_zuihouyuanwang: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - vanish: true, - enable: true, - filterTarget(card, player, target) { - return target == player; - }, - selectTarget: -1, - // contentBefore:function(){ - // player.$skill('最后愿望','legend','water'); - // game.delay(2); - // }, - content() { - "step 0"; - event.num = game.countPlayer(); - player.draw(event.num); - "step 1"; - player.chooseToDiscard(true, event.num, "he"); - }, - ai: { - value: 6, - useful: [4, 1], - result: { - player(player) { - var num = player.countCards("he"); - if (num <= 1) { - return 0; - } - if (num <= 3 && !player.needsToDiscard()) { - return 0; - } - return 1; - }, - }, - order: 7, - }, - }, - gw_zirankuizeng: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - vanish: true, - enable: true, - notarget: true, - async content(event, trigger, player) { - var list = []; - for (var i in lib.card) { - if (lib.card[i].subtype == "spell_bronze") { - list.push([event.card.suit, event.card.number, i]); - } //QQQ - } - var dialog = ui.create.dialog("自然馈赠", [list, "vcard"]); - var aozu = game.hasPlayer(function (current) { - return player.canUse("gw_aozuzhilei", current, true, true) && current.hp <= 3 && get.effect(current, { name: "gw_aozuzhilei" }, player, player) > 0; - }); - var aozu2 = game.hasPlayer(function (current) { - return player.canUse("gw_aozuzhilei", current, true, true) && current.hp <= 2 && get.effect(current, { name: "gw_aozuzhilei" }, player, player) > 0; - }); - var aozu3 = game.hasPlayer(function (current) { - return player.canUse("gw_aozuzhilei", current, true, true) && get.effect(current, { name: "gw_aozuzhilei" }, player, player) > 0; - }); - var baoxue = game.hasPlayer(function (current) { - return player.canUse("gw_baoxueyaoshui", current, true, true) && get.attitude(player, current) < 0 && [2, 3].includes(current.countCards("h")) && !current.hasSkillTag("noh"); - }); - var baoxue2 = game.hasPlayer(function (current) { - return player.canUse("gw_baoxueyaoshui", current, true, true) && get.attitude(player, current) < 0 && [2].includes(current.countCards("h")) && !current.hasSkillTag("noh"); - }); - var baoxue3 = game.hasPlayer(function (current) { - return player.canUse("gw_baoxueyaoshui", current, true, true) && get.attitude(player, current) < 0 && current.countCards("h") >= 2 && !current.hasSkillTag("noh"); - }); - var nongwu = game.hasPlayer(function (current) { - return get.attitude(player, current) < 0 && (!current.getNext() || get.attitude(player, current.getNext()) < 0) && (!current.getPrevious() || get.attitude(player, current.getPrevious()) < 0); - }); - var nongwu2 = game.hasPlayer(function (current) { - return get.attitude(player, current) < 0 && (!current.getNext() || get.attitude(player, current.getNext()) < 0) && (!current.getPrevious() || get.attitude(player, current.getPrevious()) < 0); - }); - var yanzi = game.hasPlayer(function (current) { - return get.attitude(player, current) > 0 && current.isMinHandcard(); - }); - const { - result: { links }, - } = await player - .chooseButton(dialog, true, function (button) { - var player = _status.event.player; //QQQ - var name = button.link[2]; - switch (name) { - case "gw_ciguhanshuang": - if (nongwu2) { - return 3; - } - if (nongwu) { - return 1; - } - return 0; - case "gw_baoxueyaoshui": - if (baoxue2) { - return 2; - } - if (baoxue) { - return 1.5; - } - if (baoxue3) { - return 0.5; - } - return 0; - case "gw_aozuzhilei": - if (aozu2) { - return 2.5; - } - if (aozu) { - return 1.2; - } - if (aozu3) { - return 0.2; - } - return 0; - case "gw_yanziyaoshui": - if (yanzi) { - return 2; - } - return 0.6; - } - if ( - game.hasPlayer(function (current) { - return player.canUse(name, current, true, true) && get.effect(current, { name: name }, player, player) > 0; - }) - ) { - return Math.random(); - } - return 0; - }) - .set("filterButton", function (button) { - var name = button.link[2]; - if (!lib.card[name].notarget) { - return game.hasPlayer(function (current) { - return player.canUse(name, current, true, true); - }); - } - return true; - }); - if (links && links[0]) { - player.chooseUseTarget(true, game.createCard(links[0][2], event.card.suit, event.card.number)); - } - }, - ai: { - value: 7, - useful: [4, 1], - result: { - player(player) { - return 1; - }, - }, - order: 7, - }, - }, - gw_nuhaifengbao: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("gw_nuhaifengbao"); - }, - content() { - target.addSkill("gw_nuhaifengbao"); - }, - ai: { - value: [7, 1], - useful: [4, 1], - result: { - target(player, target) { - return -2 / Math.sqrt(1 + target.hp); - }, - }, - order: 1.2, - }, - }, - gw_baishuang: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("gw_ciguhanshuang"); - }, - selectTarget: [1, 3], - content() { - target.addSkill("gw_ciguhanshuang"); - }, - ai: { - value: [7.5, 1], - useful: [5, 1], - result: { - target: -1, - }, - order: 1.2, - }, - }, - gw_baobaoshu: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("gw_baobaoshu"); - }, - selectTarget: [1, 2], - content() { - target.addTempSkill("gw_baobaoshu", { player: "phaseAfter" }); - }, - ai: { - value: [7.5, 1], - useful: [5, 1], - result: { - target(player, target) { - return -Math.sqrt(target.countCards("h")) - 0.5; - }, - }, - order: 1.2, - }, - }, - gw_guaiwuchaoxue: { - fullborder: "silver", - type: "spell", - subtype: "spell_silver", - enable: true, - usable: 1, - updateUsable: "phaseUse", - forceUsable: true, - filterTarget(card, player, target) { - return target == player; - }, - selectTarget: -1, - content() { - var list = get.gainableSkills(function (info, skill) { - return info.ai && info.ai.maixie_hp && !player.hasSkill(skill); - }); - list.remove("guixin"); - if (list.length) { - var skill = list.randomGet(); - player.popup(skill); - player.addTempSkill(skill, { player: "phaseBegin" }); - var enemies = player.getEnemies(); - if (enemies.length) { - var source = enemies.randomGet(); - source.line(player); - source.addExpose(0.1); - player.damage(source); - player.recover(); - } - } - }, - ai: { - value: [8, 1], - useful: [3, 1], - result: { - target(player, target) { - if (target.hp <= 1 || target.hujia) { - return 0; - } - return 1; - }, - }, - order: 1, - }, - }, - gw_qinpendayu: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("gw_qinpendayu"); - }, - changeTarget(player, targets) { - game.filterPlayer(function (current) { - return get.distance(targets[0], current, "pure") == 1; - }, targets); - }, - content() { - target.addSkill("gw_qinpendayu"); - }, - ai: { - value: [5, 1], - useful: [3, 1], - result: { - target(player, current) { - if (current.hasSkill("gw_qinpendayu")) { - return 0; - } - return Math.max(-1, -0.1 - 0.3 * current.needsToDiscard(2)); - }, - }, - order: 1.2, - }, - }, - gw_birinongwu: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("gw_birinongwu"); - }, - changeTarget(player, targets) { - game.filterPlayer(function (current) { - return get.distance(targets[0], current, "pure") == 1; - }, targets); - }, - content() { - target.addSkill("gw_birinongwu"); - }, - ai: { - value: [5, 1], - useful: [3, 1], - result: { - player(player, current) { - if (current.hasSkill("gw_birinongwu")) { - return 0; - } - return -1; - }, - }, - order: 1.2, - }, - }, - gw_ciguhanshuang: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("gw_ciguhanshuang"); - }, - changeTarget(player, targets) { - game.filterPlayer(function (current) { - return get.distance(targets[0], current, "pure") == 1; - }, targets); - }, - content() { - target.addSkill("gw_ciguhanshuang"); - }, - ai: { - value: [5, 1], - useful: [3, 1], - result: { - target(player, target) { - if (target.hasSkill("gw_ciguhanshuang")) { - return 0; - } - return -1; - }, - }, - order: 1.2, - }, - }, - gw_baoxueyaoshui: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - filterTarget: true, - content() { - "step 0"; - target.chooseToDiscard("h", 2, true).delay = false; - "step 1"; - target.draw(); - }, - ai: { - value: 6, - useful: [3, 1], - result: { - target(player, target) { - if (target.hasSkillTag("noh")) { - return 0.1; - } - switch (target.countCards("h")) { - case 0: - return 0.5; - case 1: - return 0; - case 2: - return -1.5; - default: - return -1; - } - }, - }, - order: 8, - tag: { - loseCard: 1, - discard: 1, - }, - }, - }, - gw_zhihuanjun: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - filterTarget(card, player, target) { - return target.isDamaged(); - }, - content() { - "step 0"; - target.loseMaxHp(true); - "step 1"; - if (target.isDamaged() && target.countCards("h") < target.maxHp) { - event.goto(0); - } - }, - ai: { - value: [4, 1], - useful: [3, 1], - result: { - target(player, target) { - if (target.maxHp - target.hp == 1) { - return -1 / target.maxHp; - } else { - return -1 / target.maxHp / 3; - } - }, - }, - order: 2, - }, - }, - gw_zumoshoukao: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - filterTarget(card, player, target) { - return target.hujia || !target.hasSkill("fengyin"); - }, - content() { - target.addTempSkill("fengyin", { player: "phaseAfter" }); - // if(target.hujia){ - // target.changeHujia(-1); - // } - }, - ai: { - value: [4.5, 1], - useful: [4, 1], - result: { - target(player, target) { - var threaten = get.threaten(target, player, true); - if (target.hasSkill("fengyin")) { - return 0; - } - if (target.hasSkillTag("maixie_hp")) { - threaten *= 1.5; - } - return -threaten; - }, - }, - order: 9.5, - }, - }, - gw_aozuzhilei: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - cardnature: "thunder", - filterTarget(card, player, target) { - return target.hp >= player.hp; - }, - content() { - "step 0"; - target.damage("thunder"); - "step 1"; - if (target.isIn()) { - target.draw(); - } - }, - ai: { - basic: { - order: 1.8, - value: [5, 1], - useful: [4, 1], - }, - result: { - target: -1, - }, - tag: { - damage: 1, - thunderDamage: 1, - natureDamage: 1, - }, - }, - }, - gw_poxiao: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - notarget: true, - content() { - "step 0"; - var choice = 1; - if ( - game.countPlayer(function (current) { - if (current.countCards("j") || current.hasSkillTag("weather")) { - if (get.attitude(player, current) > 0) { - choice = 0; - } - return true; - } - }) - ) { - player - .chooseControl(function () { - return choice; - }) - .set("choiceList", ["解除任意名角色的天气效果并移除其判定区内的牌", "随机获得一张铜卡法术(破晓除外)并展示之"]); - } else { - event.directfalse = true; - } - "step 1"; - if (!event.directfalse && result.index == 0) { - player.chooseTarget(true, [1, Infinity], "解除任意名角色的天气效果并移除其判定区内的牌", function (card, player, target) { - return target.countCards("j") || target.hasSkillTag("weather"); - }).ai = function (target) { - return get.attitude(player, target); - }; - } else { - var list = get.libCard(function (info, name) { - return name != "gw_poxiao" && info.subtype == "spell_bronze"; - }); - if (list.length) { - player.gain(game.createCard(list.randomGet()), "gain2"); - } else { - player.draw(); - } - event.finish(); - } - "step 2"; - event.list = result.targets.slice(0).sortBySeat(); - "step 3"; - if (event.list.length) { - var target = event.list.shift(); - player.line(target, "green"); - var cards = target.getCards("j"); - if (cards.length) { - target.discard(cards); - } - if (target.hasSkillTag("weather")) { - var skills = target.getSkills(); - for (var i = 0; i < skills.length; i++) { - var info = get.info(skills[i]); - if (info && info.ai && info.ai.weather) { - target.removeSkill(skills[i]); - game.log(target, "解除了", "【" + get.translation(skills[i]) + "】", "的效果"); - } - } - } - event.redo(); - } - }, - ai: { - order: 4, - value: [5, 1], - useful: [4, 1], - result: { - player: 1, - }, - }, - }, - gw_kunenfayin: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - filterTarget(card, player, target) { - return !target.hasSkill("gw_kunenfayin"); - }, - content() { - target.addSkill("gw_kunenfayin"); - }, - ai: { - basic: { - order: 2, - value: [5, 1], - useful: [4, 1], - }, - result: { - target(player, target) { - if (target == player) { - return get.threaten(target, player) / 1.5; - } - return get.threaten(target, player); - }, - }, - }, - }, - gw_yanziyaoshui: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - filterTarget: true, - content() { - if (target.isMinHandcard()) { - target.draw(2); - } else { - target.draw(); - } - }, - ai: { - basic: { - order: 6, - value: [6, 1], - useful: [4, 1], - }, - result: { - target(player, target) { - if (target.isMinHandcard()) { - return 2; - } - return 1; - }, - }, - }, - }, - gw_wenyi: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable: true, - filterTarget(card, player, target) { - return target.isMinHp(); - }, - selectTarget: -1, - content() { - if (target.countCards("h")) { - target.randomDiscard("h"); - } else { - target.loseHp(); - } - }, - ai: { - basic: { - order: 6, - value: [6, 1], - useful: [4, 1], - }, - result: { - target(player, target) { - if (target.countCards("h")) { - return -1; - } - return -2; - }, - }, - tag: { - multitarget: 1, - multineg: 1, - }, - }, - }, - gw_shanbengshu: { - fullborder: "bronze", - type: "spell", - subtype: "spell_bronze", - enable(event, player) { - var list = player.getEnemies(); - for (var i = 0; i < list.length; i++) { - if (list[i].countCards("e")) { - return true; - } - } - return false; - }, - filterTarget(card, player, target) { - return target == player; - }, - selectTarget: -1, - content() { - var list = target.getEnemies(); - var equips = []; - for (var i = 0; i < list.length; i++) { - equips.addArray(list[i].getCards("e")); - } - equips = equips.randomGets(2); - if (equips.length == 2) { - var target1 = get.owner(equips[0]); - var target2 = get.owner(equips[1]); - if (target1 == target2) { - target1.discard(equips); - player.line(target1); - } else { - target1.discard(equips[0]).delay = false; - target2.discard(equips[1]); - player.line(target1); - player.line(target2); - } - } else if (equips.length) { - var target1 = get.owner(equips[0]); - target1.discard(equips[0]); - player.line(target1); - } - }, - ai: { - basic: { - order: 9, - value: [6, 1], - useful: [4, 1], - }, - result: { - target: 1, - }, - tag: { - multitarget: 1, - multineg: 1, - }, - }, - }, - }, - skill: { - gw_aerdeyin: { - trigger: { global: "roundStart" }, - silent: true, - mark: true, - intro: { - content: "新的一轮开始时,若武将牌正面朝上,则在当前回合结束后进行一个额外回合,否则将武将牌翻回正面", - }, - content() { - if (player.isTurnedOver()) { - player.turnOver(); - player.removeSkill("gw_aerdeyin"); - player.logSkill("gw_aerdeyin"); - } else { - player.insertPhase(); - } - }, - group: "gw_aerdeyin_phase", - subSkill: { - phase: { - trigger: { player: "phaseBefore" }, - silent: true, - filter(event, player) { - return event.skill == "gw_aerdeyin"; - }, - content() { - player.removeSkill("gw_aerdeyin"); - player.logSkill("gw_aerdeyin"); - }, - }, - }, - }, - gw_kunenfayin: { - mark: true, - nopop: true, - intro: { - content: "防止所有非属性伤害(剩余个#角色的回合)", - }, - init(player) { - player.storage.gw_kunenfayin = Math.min(5, game.countPlayer()); - }, - trigger: { player: "damageBefore" }, - filter(event) { - return !event.nature; - }, - forced: true, - content() { - trigger.cancel(); - }, - ai: { - nodamage: true, - effect: { - target(card, player, target, current) { - if (get.tag(card, "damage") && !get.tag(card, "natureDamage")) { - return "zeroplayertarget"; - } - }, - }, - }, - subSkill: { - count: { - trigger: { global: "phaseEnd" }, - silent: true, - content() { - player.storage.gw_kunenfayin--; - if (player.storage.gw_kunenfayin > 0) { - player.updateMarks(); - } else { - player.removeSkill("gw_kunenfayin"); - } - }, - }, - }, - group: "gw_kunenfayin_count", - onremove: true, - }, - gw_baobaoshu: { - mark: true, - nopop: true, - intro: { - content: "每使用一张基本牌或锦囊牌,需弃置一张牌", - }, - trigger: { player: "useCard" }, - forced: true, - filter(event, player) { - if (player.countCards("he") == 0) { - return false; - } - var type = get.type(event.card, "trick"); - return type == "basic" || type == "trick"; - }, - content() { - if (!event.isMine()) { - game.delay(0.5); - } - player.chooseToDiscard(true, "he"); - }, - ai: { - weather: true, - effect: { - player_use(card, player) { - return [ - 1, - player.needsToDiscard(0, (i, p) => { - if (p.canIgnoreHandcard(i)) { - return false; - } - if (i === card || (card.cards && card.cards.includes(i))) { - return false; - } - return true; - }) - ? -0.4 - : -1, - ]; - }, - }, - }, - }, - gw_nuhaifengbao: { - mark: true, - intro: { - content: "结束阶段随机弃置一张牌(剩余#回合)", - }, - init(player) { - player.storage.gw_nuhaifengbao = 2; - }, - trigger: { player: "phaseEnd" }, - forced: true, - nopop: true, - content() { - player.randomDiscard(); - player.storage.gw_nuhaifengbao--; - if (player.storage.gw_nuhaifengbao > 0) { - player.updateMarks(); - } else { - player.removeSkill("gw_nuhaifengbao"); - } - }, - onremove: true, - ai: { - neg: true, - weather: true, - }, - }, - gw_youer: { - trigger: { global: "phaseEnd", player: "dieBegin" }, - forced: true, - audio: false, - mark: true, - intro: { - content: "cards", - }, - content() { - if (player.storage.gw_youer) { - if (trigger.name == "phase") { - player.gain(player.storage.gw_youer); - } else { - player.$throw(player.storage.gw_youer, 1000); - for (var i = 0; i < player.storage.gw_youer.length; i++) { - player.storage.gw_youer[i].discard(); - } - game.log(player, "弃置了", player.storage.gw_youer); - } - } - delete player.storage.gw_youer; - player.removeSkill("gw_youer"); - }, - }, - gw_qinpendayu: { - mark: true, - nopop: true, - intro: { - content: "手牌上限-1直到下一个弃牌阶段结束", - }, - mod: { - maxHandcard(player, num) { - return num - 1; - }, - }, - ai: { - weather: true, - }, - group: "gw_qinpendayu_clear", - subSkill: { - clear: { - trigger: { player: "phaseDiscardAfter" }, - silent: true, - content() { - player.removeSkill("gw_qinpendayu"); - }, - }, - }, - }, - gw_birinongwu: { - mark: true, - nopop: true, - intro: { - content: "不能使用杀直到下一个出牌阶段结束", - }, - mod: { - cardEnabled(card) { - if (card.name == "sha") { - return false; - } - }, - }, - ai: { - weather: true, - }, - group: "gw_birinongwu_clear", - subSkill: { - clear: { - trigger: { player: "phaseUseAfter" }, - silent: true, - content() { - player.removeSkill("gw_birinongwu"); - }, - }, - }, - }, - gw_ciguhanshuang: { - trigger: { player: "phaseDrawBegin" }, - forced: true, - mark: true, - nopop: true, - intro: { - content: "下个摸牌阶段摸牌数-1", - }, - filter(event) { - return event.num > 0; - }, - content() { - trigger.num--; - player.removeSkill("gw_ciguhanshuang"); - }, - ai: { - weather: true, - }, - }, - gw_dieyi: { - init(player) { - player.storage.gw_dieyi = 1; - }, - onremove: true, - trigger: { global: "phaseEnd" }, - forced: true, - mark: true, - nopop: true, - process(player) { - if (player.hasSkill("gw_dieyi")) { - player.storage.gw_dieyi++; - } else { - player.addSkill("gw_dieyi"); - } - player.syncStorage("gw_dieyi"); - player.updateMarks(); - }, - intro: { - content: "在当前回合的结束阶段,你随机弃置#张牌", - }, - content() { - player.randomDiscard(player.storage.gw_dieyi); - player.removeSkill("gw_dieyi"); - }, - }, - gw_leizhoushu: { - mark: true, - intro: { - content(storage, player) { - if (storage >= 2) { - return "锁定技,准备阶段,你令手牌数为全场最多的所有其他角色各随机弃置一张手牌,若目标不包含敌方角色,将一名随机敌方角色追加为额外目标(重复" + storage + "次)"; - } else { - return "锁定技,准备阶段,你令手牌数为全场最多的所有其他角色各随机弃置一张手牌,若目标不包含敌方角色,将一名随机敌方角色追加为额外目标"; - } - }, - }, - nopop: true, - trigger: { player: "phaseBegin" }, - forced: true, - filter(event, player) { - var list = game.filterPlayer(); - for (var i = 0; i < list.length; i++) { - if (list[i] != player && list[i].isMaxHandcard()) { - return true; - } - } - return false; - }, - content() { - "step 0"; - if (typeof player.storage.gw_leizhoushu == "number") { - event.num = player.storage.gw_leizhoushu; - } else { - event.num = 1; - } - "step 1"; - if (event.num) { - var max = 0; - var maxp = null; - var list = game - .filterPlayer(function (current) { - return current.isMaxHandcard(); - }) - .sortBySeat(); - var enemies = player.getEnemies(); - for (var i = 0; i < enemies.length; i++) { - if (list.includes(enemies[i])) { - break; - } - } - if (i == enemies.length) { - list.push(enemies.randomGet()); - } - list.remove(player); - if (!list.length) { - event.finish(); - return; - } - player.line(list, "green"); - for (var i = 0; i < list.length; i++) { - list[i].randomDiscard("h", false); - } - } else { - event.finish(); - } - "step 2"; - event.num--; - event.goto(1); - game.delay(); - }, - }, - _gainspell: { - trigger: { player: "drawBegin" }, - silent: true, - priority: -11, - filter(event, player) { - if (_status.connectMode) { - return false; - } - if (!lib.config.cards.includes("gwent")) { - return false; - } - if (player.isMin()) { - return false; - } - if (game.fixedPile) { - return false; - } - return event.num > 0 && event.parent.name == "phaseDraw"; - }, - content() { - if (!player.storage.spell_gain || Math.max.apply(null, player.storage.spell_gain) < 0) { - var tmp = player.storage.spell_gain2; - player.storage.spell_gain = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].randomGets(3); - player.storage.spell_gain2 = Math.floor((15 - Math.max.apply(null, player.storage.spell_gain)) / 2); - if (tmp) { - for (var i = 0; i < 3; i++) { - player.storage.spell_gain[i] += tmp; - } - } - } - for (var i = 0; i < 3; i++) { - if (player.storage.spell_gain[i] == 0) { - var list; - if (i == 0) { - list = get.libCard(function (info) { - return info.subtype == "spell_gold"; - }); - if (get.mode() == "stone") { - list.remove("gw_aerdeyin"); - list.remove("gw_niuquzhijing"); - } - } else { - list = get.libCard(function (info) { - return info.subtype == "spell_silver"; - }); - if (get.mode() == "stone") { - list.remove("gw_butianshu"); - } - } - if (list && list.length) { - ui.cardPile.insertBefore(game.createCard(list.randomGet()), ui.cardPile.firstChild); - } - } - player.storage.spell_gain[i]--; - } - }, - }, - }, - help: { - 昆特牌: "
O[!a`#}YOy%Qz!O%Q!O!P;Z!P!Q%Q!Q![=w![!g%Q!g!hyS!^YOy%Qz;'S%Q;'S;=`%c<%lO%Qj?[WvWOy%Qz!O%Q!O!P:r!P!Q%Q!Q![=w![;'S%Q;'S;=`%c<%lO%Qj?yU]YOy%Qz!Q%Q!Q![;Z![;'S%Q;'S;=`%c<%lO%Q~@bTvWOy%Qz{@q{;'S%Q;'S;=`%c<%lO%Q~@xS!a`#t~Oy%Qz;'S%Q;'S;=`%c<%lO%QjAZ[#}YOy%Qz!O%Q!O!P;Z!P!Q%Q!Q![=w![!g%Q!g!hspec_callee[value] || -1},{term: 125, get: (value) => spec_queryIdentifier[value] || -1},{term: 4, get: (value) => spec_QueryCallee[value] || -1},{term: 25, get: (value) => spec_AtKeyword[value] || -1},{term: 123, get: (value) => spec_identifier[value] || -1}], + tokenPrec: 1963 +}); + +exports.parser = parser; diff --git a/node_modules/@lezer/css/dist/index.d.cts b/node_modules/@lezer/css/dist/index.d.cts new file mode 100644 index 0000000000..b1518ec128 --- /dev/null +++ b/node_modules/@lezer/css/dist/index.d.cts @@ -0,0 +1,3 @@ +import {LRParser} from "@lezer/lr" + +export const parser: LRParser diff --git a/node_modules/@lezer/css/dist/index.d.ts b/node_modules/@lezer/css/dist/index.d.ts new file mode 100644 index 0000000000..b1518ec128 --- /dev/null +++ b/node_modules/@lezer/css/dist/index.d.ts @@ -0,0 +1,3 @@ +import {LRParser} from "@lezer/lr" + +export const parser: LRParser diff --git a/node_modules/@lezer/css/dist/index.js b/node_modules/@lezer/css/dist/index.js new file mode 100644 index 0000000000..747bd93dc0 --- /dev/null +++ b/node_modules/@lezer/css/dist/index.js @@ -0,0 +1,144 @@ +import { ExternalTokenizer, LRParser, LocalTokenGroup } from '@lezer/lr'; +import { styleTags, tags } from '@lezer/highlight'; + +// This file was generated by lezer-generator. You probably shouldn't edit it. +const descendantOp = 122, + Unit = 1, + identifier = 123, + callee = 124, + VariableName = 2, + queryIdentifier = 125, + queryVariableName = 3, + QueryCallee = 4; + +/* Hand-written tokenizers for CSS tokens that can't be + expressed by Lezer's built-in tokenizer. */ + +const space = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, + 8198, 8199, 8200, 8201, 8202, 8232, 8233, 8239, 8287, 12288]; +const colon = 58, parenL = 40, underscore = 95, bracketL = 91, dash = 45, period = 46, + hash = 35, percent = 37, ampersand = 38, backslash = 92, newline = 10, asterisk = 42; + +function isAlpha(ch) { return ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch >= 161 } + +function isDigit(ch) { return ch >= 48 && ch <= 57 } + +function isHex(ch) { return isDigit(ch) || ch >= 97 && ch <= 102 || ch >= 65 && ch <= 70 } + +const identifierTokens = (id, varName, callee) => (input, stack) => { + for (let inside = false, dashes = 0, i = 0;; i++) { + let {next} = input; + if (isAlpha(next) || next == dash || next == underscore || (inside && isDigit(next))) { + if (!inside && (next != dash || i > 0)) inside = true; + if (dashes === i && next == dash) dashes++; + input.advance(); + } else if (next == backslash && input.peek(1) != newline) { + input.advance(); + if (isHex(input.next)) { + do { input.advance(); } while (isHex(input.next)) + if (input.next == 32) input.advance(); + } else if (input.next > -1) { + input.advance(); + } + inside = true; + } else { + if (inside) input.acceptToken( + dashes == 2 && stack.canShift(VariableName) ? varName : next == parenL ? callee : id + ); + break + } + } +}; + +const identifiers = new ExternalTokenizer( + identifierTokens(identifier, VariableName, callee) +); +const queryIdentifiers = new ExternalTokenizer( + identifierTokens(queryIdentifier, queryVariableName, QueryCallee) +); + +const descendant = new ExternalTokenizer(input => { + if (space.includes(input.peek(-1))) { + let {next} = input; + if (isAlpha(next) || next == underscore || next == hash || next == period || + next == asterisk || next == bracketL || next == colon && isAlpha(input.peek(1)) || + next == dash || next == ampersand) + input.acceptToken(descendantOp); + } +}); + +const unitToken = new ExternalTokenizer(input => { + if (!space.includes(input.peek(-1))) { + let {next} = input; + if (next == percent) { input.advance(); input.acceptToken(Unit); } + if (isAlpha(next)) { + do { input.advance(); } while (isAlpha(input.next) || isDigit(input.next)) + input.acceptToken(Unit); + } + } +}); + +const cssHighlighting = styleTags({ + "AtKeyword import charset namespace keyframes media supports": tags.definitionKeyword, + "from to selector": tags.keyword, + NamespaceName: tags.namespace, + KeyframeName: tags.labelName, + KeyframeRangeName: tags.operatorKeyword, + TagName: tags.tagName, + ClassName: tags.className, + PseudoClassName: tags.constant(tags.className), + IdName: tags.labelName, + "FeatureName PropertyName": tags.propertyName, + AttributeName: tags.attributeName, + NumberLiteral: tags.number, + KeywordQuery: tags.keyword, + UnaryQueryOp: tags.operatorKeyword, + "CallTag ValueName": tags.atom, + VariableName: tags.variableName, + Callee: tags.operatorKeyword, + Unit: tags.unit, + "UniversalSelector NestingSelector": tags.definitionOperator, + "MatchOp CompareOp": tags.compareOperator, + "ChildOp SiblingOp, LogicOp": tags.logicOperator, + BinOp: tags.arithmeticOperator, + Important: tags.modifier, + Comment: tags.blockComment, + ColorLiteral: tags.color, + "ParenthesizedContent StringLiteral": tags.string, + ":": tags.punctuation, + "PseudoOp #": tags.derefOperator, + "; ,": tags.separator, + "( )": tags.paren, + "[ ]": tags.squareBracket, + "{ }": tags.brace +}); + +// This file was generated by lezer-generator. You probably shouldn't edit it. +const spec_callee = {__proto__:null,lang:38, "nth-child":38, "nth-last-child":38, "nth-of-type":38, "nth-last-of-type":38, dir:38, "host-context":38, if:84, url:124, "url-prefix":124, domain:124, regexp:124}; +const spec_queryIdentifier = {__proto__:null,or:98, and:98, not:106, only:106, layer:170}; +const spec_QueryCallee = {__proto__:null,selector:112, layer:166}; +const spec_AtKeyword = {__proto__:null,"@import":162, "@media":174, "@charset":178, "@namespace":182, "@keyframes":188, "@supports":200, "@scope":204}; +const spec_identifier = {__proto__:null,to:207}; +const parser = LRParser.deserialize({ + version: 14, + states: "EbQYQdOOO#qQdOOP#xO`OOOOQP'#Cf'#CfOOQP'#Ce'#CeO#}QdO'#ChO$nQaO'#CcO$xQdO'#CkO%TQdO'#DpO%YQdO'#DrO%_QdO'#DuO%_QdO'#DxOOQP'#FV'#FVO&eQhO'#EhOOQS'#FU'#FUOOQS'#Ek'#EkQYQdOOO&lQdO'#EOO&PQhO'#EUO&lQdO'#EWO'aQdO'#EYO'lQdO'#E]O'tQhO'#EcO(VQdO'#EeO(bQaO'#CfO)VQ`O'#D{O)[Q`O'#F`O)gQdO'#F`QOQ`OOP)qO&jO'#CaPOOO)C@t)C@tOOQP'#Cj'#CjOOQP,59S,59SO#}QdO,59SO)|QdO,59VO%TQdO,5:[O%YQdO,5:^O%_QdO,5:aO%_QdO,5:cO%_QdO,5:dO%_QdO'#ErO*XQ`O,58}O*aQdO'#DzOOQS,58},58}OOQP'#Cn'#CnOOQO'#Dn'#DnOOQP,59V,59VO*hQ`O,59VO*mQ`O,59VOOQP'#Dq'#DqOOQP,5:[,5:[OOQO'#Ds'#DsO*rQpO,5:^O+]QaO,5:aO+sQaO,5:dOOQW'#DZ'#DZO,ZQhO'#DdO,xQhO'#FaO'tQhO'#DbO-WQ`O'#DhOOQW'#F['#F[O-]Q`O,5;SO-eQ`O'#DeOOQS-E8i-E8iOOQ['#Cs'#CsO-jQdO'#CtO.QQdO'#CzO.hQdO'#C}O/OQ!pO'#DPO1RQ!jO,5:jOOQO'#DU'#DUO*mQ`O'#DTO1cQ!nO'#FXO3`Q`O'#DVO3eQ`O'#DkOOQ['#FX'#FXO-`Q`O,5:pO3jQ!bO,5:rOOQS'#E['#E[O3rQ`O,5:tO3wQdO,5:tOOQO'#E_'#E_O4PQ`O,5:wO4UQhO,5:}O%_QdO'#DgOOQS,5;P,5;PO-eQ`O,5;PO4^QdO,5;PO4fQdO,5:gO4vQdO'#EtO5TQ`O,5;zO5TQ`O,5;zPOOO'#Ej'#EjP5`O&jO,58{POOO,58{,58{OOQP1G.n1G.nOOQP1G.q1G.qO*hQ`O1G.qO*mQ`O1G.qOOQP1G/v1G/vO5kQpO1G/xO5sQaO1G/{O6ZQaO1G/}O6qQaO1G0OO7XQaO,5;^OOQO-E8p-E8pOOQS1G.i1G.iO7cQ`O,5:fO7hQdO'#DoO7oQdO'#CrOOQP1G/x1G/xO&lQdO1G/xO7vQ!jO'#DZO8UQ!bO,59vO8^QhO,5:OOOQO'#F]'#F]O8XQ!bO,59zO'tQhO,59xO8fQhO'#EvO8sQ`O,5;{O9OQhO,59|O9uQhO'#DiOOQW,5:S,5:SOOQS1G0n1G0nOOQW,5:P,5:PO9|Q!fO'#FYOOQS'#FY'#FYOOQS'#Em'#EmO;^QdO,59`OOQ[,59`,59`O;tQdO,59fOOQ[,59f,59fO<[QdO,59iOOQ[,59i,59iOOQ[,59k,59kO&lQdO,59mOPQ!fO1G0ROOQO1G0R1G0ROOQO,5;`,5;`O>gQdO,5;`OOQO-E8r-E8rO>tQ`O1G1fPOOO-E8h-E8hPOOO1G.g1G.gOOQP7+$]7+$]OOQP7+%d7+%dO&lQdO7+%dOOQS1G0Q1G0QO?PQaO'#F_O?ZQ`O,5:ZO?`Q!fO'#ElO@^QdO'#FWO@hQ`O,59^O@mQ!bO7+%dO&lQdO1G/bO@uQhO1G/fOOQW1G/j1G/jOOQW1G/d1G/dOAWQhO,5;bOOQO-E8t-E8tOAfQhO'#DZOAtQhO'#F^OBPQ`O'#F^OBUQ`O,5:TOOQS-E8k-E8kOOQ[1G.z1G.zOOQ[1G/Q1G/QOOQ[1G/T1G/TOOQ[1G/X1G/XOBZQdO,5:lOOQS7+%p7+%pOB`Q`O7+%pOBeQhO'#DYOBmQ`O,59sO'tQhO,59sOOQ[1G/q1G/qOBuQ`O1G/qOOQS7+%z7+%zOBzQbO'#DPOOQO'#Eb'#EbOCYQ`O'#EaOOQO'#Ea'#EaOCeQ`O'#EwOCmQdO,5:zOOQS,5:z,5:zOOQ[1G/m1G/mOOQS7+&V7+&VO-`Q`O7+&VOCxQ!fO'#EsO&lQdO'#EsOEPQdO7+%mOOQO7+%m7+%mOOQO1G0z1G0zOEdQ!bO< jAN>jOIUQaO,5;]OOQO-E8o-E8oOI`QdO,5;[OOQO-E8n-E8nOOQW< WO&lQdO1G0uOK]Q`O7+'OOOQO,5;a,5;aOOQO-E8s-E8sOOQW<t}!O?V!O!P?t!P!Q@]!Q![AU![!]BP!]!^B{!^!_C^!_!`DY!`!aDm!a!b$q!b!cEn!c!}$q!}#OG{#O#P$q#P#QH^#Q#R6W#R#o$q#o#pHo#p#q6W#q#rIQ#r#sIc#s#y$q#y#z%i#z$f$q$f$g%i$g#BY$q#BY#BZ%i#BZ$IS$q$IS$I_%i$I_$I|$q$I|$JO%i$JO$JT$q$JT$JU%i$JU$KV$q$KV$KW%i$KW&FU$q&FU&FV%i&FV;'S$q;'S;=`Iz<%lO$q`$tSOy%Qz;'S%Q;'S;=`%c<%lO%Q`%VS!a`Oy%Qz;'S%Q;'S;=`%c<%lO%Q`%fP;=`<%l%Q~%nh#s~OX%QX^'Y^p%Qpq'Yqy%Qz#y%Q#y#z'Y#z$f%Q$f$g'Y$g#BY%Q#BY#BZ'Y#BZ$IS%Q$IS$I_'Y$I_$I|%Q$I|$JO'Y$JO$JT%Q$JT$JU'Y$JU$KV%Q$KV$KW'Y$KW&FU%Q&FU&FV'Y&FV;'S%Q;'S;=`%c<%lO%Q~'ah#s~!a`OX%QX^'Y^p%Qpq'Yqy%Qz#y%Q#y#z'Y#z$f%Q$f$g'Y$g#BY%Q#BY#BZ'Y#BZ$IS%Q$IS$I_'Y$I_$I|%Q$I|$JO'Y$JO$JT%Q$JT$JU'Y$JU$KV%Q$KV$KW'Y$KW&FU%Q&FU&FV'Y&FV;'S%Q;'S;=`%c<%lO%Qj)OUOy%Qz#]%Q#]#^)b#^;'S%Q;'S;=`%c<%lO%Qj)gU!a`Oy%Qz#a%Q#a#b)y#b;'S%Q;'S;=`%c<%lO%Qj*OU!a`Oy%Qz#d%Q#d#e*b#e;'S%Q;'S;=`%c<%lO%Qj*gU!a`Oy%Qz#c%Q#c#d*y#d;'S%Q;'S;=`%c<%lO%Qj+OU!a`Oy%Qz#f%Q#f#g+b#g;'S%Q;'S;=`%c<%lO%Qj+gU!a`Oy%Qz#h%Q#h#i+y#i;'S%Q;'S;=`%c<%lO%Qj,OU!a`Oy%Qz#T%Q#T#U,b#U;'S%Q;'S;=`%c<%lO%Qj,gU!a`Oy%Qz#b%Q#b#c,y#c;'S%Q;'S;=`%c<%lO%Qj-OU!a`Oy%Qz#h%Q#h#i-b#i;'S%Q;'S;=`%c<%lO%Qj-iS!qY!a`Oy%Qz;'S%Q;'S;=`%c<%lO%Q~-xWOY-uZr-urs.bs#O-u#O#P.g#P;'S-u;'S;=`/c<%lO-u~.gOt~~.jRO;'S-u;'S;=`.s;=`O-u~.vXOY-uZr-urs.bs#O-u#O#P.g#P;'S-u;'S;=`/c;=`<%l-u<%lO-u~/fP;=`<%l-uj/nYjYOy%Qz!Q%Q!Q![0^![!c%Q!c!i0^!i#T%Q#T#Z0^#Z;'S%Q;'S;=`%c<%lO%Qj0cY!a`Oy%Qz!Q%Q!Q![1R![!c%Q!c!i1R!i#T%Q#T#Z1R#Z;'S%Q;'S;=`%c<%lO%Qj1WY!a`Oy%Qz!Q%Q!Q![1v![!c%Q!c!i1v!i#T%Q#T#Z1v#Z;'S%Q;'S;=`%c<%lO%Qj1}YrY!a`Oy%Qz!Q%Q!Q![2m![!c%Q!c!i2m!i#T%Q#T#Z2m#Z;'S%Q;'S;=`%c<%lO%Qj2tYrY!a`Oy%Qz!Q%Q!Q![3d![!c%Q!c!i3d!i#T%Q#T#Z3d#Z;'S%Q;'S;=`%c<%lO%Qj3iY!a`Oy%Qz!Q%Q!Q![4X![!c%Q!c!i4X!i#T%Q#T#Z4X#Z;'S%Q;'S;=`%c<%lO%Qj4`YrY!a`Oy%Qz!Q%Q!Q![5O![!c%Q!c!i5O!i#T%Q#T#Z5O#Z;'S%Q;'S;=`%c<%lO%Qj5TY!a`Oy%Qz!Q%Q!Q![5s![!c%Q!c!i5s!i#T%Q#T#Z5s#Z;'S%Q;'S;=`%c<%lO%Qj5zSrY!a`Oy%Qz;'S%Q;'S;=`%c<%lO%Qd6ZUOy%Qz!_%Q!_!`6m!`;'S%Q;'S;=`%c<%lO%Qd6tS!hS!a`Oy%Qz;'S%Q;'S;=`%c<%lO%Qb7VSZQOy%Qz;'S%Q;'S;=`%c<%lO%Q~7fWOY7cZw7cwx.bx#O7c#O#P8O#P;'S7c;'S;=`8z<%lO7c~8RRO;'S7c;'S;=`8[;=`O7c~8_XOY7cZw7cwx.bx#O7c#O#P8O#P;'S7c;'S;=`8z;=`<%l7c<%lO7c~8}P;=`<%l7cj9VSeYOy%Qz;'S%Q;'S;=`%c<%lO%Q~9hOd~n9oUWQvWOy%Qz!_%Q!_!`6m!`;'S%Q;'S;=`%c<%lO%Qj:YWvW!mQOy%Qz!O%Q!O!P:r!P!Q%Q!Q![=w![;'S%Q;'S;=`%c<%lO%Qj:wU!a`Oy%Qz!Q%Q!Q![;Z![;'S%Q;'S;=`%c<%lO%Qj;bY!a`#}YOy%Qz!Q%Q!Q![;Z![!g%Q!g!h O[!a`#}YOy%Qz!O%Q!O!P;Z!P!Q%Q!Q![=w![!g%Q!g!hyS!^YOy%Qz;'S%Q;'S;=`%c<%lO%Qj?[WvWOy%Qz!O%Q!O!P:r!P!Q%Q!Q![=w![;'S%Q;'S;=`%c<%lO%Qj?yU]YOy%Qz!Q%Q!Q![;Z![;'S%Q;'S;=`%c<%lO%Q~@bTvWOy%Qz{@q{;'S%Q;'S;=`%c<%lO%Q~@xS!a`#t~Oy%Qz;'S%Q;'S;=`%c<%lO%QjAZ[#}YOy%Qz!O%Q!O!P;Z!P!Q%Q!Q![=w![!g%Q!g!hspec_callee[value] || -1},{term: 125, get: (value) => spec_queryIdentifier[value] || -1},{term: 4, get: (value) => spec_QueryCallee[value] || -1},{term: 25, get: (value) => spec_AtKeyword[value] || -1},{term: 123, get: (value) => spec_identifier[value] || -1}], + tokenPrec: 1963 +}); + +export { parser }; diff --git a/node_modules/@lezer/css/package.json b/node_modules/@lezer/css/package.json new file mode 100644 index 0000000000..bc9a38fbb0 --- /dev/null +++ b/node_modules/@lezer/css/package.json @@ -0,0 +1,36 @@ +{ + "name": "@lezer/css", + "version": "1.3.0", + "description": "lezer-based CSS grammar", + "main": "dist/index.cjs", + "type": "module", + "exports": { + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "module": "dist/index.js", + "types": "dist/index.d.ts", + "author": "Marijn Haverbeke", + "license": "MIT", + "devDependencies": { + "@lezer/generator": "^1.8.0", + "mocha": "^10.2.0", + "rollup": "^2.52.2", + "@rollup/plugin-node-resolve": "^9.0.0" + }, + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/lr": "^1.3.0", + "@lezer/highlight": "^1.0.0" + }, + "repository": { + "type" : "git", + "url" : "https://github.com/lezer-parser/css.git" + }, + "scripts": { + "build": "lezer-generator src/css.grammar -o src/parser && rollup -c", + "build-debug": "lezer-generator src/css.grammar --names -o src/parser && rollup -c", + "prepare": "npm run build", + "test": "mocha test/test-*.js" + } +} diff --git a/node_modules/@lezer/css/rollup.config.js b/node_modules/@lezer/css/rollup.config.js new file mode 100644 index 0000000000..35012b4ced --- /dev/null +++ b/node_modules/@lezer/css/rollup.config.js @@ -0,0 +1,16 @@ +import {nodeResolve} from "@rollup/plugin-node-resolve" + +export default { + input: "./src/parser.js", + output: [{ + format: "cjs", + file: "./dist/index.cjs" + }, { + format: "es", + file: "./dist/index.js" + }], + external(id) { return !/^[\.\/]/.test(id) }, + plugins: [ + nodeResolve() + ] +} diff --git a/node_modules/@lezer/css/src/css.grammar b/node_modules/@lezer/css/src/css.grammar new file mode 100644 index 0000000000..5038f89686 --- /dev/null +++ b/node_modules/@lezer/css/src/css.grammar @@ -0,0 +1,274 @@ +@precedence { + attribute @left, + structure @left, + call, + valueCompareOp, + valueOp @left, + layerName +} + +@skip { whitespace | Comment } + +@top StyleSheet { item* } + +@top Styles { blockContent } + +item { + RuleSet | + ImportStatement | + MediaStatement | + CharsetStatement | + NamespaceStatement | + KeyframesStatement | + SupportsStatement | + ScopeStatement | + AtRule +} + +RuleSet { + selector ("," selector)* Block +} + +ImportStatement { + atKw<"import"> + value + Layer { + queryCalleeKw<"layer"> (!layerName "(" LayerName ("." LayerName)* ")")? | + queryKw<"layer"> + }? + commaSep ";" +} + +LayerName { identifier } + +MediaStatement { + atKw<"media"> commaSep Block +} + +CharsetStatement { + atKw<"charset"> value ";" +} + +NamespaceStatement { + atKw<"namespace"> + NamespaceName { identifier }? + (StringLiteral | CallLiteral) ";" +} + +KeyframesStatement { + atKw<"keyframes"> + KeyframeName { identifier | StringLiteral } + KeyframeList +} + +KeyframeSelector { + KeyframeRangeName { identifier } NumberLiteral? | + NumberLiteral +} + +KeyframeList { + "{" (KeyframeSelector ("," KeyframeSelector)* Block)* "}" +} + +SupportsStatement { + atKw<"supports"> query Block +} + +ScopeStatement { + atKw<"scope"> + ParenthesizedSelector? + (@extend[@name=to] ParenthesizedSelector)? + Block +} + +AtRule { AtKeyword commaSep (";" | Block) } + +Block { "{" blockContent "}" } + +blockContent { ~item item* (Declaration (";" ~item item* Declaration?)*)? } + +selector { + UniversalSelector | + TagSelector { ~item TagName { identifier ~item } } | + NestingSelector | + ClassSelector { selector? !attribute "." ClassName { identifier } } | + PseudoClassSelector { + selector? !attribute (":" | "::") ( + PseudoClassName { identifier } | + pseudoClassWithArg ArgList | + PseudoClassName { callee } ArgList ) + } | + IdSelector { selector? !attribute "#" IdName { identifier } } | + AttributeSelector { selector? !attribute "[" AttributeName { identifier } (MatchOp value)? "]" } | + ChildSelector { selector? !structure ChildOp selector } | + DescendantSelector { selector !structure descendantOp selector } | + SiblingSelector { selector? !structure SiblingOp selector } +} + +pseudoClassWithArg { + @specialize[@name=PseudoClassName] +} + +NumberLiteral { + numberLiteralInner Unit? +} + +ArgList { "(" commaSep ")" } + +Declaration { + (PropertyName { identifier ~item } | VariableName) + ":" (value (","? value)*)? Important? +} + +query { + KeywordQuery { queryIdentifier } | + FeatureQuery { "(" FeatureName ":" value+ ")" } | + BinaryQuery { query !valueOp @specialize[@name=LogicOp] query } | + ComparisonQuery { + "(" + (queryValue | FeatureName) !valueCompareOp CompareOp (queryValue | FeatureName) + (!valueCompareOp CompareOp (queryValue | FeatureName))? + ")" + } | + UnaryQuery { @specialize[@name=UnaryQueryOp] query } | + ParenthesizedQuery { "(" query ")" } | + SelectorQuery { queryCalleeKw<"selector"> ParenthesizedSelector } | + CallQuery { QueryCallee ArgList } +} + +ParenthesizedSelector { "(" selector ")" } + +FeatureName { queryIdentifier } + +value { + VariableName | + ValueName { identifier } | + ParenthesizedValue { "(" token* ")" } | + BracketedValue { "[" token* "]" } | + BracedValue { "{" token* "}" } | + ColorLiteral | + NumberLiteral | + StringLiteral | + BinaryExpression { value !valueOp BinOp value } | + CallExpression | + IfExpression | + CallLiteral +} + +token { + value | + AtKeyword | + "#" | ";" | "." | ":" +} + +queryValue { + queryVariableName | + ColorLiteral | + NumberLiteral | + StringLiteral +} + +IfExpression { + @specialize[@name=if] ArgList { + "(" (IfBranch ";")* IfBranch ";"? ")" + } +} + +IfBranch { query ":" value } + +CallLiteral { + @specialize[@name=CallTag] + "(" (ParenthesizedContent | StringLiteral)? ")" +} + +CallExpression { + (Callee { callee } | VariableName) !call ArgList +} + +@skip {} { + Comment[isolate] { "/*" (commentContent | commentLineBreak)* commentEnd } +} + +@local tokens { + commentEnd { "*/" | @eof } + commentLineBreak { "\n" } + @else commentContent +} + +commaSep { "" | value ("," value?)* } + +queryKw { @specialize[@name={name}] } +queryCalleeKw { @specialize[@name={name}] } + +atKw { @specialize[@name={name}] } + +@external tokens descendant from "./tokens" { + descendantOp +} + +@external tokens unitToken from "./tokens" { + Unit +} + +@external tokens identifiers from "./tokens" { + identifier, + callee, + VariableName +} + +@external tokens queryIdentifiers from "./tokens" { + @conflict { identifier, VariableName, callee } + queryIdentifier, + queryVariableName[@name=VariableName], + QueryCallee +} + +@tokens { + UniversalSelector { "*" } + + NestingSelector { "&" } + + AtKeyword { "@" "-"? @asciiLetter (@asciiLetter | @digit | "-")* } + + MatchOp { $[~^|*$]? "=" } + + ChildOp { ">" ">"? } + + CompareOp { $[<>] "="? | "=" } + + SiblingOp { "~" | "+" } + + BinOp { $[+\-*/] } + + Important { "!important" } + + whitespace { @whitespace+ } + + hexDigit { @digit | $[a-fA-F] } + + ParenthesizedContent { !['")] ![)]+ } + + @precedence { whitespace, ParenthesizedContent, "/*" } + + ColorLiteral { + "#" hexDigit hexDigit hexDigit (hexDigit (hexDigit hexDigit (hexDigit hexDigit)?)?)? + } + + numberLiteralInner { ("+" | "-")? (@digit+ ("." @digit*)? | "." @digit+) (("e" | "E") ("+" | "-")? @digit+)? } + + @precedence { numberLiteralInner, BinOp, SiblingOp } + + @precedence { numberLiteralInner, "." } + + StringLiteral[isolate] { "\"" (!["\n\\] | "\\" _)* "\"" | "'" (!['\n\\] | "\\" _)* "'" } + + "#" "." + + ":" "::" ";" "," + + "(" ")" "[" "]" "{" "}" +} + +@external propSource cssHighlighting from "./highlight" + +@detectDelim diff --git a/node_modules/@lezer/css/src/highlight.js b/node_modules/@lezer/css/src/highlight.js new file mode 100644 index 0000000000..8234fa007e --- /dev/null +++ b/node_modules/@lezer/css/src/highlight.js @@ -0,0 +1,36 @@ +import {styleTags, tags as t} from "@lezer/highlight" + +export const cssHighlighting = styleTags({ + "AtKeyword import charset namespace keyframes media supports": t.definitionKeyword, + "from to selector": t.keyword, + NamespaceName: t.namespace, + KeyframeName: t.labelName, + KeyframeRangeName: t.operatorKeyword, + TagName: t.tagName, + ClassName: t.className, + PseudoClassName: t.constant(t.className), + IdName: t.labelName, + "FeatureName PropertyName": t.propertyName, + AttributeName: t.attributeName, + NumberLiteral: t.number, + KeywordQuery: t.keyword, + UnaryQueryOp: t.operatorKeyword, + "CallTag ValueName": t.atom, + VariableName: t.variableName, + Callee: t.operatorKeyword, + Unit: t.unit, + "UniversalSelector NestingSelector": t.definitionOperator, + "MatchOp CompareOp": t.compareOperator, + "ChildOp SiblingOp, LogicOp": t.logicOperator, + BinOp: t.arithmeticOperator, + Important: t.modifier, + Comment: t.blockComment, + ColorLiteral: t.color, + "ParenthesizedContent StringLiteral": t.string, + ":": t.punctuation, + "PseudoOp #": t.derefOperator, + "; ,": t.separator, + "( )": t.paren, + "[ ]": t.squareBracket, + "{ }": t.brace +}) diff --git a/node_modules/@lezer/css/src/parser.js b/node_modules/@lezer/css/src/parser.js new file mode 100644 index 0000000000..48b9752b71 --- /dev/null +++ b/node_modules/@lezer/css/src/parser.js @@ -0,0 +1,30 @@ +// This file was generated by lezer-generator. You probably shouldn't edit it. +import {LRParser, LocalTokenGroup} from "@lezer/lr" +import {descendant, unitToken, identifiers, queryIdentifiers} from "./tokens" +import {cssHighlighting} from "./highlight" +const spec_callee = {__proto__:null,lang:38, "nth-child":38, "nth-last-child":38, "nth-of-type":38, "nth-last-of-type":38, dir:38, "host-context":38, if:84, url:124, "url-prefix":124, domain:124, regexp:124} +const spec_queryIdentifier = {__proto__:null,or:98, and:98, not:106, only:106, layer:170} +const spec_QueryCallee = {__proto__:null,selector:112, layer:166} +const spec_AtKeyword = {__proto__:null,"@import":162, "@media":174, "@charset":178, "@namespace":182, "@keyframes":188, "@supports":200, "@scope":204} +const spec_identifier = {__proto__:null,to:207} +export const parser = LRParser.deserialize({ + version: 14, + states: "EbQYQdOOO#qQdOOP#xO`OOOOQP'#Cf'#CfOOQP'#Ce'#CeO#}QdO'#ChO$nQaO'#CcO$xQdO'#CkO%TQdO'#DpO%YQdO'#DrO%_QdO'#DuO%_QdO'#DxOOQP'#FV'#FVO&eQhO'#EhOOQS'#FU'#FUOOQS'#Ek'#EkQYQdOOO&lQdO'#EOO&PQhO'#EUO&lQdO'#EWO'aQdO'#EYO'lQdO'#E]O'tQhO'#EcO(VQdO'#EeO(bQaO'#CfO)VQ`O'#D{O)[Q`O'#F`O)gQdO'#F`QOQ`OOP)qO&jO'#CaPOOO)C@t)C@tOOQP'#Cj'#CjOOQP,59S,59SO#}QdO,59SO)|QdO,59VO%TQdO,5:[O%YQdO,5:^O%_QdO,5:aO%_QdO,5:cO%_QdO,5:dO%_QdO'#ErO*XQ`O,58}O*aQdO'#DzOOQS,58},58}OOQP'#Cn'#CnOOQO'#Dn'#DnOOQP,59V,59VO*hQ`O,59VO*mQ`O,59VOOQP'#Dq'#DqOOQP,5:[,5:[OOQO'#Ds'#DsO*rQpO,5:^O+]QaO,5:aO+sQaO,5:dOOQW'#DZ'#DZO,ZQhO'#DdO,xQhO'#FaO'tQhO'#DbO-WQ`O'#DhOOQW'#F['#F[O-]Q`O,5;SO-eQ`O'#DeOOQS-E8i-E8iOOQ['#Cs'#CsO-jQdO'#CtO.QQdO'#CzO.hQdO'#C}O/OQ!pO'#DPO1RQ!jO,5:jOOQO'#DU'#DUO*mQ`O'#DTO1cQ!nO'#FXO3`Q`O'#DVO3eQ`O'#DkOOQ['#FX'#FXO-`Q`O,5:pO3jQ!bO,5:rOOQS'#E['#E[O3rQ`O,5:tO3wQdO,5:tOOQO'#E_'#E_O4PQ`O,5:wO4UQhO,5:}O%_QdO'#DgOOQS,5;P,5;PO-eQ`O,5;PO4^QdO,5;PO4fQdO,5:gO4vQdO'#EtO5TQ`O,5;zO5TQ`O,5;zPOOO'#Ej'#EjP5`O&jO,58{POOO,58{,58{OOQP1G.n1G.nOOQP1G.q1G.qO*hQ`O1G.qO*mQ`O1G.qOOQP1G/v1G/vO5kQpO1G/xO5sQaO1G/{O6ZQaO1G/}O6qQaO1G0OO7XQaO,5;^OOQO-E8p-E8pOOQS1G.i1G.iO7cQ`O,5:fO7hQdO'#DoO7oQdO'#CrOOQP1G/x1G/xO&lQdO1G/xO7vQ!jO'#DZO8UQ!bO,59vO8^QhO,5:OOOQO'#F]'#F]O8XQ!bO,59zO'tQhO,59xO8fQhO'#EvO8sQ`O,5;{O9OQhO,59|O9uQhO'#DiOOQW,5:S,5:SOOQS1G0n1G0nOOQW,5:P,5:PO9|Q!fO'#FYOOQS'#FY'#FYOOQS'#Em'#EmO;^QdO,59`OOQ[,59`,59`O;tQdO,59fOOQ[,59f,59fO<[QdO,59iOOQ[,59i,59iOOQ[,59k,59kO&lQdO,59mO PQ!fO1G0ROOQO1G0R1G0ROOQO,5;`,5;`O>gQdO,5;`OOQO-E8r-E8rO>tQ`O1G1fPOOO-E8h-E8hPOOO1G.g1G.gOOQP7+$]7+$]OOQP7+%d7+%dO&lQdO7+%dOOQS1G0Q1G0QO?PQaO'#F_O?ZQ`O,5:ZO?`Q!fO'#ElO@^QdO'#FWO@hQ`O,59^O@mQ!bO7+%dO&lQdO1G/bO@uQhO1G/fOOQW1G/j1G/jOOQW1G/d1G/dOAWQhO,5;bOOQO-E8t-E8tOAfQhO'#DZOAtQhO'#F^OBPQ`O'#F^OBUQ`O,5:TOOQS-E8k-E8kOOQ[1G.z1G.zOOQ[1G/Q1G/QOOQ[1G/T1G/TOOQ[1G/X1G/XOBZQdO,5:lOOQS7+%p7+%pOB`Q`O7+%pOBeQhO'#DYOBmQ`O,59sO'tQhO,59sOOQ[1G/q1G/qOBuQ`O1G/qOOQS7+%z7+%zOBzQbO'#DPOOQO'#Eb'#EbOCYQ`O'#EaOOQO'#Ea'#EaOCeQ`O'#EwOCmQdO,5:zOOQS,5:z,5:zOOQ[1G/m1G/mOOQS7+&V7+&VO-`Q`O7+&VOCxQ!fO'#EsO&lQdO'#EsOEPQdO7+%mOOQO7+%m7+%mOOQO1G0z1G0zOEdQ!bO< jAN>jOIUQaO,5;]OOQO-E8o-E8oOI`QdO,5;[OOQO-E8n-E8nOOQW< WO&lQdO1G0uOK]Q`O7+'OOOQO,5;a,5;aOOQO-E8s-E8sOOQW<t}!O?V!O!P?t!P!Q@]!Q![AU![!]BP!]!^B{!^!_C^!_!`DY!`!aDm!a!b$q!b!cEn!c!}$q!}#OG{#O#P$q#P#QH^#Q#R6W#R#o$q#o#pHo#p#q6W#q#rIQ#r#sIc#s#y$q#y#z%i#z$f$q$f$g%i$g#BY$q#BY#BZ%i#BZ$IS$q$IS$I_%i$I_$I|$q$I|$JO%i$JO$JT$q$JT$JU%i$JU$KV$q$KV$KW%i$KW&FU$q&FU&FV%i&FV;'S$q;'S;=`Iz<%lO$q`$tSOy%Qz;'S%Q;'S;=`%c<%lO%Q`%VS!a`Oy%Qz;'S%Q;'S;=`%c<%lO%Q`%fP;=`<%l%Q~%nh#s~OX%QX^'Y^p%Qpq'Yqy%Qz#y%Q#y#z'Y#z$f%Q$f$g'Y$g#BY%Q#BY#BZ'Y#BZ$IS%Q$IS$I_'Y$I_$I|%Q$I|$JO'Y$JO$JT%Q$JT$JU'Y$JU$KV%Q$KV$KW'Y$KW&FU%Q&FU&FV'Y&FV;'S%Q;'S;=`%c<%lO%Q~'ah#s~!a`OX%QX^'Y^p%Qpq'Yqy%Qz#y%Q#y#z'Y#z$f%Q$f$g'Y$g#BY%Q#BY#BZ'Y#BZ$IS%Q$IS$I_'Y$I_$I|%Q$I|$JO'Y$JO$JT%Q$JT$JU'Y$JU$KV%Q$KV$KW'Y$KW&FU%Q&FU&FV'Y&FV;'S%Q;'S;=`%c<%lO%Qj)OUOy%Qz#]%Q#]#^)b#^;'S%Q;'S;=`%c<%lO%Qj)gU!a`Oy%Qz#a%Q#a#b)y#b;'S%Q;'S;=`%c<%lO%Qj*OU!a`Oy%Qz#d%Q#d#e*b#e;'S%Q;'S;=`%c<%lO%Qj*gU!a`Oy%Qz#c%Q#c#d*y#d;'S%Q;'S;=`%c<%lO%Qj+OU!a`Oy%Qz#f%Q#f#g+b#g;'S%Q;'S;=`%c<%lO%Qj+gU!a`Oy%Qz#h%Q#h#i+y#i;'S%Q;'S;=`%c<%lO%Qj,OU!a`Oy%Qz#T%Q#T#U,b#U;'S%Q;'S;=`%c<%lO%Qj,gU!a`Oy%Qz#b%Q#b#c,y#c;'S%Q;'S;=`%c<%lO%Qj-OU!a`Oy%Qz#h%Q#h#i-b#i;'S%Q;'S;=`%c<%lO%Qj-iS!qY!a`Oy%Qz;'S%Q;'S;=`%c<%lO%Q~-xWOY-uZr-urs.bs#O-u#O#P.g#P;'S-u;'S;=`/c<%lO-u~.gOt~~.jRO;'S-u;'S;=`.s;=`O-u~.vXOY-uZr-urs.bs#O-u#O#P.g#P;'S-u;'S;=`/c;=`<%l-u<%lO-u~/fP;=`<%l-uj/nYjYOy%Qz!Q%Q!Q![0^![!c%Q!c!i0^!i#T%Q#T#Z0^#Z;'S%Q;'S;=`%c<%lO%Qj0cY!a`Oy%Qz!Q%Q!Q![1R![!c%Q!c!i1R!i#T%Q#T#Z1R#Z;'S%Q;'S;=`%c<%lO%Qj1WY!a`Oy%Qz!Q%Q!Q![1v![!c%Q!c!i1v!i#T%Q#T#Z1v#Z;'S%Q;'S;=`%c<%lO%Qj1}YrY!a`Oy%Qz!Q%Q!Q![2m![!c%Q!c!i2m!i#T%Q#T#Z2m#Z;'S%Q;'S;=`%c<%lO%Qj2tYrY!a`Oy%Qz!Q%Q!Q![3d![!c%Q!c!i3d!i#T%Q#T#Z3d#Z;'S%Q;'S;=`%c<%lO%Qj3iY!a`Oy%Qz!Q%Q!Q![4X![!c%Q!c!i4X!i#T%Q#T#Z4X#Z;'S%Q;'S;=`%c<%lO%Qj4`YrY!a`Oy%Qz!Q%Q!Q![5O![!c%Q!c!i5O!i#T%Q#T#Z5O#Z;'S%Q;'S;=`%c<%lO%Qj5TY!a`Oy%Qz!Q%Q!Q![5s![!c%Q!c!i5s!i#T%Q#T#Z5s#Z;'S%Q;'S;=`%c<%lO%Qj5zSrY!a`Oy%Qz;'S%Q;'S;=`%c<%lO%Qd6ZUOy%Qz!_%Q!_!`6m!`;'S%Q;'S;=`%c<%lO%Qd6tS!hS!a`Oy%Qz;'S%Q;'S;=`%c<%lO%Qb7VSZQOy%Qz;'S%Q;'S;=`%c<%lO%Q~7fWOY7cZw7cwx.bx#O7c#O#P8O#P;'S7c;'S;=`8z<%lO7c~8RRO;'S7c;'S;=`8[;=`O7c~8_XOY7cZw7cwx.bx#O7c#O#P8O#P;'S7c;'S;=`8z;=`<%l7c<%lO7c~8}P;=`<%l7cj9VSeYOy%Qz;'S%Q;'S;=`%c<%lO%Q~9hOd~n9oUWQvWOy%Qz!_%Q!_!`6m!`;'S%Q;'S;=`%c<%lO%Qj:YWvW!mQOy%Qz!O%Q!O!P:r!P!Q%Q!Q![=w![;'S%Q;'S;=`%c<%lO%Qj:wU!a`Oy%Qz!Q%Q!Q![;Z![;'S%Q;'S;=`%c<%lO%Qj;bY!a`#}YOy%Qz!Q%Q!Q![;Z![!g%Q!g!h O[!a`#}YOy%Qz!O%Q!O!P;Z!P!Q%Q!Q![=w![!g%Q!g!hyS!^YOy%Qz;'S%Q;'S;=`%c<%lO%Qj?[WvWOy%Qz!O%Q!O!P:r!P!Q%Q!Q![=w![;'S%Q;'S;=`%c<%lO%Qj?yU]YOy%Qz!Q%Q!Q![;Z![;'S%Q;'S;=`%c<%lO%Q~@bTvWOy%Qz{@q{;'S%Q;'S;=`%c<%lO%Q~@xS!a`#t~Oy%Qz;'S%Q;'S;=`%c<%lO%QjAZ[#}YOy%Qz!O%Q!O!P;Z!P!Q%Q!Q![=w![!g%Q!g!hspec_callee[value] || -1},{term: 125, get: (value) => spec_queryIdentifier[value] || -1},{term: 4, get: (value) => spec_QueryCallee[value] || -1},{term: 25, get: (value) => spec_AtKeyword[value] || -1},{term: 123, get: (value) => spec_identifier[value] || -1}], + tokenPrec: 1963 +}) diff --git a/node_modules/@lezer/css/src/parser.terms.js b/node_modules/@lezer/css/src/parser.terms.js new file mode 100644 index 0000000000..b8204facb5 --- /dev/null +++ b/node_modules/@lezer/css/src/parser.terms.js @@ -0,0 +1,61 @@ +// This file was generated by lezer-generator. You probably shouldn't edit it. +export const + descendantOp = 122, + Unit = 1, + identifier = 123, + callee = 124, + VariableName = 2, + queryIdentifier = 125, + queryVariableName = 3, + QueryCallee = 4, + Comment = 5, + StyleSheet = 6, + RuleSet = 7, + UniversalSelector = 8, + NestingSelector = 11, + PseudoClassName = 19, + AtKeyword = 25, + ColorLiteral = 34, + NumberLiteral = 35, + StringLiteral = 36, + BinOp = 38, + CallExpression = 39, + IfExpression = 41, + _if = 42, + IfBranch = 44, + FeatureName = 47, + LogicOp = 49, + CompareOp = 51, + UnaryQueryOp = 53, + selector = 56, + ParenthesizedSelector = 57, + CallLiteral = 61, + CallTag = 62, + ParenthesizedContent = 63, + MatchOp = 70, + ChildOp = 72, + SiblingOp = 75, + Block = 76, + Declaration = 77, + Important = 79, + ImportStatement = 80, + _import = 81, + layer = 85, + LayerName = 84, + MediaStatement = 86, + media = 87, + CharsetStatement = 88, + charset = 89, + NamespaceStatement = 90, + namespace = 91, + KeyframesStatement = 93, + keyframes = 94, + KeyframeList = 96, + KeyframeSelector = 97, + SupportsStatement = 99, + supports = 100, + ScopeStatement = 101, + scope = 102, + to = 103, + AtRule = 104, + Styles = 105 diff --git a/node_modules/@lezer/css/src/tokens.js b/node_modules/@lezer/css/src/tokens.js new file mode 100644 index 0000000000..8205c9597f --- /dev/null +++ b/node_modules/@lezer/css/src/tokens.js @@ -0,0 +1,73 @@ +/* Hand-written tokenizers for CSS tokens that can't be + expressed by Lezer's built-in tokenizer. */ + +import {ExternalTokenizer} from "@lezer/lr" +import { + identifier, callee, VariableName, + queryIdentifier, queryVariableName, QueryCallee, + descendantOp, Unit +} from "./parser.terms.js" + +const space = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, + 8198, 8199, 8200, 8201, 8202, 8232, 8233, 8239, 8287, 12288] +const colon = 58, parenL = 40, underscore = 95, bracketL = 91, dash = 45, period = 46, + hash = 35, percent = 37, ampersand = 38, backslash = 92, newline = 10, asterisk = 42 + +function isAlpha(ch) { return ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch >= 161 } + +function isDigit(ch) { return ch >= 48 && ch <= 57 } + +function isHex(ch) { return isDigit(ch) || ch >= 97 && ch <= 102 || ch >= 65 && ch <= 70 } + +const identifierTokens = (id, varName, callee) => (input, stack) => { + for (let inside = false, dashes = 0, i = 0;; i++) { + let {next} = input + if (isAlpha(next) || next == dash || next == underscore || (inside && isDigit(next))) { + if (!inside && (next != dash || i > 0)) inside = true + if (dashes === i && next == dash) dashes++ + input.advance() + } else if (next == backslash && input.peek(1) != newline) { + input.advance() + if (isHex(input.next)) { + do { input.advance() } while (isHex(input.next)) + if (input.next == 32) input.advance() + } else if (input.next > -1) { + input.advance() + } + inside = true + } else { + if (inside) input.acceptToken( + dashes == 2 && stack.canShift(VariableName) ? varName : next == parenL ? callee : id + ) + break + } + } +} + +export const identifiers = new ExternalTokenizer( + identifierTokens(identifier, VariableName, callee) +) +export const queryIdentifiers = new ExternalTokenizer( + identifierTokens(queryIdentifier, queryVariableName, QueryCallee) +) + +export const descendant = new ExternalTokenizer(input => { + if (space.includes(input.peek(-1))) { + let {next} = input + if (isAlpha(next) || next == underscore || next == hash || next == period || + next == asterisk || next == bracketL || next == colon && isAlpha(input.peek(1)) || + next == dash || next == ampersand) + input.acceptToken(descendantOp) + } +}) + +export const unitToken = new ExternalTokenizer(input => { + if (!space.includes(input.peek(-1))) { + let {next} = input + if (next == percent) { input.advance(); input.acceptToken(Unit) } + if (isAlpha(next)) { + do { input.advance() } while (isAlpha(input.next) || isDigit(input.next)) + input.acceptToken(Unit) + } + } +}) diff --git a/node_modules/@lezer/css/test/declarations.txt b/node_modules/@lezer/css/test/declarations.txt new file mode 100644 index 0000000000..974ef1a80b --- /dev/null +++ b/node_modules/@lezer/css/test/declarations.txt @@ -0,0 +1,204 @@ +# Function calls + +a { + color: rgba(0, 255, 0, 0.5); +} + +==> + +StyleSheet( + RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,CallExpression(Callee,ArgList(NumberLiteral,NumberLiteral,NumberLiteral,NumberLiteral)))))) + +# Calls where each argument has multiple values + +div { + background: repeating-linear-gradient(red, orange 50px); + clip-path: polygon(50% 0%, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0% 50%, 40% 40%) +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,CallExpression(Callee,ArgList(ValueName,ValueName,NumberLiteral(Unit)))), + Declaration(PropertyName,CallExpression(Callee,ArgList( + NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit), + NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit), + NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit), + NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit))))))) + +# Color literals + +a { + b: #fafd04; + c: #fafd0401; +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,ColorLiteral), + Declaration(PropertyName,ColorLiteral)))) + +# Numbers + +a { + b: 0.5%; + c: 5em; + margin: 10E3px; + margin: -456.8px; + margin: -0.0px; +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,NumberLiteral(Unit)), + Declaration(PropertyName,NumberLiteral(Unit)), + Declaration(PropertyName,NumberLiteral(Unit)), + Declaration(PropertyName,NumberLiteral(Unit)), + Declaration(PropertyName,NumberLiteral(Unit))))) + +# Binary arithmetic operators + +a { + width: calc(100% - 80px); + aspect-ratio: 1/2; + font-size: calc(10px + (56 - 10) * ((100vw - 320px) / (1920 - 320))); +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,CallExpression(Callee,ArgList(BinaryExpression(NumberLiteral(Unit),BinOp,NumberLiteral(Unit))))), + Declaration(PropertyName,BinaryExpression(NumberLiteral,BinOp,NumberLiteral)), + Declaration(PropertyName,CallExpression(Callee,ArgList( + BinaryExpression(BinaryExpression(NumberLiteral(Unit),BinOp,ParenthesizedValue( + BinaryExpression(NumberLiteral,BinOp,NumberLiteral))),BinOp,ParenthesizedValue( + BinaryExpression(ParenthesizedValue(BinaryExpression(NumberLiteral(Unit),BinOp,NumberLiteral(Unit))),BinOp, + ParenthesizedValue(BinaryExpression(NumberLiteral,BinOp,NumberLiteral))))))))))) + +# Strings + +a { + b: ''; + c: '\'hi\''; +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block(Declaration(PropertyName,StringLiteral),Declaration(PropertyName,StringLiteral)))) + +# URLs + +a { + b: url(http://something-else?foo=bar); + c: url(); +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,CallLiteral(CallTag,ParenthesizedContent)), + Declaration(PropertyName,CallLiteral(CallTag))))) + +# Important declarations + +a { + b: c !important; +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block(Declaration(PropertyName,ValueName,Important)))) + +# Comments right after numbers + +a { + shape-outside: circle(20em/*=*/at 50% 50%); + shape-outside: inset(1em, 1em, 1em, 1em); +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,CallExpression(Callee,ArgList(NumberLiteral(Unit),Comment,ValueName,NumberLiteral(Unit),NumberLiteral(Unit)))), + Declaration(PropertyName,CallExpression(Callee,ArgList(NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit),NumberLiteral(Unit))))))) + +# Unfinished rule + +a { foo: 2 + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block(Declaration(PropertyName,NumberLiteral),⚠))) + +# Variable names + +foo { + --my-variable: white; + color: var(--my-variable); +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(VariableName,ValueName), + Declaration(PropertyName,CallExpression(Callee,ArgList(VariableName)))))) + +# Trailing comma + +div { color: var(--c,) } + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,CallExpression(Callee,ArgList(VariableName)))))) + +# Space before colon + +div { + color : red; + .x :active { + color : blue; + } +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,ValueName), + RuleSet(DescendantSelector(ClassSelector(ClassName),PseudoClassSelector(PseudoClassName)),Block( + Declaration(PropertyName,ValueName)))))) + +# Empty value + +p { + --var-name: ; +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block(Declaration(VariableName)))) + +# Bracketed values + +div { + --myvar: [ some: value; ] +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(VariableName,BracketedValue("[", ValueName, ":", ValueName, ";", "]"))))) + +# Call to variables + +.foo { + box-shadow: --shadow(blue); +} + +==> + +StyleSheet(RuleSet(ClassSelector(ClassName),Block( + Declaration(PropertyName,CallExpression(VariableName,ArgList(ValueName)))))) diff --git a/node_modules/@lezer/css/test/selector.txt b/node_modules/@lezer/css/test/selector.txt new file mode 100644 index 0000000000..c765c5b036 --- /dev/null +++ b/node_modules/@lezer/css/test/selector.txt @@ -0,0 +1,150 @@ +# Universal selectors + +* {} +div * {} + +==> + +StyleSheet( + RuleSet(UniversalSelector,Block), + RuleSet(DescendantSelector(TagSelector(TagName),UniversalSelector),Block)) + +# Type selectors + +div, span {} +h1, h2, h3, h4 {} + +==> + +StyleSheet( + RuleSet(TagSelector(TagName),TagSelector(TagName),Block), + RuleSet(TagSelector(TagName),TagSelector(TagName),TagSelector(TagName),TagSelector(TagName),Block)) + +# Class selectors + +.class-a {} +div.class-b, .class-c.class-d {} + +==> + +StyleSheet( + RuleSet(ClassSelector(ClassName),Block), + RuleSet(ClassSelector(TagSelector(TagName),ClassName),ClassSelector(ClassSelector(ClassName),ClassName),Block)) + +# Id selectors + +#some-id, a#another-id {} + +==> + +StyleSheet(RuleSet(IdSelector(IdName),IdSelector(TagSelector(TagName),IdName),Block)) + +# Attribute selectors + +[a] {} +[b=c] {} +[d~=e] {} +a[b] {} + +==> + +StyleSheet( + RuleSet(AttributeSelector(AttributeName),Block), + RuleSet(AttributeSelector(AttributeName,MatchOp,ValueName),Block), + RuleSet(AttributeSelector(AttributeName,MatchOp,ValueName),Block), + RuleSet(AttributeSelector(TagSelector(TagName),AttributeName),Block)) + +# Pseudo-class selectors + +a:hover {} +:nth-child(2) {} + +==> + +StyleSheet( + RuleSet(PseudoClassSelector(TagSelector(TagName),":",PseudoClassName),Block), + RuleSet(PseudoClassSelector(":",PseudoClassName,ArgList(NumberLiteral)),Block)) + +# Pseudo-element selectors + +a::first-line {} + +==> + +StyleSheet(RuleSet(PseudoClassSelector(TagSelector(TagName),"::",PseudoClassName),Block)) + +# Child selectors + +a > b {} +c > d > e {} + +==> + +StyleSheet( + RuleSet(ChildSelector(TagSelector(TagName),ChildOp,TagSelector(TagName)),Block), + RuleSet(ChildSelector(ChildSelector(TagSelector(TagName),ChildOp,TagSelector(TagName)),ChildOp,TagSelector(TagName)),Block)) + +# Descendant selectors + +a b {} +c d e {} + +==> + +StyleSheet( + RuleSet(DescendantSelector(TagSelector(TagName),TagSelector(TagName)),Block), + RuleSet(DescendantSelector(DescendantSelector(TagSelector(TagName),TagSelector(TagName)),TagSelector(TagName)),Block)) + +# Nesting selectors + +a { + &.b {} + & c {} + c & {} + & > d {} +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + RuleSet(ClassSelector(NestingSelector,ClassName),Block), + RuleSet(DescendantSelector(NestingSelector,TagSelector(TagName)),Block), + RuleSet(DescendantSelector(TagSelector(TagName), NestingSelector),Block), + RuleSet(ChildSelector(NestingSelector,ChildOp,TagSelector(TagName)),Block)))) + +# Relative selectors + +a { + p {} + > f {} + + g {} +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + RuleSet(TagSelector(TagName),Block), + RuleSet(ChildSelector(ChildOp,TagSelector(TagName)),Block), + RuleSet(SiblingSelector(SiblingOp,TagSelector(TagName)),Block)))) + +# Sibling selectors + +a.b ~ c.d {} +.e.f + .g.h {} + +==> + +StyleSheet( + RuleSet(SiblingSelector(ClassSelector(TagSelector(TagName),ClassName),SiblingOp,ClassSelector(TagSelector(TagName),ClassName)),Block), + RuleSet(SiblingSelector(ClassSelector(ClassSelector(ClassName),ClassName),SiblingOp,ClassSelector(ClassSelector(ClassName),ClassName)),Block)) + +# The :not selector + +a:not(:hover) {} +.b:not(c > .d) {} + +==> + +StyleSheet( + RuleSet(PseudoClassSelector(TagSelector(TagName),":",PseudoClassName,ArgList(PseudoClassSelector(":",PseudoClassName))),Block), + RuleSet(PseudoClassSelector(ClassSelector(ClassName),":",PseudoClassName,ArgList(ChildSelector(TagSelector(TagName),ChildOp,ClassSelector(ClassName)))),Block)) diff --git a/node_modules/@lezer/css/test/statements.txt b/node_modules/@lezer/css/test/statements.txt new file mode 100644 index 0000000000..0d10728136 --- /dev/null +++ b/node_modules/@lezer/css/test/statements.txt @@ -0,0 +1,214 @@ +# Empty stylesheets + +/* Just a comment */ + +==> + +StyleSheet(Comment) + +# Import statements + +@import url("fineprint.css") print; +@import url("bluish.css") speech; +@import 'custom.css'; +@import url("chrome://communicator/skin/"); +@import "common.css" screen; +@import "reset.css" layer(framework.component); +@import "components.css" layer screen; + +==> + +StyleSheet( + ImportStatement(import,CallLiteral(CallTag,StringLiteral),KeywordQuery), + ImportStatement(import,CallLiteral(CallTag,StringLiteral),KeywordQuery), + ImportStatement(import,StringLiteral), + ImportStatement(import,CallLiteral(CallTag,StringLiteral)), + ImportStatement(import,StringLiteral,KeywordQuery), + ImportStatement(import,StringLiteral,Layer(layer,LayerName,LayerName)), + ImportStatement(import,StringLiteral,Layer(layer),KeywordQuery)) + +# Namespace statements + +/* Default namespace */ +@namespace url(XML-namespace-URL); +@namespace "XML-namespace-URL"; +@namespace url(http://www.w3.org/1999/xhtml); +@namespace svg url(http://www.w3.org/2000/svg); + +/* Prefixed namespace */ +@namespace prefix url(XML-namespace-URL); +@namespace prefix "XML-namespace-URL"; + +==> + +StyleSheet( + Comment, + NamespaceStatement(namespace,CallLiteral(CallTag,ParenthesizedContent)), + NamespaceStatement(namespace,StringLiteral), + NamespaceStatement(namespace,CallLiteral(CallTag,ParenthesizedContent)), + NamespaceStatement(namespace,NamespaceName,CallLiteral(CallTag,ParenthesizedContent)), + Comment, + NamespaceStatement(namespace,NamespaceName,CallLiteral(CallTag,ParenthesizedContent)), + NamespaceStatement(namespace,NamespaceName,StringLiteral)) + +# Keyframes statements + +@keyframes important1 { + from { margin-top: 50px; } + 50%, 60% { margin-top: 150px !important; } /* ignored */ + to { margin-top: 100px; } +} + +==> + +StyleSheet(KeyframesStatement(keyframes,KeyframeName,KeyframeList( + KeyframeSelector(KeyframeRangeName),Block(Declaration(PropertyName,NumberLiteral(Unit))), + KeyframeSelector(NumberLiteral(Unit)),KeyframeSelector(NumberLiteral(Unit)),Block( + Declaration(PropertyName,NumberLiteral(Unit),Important)), + Comment, + KeyframeSelector(KeyframeRangeName),Block(Declaration(PropertyName,NumberLiteral(Unit)))))) + +# Keyframes statements with range + +@keyframes anim-1 { + entry 0% { margin-top: 50px; } + entry 100% { margin-top: 50px; } + exit 0% { margin-top: 50px; } + exit 100% { margin-top: 50px; } +} + +==> + +StyleSheet(KeyframesStatement(keyframes,KeyframeName,KeyframeList( + KeyframeSelector(KeyframeRangeName,NumberLiteral(Unit)),Block(Declaration(PropertyName,NumberLiteral(Unit))), + KeyframeSelector(KeyframeRangeName,NumberLiteral(Unit)),Block(Declaration(PropertyName,NumberLiteral(Unit))), + KeyframeSelector(KeyframeRangeName,NumberLiteral(Unit)),Block(Declaration(PropertyName,NumberLiteral(Unit))), + KeyframeSelector(KeyframeRangeName,NumberLiteral(Unit)),Block(Declaration(PropertyName,NumberLiteral(Unit)))))) + +# Keyframes statements with range and multiple keyframe selectors + +@keyframes fade-in-out-animation { + entry 0%, exit 100% { opacity: 0 } + entry 100%, exit 0% { opacity: 1 } +} + +==> + +StyleSheet(KeyframesStatement(keyframes,KeyframeName,KeyframeList( + KeyframeSelector(KeyframeRangeName,NumberLiteral(Unit)),KeyframeSelector(KeyframeRangeName,NumberLiteral(Unit)),Block( + Declaration(PropertyName,NumberLiteral)), + KeyframeSelector(KeyframeRangeName,NumberLiteral(Unit)),KeyframeSelector(KeyframeRangeName,NumberLiteral(Unit)),Block( + Declaration(PropertyName,NumberLiteral))))) + +# Media statements + +@media screen and (min-width: 30em) and (orientation: landscape) {} +@media (min-height: 680px), screen and (orientation: portrait) {} +@media not all and (monochrome) {} +@media only screen {} +@media (10em <= width < 30em) {} + +==> + +StyleSheet( + MediaStatement(media,BinaryQuery(BinaryQuery(KeywordQuery,LogicOp,FeatureQuery(FeatureName,NumberLiteral(Unit))),LogicOp, + FeatureQuery(FeatureName,ValueName)),Block), + MediaStatement(media,FeatureQuery(FeatureName,NumberLiteral(Unit)),BinaryQuery(KeywordQuery,LogicOp,FeatureQuery(FeatureName,ValueName)),Block), + MediaStatement(media,UnaryQuery(UnaryQueryOp,BinaryQuery(KeywordQuery,LogicOp,ParenthesizedQuery(KeywordQuery))),Block), + MediaStatement(media,UnaryQuery(UnaryQueryOp,KeywordQuery),Block), + MediaStatement(media,ComparisonQuery(NumberLiteral(Unit),CompareOp,FeatureName,CompareOp,NumberLiteral(Unit)),Block)) + +# Supports statements + +@supports (animation-name: test) { + div { animation-name: test; } +} +@supports (transform-style: preserve) or (-moz-transform-style: preserve) {} +@supports not ((text-align-last: justify) or (-moz-text-align-last: justify)) {} +@supports not selector(:matches(a, b)) {} + +==> + +StyleSheet( + SupportsStatement(supports,FeatureQuery(FeatureName,ValueName),Block(RuleSet(TagSelector(TagName),Block(Declaration(PropertyName,ValueName))))), + SupportsStatement(supports,BinaryQuery(FeatureQuery(FeatureName,ValueName),LogicOp,FeatureQuery(FeatureName,ValueName)),Block), + SupportsStatement(supports,UnaryQuery(UnaryQueryOp,ParenthesizedQuery( + BinaryQuery(FeatureQuery(FeatureName,ValueName),LogicOp,FeatureQuery(FeatureName,ValueName)))),Block), + SupportsStatement(supports,UnaryQuery(UnaryQueryOp,SelectorQuery(selector,ParenthesizedSelector(PseudoClassSelector(PseudoClassName,ArgList(TagSelector(TagName),TagSelector(TagName)))))),Block)) + +# Charset statements + +@charset "utf-8"; + +==> + +StyleSheet(CharsetStatement(charset,StringLiteral)) + +# Other at-statements + +@font-face { + font-family: "Open Sans"; + src: url("/a") format("woff2"), url("/b/c") format("woff"); +} + +==> + +StyleSheet(AtRule(AtKeyword,Block( + Declaration(PropertyName,StringLiteral), + Declaration(PropertyName,CallLiteral(CallTag,StringLiteral),CallExpression(Callee,ArgList(StringLiteral)), + CallLiteral(CallTag,StringLiteral),CallExpression(Callee,ArgList(StringLiteral)))))) + +# Unterminated Comment + +p {} +/* +div {} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block),Comment) + +# Escaped identifiers + +#foo\ bar { + --weird\\var: 5px; + width: var(--weird\\var); + c\6f lor: b\6c ue; +} +==> + +StyleSheet(RuleSet(IdSelector(IdName),Block( + Declaration(VariableName,NumberLiteral(Unit)), + Declaration(PropertyName,CallExpression(Callee,ArgList(VariableName))), + Declaration(PropertyName, ValueName)))) + +# Scope + +@scope { .x {} } +@scope (div) {} +@scope (.a) to (.b) {} + +==> + +StyleSheet( + ScopeStatement(scope,Block(RuleSet(ClassSelector(ClassName),Block))), + ScopeStatement(scope,ParenthesizedSelector(TagSelector(TagName)),Block), + ScopeStatement(scope,ParenthesizedSelector(ClassSelector(ClassName)),to,ParenthesizedSelector(ClassSelector(ClassName)),Block)) + +# If Expressions + +p { + background-color: if( + style(--color: white): black; + supports(foo: bar): red; + else: pink + ); +} + +==> + +StyleSheet(RuleSet(TagSelector(TagName),Block( + Declaration(PropertyName,IfExpression(if,ArgList( + IfBranch(CallQuery(QueryCallee,ArgList(FeatureName,ValueName)),ValueName), + IfBranch(CallQuery(QueryCallee,ArgList(FeatureName,ValueName)),ValueName), + IfBranch(KeywordQuery,ValueName))))))) diff --git a/node_modules/@lezer/css/test/test-css.js b/node_modules/@lezer/css/test/test-css.js new file mode 100644 index 0000000000..0fbd5690e6 --- /dev/null +++ b/node_modules/@lezer/css/test/test-css.js @@ -0,0 +1,16 @@ +import {parser} from "../dist/index.js" +import {fileTests} from "@lezer/generator/dist/test" + +import * as fs from "fs" +import * as path from "path" +import {fileURLToPath} from "url" +let caseDir = path.dirname(fileURLToPath(import.meta.url)) + +for (let file of fs.readdirSync(caseDir)) { + if (!/\.txt$/.test(file)) continue + let name = /^[^\.]*/.exec(file)[0] + describe(name, () => { + for (let {name, run} of fileTests(fs.readFileSync(path.join(caseDir, file), "utf8"), file)) + it(name, () => run(parser)) + }) +} diff --git a/node_modules/@lezer/highlight/LICENSE b/node_modules/@lezer/highlight/LICENSE new file mode 100644 index 0000000000..c21df7e44f --- /dev/null +++ b/node_modules/@lezer/highlight/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (C) 2018 by Marijn Haverbekeand others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/@lezer/highlight/README.md b/node_modules/@lezer/highlight/README.md new file mode 100644 index 0000000000..e6309ee214 --- /dev/null +++ b/node_modules/@lezer/highlight/README.md @@ -0,0 +1,14 @@ +# @lezer/highlight + +[ [**WEBSITE**](http://lezer.codemirror.net) | [**ISSUES**](https://github.com/lezer-parser/lezer/issues) | [**FORUM**](https://discuss.codemirror.net/c/lezer) | [**CHANGELOG**](https://github.com/lezer-parser/highlight/blob/master/CHANGELOG.md) ] + +[Lezer](https://lezer.codemirror.net/) is an incremental parser system +intended for use in an editor or similar system. + +@lezer/highlight provides a syntax highlighting framework for Lezer +parse trees. + +Its programming interface is documented on [the +website](https://lezer.codemirror.net/docs/ref/#highlight). + +This code is licensed under an MIT license. diff --git a/node_modules/@lezer/highlight/dist/index.cjs b/node_modules/@lezer/highlight/dist/index.cjs new file mode 100644 index 0000000000..e7fd1f1d21 --- /dev/null +++ b/node_modules/@lezer/highlight/dist/index.cjs @@ -0,0 +1,915 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var common = require('@lezer/common'); + +let nextTagID = 0; +/** +Highlighting tags are markers that denote a highlighting category. +They are [associated](#highlight.styleTags) with parts of a syntax +tree by a language mode, and then mapped to an actual CSS style by +a [highlighter](#highlight.Highlighter). + +Because syntax tree node types and highlight styles have to be +able to talk the same language, CodeMirror uses a mostly _closed_ +[vocabulary](#highlight.tags) of syntax tags (as opposed to +traditional open string-based systems, which make it hard for +highlighting themes to cover all the tokens produced by the +various languages). + +It _is_ possible to [define](#highlight.Tag^define) your own +highlighting tags for system-internal use (where you control both +the language package and the highlighter), but such tags will not +be picked up by regular highlighters (though you can derive them +from standard tags to allow highlighters to fall back to those). +*/ +class Tag { + /** + @internal + */ + constructor( + /** + The optional name of the base tag @internal + */ + name, + /** + The set of this tag and all its parent tags, starting with + this one itself and sorted in order of decreasing specificity. + */ + set, + /** + The base unmodified tag that this one is based on, if it's + modified @internal + */ + base, + /** + The modifiers applied to this.base @internal + */ + modified) { + this.name = name; + this.set = set; + this.base = base; + this.modified = modified; + /** + @internal + */ + this.id = nextTagID++; + } + toString() { + let { name } = this; + for (let mod of this.modified) + if (mod.name) + name = `${mod.name}(${name})`; + return name; + } + static define(nameOrParent, parent) { + let name = typeof nameOrParent == "string" ? nameOrParent : "?"; + if (nameOrParent instanceof Tag) + parent = nameOrParent; + if (parent === null || parent === void 0 ? void 0 : parent.base) + throw new Error("Can not derive from a modified tag"); + let tag = new Tag(name, [], null, []); + tag.set.push(tag); + if (parent) + for (let t of parent.set) + tag.set.push(t); + return tag; + } + /** + Define a tag _modifier_, which is a function that, given a tag, + will return a tag that is a subtag of the original. Applying the + same modifier to a twice tag will return the same value (`m1(t1) + == m1(t1)`) and applying multiple modifiers will, regardless or + order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`). + + When multiple modifiers are applied to a given base tag, each + smaller set of modifiers is registered as a parent, so that for + example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`, + `m1(m3(t1)`, and so on. + */ + static defineModifier(name) { + let mod = new Modifier(name); + return (tag) => { + if (tag.modified.indexOf(mod) > -1) + return tag; + return Modifier.get(tag.base || tag, tag.modified.concat(mod).sort((a, b) => a.id - b.id)); + }; + } +} +let nextModifierID = 0; +class Modifier { + constructor(name) { + this.name = name; + this.instances = []; + this.id = nextModifierID++; + } + static get(base, mods) { + if (!mods.length) + return base; + let exists = mods[0].instances.find(t => t.base == base && sameArray(mods, t.modified)); + if (exists) + return exists; + let set = [], tag = new Tag(base.name, set, base, mods); + for (let m of mods) + m.instances.push(tag); + let configs = powerSet(mods); + for (let parent of base.set) + if (!parent.modified.length) + for (let config of configs) + set.push(Modifier.get(parent, config)); + return tag; + } +} +function sameArray(a, b) { + return a.length == b.length && a.every((x, i) => x == b[i]); +} +function powerSet(array) { + let sets = [[]]; + for (let i = 0; i < array.length; i++) { + for (let j = 0, e = sets.length; j < e; j++) { + sets.push(sets[j].concat(array[i])); + } + } + return sets.sort((a, b) => b.length - a.length); +} +/** +This function is used to add a set of tags to a language syntax +via [`NodeSet.extend`](#common.NodeSet.extend) or +[`LRParser.configure`](#lr.LRParser.configure). + +The argument object maps node selectors to [highlighting +tags](#highlight.Tag) or arrays of tags. + +Node selectors may hold one or more (space-separated) node paths. +Such a path can be a [node name](#common.NodeType.name), or +multiple node names (or `*` wildcards) separated by slash +characters, as in `"Block/Declaration/VariableName"`. Such a path +matches the final node but only if its direct parent nodes are the +other nodes mentioned. A `*` in such a path matches any parent, +but only a single level—wildcards that match multiple parents +aren't supported, both for efficiency reasons and because Lezer +trees make it rather hard to reason about what they would match.) + +A path can be ended with `/...` to indicate that the tag assigned +to the node should also apply to all child nodes, even if they +match their own style (by default, only the innermost style is +used). + +When a path ends in `!`, as in `Attribute!`, no further matching +happens for the node's child nodes, and the entire node gets the +given style. + +In this notation, node names that contain `/`, `!`, `*`, or `...` +must be quoted as JSON strings. + +For example: + +```javascript +parser.withProps( + styleTags({ + // Style Number and BigNumber nodes + "Number BigNumber": tags.number, + // Style Escape nodes whose parent is String + "String/Escape": tags.escape, + // Style anything inside Attributes nodes + "Attributes!": tags.meta, + // Add a style to all content inside Italic nodes + "Italic/...": tags.emphasis, + // Style InvalidString nodes as both `string` and `invalid` + "InvalidString": [tags.string, tags.invalid], + // Style the node named "/" as punctuation + '"/"': tags.punctuation + }) +) +``` +*/ +function styleTags(spec) { + let byName = Object.create(null); + for (let prop in spec) { + let tags = spec[prop]; + if (!Array.isArray(tags)) + tags = [tags]; + for (let part of prop.split(" ")) + if (part) { + let pieces = [], mode = 2 /* Mode.Normal */, rest = part; + for (let pos = 0;;) { + if (rest == "..." && pos > 0 && pos + 3 == part.length) { + mode = 1 /* Mode.Inherit */; + break; + } + let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest); + if (!m) + throw new RangeError("Invalid path: " + part); + pieces.push(m[0] == "*" ? "" : m[0][0] == '"' ? JSON.parse(m[0]) : m[0]); + pos += m[0].length; + if (pos == part.length) + break; + let next = part[pos++]; + if (pos == part.length && next == "!") { + mode = 0 /* Mode.Opaque */; + break; + } + if (next != "/") + throw new RangeError("Invalid path: " + part); + rest = part.slice(pos); + } + let last = pieces.length - 1, inner = pieces[last]; + if (!inner) + throw new RangeError("Invalid path: " + part); + let rule = new Rule(tags, mode, last > 0 ? pieces.slice(0, last) : null); + byName[inner] = rule.sort(byName[inner]); + } + } + return ruleNodeProp.add(byName); +} +const ruleNodeProp = new common.NodeProp(); +class Rule { + constructor(tags, mode, context, next) { + this.tags = tags; + this.mode = mode; + this.context = context; + this.next = next; + } + get opaque() { return this.mode == 0 /* Mode.Opaque */; } + get inherit() { return this.mode == 1 /* Mode.Inherit */; } + sort(other) { + if (!other || other.depth < this.depth) { + this.next = other; + return this; + } + other.next = this.sort(other.next); + return other; + } + get depth() { return this.context ? this.context.length : 0; } +} +Rule.empty = new Rule([], 2 /* Mode.Normal */, null); +/** +Define a [highlighter](#highlight.Highlighter) from an array of +tag/class pairs. Classes associated with more specific tags will +take precedence. +*/ +function tagHighlighter(tags, options) { + let map = Object.create(null); + for (let style of tags) { + if (!Array.isArray(style.tag)) + map[style.tag.id] = style.class; + else + for (let tag of style.tag) + map[tag.id] = style.class; + } + let { scope, all = null } = options || {}; + return { + style: (tags) => { + let cls = all; + for (let tag of tags) { + for (let sub of tag.set) { + let tagClass = map[sub.id]; + if (tagClass) { + cls = cls ? cls + " " + tagClass : tagClass; + break; + } + } + } + return cls; + }, + scope + }; +} +function highlightTags(highlighters, tags) { + let result = null; + for (let highlighter of highlighters) { + let value = highlighter.style(tags); + if (value) + result = result ? result + " " + value : value; + } + return result; +} +/** +Highlight the given [tree](#common.Tree) with the given +[highlighter](#highlight.Highlighter). Often, the higher-level +[`highlightCode`](#highlight.highlightCode) function is easier to +use. +*/ +function highlightTree(tree, highlighter, +/** +Assign styling to a region of the text. Will be called, in order +of position, for any ranges where more than zero classes apply. +`classes` is a space separated string of CSS classes. +*/ +putStyle, +/** +The start of the range to highlight. +*/ +from = 0, +/** +The end of the range. +*/ +to = tree.length) { + let builder = new HighlightBuilder(from, Array.isArray(highlighter) ? highlighter : [highlighter], putStyle); + builder.highlightRange(tree.cursor(), from, to, "", builder.highlighters); + builder.flush(to); +} +/** +Highlight the given tree with the given highlighter, calling +`putText` for every piece of text, either with a set of classes or +with the empty string when unstyled, and `putBreak` for every line +break. +*/ +function highlightCode(code, tree, highlighter, putText, putBreak, from = 0, to = code.length) { + let pos = from; + function writeTo(p, classes) { + if (p <= pos) + return; + for (let text = code.slice(pos, p), i = 0;;) { + let nextBreak = text.indexOf("\n", i); + let upto = nextBreak < 0 ? text.length : nextBreak; + if (upto > i) + putText(text.slice(i, upto), classes); + if (nextBreak < 0) + break; + putBreak(); + i = nextBreak + 1; + } + pos = p; + } + highlightTree(tree, highlighter, (from, to, classes) => { + writeTo(from, ""); + writeTo(to, classes); + }, from, to); + writeTo(to, ""); +} +class HighlightBuilder { + constructor(at, highlighters, span) { + this.at = at; + this.highlighters = highlighters; + this.span = span; + this.class = ""; + } + startSpan(at, cls) { + if (cls != this.class) { + this.flush(at); + if (at > this.at) + this.at = at; + this.class = cls; + } + } + flush(to) { + if (to > this.at && this.class) + this.span(this.at, to, this.class); + } + highlightRange(cursor, from, to, inheritedClass, highlighters) { + let { type, from: start, to: end } = cursor; + if (start >= to || end <= from) + return; + if (type.isTop) + highlighters = this.highlighters.filter(h => !h.scope || h.scope(type)); + let cls = inheritedClass; + let rule = getStyleTags(cursor) || Rule.empty; + let tagCls = highlightTags(highlighters, rule.tags); + if (tagCls) { + if (cls) + cls += " "; + cls += tagCls; + if (rule.mode == 1 /* Mode.Inherit */) + inheritedClass += (inheritedClass ? " " : "") + tagCls; + } + this.startSpan(Math.max(from, start), cls); + if (rule.opaque) + return; + let mounted = cursor.tree && cursor.tree.prop(common.NodeProp.mounted); + if (mounted && mounted.overlay) { + let inner = cursor.node.enter(mounted.overlay[0].from + start, 1); + let innerHighlighters = this.highlighters.filter(h => !h.scope || h.scope(mounted.tree.type)); + let hasChild = cursor.firstChild(); + for (let i = 0, pos = start;; i++) { + let next = i < mounted.overlay.length ? mounted.overlay[i] : null; + let nextPos = next ? next.from + start : end; + let rangeFrom = Math.max(from, pos), rangeTo = Math.min(to, nextPos); + if (rangeFrom < rangeTo && hasChild) { + while (cursor.from < rangeTo) { + this.highlightRange(cursor, rangeFrom, rangeTo, inheritedClass, highlighters); + this.startSpan(Math.min(rangeTo, cursor.to), cls); + if (cursor.to >= nextPos || !cursor.nextSibling()) + break; + } + } + if (!next || nextPos > to) + break; + pos = next.to + start; + if (pos > from) { + this.highlightRange(inner.cursor(), Math.max(from, next.from + start), Math.min(to, pos), "", innerHighlighters); + this.startSpan(Math.min(to, pos), cls); + } + } + if (hasChild) + cursor.parent(); + } + else if (cursor.firstChild()) { + if (mounted) + inheritedClass = ""; + do { + if (cursor.to <= from) + continue; + if (cursor.from >= to) + break; + this.highlightRange(cursor, from, to, inheritedClass, highlighters); + this.startSpan(Math.min(to, cursor.to), cls); + } while (cursor.nextSibling()); + cursor.parent(); + } + } +} +/** +Match a syntax node's [highlight rules](#highlight.styleTags). If +there's a match, return its set of tags, and whether it is +opaque (uses a `!`) or applies to all child nodes (`/...`). +*/ +function getStyleTags(node) { + let rule = node.type.prop(ruleNodeProp); + while (rule && rule.context && !node.matchContext(rule.context)) + rule = rule.next; + return rule || null; +} +const t = Tag.define; +const comment = t(), name = t(), typeName = t(name), propertyName = t(name), literal = t(), string = t(literal), number = t(literal), content = t(), heading = t(content), keyword = t(), operator = t(), punctuation = t(), bracket = t(punctuation), meta = t(); +/** +The default set of highlighting [tags](#highlight.Tag). + +This collection is heavily biased towards programming languages, +and necessarily incomplete. A full ontology of syntactic +constructs would fill a stack of books, and be impractical to +write themes for. So try to make do with this set. If all else +fails, [open an +issue](https://github.com/codemirror/codemirror.next) to propose a +new tag, or [define](#highlight.Tag^define) a local custom tag for +your use case. + +Note that it is not obligatory to always attach the most specific +tag possible to an element—if your grammar can't easily +distinguish a certain type of element (such as a local variable), +it is okay to style it as its more general variant (a variable). + +For tags that extend some parent tag, the documentation links to +the parent. +*/ +const tags = { + /** + A comment. + */ + comment, + /** + A line [comment](#highlight.tags.comment). + */ + lineComment: t(comment), + /** + A block [comment](#highlight.tags.comment). + */ + blockComment: t(comment), + /** + A documentation [comment](#highlight.tags.comment). + */ + docComment: t(comment), + /** + Any kind of identifier. + */ + name, + /** + The [name](#highlight.tags.name) of a variable. + */ + variableName: t(name), + /** + A type [name](#highlight.tags.name). + */ + typeName: typeName, + /** + A tag name (subtag of [`typeName`](#highlight.tags.typeName)). + */ + tagName: t(typeName), + /** + A property or field [name](#highlight.tags.name). + */ + propertyName: propertyName, + /** + An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)). + */ + attributeName: t(propertyName), + /** + The [name](#highlight.tags.name) of a class. + */ + className: t(name), + /** + A label [name](#highlight.tags.name). + */ + labelName: t(name), + /** + A namespace [name](#highlight.tags.name). + */ + namespace: t(name), + /** + The [name](#highlight.tags.name) of a macro. + */ + macroName: t(name), + /** + A literal value. + */ + literal, + /** + A string [literal](#highlight.tags.literal). + */ + string, + /** + A documentation [string](#highlight.tags.string). + */ + docString: t(string), + /** + A character literal (subtag of [string](#highlight.tags.string)). + */ + character: t(string), + /** + An attribute value (subtag of [string](#highlight.tags.string)). + */ + attributeValue: t(string), + /** + A number [literal](#highlight.tags.literal). + */ + number, + /** + An integer [number](#highlight.tags.number) literal. + */ + integer: t(number), + /** + A floating-point [number](#highlight.tags.number) literal. + */ + float: t(number), + /** + A boolean [literal](#highlight.tags.literal). + */ + bool: t(literal), + /** + Regular expression [literal](#highlight.tags.literal). + */ + regexp: t(literal), + /** + An escape [literal](#highlight.tags.literal), for example a + backslash escape in a string. + */ + escape: t(literal), + /** + A color [literal](#highlight.tags.literal). + */ + color: t(literal), + /** + A URL [literal](#highlight.tags.literal). + */ + url: t(literal), + /** + A language keyword. + */ + keyword, + /** + The [keyword](#highlight.tags.keyword) for the self or this + object. + */ + self: t(keyword), + /** + The [keyword](#highlight.tags.keyword) for null. + */ + null: t(keyword), + /** + A [keyword](#highlight.tags.keyword) denoting some atomic value. + */ + atom: t(keyword), + /** + A [keyword](#highlight.tags.keyword) that represents a unit. + */ + unit: t(keyword), + /** + A modifier [keyword](#highlight.tags.keyword). + */ + modifier: t(keyword), + /** + A [keyword](#highlight.tags.keyword) that acts as an operator. + */ + operatorKeyword: t(keyword), + /** + A control-flow related [keyword](#highlight.tags.keyword). + */ + controlKeyword: t(keyword), + /** + A [keyword](#highlight.tags.keyword) that defines something. + */ + definitionKeyword: t(keyword), + /** + A [keyword](#highlight.tags.keyword) related to defining or + interfacing with modules. + */ + moduleKeyword: t(keyword), + /** + An operator. + */ + operator, + /** + An [operator](#highlight.tags.operator) that dereferences something. + */ + derefOperator: t(operator), + /** + Arithmetic-related [operator](#highlight.tags.operator). + */ + arithmeticOperator: t(operator), + /** + Logical [operator](#highlight.tags.operator). + */ + logicOperator: t(operator), + /** + Bit [operator](#highlight.tags.operator). + */ + bitwiseOperator: t(operator), + /** + Comparison [operator](#highlight.tags.operator). + */ + compareOperator: t(operator), + /** + [Operator](#highlight.tags.operator) that updates its operand. + */ + updateOperator: t(operator), + /** + [Operator](#highlight.tags.operator) that defines something. + */ + definitionOperator: t(operator), + /** + Type-related [operator](#highlight.tags.operator). + */ + typeOperator: t(operator), + /** + Control-flow [operator](#highlight.tags.operator). + */ + controlOperator: t(operator), + /** + Program or markup punctuation. + */ + punctuation, + /** + [Punctuation](#highlight.tags.punctuation) that separates + things. + */ + separator: t(punctuation), + /** + Bracket-style [punctuation](#highlight.tags.punctuation). + */ + bracket, + /** + Angle [brackets](#highlight.tags.bracket) (usually `<` and `>` + tokens). + */ + angleBracket: t(bracket), + /** + Square [brackets](#highlight.tags.bracket) (usually `[` and `]` + tokens). + */ + squareBracket: t(bracket), + /** + Parentheses (usually `(` and `)` tokens). Subtag of + [bracket](#highlight.tags.bracket). + */ + paren: t(bracket), + /** + Braces (usually `{` and `}` tokens). Subtag of + [bracket](#highlight.tags.bracket). + */ + brace: t(bracket), + /** + Content, for example plain text in XML or markup documents. + */ + content, + /** + [Content](#highlight.tags.content) that represents a heading. + */ + heading, + /** + A level 1 [heading](#highlight.tags.heading). + */ + heading1: t(heading), + /** + A level 2 [heading](#highlight.tags.heading). + */ + heading2: t(heading), + /** + A level 3 [heading](#highlight.tags.heading). + */ + heading3: t(heading), + /** + A level 4 [heading](#highlight.tags.heading). + */ + heading4: t(heading), + /** + A level 5 [heading](#highlight.tags.heading). + */ + heading5: t(heading), + /** + A level 6 [heading](#highlight.tags.heading). + */ + heading6: t(heading), + /** + A prose [content](#highlight.tags.content) separator (such as a horizontal rule). + */ + contentSeparator: t(content), + /** + [Content](#highlight.tags.content) that represents a list. + */ + list: t(content), + /** + [Content](#highlight.tags.content) that represents a quote. + */ + quote: t(content), + /** + [Content](#highlight.tags.content) that is emphasized. + */ + emphasis: t(content), + /** + [Content](#highlight.tags.content) that is styled strong. + */ + strong: t(content), + /** + [Content](#highlight.tags.content) that is part of a link. + */ + link: t(content), + /** + [Content](#highlight.tags.content) that is styled as code or + monospace. + */ + monospace: t(content), + /** + [Content](#highlight.tags.content) that has a strike-through + style. + */ + strikethrough: t(content), + /** + Inserted text in a change-tracking format. + */ + inserted: t(), + /** + Deleted text. + */ + deleted: t(), + /** + Changed text. + */ + changed: t(), + /** + An invalid or unsyntactic element. + */ + invalid: t(), + /** + Metadata or meta-instruction. + */ + meta, + /** + [Metadata](#highlight.tags.meta) that applies to the entire + document. + */ + documentMeta: t(meta), + /** + [Metadata](#highlight.tags.meta) that annotates or adds + attributes to a given syntactic element. + */ + annotation: t(meta), + /** + Processing instruction or preprocessor directive. Subtag of + [meta](#highlight.tags.meta). + */ + processingInstruction: t(meta), + /** + [Modifier](#highlight.Tag^defineModifier) that indicates that a + given element is being defined. Expected to be used with the + various [name](#highlight.tags.name) tags. + */ + definition: Tag.defineModifier("definition"), + /** + [Modifier](#highlight.Tag^defineModifier) that indicates that + something is constant. Mostly expected to be used with + [variable names](#highlight.tags.variableName). + */ + constant: Tag.defineModifier("constant"), + /** + [Modifier](#highlight.Tag^defineModifier) used to indicate that + a [variable](#highlight.tags.variableName) or [property + name](#highlight.tags.propertyName) is being called or defined + as a function. + */ + function: Tag.defineModifier("function"), + /** + [Modifier](#highlight.Tag^defineModifier) that can be applied to + [names](#highlight.tags.name) to indicate that they belong to + the language's standard environment. + */ + standard: Tag.defineModifier("standard"), + /** + [Modifier](#highlight.Tag^defineModifier) that indicates a given + [names](#highlight.tags.name) is local to some scope. + */ + local: Tag.defineModifier("local"), + /** + A generic variant [modifier](#highlight.Tag^defineModifier) that + can be used to tag language-specific alternative variants of + some common tag. It is recommended for themes to define special + forms of at least the [string](#highlight.tags.string) and + [variable name](#highlight.tags.variableName) tags, since those + come up a lot. + */ + special: Tag.defineModifier("special") +}; +for (let name in tags) { + let val = tags[name]; + if (val instanceof Tag) + val.name = name; +} +/** +This is a highlighter that adds stable, predictable classes to +tokens, for styling with external CSS. + +The following tags are mapped to their name prefixed with `"tok-"` +(for example `"tok-comment"`): + +* [`link`](#highlight.tags.link) +* [`heading`](#highlight.tags.heading) +* [`emphasis`](#highlight.tags.emphasis) +* [`strong`](#highlight.tags.strong) +* [`keyword`](#highlight.tags.keyword) +* [`atom`](#highlight.tags.atom) +* [`bool`](#highlight.tags.bool) +* [`url`](#highlight.tags.url) +* [`labelName`](#highlight.tags.labelName) +* [`inserted`](#highlight.tags.inserted) +* [`deleted`](#highlight.tags.deleted) +* [`literal`](#highlight.tags.literal) +* [`string`](#highlight.tags.string) +* [`number`](#highlight.tags.number) +* [`variableName`](#highlight.tags.variableName) +* [`typeName`](#highlight.tags.typeName) +* [`namespace`](#highlight.tags.namespace) +* [`className`](#highlight.tags.className) +* [`macroName`](#highlight.tags.macroName) +* [`propertyName`](#highlight.tags.propertyName) +* [`operator`](#highlight.tags.operator) +* [`comment`](#highlight.tags.comment) +* [`meta`](#highlight.tags.meta) +* [`punctuation`](#highlight.tags.punctuation) +* [`invalid`](#highlight.tags.invalid) + +In addition, these mappings are provided: + +* [`regexp`](#highlight.tags.regexp), + [`escape`](#highlight.tags.escape), and + [`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string) + are mapped to `"tok-string2"` +* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName2"` +* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName tok-local"` +* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName tok-definition"` +* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName) + to `"tok-propertyName tok-definition"` +*/ +const classHighlighter = tagHighlighter([ + { tag: tags.link, class: "tok-link" }, + { tag: tags.heading, class: "tok-heading" }, + { tag: tags.emphasis, class: "tok-emphasis" }, + { tag: tags.strong, class: "tok-strong" }, + { tag: tags.keyword, class: "tok-keyword" }, + { tag: tags.atom, class: "tok-atom" }, + { tag: tags.bool, class: "tok-bool" }, + { tag: tags.url, class: "tok-url" }, + { tag: tags.labelName, class: "tok-labelName" }, + { tag: tags.inserted, class: "tok-inserted" }, + { tag: tags.deleted, class: "tok-deleted" }, + { tag: tags.literal, class: "tok-literal" }, + { tag: tags.string, class: "tok-string" }, + { tag: tags.number, class: "tok-number" }, + { tag: [tags.regexp, tags.escape, tags.special(tags.string)], class: "tok-string2" }, + { tag: tags.variableName, class: "tok-variableName" }, + { tag: tags.local(tags.variableName), class: "tok-variableName tok-local" }, + { tag: tags.definition(tags.variableName), class: "tok-variableName tok-definition" }, + { tag: tags.special(tags.variableName), class: "tok-variableName2" }, + { tag: tags.definition(tags.propertyName), class: "tok-propertyName tok-definition" }, + { tag: tags.typeName, class: "tok-typeName" }, + { tag: tags.namespace, class: "tok-namespace" }, + { tag: tags.className, class: "tok-className" }, + { tag: tags.macroName, class: "tok-macroName" }, + { tag: tags.propertyName, class: "tok-propertyName" }, + { tag: tags.operator, class: "tok-operator" }, + { tag: tags.comment, class: "tok-comment" }, + { tag: tags.meta, class: "tok-meta" }, + { tag: tags.invalid, class: "tok-invalid" }, + { tag: tags.punctuation, class: "tok-punctuation" } +]); + +exports.Tag = Tag; +exports.classHighlighter = classHighlighter; +exports.getStyleTags = getStyleTags; +exports.highlightCode = highlightCode; +exports.highlightTree = highlightTree; +exports.styleTags = styleTags; +exports.tagHighlighter = tagHighlighter; +exports.tags = tags; diff --git a/node_modules/@lezer/highlight/dist/index.d.cts b/node_modules/@lezer/highlight/dist/index.d.cts new file mode 100644 index 0000000000..670d899e00 --- /dev/null +++ b/node_modules/@lezer/highlight/dist/index.d.cts @@ -0,0 +1,621 @@ +import * as _lezer_common from '@lezer/common'; +import { NodeType, Tree, SyntaxNodeRef } from '@lezer/common'; + +/** +Highlighting tags are markers that denote a highlighting category. +They are [associated](#highlight.styleTags) with parts of a syntax +tree by a language mode, and then mapped to an actual CSS style by +a [highlighter](#highlight.Highlighter). + +Because syntax tree node types and highlight styles have to be +able to talk the same language, CodeMirror uses a mostly _closed_ +[vocabulary](#highlight.tags) of syntax tags (as opposed to +traditional open string-based systems, which make it hard for +highlighting themes to cover all the tokens produced by the +various languages). + +It _is_ possible to [define](#highlight.Tag^define) your own +highlighting tags for system-internal use (where you control both +the language package and the highlighter), but such tags will not +be picked up by regular highlighters (though you can derive them +from standard tags to allow highlighters to fall back to those). +*/ +declare class Tag { + /** + The set of this tag and all its parent tags, starting with + this one itself and sorted in order of decreasing specificity. + */ + readonly set: Tag[]; + /** + Define a new tag. If `parent` is given, the tag is treated as a + sub-tag of that parent, and + [highlighters](#highlight.tagHighlighter) that don't mention + this tag will try to fall back to the parent tag (or grandparent + tag, etc). + */ + static define(parent?: Tag): Tag; + /** + Define a tag _modifier_, which is a function that, given a tag, + will return a tag that is a subtag of the original. Applying the + same modifier to a twice tag will return the same value (`m1(t1) + == m1(t1)`) and applying multiple modifiers will, regardless or + order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`). + + When multiple modifiers are applied to a given base tag, each + smaller set of modifiers is registered as a parent, so that for + example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`, + `m1(m3(t1)`, and so on. + */ + static defineModifier(): (tag: Tag) => Tag; +} +/** +This function is used to add a set of tags to a language syntax +via [`NodeSet.extend`](#common.NodeSet.extend) or +[`LRParser.configure`](#lr.LRParser.configure). + +The argument object maps node selectors to [highlighting +tags](#highlight.Tag) or arrays of tags. + +Node selectors may hold one or more (space-separated) node paths. +Such a path can be a [node name](#common.NodeType.name), or +multiple node names (or `*` wildcards) separated by slash +characters, as in `"Block/Declaration/VariableName"`. Such a path +matches the final node but only if its direct parent nodes are the +other nodes mentioned. A `*` in such a path matches any parent, +but only a single level—wildcards that match multiple parents +aren't supported, both for efficiency reasons and because Lezer +trees make it rather hard to reason about what they would match.) + +A path can be ended with `/...` to indicate that the tag assigned +to the node should also apply to all child nodes, even if they +match their own style (by default, only the innermost style is +used). + +When a path ends in `!`, as in `Attribute!`, no further matching +happens for the node's child nodes, and the entire node gets the +given style. + +In this notation, node names that contain `/`, `!`, `*`, or `...` +must be quoted as JSON strings. + +For example: + +```javascript +parser.withProps( + styleTags({ + // Style Number and BigNumber nodes + "Number BigNumber": tags.number, + // Style Escape nodes whose parent is String + "String/Escape": tags.escape, + // Style anything inside Attributes nodes + "Attributes!": tags.meta, + // Add a style to all content inside Italic nodes + "Italic/...": tags.emphasis, + // Style InvalidString nodes as both `string` and `invalid` + "InvalidString": [tags.string, tags.invalid], + // Style the node named "/" as punctuation + '"/"': tags.punctuation + }) +) +``` +*/ +declare function styleTags(spec: { + [selector: string]: Tag | readonly Tag[]; +}): _lezer_common.NodePropSource; +/** +A highlighter defines a mapping from highlighting tags and +language scopes to CSS class names. They are usually defined via +[`tagHighlighter`](#highlight.tagHighlighter) or some wrapper +around that, but it is also possible to implement them from +scratch. +*/ +interface Highlighter { + /** + Get the set of classes that should be applied to the given set + of highlighting tags, or null if this highlighter doesn't assign + a style to the tags. + */ + style(tags: readonly Tag[]): string | null; + /** + When given, the highlighter will only be applied to trees on + whose [top](#common.NodeType.isTop) node this predicate returns + true. + */ + scope?(node: NodeType): boolean; +} +/** +Define a [highlighter](#highlight.Highlighter) from an array of +tag/class pairs. Classes associated with more specific tags will +take precedence. +*/ +declare function tagHighlighter(tags: readonly { + tag: Tag | readonly Tag[]; + class: string; +}[], options?: { + /** + By default, highlighters apply to the entire document. You can + scope them to a single language by providing the tree's + [top](#common.NodeType.isTop) node type here. + */ + scope?: (node: NodeType) => boolean; + /** + Add a style to _all_ tokens. Probably only useful in combination + with `scope`. + */ + all?: string; +}): Highlighter; +/** +Highlight the given [tree](#common.Tree) with the given +[highlighter](#highlight.Highlighter). Often, the higher-level +[`highlightCode`](#highlight.highlightCode) function is easier to +use. +*/ +declare function highlightTree(tree: Tree, highlighter: Highlighter | readonly Highlighter[], +/** +Assign styling to a region of the text. Will be called, in order +of position, for any ranges where more than zero classes apply. +`classes` is a space separated string of CSS classes. +*/ +putStyle: (from: number, to: number, classes: string) => void, +/** +The start of the range to highlight. +*/ +from?: number, +/** +The end of the range. +*/ +to?: number): void; +/** +Highlight the given tree with the given highlighter, calling +`putText` for every piece of text, either with a set of classes or +with the empty string when unstyled, and `putBreak` for every line +break. +*/ +declare function highlightCode(code: string, tree: Tree, highlighter: Highlighter | readonly Highlighter[], putText: (code: string, classes: string) => void, putBreak: () => void, from?: number, to?: number): void; +/** +Match a syntax node's [highlight rules](#highlight.styleTags). If +there's a match, return its set of tags, and whether it is +opaque (uses a `!`) or applies to all child nodes (`/...`). +*/ +declare function getStyleTags(node: SyntaxNodeRef): { + tags: readonly Tag[]; + opaque: boolean; + inherit: boolean; +} | null; +/** +The default set of highlighting [tags](#highlight.Tag). + +This collection is heavily biased towards programming languages, +and necessarily incomplete. A full ontology of syntactic +constructs would fill a stack of books, and be impractical to +write themes for. So try to make do with this set. If all else +fails, [open an +issue](https://github.com/codemirror/codemirror.next) to propose a +new tag, or [define](#highlight.Tag^define) a local custom tag for +your use case. + +Note that it is not obligatory to always attach the most specific +tag possible to an element—if your grammar can't easily +distinguish a certain type of element (such as a local variable), +it is okay to style it as its more general variant (a variable). + +For tags that extend some parent tag, the documentation links to +the parent. +*/ +declare const tags: { + /** + A comment. + */ + comment: Tag; + /** + A line [comment](#highlight.tags.comment). + */ + lineComment: Tag; + /** + A block [comment](#highlight.tags.comment). + */ + blockComment: Tag; + /** + A documentation [comment](#highlight.tags.comment). + */ + docComment: Tag; + /** + Any kind of identifier. + */ + name: Tag; + /** + The [name](#highlight.tags.name) of a variable. + */ + variableName: Tag; + /** + A type [name](#highlight.tags.name). + */ + typeName: Tag; + /** + A tag name (subtag of [`typeName`](#highlight.tags.typeName)). + */ + tagName: Tag; + /** + A property or field [name](#highlight.tags.name). + */ + propertyName: Tag; + /** + An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)). + */ + attributeName: Tag; + /** + The [name](#highlight.tags.name) of a class. + */ + className: Tag; + /** + A label [name](#highlight.tags.name). + */ + labelName: Tag; + /** + A namespace [name](#highlight.tags.name). + */ + namespace: Tag; + /** + The [name](#highlight.tags.name) of a macro. + */ + macroName: Tag; + /** + A literal value. + */ + literal: Tag; + /** + A string [literal](#highlight.tags.literal). + */ + string: Tag; + /** + A documentation [string](#highlight.tags.string). + */ + docString: Tag; + /** + A character literal (subtag of [string](#highlight.tags.string)). + */ + character: Tag; + /** + An attribute value (subtag of [string](#highlight.tags.string)). + */ + attributeValue: Tag; + /** + A number [literal](#highlight.tags.literal). + */ + number: Tag; + /** + An integer [number](#highlight.tags.number) literal. + */ + integer: Tag; + /** + A floating-point [number](#highlight.tags.number) literal. + */ + float: Tag; + /** + A boolean [literal](#highlight.tags.literal). + */ + bool: Tag; + /** + Regular expression [literal](#highlight.tags.literal). + */ + regexp: Tag; + /** + An escape [literal](#highlight.tags.literal), for example a + backslash escape in a string. + */ + escape: Tag; + /** + A color [literal](#highlight.tags.literal). + */ + color: Tag; + /** + A URL [literal](#highlight.tags.literal). + */ + url: Tag; + /** + A language keyword. + */ + keyword: Tag; + /** + The [keyword](#highlight.tags.keyword) for the self or this + object. + */ + self: Tag; + /** + The [keyword](#highlight.tags.keyword) for null. + */ + null: Tag; + /** + A [keyword](#highlight.tags.keyword) denoting some atomic value. + */ + atom: Tag; + /** + A [keyword](#highlight.tags.keyword) that represents a unit. + */ + unit: Tag; + /** + A modifier [keyword](#highlight.tags.keyword). + */ + modifier: Tag; + /** + A [keyword](#highlight.tags.keyword) that acts as an operator. + */ + operatorKeyword: Tag; + /** + A control-flow related [keyword](#highlight.tags.keyword). + */ + controlKeyword: Tag; + /** + A [keyword](#highlight.tags.keyword) that defines something. + */ + definitionKeyword: Tag; + /** + A [keyword](#highlight.tags.keyword) related to defining or + interfacing with modules. + */ + moduleKeyword: Tag; + /** + An operator. + */ + operator: Tag; + /** + An [operator](#highlight.tags.operator) that dereferences something. + */ + derefOperator: Tag; + /** + Arithmetic-related [operator](#highlight.tags.operator). + */ + arithmeticOperator: Tag; + /** + Logical [operator](#highlight.tags.operator). + */ + logicOperator: Tag; + /** + Bit [operator](#highlight.tags.operator). + */ + bitwiseOperator: Tag; + /** + Comparison [operator](#highlight.tags.operator). + */ + compareOperator: Tag; + /** + [Operator](#highlight.tags.operator) that updates its operand. + */ + updateOperator: Tag; + /** + [Operator](#highlight.tags.operator) that defines something. + */ + definitionOperator: Tag; + /** + Type-related [operator](#highlight.tags.operator). + */ + typeOperator: Tag; + /** + Control-flow [operator](#highlight.tags.operator). + */ + controlOperator: Tag; + /** + Program or markup punctuation. + */ + punctuation: Tag; + /** + [Punctuation](#highlight.tags.punctuation) that separates + things. + */ + separator: Tag; + /** + Bracket-style [punctuation](#highlight.tags.punctuation). + */ + bracket: Tag; + /** + Angle [brackets](#highlight.tags.bracket) (usually `<` and `>` + tokens). + */ + angleBracket: Tag; + /** + Square [brackets](#highlight.tags.bracket) (usually `[` and `]` + tokens). + */ + squareBracket: Tag; + /** + Parentheses (usually `(` and `)` tokens). Subtag of + [bracket](#highlight.tags.bracket). + */ + paren: Tag; + /** + Braces (usually `{` and `}` tokens). Subtag of + [bracket](#highlight.tags.bracket). + */ + brace: Tag; + /** + Content, for example plain text in XML or markup documents. + */ + content: Tag; + /** + [Content](#highlight.tags.content) that represents a heading. + */ + heading: Tag; + /** + A level 1 [heading](#highlight.tags.heading). + */ + heading1: Tag; + /** + A level 2 [heading](#highlight.tags.heading). + */ + heading2: Tag; + /** + A level 3 [heading](#highlight.tags.heading). + */ + heading3: Tag; + /** + A level 4 [heading](#highlight.tags.heading). + */ + heading4: Tag; + /** + A level 5 [heading](#highlight.tags.heading). + */ + heading5: Tag; + /** + A level 6 [heading](#highlight.tags.heading). + */ + heading6: Tag; + /** + A prose separator (such as a horizontal rule). + */ + contentSeparator: Tag; + /** + [Content](#highlight.tags.content) that represents a list. + */ + list: Tag; + /** + [Content](#highlight.tags.content) that represents a quote. + */ + quote: Tag; + /** + [Content](#highlight.tags.content) that is emphasized. + */ + emphasis: Tag; + /** + [Content](#highlight.tags.content) that is styled strong. + */ + strong: Tag; + /** + [Content](#highlight.tags.content) that is part of a link. + */ + link: Tag; + /** + [Content](#highlight.tags.content) that is styled as code or + monospace. + */ + monospace: Tag; + /** + [Content](#highlight.tags.content) that has a strike-through + style. + */ + strikethrough: Tag; + /** + Inserted text in a change-tracking format. + */ + inserted: Tag; + /** + Deleted text. + */ + deleted: Tag; + /** + Changed text. + */ + changed: Tag; + /** + An invalid or unsyntactic element. + */ + invalid: Tag; + /** + Metadata or meta-instruction. + */ + meta: Tag; + /** + [Metadata](#highlight.tags.meta) that applies to the entire + document. + */ + documentMeta: Tag; + /** + [Metadata](#highlight.tags.meta) that annotates or adds + attributes to a given syntactic element. + */ + annotation: Tag; + /** + Processing instruction or preprocessor directive. Subtag of + [meta](#highlight.tags.meta). + */ + processingInstruction: Tag; + /** + [Modifier](#highlight.Tag^defineModifier) that indicates that a + given element is being defined. Expected to be used with the + various [name](#highlight.tags.name) tags. + */ + definition: (tag: Tag) => Tag; + /** + [Modifier](#highlight.Tag^defineModifier) that indicates that + something is constant. Mostly expected to be used with + [variable names](#highlight.tags.variableName). + */ + constant: (tag: Tag) => Tag; + /** + [Modifier](#highlight.Tag^defineModifier) used to indicate that + a [variable](#highlight.tags.variableName) or [property + name](#highlight.tags.propertyName) is being called or defined + as a function. + */ + function: (tag: Tag) => Tag; + /** + [Modifier](#highlight.Tag^defineModifier) that can be applied to + [names](#highlight.tags.name) to indicate that they belong to + the language's standard environment. + */ + standard: (tag: Tag) => Tag; + /** + [Modifier](#highlight.Tag^defineModifier) that indicates a given + [names](#highlight.tags.name) is local to some scope. + */ + local: (tag: Tag) => Tag; + /** + A generic variant [modifier](#highlight.Tag^defineModifier) that + can be used to tag language-specific alternative variants of + some common tag. It is recommended for themes to define special + forms of at least the [string](#highlight.tags.string) and + [variable name](#highlight.tags.variableName) tags, since those + come up a lot. + */ + special: (tag: Tag) => Tag; +}; +/** +This is a highlighter that adds stable, predictable classes to +tokens, for styling with external CSS. + +The following tags are mapped to their name prefixed with `"tok-"` +(for example `"tok-comment"`): + +* [`link`](#highlight.tags.link) +* [`heading`](#highlight.tags.heading) +* [`emphasis`](#highlight.tags.emphasis) +* [`strong`](#highlight.tags.strong) +* [`keyword`](#highlight.tags.keyword) +* [`atom`](#highlight.tags.atom) +* [`bool`](#highlight.tags.bool) +* [`url`](#highlight.tags.url) +* [`labelName`](#highlight.tags.labelName) +* [`inserted`](#highlight.tags.inserted) +* [`deleted`](#highlight.tags.deleted) +* [`literal`](#highlight.tags.literal) +* [`string`](#highlight.tags.string) +* [`number`](#highlight.tags.number) +* [`variableName`](#highlight.tags.variableName) +* [`typeName`](#highlight.tags.typeName) +* [`namespace`](#highlight.tags.namespace) +* [`className`](#highlight.tags.className) +* [`macroName`](#highlight.tags.macroName) +* [`propertyName`](#highlight.tags.propertyName) +* [`operator`](#highlight.tags.operator) +* [`comment`](#highlight.tags.comment) +* [`meta`](#highlight.tags.meta) +* [`punctuation`](#highlight.tags.punctuation) +* [`invalid`](#highlight.tags.invalid) + +In addition, these mappings are provided: + +* [`regexp`](#highlight.tags.regexp), + [`escape`](#highlight.tags.escape), and + [`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string) + are mapped to `"tok-string2"` +* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName2"` +* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName tok-local"` +* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName tok-definition"` +* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName) + to `"tok-propertyName tok-definition"` +*/ +declare const classHighlighter: Highlighter; + +export { type Highlighter, Tag, classHighlighter, getStyleTags, highlightCode, highlightTree, styleTags, tagHighlighter, tags }; diff --git a/node_modules/@lezer/highlight/dist/index.d.ts b/node_modules/@lezer/highlight/dist/index.d.ts new file mode 100644 index 0000000000..475f30c685 --- /dev/null +++ b/node_modules/@lezer/highlight/dist/index.d.ts @@ -0,0 +1,623 @@ +import * as _lezer_common from '@lezer/common'; +import { NodeType, Tree, SyntaxNodeRef } from '@lezer/common'; + +/** +Highlighting tags are markers that denote a highlighting category. +They are [associated](#highlight.styleTags) with parts of a syntax +tree by a language mode, and then mapped to an actual CSS style by +a [highlighter](#highlight.Highlighter). + +Because syntax tree node types and highlight styles have to be +able to talk the same language, CodeMirror uses a mostly _closed_ +[vocabulary](#highlight.tags) of syntax tags (as opposed to +traditional open string-based systems, which make it hard for +highlighting themes to cover all the tokens produced by the +various languages). + +It _is_ possible to [define](#highlight.Tag^define) your own +highlighting tags for system-internal use (where you control both +the language package and the highlighter), but such tags will not +be picked up by regular highlighters (though you can derive them +from standard tags to allow highlighters to fall back to those). +*/ +declare class Tag { + /** + The set of this tag and all its parent tags, starting with + this one itself and sorted in order of decreasing specificity. + */ + readonly set: Tag[]; + toString(): string; + /** + Define a new tag. If `parent` is given, the tag is treated as a + sub-tag of that parent, and + [highlighters](#highlight.tagHighlighter) that don't mention + this tag will try to fall back to the parent tag (or grandparent + tag, etc). + */ + static define(name?: string, parent?: Tag): Tag; + static define(parent?: Tag): Tag; + /** + Define a tag _modifier_, which is a function that, given a tag, + will return a tag that is a subtag of the original. Applying the + same modifier to a twice tag will return the same value (`m1(t1) + == m1(t1)`) and applying multiple modifiers will, regardless or + order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`). + + When multiple modifiers are applied to a given base tag, each + smaller set of modifiers is registered as a parent, so that for + example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`, + `m1(m3(t1)`, and so on. + */ + static defineModifier(name?: string): (tag: Tag) => Tag; +} +/** +This function is used to add a set of tags to a language syntax +via [`NodeSet.extend`](#common.NodeSet.extend) or +[`LRParser.configure`](#lr.LRParser.configure). + +The argument object maps node selectors to [highlighting +tags](#highlight.Tag) or arrays of tags. + +Node selectors may hold one or more (space-separated) node paths. +Such a path can be a [node name](#common.NodeType.name), or +multiple node names (or `*` wildcards) separated by slash +characters, as in `"Block/Declaration/VariableName"`. Such a path +matches the final node but only if its direct parent nodes are the +other nodes mentioned. A `*` in such a path matches any parent, +but only a single level—wildcards that match multiple parents +aren't supported, both for efficiency reasons and because Lezer +trees make it rather hard to reason about what they would match.) + +A path can be ended with `/...` to indicate that the tag assigned +to the node should also apply to all child nodes, even if they +match their own style (by default, only the innermost style is +used). + +When a path ends in `!`, as in `Attribute!`, no further matching +happens for the node's child nodes, and the entire node gets the +given style. + +In this notation, node names that contain `/`, `!`, `*`, or `...` +must be quoted as JSON strings. + +For example: + +```javascript +parser.withProps( + styleTags({ + // Style Number and BigNumber nodes + "Number BigNumber": tags.number, + // Style Escape nodes whose parent is String + "String/Escape": tags.escape, + // Style anything inside Attributes nodes + "Attributes!": tags.meta, + // Add a style to all content inside Italic nodes + "Italic/...": tags.emphasis, + // Style InvalidString nodes as both `string` and `invalid` + "InvalidString": [tags.string, tags.invalid], + // Style the node named "/" as punctuation + '"/"': tags.punctuation + }) +) +``` +*/ +declare function styleTags(spec: { + [selector: string]: Tag | readonly Tag[]; +}): _lezer_common.NodePropSource; +/** +A highlighter defines a mapping from highlighting tags and +language scopes to CSS class names. They are usually defined via +[`tagHighlighter`](#highlight.tagHighlighter) or some wrapper +around that, but it is also possible to implement them from +scratch. +*/ +interface Highlighter { + /** + Get the set of classes that should be applied to the given set + of highlighting tags, or null if this highlighter doesn't assign + a style to the tags. + */ + style(tags: readonly Tag[]): string | null; + /** + When given, the highlighter will only be applied to trees on + whose [top](#common.NodeType.isTop) node this predicate returns + true. + */ + scope?(node: NodeType): boolean; +} +/** +Define a [highlighter](#highlight.Highlighter) from an array of +tag/class pairs. Classes associated with more specific tags will +take precedence. +*/ +declare function tagHighlighter(tags: readonly { + tag: Tag | readonly Tag[]; + class: string; +}[], options?: { + /** + By default, highlighters apply to the entire document. You can + scope them to a single language by providing the tree's + [top](#common.NodeType.isTop) node type here. + */ + scope?: (node: NodeType) => boolean; + /** + Add a style to _all_ tokens. Probably only useful in combination + with `scope`. + */ + all?: string; +}): Highlighter; +/** +Highlight the given [tree](#common.Tree) with the given +[highlighter](#highlight.Highlighter). Often, the higher-level +[`highlightCode`](#highlight.highlightCode) function is easier to +use. +*/ +declare function highlightTree(tree: Tree, highlighter: Highlighter | readonly Highlighter[], +/** +Assign styling to a region of the text. Will be called, in order +of position, for any ranges where more than zero classes apply. +`classes` is a space separated string of CSS classes. +*/ +putStyle: (from: number, to: number, classes: string) => void, +/** +The start of the range to highlight. +*/ +from?: number, +/** +The end of the range. +*/ +to?: number): void; +/** +Highlight the given tree with the given highlighter, calling +`putText` for every piece of text, either with a set of classes or +with the empty string when unstyled, and `putBreak` for every line +break. +*/ +declare function highlightCode(code: string, tree: Tree, highlighter: Highlighter | readonly Highlighter[], putText: (code: string, classes: string) => void, putBreak: () => void, from?: number, to?: number): void; +/** +Match a syntax node's [highlight rules](#highlight.styleTags). If +there's a match, return its set of tags, and whether it is +opaque (uses a `!`) or applies to all child nodes (`/...`). +*/ +declare function getStyleTags(node: SyntaxNodeRef): { + tags: readonly Tag[]; + opaque: boolean; + inherit: boolean; +} | null; +/** +The default set of highlighting [tags](#highlight.Tag). + +This collection is heavily biased towards programming languages, +and necessarily incomplete. A full ontology of syntactic +constructs would fill a stack of books, and be impractical to +write themes for. So try to make do with this set. If all else +fails, [open an +issue](https://github.com/codemirror/codemirror.next) to propose a +new tag, or [define](#highlight.Tag^define) a local custom tag for +your use case. + +Note that it is not obligatory to always attach the most specific +tag possible to an element—if your grammar can't easily +distinguish a certain type of element (such as a local variable), +it is okay to style it as its more general variant (a variable). + +For tags that extend some parent tag, the documentation links to +the parent. +*/ +declare const tags: { + /** + A comment. + */ + comment: Tag; + /** + A line [comment](#highlight.tags.comment). + */ + lineComment: Tag; + /** + A block [comment](#highlight.tags.comment). + */ + blockComment: Tag; + /** + A documentation [comment](#highlight.tags.comment). + */ + docComment: Tag; + /** + Any kind of identifier. + */ + name: Tag; + /** + The [name](#highlight.tags.name) of a variable. + */ + variableName: Tag; + /** + A type [name](#highlight.tags.name). + */ + typeName: Tag; + /** + A tag name (subtag of [`typeName`](#highlight.tags.typeName)). + */ + tagName: Tag; + /** + A property or field [name](#highlight.tags.name). + */ + propertyName: Tag; + /** + An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)). + */ + attributeName: Tag; + /** + The [name](#highlight.tags.name) of a class. + */ + className: Tag; + /** + A label [name](#highlight.tags.name). + */ + labelName: Tag; + /** + A namespace [name](#highlight.tags.name). + */ + namespace: Tag; + /** + The [name](#highlight.tags.name) of a macro. + */ + macroName: Tag; + /** + A literal value. + */ + literal: Tag; + /** + A string [literal](#highlight.tags.literal). + */ + string: Tag; + /** + A documentation [string](#highlight.tags.string). + */ + docString: Tag; + /** + A character literal (subtag of [string](#highlight.tags.string)). + */ + character: Tag; + /** + An attribute value (subtag of [string](#highlight.tags.string)). + */ + attributeValue: Tag; + /** + A number [literal](#highlight.tags.literal). + */ + number: Tag; + /** + An integer [number](#highlight.tags.number) literal. + */ + integer: Tag; + /** + A floating-point [number](#highlight.tags.number) literal. + */ + float: Tag; + /** + A boolean [literal](#highlight.tags.literal). + */ + bool: Tag; + /** + Regular expression [literal](#highlight.tags.literal). + */ + regexp: Tag; + /** + An escape [literal](#highlight.tags.literal), for example a + backslash escape in a string. + */ + escape: Tag; + /** + A color [literal](#highlight.tags.literal). + */ + color: Tag; + /** + A URL [literal](#highlight.tags.literal). + */ + url: Tag; + /** + A language keyword. + */ + keyword: Tag; + /** + The [keyword](#highlight.tags.keyword) for the self or this + object. + */ + self: Tag; + /** + The [keyword](#highlight.tags.keyword) for null. + */ + null: Tag; + /** + A [keyword](#highlight.tags.keyword) denoting some atomic value. + */ + atom: Tag; + /** + A [keyword](#highlight.tags.keyword) that represents a unit. + */ + unit: Tag; + /** + A modifier [keyword](#highlight.tags.keyword). + */ + modifier: Tag; + /** + A [keyword](#highlight.tags.keyword) that acts as an operator. + */ + operatorKeyword: Tag; + /** + A control-flow related [keyword](#highlight.tags.keyword). + */ + controlKeyword: Tag; + /** + A [keyword](#highlight.tags.keyword) that defines something. + */ + definitionKeyword: Tag; + /** + A [keyword](#highlight.tags.keyword) related to defining or + interfacing with modules. + */ + moduleKeyword: Tag; + /** + An operator. + */ + operator: Tag; + /** + An [operator](#highlight.tags.operator) that dereferences something. + */ + derefOperator: Tag; + /** + Arithmetic-related [operator](#highlight.tags.operator). + */ + arithmeticOperator: Tag; + /** + Logical [operator](#highlight.tags.operator). + */ + logicOperator: Tag; + /** + Bit [operator](#highlight.tags.operator). + */ + bitwiseOperator: Tag; + /** + Comparison [operator](#highlight.tags.operator). + */ + compareOperator: Tag; + /** + [Operator](#highlight.tags.operator) that updates its operand. + */ + updateOperator: Tag; + /** + [Operator](#highlight.tags.operator) that defines something. + */ + definitionOperator: Tag; + /** + Type-related [operator](#highlight.tags.operator). + */ + typeOperator: Tag; + /** + Control-flow [operator](#highlight.tags.operator). + */ + controlOperator: Tag; + /** + Program or markup punctuation. + */ + punctuation: Tag; + /** + [Punctuation](#highlight.tags.punctuation) that separates + things. + */ + separator: Tag; + /** + Bracket-style [punctuation](#highlight.tags.punctuation). + */ + bracket: Tag; + /** + Angle [brackets](#highlight.tags.bracket) (usually `<` and `>` + tokens). + */ + angleBracket: Tag; + /** + Square [brackets](#highlight.tags.bracket) (usually `[` and `]` + tokens). + */ + squareBracket: Tag; + /** + Parentheses (usually `(` and `)` tokens). Subtag of + [bracket](#highlight.tags.bracket). + */ + paren: Tag; + /** + Braces (usually `{` and `}` tokens). Subtag of + [bracket](#highlight.tags.bracket). + */ + brace: Tag; + /** + Content, for example plain text in XML or markup documents. + */ + content: Tag; + /** + [Content](#highlight.tags.content) that represents a heading. + */ + heading: Tag; + /** + A level 1 [heading](#highlight.tags.heading). + */ + heading1: Tag; + /** + A level 2 [heading](#highlight.tags.heading). + */ + heading2: Tag; + /** + A level 3 [heading](#highlight.tags.heading). + */ + heading3: Tag; + /** + A level 4 [heading](#highlight.tags.heading). + */ + heading4: Tag; + /** + A level 5 [heading](#highlight.tags.heading). + */ + heading5: Tag; + /** + A level 6 [heading](#highlight.tags.heading). + */ + heading6: Tag; + /** + A prose [content](#highlight.tags.content) separator (such as a horizontal rule). + */ + contentSeparator: Tag; + /** + [Content](#highlight.tags.content) that represents a list. + */ + list: Tag; + /** + [Content](#highlight.tags.content) that represents a quote. + */ + quote: Tag; + /** + [Content](#highlight.tags.content) that is emphasized. + */ + emphasis: Tag; + /** + [Content](#highlight.tags.content) that is styled strong. + */ + strong: Tag; + /** + [Content](#highlight.tags.content) that is part of a link. + */ + link: Tag; + /** + [Content](#highlight.tags.content) that is styled as code or + monospace. + */ + monospace: Tag; + /** + [Content](#highlight.tags.content) that has a strike-through + style. + */ + strikethrough: Tag; + /** + Inserted text in a change-tracking format. + */ + inserted: Tag; + /** + Deleted text. + */ + deleted: Tag; + /** + Changed text. + */ + changed: Tag; + /** + An invalid or unsyntactic element. + */ + invalid: Tag; + /** + Metadata or meta-instruction. + */ + meta: Tag; + /** + [Metadata](#highlight.tags.meta) that applies to the entire + document. + */ + documentMeta: Tag; + /** + [Metadata](#highlight.tags.meta) that annotates or adds + attributes to a given syntactic element. + */ + annotation: Tag; + /** + Processing instruction or preprocessor directive. Subtag of + [meta](#highlight.tags.meta). + */ + processingInstruction: Tag; + /** + [Modifier](#highlight.Tag^defineModifier) that indicates that a + given element is being defined. Expected to be used with the + various [name](#highlight.tags.name) tags. + */ + definition: (tag: Tag) => Tag; + /** + [Modifier](#highlight.Tag^defineModifier) that indicates that + something is constant. Mostly expected to be used with + [variable names](#highlight.tags.variableName). + */ + constant: (tag: Tag) => Tag; + /** + [Modifier](#highlight.Tag^defineModifier) used to indicate that + a [variable](#highlight.tags.variableName) or [property + name](#highlight.tags.propertyName) is being called or defined + as a function. + */ + function: (tag: Tag) => Tag; + /** + [Modifier](#highlight.Tag^defineModifier) that can be applied to + [names](#highlight.tags.name) to indicate that they belong to + the language's standard environment. + */ + standard: (tag: Tag) => Tag; + /** + [Modifier](#highlight.Tag^defineModifier) that indicates a given + [names](#highlight.tags.name) is local to some scope. + */ + local: (tag: Tag) => Tag; + /** + A generic variant [modifier](#highlight.Tag^defineModifier) that + can be used to tag language-specific alternative variants of + some common tag. It is recommended for themes to define special + forms of at least the [string](#highlight.tags.string) and + [variable name](#highlight.tags.variableName) tags, since those + come up a lot. + */ + special: (tag: Tag) => Tag; +}; +/** +This is a highlighter that adds stable, predictable classes to +tokens, for styling with external CSS. + +The following tags are mapped to their name prefixed with `"tok-"` +(for example `"tok-comment"`): + +* [`link`](#highlight.tags.link) +* [`heading`](#highlight.tags.heading) +* [`emphasis`](#highlight.tags.emphasis) +* [`strong`](#highlight.tags.strong) +* [`keyword`](#highlight.tags.keyword) +* [`atom`](#highlight.tags.atom) +* [`bool`](#highlight.tags.bool) +* [`url`](#highlight.tags.url) +* [`labelName`](#highlight.tags.labelName) +* [`inserted`](#highlight.tags.inserted) +* [`deleted`](#highlight.tags.deleted) +* [`literal`](#highlight.tags.literal) +* [`string`](#highlight.tags.string) +* [`number`](#highlight.tags.number) +* [`variableName`](#highlight.tags.variableName) +* [`typeName`](#highlight.tags.typeName) +* [`namespace`](#highlight.tags.namespace) +* [`className`](#highlight.tags.className) +* [`macroName`](#highlight.tags.macroName) +* [`propertyName`](#highlight.tags.propertyName) +* [`operator`](#highlight.tags.operator) +* [`comment`](#highlight.tags.comment) +* [`meta`](#highlight.tags.meta) +* [`punctuation`](#highlight.tags.punctuation) +* [`invalid`](#highlight.tags.invalid) + +In addition, these mappings are provided: + +* [`regexp`](#highlight.tags.regexp), + [`escape`](#highlight.tags.escape), and + [`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string) + are mapped to `"tok-string2"` +* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName2"` +* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName tok-local"` +* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName tok-definition"` +* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName) + to `"tok-propertyName tok-definition"` +*/ +declare const classHighlighter: Highlighter; + +export { Highlighter, Tag, classHighlighter, getStyleTags, highlightCode, highlightTree, styleTags, tagHighlighter, tags }; diff --git a/node_modules/@lezer/highlight/dist/index.js b/node_modules/@lezer/highlight/dist/index.js new file mode 100644 index 0000000000..9c1d712af2 --- /dev/null +++ b/node_modules/@lezer/highlight/dist/index.js @@ -0,0 +1,904 @@ +import { NodeProp } from '@lezer/common'; + +let nextTagID = 0; +/** +Highlighting tags are markers that denote a highlighting category. +They are [associated](#highlight.styleTags) with parts of a syntax +tree by a language mode, and then mapped to an actual CSS style by +a [highlighter](#highlight.Highlighter). + +Because syntax tree node types and highlight styles have to be +able to talk the same language, CodeMirror uses a mostly _closed_ +[vocabulary](#highlight.tags) of syntax tags (as opposed to +traditional open string-based systems, which make it hard for +highlighting themes to cover all the tokens produced by the +various languages). + +It _is_ possible to [define](#highlight.Tag^define) your own +highlighting tags for system-internal use (where you control both +the language package and the highlighter), but such tags will not +be picked up by regular highlighters (though you can derive them +from standard tags to allow highlighters to fall back to those). +*/ +class Tag { + /** + @internal + */ + constructor( + /** + The optional name of the base tag @internal + */ + name, + /** + The set of this tag and all its parent tags, starting with + this one itself and sorted in order of decreasing specificity. + */ + set, + /** + The base unmodified tag that this one is based on, if it's + modified @internal + */ + base, + /** + The modifiers applied to this.base @internal + */ + modified) { + this.name = name; + this.set = set; + this.base = base; + this.modified = modified; + /** + @internal + */ + this.id = nextTagID++; + } + toString() { + let { name } = this; + for (let mod of this.modified) + if (mod.name) + name = `${mod.name}(${name})`; + return name; + } + static define(nameOrParent, parent) { + let name = typeof nameOrParent == "string" ? nameOrParent : "?"; + if (nameOrParent instanceof Tag) + parent = nameOrParent; + if (parent === null || parent === void 0 ? void 0 : parent.base) + throw new Error("Can not derive from a modified tag"); + let tag = new Tag(name, [], null, []); + tag.set.push(tag); + if (parent) + for (let t of parent.set) + tag.set.push(t); + return tag; + } + /** + Define a tag _modifier_, which is a function that, given a tag, + will return a tag that is a subtag of the original. Applying the + same modifier to a twice tag will return the same value (`m1(t1) + == m1(t1)`) and applying multiple modifiers will, regardless or + order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`). + + When multiple modifiers are applied to a given base tag, each + smaller set of modifiers is registered as a parent, so that for + example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`, + `m1(m3(t1)`, and so on. + */ + static defineModifier(name) { + let mod = new Modifier(name); + return (tag) => { + if (tag.modified.indexOf(mod) > -1) + return tag; + return Modifier.get(tag.base || tag, tag.modified.concat(mod).sort((a, b) => a.id - b.id)); + }; + } +} +let nextModifierID = 0; +class Modifier { + constructor(name) { + this.name = name; + this.instances = []; + this.id = nextModifierID++; + } + static get(base, mods) { + if (!mods.length) + return base; + let exists = mods[0].instances.find(t => t.base == base && sameArray(mods, t.modified)); + if (exists) + return exists; + let set = [], tag = new Tag(base.name, set, base, mods); + for (let m of mods) + m.instances.push(tag); + let configs = powerSet(mods); + for (let parent of base.set) + if (!parent.modified.length) + for (let config of configs) + set.push(Modifier.get(parent, config)); + return tag; + } +} +function sameArray(a, b) { + return a.length == b.length && a.every((x, i) => x == b[i]); +} +function powerSet(array) { + let sets = [[]]; + for (let i = 0; i < array.length; i++) { + for (let j = 0, e = sets.length; j < e; j++) { + sets.push(sets[j].concat(array[i])); + } + } + return sets.sort((a, b) => b.length - a.length); +} +/** +This function is used to add a set of tags to a language syntax +via [`NodeSet.extend`](#common.NodeSet.extend) or +[`LRParser.configure`](#lr.LRParser.configure). + +The argument object maps node selectors to [highlighting +tags](#highlight.Tag) or arrays of tags. + +Node selectors may hold one or more (space-separated) node paths. +Such a path can be a [node name](#common.NodeType.name), or +multiple node names (or `*` wildcards) separated by slash +characters, as in `"Block/Declaration/VariableName"`. Such a path +matches the final node but only if its direct parent nodes are the +other nodes mentioned. A `*` in such a path matches any parent, +but only a single level—wildcards that match multiple parents +aren't supported, both for efficiency reasons and because Lezer +trees make it rather hard to reason about what they would match.) + +A path can be ended with `/...` to indicate that the tag assigned +to the node should also apply to all child nodes, even if they +match their own style (by default, only the innermost style is +used). + +When a path ends in `!`, as in `Attribute!`, no further matching +happens for the node's child nodes, and the entire node gets the +given style. + +In this notation, node names that contain `/`, `!`, `*`, or `...` +must be quoted as JSON strings. + +For example: + +```javascript +parser.withProps( + styleTags({ + // Style Number and BigNumber nodes + "Number BigNumber": tags.number, + // Style Escape nodes whose parent is String + "String/Escape": tags.escape, + // Style anything inside Attributes nodes + "Attributes!": tags.meta, + // Add a style to all content inside Italic nodes + "Italic/...": tags.emphasis, + // Style InvalidString nodes as both `string` and `invalid` + "InvalidString": [tags.string, tags.invalid], + // Style the node named "/" as punctuation + '"/"': tags.punctuation + }) +) +``` +*/ +function styleTags(spec) { + let byName = Object.create(null); + for (let prop in spec) { + let tags = spec[prop]; + if (!Array.isArray(tags)) + tags = [tags]; + for (let part of prop.split(" ")) + if (part) { + let pieces = [], mode = 2 /* Mode.Normal */, rest = part; + for (let pos = 0;;) { + if (rest == "..." && pos > 0 && pos + 3 == part.length) { + mode = 1 /* Mode.Inherit */; + break; + } + let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest); + if (!m) + throw new RangeError("Invalid path: " + part); + pieces.push(m[0] == "*" ? "" : m[0][0] == '"' ? JSON.parse(m[0]) : m[0]); + pos += m[0].length; + if (pos == part.length) + break; + let next = part[pos++]; + if (pos == part.length && next == "!") { + mode = 0 /* Mode.Opaque */; + break; + } + if (next != "/") + throw new RangeError("Invalid path: " + part); + rest = part.slice(pos); + } + let last = pieces.length - 1, inner = pieces[last]; + if (!inner) + throw new RangeError("Invalid path: " + part); + let rule = new Rule(tags, mode, last > 0 ? pieces.slice(0, last) : null); + byName[inner] = rule.sort(byName[inner]); + } + } + return ruleNodeProp.add(byName); +} +const ruleNodeProp = new NodeProp(); +class Rule { + constructor(tags, mode, context, next) { + this.tags = tags; + this.mode = mode; + this.context = context; + this.next = next; + } + get opaque() { return this.mode == 0 /* Mode.Opaque */; } + get inherit() { return this.mode == 1 /* Mode.Inherit */; } + sort(other) { + if (!other || other.depth < this.depth) { + this.next = other; + return this; + } + other.next = this.sort(other.next); + return other; + } + get depth() { return this.context ? this.context.length : 0; } +} +Rule.empty = new Rule([], 2 /* Mode.Normal */, null); +/** +Define a [highlighter](#highlight.Highlighter) from an array of +tag/class pairs. Classes associated with more specific tags will +take precedence. +*/ +function tagHighlighter(tags, options) { + let map = Object.create(null); + for (let style of tags) { + if (!Array.isArray(style.tag)) + map[style.tag.id] = style.class; + else + for (let tag of style.tag) + map[tag.id] = style.class; + } + let { scope, all = null } = options || {}; + return { + style: (tags) => { + let cls = all; + for (let tag of tags) { + for (let sub of tag.set) { + let tagClass = map[sub.id]; + if (tagClass) { + cls = cls ? cls + " " + tagClass : tagClass; + break; + } + } + } + return cls; + }, + scope + }; +} +function highlightTags(highlighters, tags) { + let result = null; + for (let highlighter of highlighters) { + let value = highlighter.style(tags); + if (value) + result = result ? result + " " + value : value; + } + return result; +} +/** +Highlight the given [tree](#common.Tree) with the given +[highlighter](#highlight.Highlighter). Often, the higher-level +[`highlightCode`](#highlight.highlightCode) function is easier to +use. +*/ +function highlightTree(tree, highlighter, +/** +Assign styling to a region of the text. Will be called, in order +of position, for any ranges where more than zero classes apply. +`classes` is a space separated string of CSS classes. +*/ +putStyle, +/** +The start of the range to highlight. +*/ +from = 0, +/** +The end of the range. +*/ +to = tree.length) { + let builder = new HighlightBuilder(from, Array.isArray(highlighter) ? highlighter : [highlighter], putStyle); + builder.highlightRange(tree.cursor(), from, to, "", builder.highlighters); + builder.flush(to); +} +/** +Highlight the given tree with the given highlighter, calling +`putText` for every piece of text, either with a set of classes or +with the empty string when unstyled, and `putBreak` for every line +break. +*/ +function highlightCode(code, tree, highlighter, putText, putBreak, from = 0, to = code.length) { + let pos = from; + function writeTo(p, classes) { + if (p <= pos) + return; + for (let text = code.slice(pos, p), i = 0;;) { + let nextBreak = text.indexOf("\n", i); + let upto = nextBreak < 0 ? text.length : nextBreak; + if (upto > i) + putText(text.slice(i, upto), classes); + if (nextBreak < 0) + break; + putBreak(); + i = nextBreak + 1; + } + pos = p; + } + highlightTree(tree, highlighter, (from, to, classes) => { + writeTo(from, ""); + writeTo(to, classes); + }, from, to); + writeTo(to, ""); +} +class HighlightBuilder { + constructor(at, highlighters, span) { + this.at = at; + this.highlighters = highlighters; + this.span = span; + this.class = ""; + } + startSpan(at, cls) { + if (cls != this.class) { + this.flush(at); + if (at > this.at) + this.at = at; + this.class = cls; + } + } + flush(to) { + if (to > this.at && this.class) + this.span(this.at, to, this.class); + } + highlightRange(cursor, from, to, inheritedClass, highlighters) { + let { type, from: start, to: end } = cursor; + if (start >= to || end <= from) + return; + if (type.isTop) + highlighters = this.highlighters.filter(h => !h.scope || h.scope(type)); + let cls = inheritedClass; + let rule = getStyleTags(cursor) || Rule.empty; + let tagCls = highlightTags(highlighters, rule.tags); + if (tagCls) { + if (cls) + cls += " "; + cls += tagCls; + if (rule.mode == 1 /* Mode.Inherit */) + inheritedClass += (inheritedClass ? " " : "") + tagCls; + } + this.startSpan(Math.max(from, start), cls); + if (rule.opaque) + return; + let mounted = cursor.tree && cursor.tree.prop(NodeProp.mounted); + if (mounted && mounted.overlay) { + let inner = cursor.node.enter(mounted.overlay[0].from + start, 1); + let innerHighlighters = this.highlighters.filter(h => !h.scope || h.scope(mounted.tree.type)); + let hasChild = cursor.firstChild(); + for (let i = 0, pos = start;; i++) { + let next = i < mounted.overlay.length ? mounted.overlay[i] : null; + let nextPos = next ? next.from + start : end; + let rangeFrom = Math.max(from, pos), rangeTo = Math.min(to, nextPos); + if (rangeFrom < rangeTo && hasChild) { + while (cursor.from < rangeTo) { + this.highlightRange(cursor, rangeFrom, rangeTo, inheritedClass, highlighters); + this.startSpan(Math.min(rangeTo, cursor.to), cls); + if (cursor.to >= nextPos || !cursor.nextSibling()) + break; + } + } + if (!next || nextPos > to) + break; + pos = next.to + start; + if (pos > from) { + this.highlightRange(inner.cursor(), Math.max(from, next.from + start), Math.min(to, pos), "", innerHighlighters); + this.startSpan(Math.min(to, pos), cls); + } + } + if (hasChild) + cursor.parent(); + } + else if (cursor.firstChild()) { + if (mounted) + inheritedClass = ""; + do { + if (cursor.to <= from) + continue; + if (cursor.from >= to) + break; + this.highlightRange(cursor, from, to, inheritedClass, highlighters); + this.startSpan(Math.min(to, cursor.to), cls); + } while (cursor.nextSibling()); + cursor.parent(); + } + } +} +/** +Match a syntax node's [highlight rules](#highlight.styleTags). If +there's a match, return its set of tags, and whether it is +opaque (uses a `!`) or applies to all child nodes (`/...`). +*/ +function getStyleTags(node) { + let rule = node.type.prop(ruleNodeProp); + while (rule && rule.context && !node.matchContext(rule.context)) + rule = rule.next; + return rule || null; +} +const t = Tag.define; +const comment = t(), name = t(), typeName = t(name), propertyName = t(name), literal = t(), string = t(literal), number = t(literal), content = t(), heading = t(content), keyword = t(), operator = t(), punctuation = t(), bracket = t(punctuation), meta = t(); +/** +The default set of highlighting [tags](#highlight.Tag). + +This collection is heavily biased towards programming languages, +and necessarily incomplete. A full ontology of syntactic +constructs would fill a stack of books, and be impractical to +write themes for. So try to make do with this set. If all else +fails, [open an +issue](https://github.com/codemirror/codemirror.next) to propose a +new tag, or [define](#highlight.Tag^define) a local custom tag for +your use case. + +Note that it is not obligatory to always attach the most specific +tag possible to an element—if your grammar can't easily +distinguish a certain type of element (such as a local variable), +it is okay to style it as its more general variant (a variable). + +For tags that extend some parent tag, the documentation links to +the parent. +*/ +const tags = { + /** + A comment. + */ + comment, + /** + A line [comment](#highlight.tags.comment). + */ + lineComment: t(comment), + /** + A block [comment](#highlight.tags.comment). + */ + blockComment: t(comment), + /** + A documentation [comment](#highlight.tags.comment). + */ + docComment: t(comment), + /** + Any kind of identifier. + */ + name, + /** + The [name](#highlight.tags.name) of a variable. + */ + variableName: t(name), + /** + A type [name](#highlight.tags.name). + */ + typeName: typeName, + /** + A tag name (subtag of [`typeName`](#highlight.tags.typeName)). + */ + tagName: t(typeName), + /** + A property or field [name](#highlight.tags.name). + */ + propertyName: propertyName, + /** + An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)). + */ + attributeName: t(propertyName), + /** + The [name](#highlight.tags.name) of a class. + */ + className: t(name), + /** + A label [name](#highlight.tags.name). + */ + labelName: t(name), + /** + A namespace [name](#highlight.tags.name). + */ + namespace: t(name), + /** + The [name](#highlight.tags.name) of a macro. + */ + macroName: t(name), + /** + A literal value. + */ + literal, + /** + A string [literal](#highlight.tags.literal). + */ + string, + /** + A documentation [string](#highlight.tags.string). + */ + docString: t(string), + /** + A character literal (subtag of [string](#highlight.tags.string)). + */ + character: t(string), + /** + An attribute value (subtag of [string](#highlight.tags.string)). + */ + attributeValue: t(string), + /** + A number [literal](#highlight.tags.literal). + */ + number, + /** + An integer [number](#highlight.tags.number) literal. + */ + integer: t(number), + /** + A floating-point [number](#highlight.tags.number) literal. + */ + float: t(number), + /** + A boolean [literal](#highlight.tags.literal). + */ + bool: t(literal), + /** + Regular expression [literal](#highlight.tags.literal). + */ + regexp: t(literal), + /** + An escape [literal](#highlight.tags.literal), for example a + backslash escape in a string. + */ + escape: t(literal), + /** + A color [literal](#highlight.tags.literal). + */ + color: t(literal), + /** + A URL [literal](#highlight.tags.literal). + */ + url: t(literal), + /** + A language keyword. + */ + keyword, + /** + The [keyword](#highlight.tags.keyword) for the self or this + object. + */ + self: t(keyword), + /** + The [keyword](#highlight.tags.keyword) for null. + */ + null: t(keyword), + /** + A [keyword](#highlight.tags.keyword) denoting some atomic value. + */ + atom: t(keyword), + /** + A [keyword](#highlight.tags.keyword) that represents a unit. + */ + unit: t(keyword), + /** + A modifier [keyword](#highlight.tags.keyword). + */ + modifier: t(keyword), + /** + A [keyword](#highlight.tags.keyword) that acts as an operator. + */ + operatorKeyword: t(keyword), + /** + A control-flow related [keyword](#highlight.tags.keyword). + */ + controlKeyword: t(keyword), + /** + A [keyword](#highlight.tags.keyword) that defines something. + */ + definitionKeyword: t(keyword), + /** + A [keyword](#highlight.tags.keyword) related to defining or + interfacing with modules. + */ + moduleKeyword: t(keyword), + /** + An operator. + */ + operator, + /** + An [operator](#highlight.tags.operator) that dereferences something. + */ + derefOperator: t(operator), + /** + Arithmetic-related [operator](#highlight.tags.operator). + */ + arithmeticOperator: t(operator), + /** + Logical [operator](#highlight.tags.operator). + */ + logicOperator: t(operator), + /** + Bit [operator](#highlight.tags.operator). + */ + bitwiseOperator: t(operator), + /** + Comparison [operator](#highlight.tags.operator). + */ + compareOperator: t(operator), + /** + [Operator](#highlight.tags.operator) that updates its operand. + */ + updateOperator: t(operator), + /** + [Operator](#highlight.tags.operator) that defines something. + */ + definitionOperator: t(operator), + /** + Type-related [operator](#highlight.tags.operator). + */ + typeOperator: t(operator), + /** + Control-flow [operator](#highlight.tags.operator). + */ + controlOperator: t(operator), + /** + Program or markup punctuation. + */ + punctuation, + /** + [Punctuation](#highlight.tags.punctuation) that separates + things. + */ + separator: t(punctuation), + /** + Bracket-style [punctuation](#highlight.tags.punctuation). + */ + bracket, + /** + Angle [brackets](#highlight.tags.bracket) (usually `<` and `>` + tokens). + */ + angleBracket: t(bracket), + /** + Square [brackets](#highlight.tags.bracket) (usually `[` and `]` + tokens). + */ + squareBracket: t(bracket), + /** + Parentheses (usually `(` and `)` tokens). Subtag of + [bracket](#highlight.tags.bracket). + */ + paren: t(bracket), + /** + Braces (usually `{` and `}` tokens). Subtag of + [bracket](#highlight.tags.bracket). + */ + brace: t(bracket), + /** + Content, for example plain text in XML or markup documents. + */ + content, + /** + [Content](#highlight.tags.content) that represents a heading. + */ + heading, + /** + A level 1 [heading](#highlight.tags.heading). + */ + heading1: t(heading), + /** + A level 2 [heading](#highlight.tags.heading). + */ + heading2: t(heading), + /** + A level 3 [heading](#highlight.tags.heading). + */ + heading3: t(heading), + /** + A level 4 [heading](#highlight.tags.heading). + */ + heading4: t(heading), + /** + A level 5 [heading](#highlight.tags.heading). + */ + heading5: t(heading), + /** + A level 6 [heading](#highlight.tags.heading). + */ + heading6: t(heading), + /** + A prose [content](#highlight.tags.content) separator (such as a horizontal rule). + */ + contentSeparator: t(content), + /** + [Content](#highlight.tags.content) that represents a list. + */ + list: t(content), + /** + [Content](#highlight.tags.content) that represents a quote. + */ + quote: t(content), + /** + [Content](#highlight.tags.content) that is emphasized. + */ + emphasis: t(content), + /** + [Content](#highlight.tags.content) that is styled strong. + */ + strong: t(content), + /** + [Content](#highlight.tags.content) that is part of a link. + */ + link: t(content), + /** + [Content](#highlight.tags.content) that is styled as code or + monospace. + */ + monospace: t(content), + /** + [Content](#highlight.tags.content) that has a strike-through + style. + */ + strikethrough: t(content), + /** + Inserted text in a change-tracking format. + */ + inserted: t(), + /** + Deleted text. + */ + deleted: t(), + /** + Changed text. + */ + changed: t(), + /** + An invalid or unsyntactic element. + */ + invalid: t(), + /** + Metadata or meta-instruction. + */ + meta, + /** + [Metadata](#highlight.tags.meta) that applies to the entire + document. + */ + documentMeta: t(meta), + /** + [Metadata](#highlight.tags.meta) that annotates or adds + attributes to a given syntactic element. + */ + annotation: t(meta), + /** + Processing instruction or preprocessor directive. Subtag of + [meta](#highlight.tags.meta). + */ + processingInstruction: t(meta), + /** + [Modifier](#highlight.Tag^defineModifier) that indicates that a + given element is being defined. Expected to be used with the + various [name](#highlight.tags.name) tags. + */ + definition: Tag.defineModifier("definition"), + /** + [Modifier](#highlight.Tag^defineModifier) that indicates that + something is constant. Mostly expected to be used with + [variable names](#highlight.tags.variableName). + */ + constant: Tag.defineModifier("constant"), + /** + [Modifier](#highlight.Tag^defineModifier) used to indicate that + a [variable](#highlight.tags.variableName) or [property + name](#highlight.tags.propertyName) is being called or defined + as a function. + */ + function: Tag.defineModifier("function"), + /** + [Modifier](#highlight.Tag^defineModifier) that can be applied to + [names](#highlight.tags.name) to indicate that they belong to + the language's standard environment. + */ + standard: Tag.defineModifier("standard"), + /** + [Modifier](#highlight.Tag^defineModifier) that indicates a given + [names](#highlight.tags.name) is local to some scope. + */ + local: Tag.defineModifier("local"), + /** + A generic variant [modifier](#highlight.Tag^defineModifier) that + can be used to tag language-specific alternative variants of + some common tag. It is recommended for themes to define special + forms of at least the [string](#highlight.tags.string) and + [variable name](#highlight.tags.variableName) tags, since those + come up a lot. + */ + special: Tag.defineModifier("special") +}; +for (let name in tags) { + let val = tags[name]; + if (val instanceof Tag) + val.name = name; +} +/** +This is a highlighter that adds stable, predictable classes to +tokens, for styling with external CSS. + +The following tags are mapped to their name prefixed with `"tok-"` +(for example `"tok-comment"`): + +* [`link`](#highlight.tags.link) +* [`heading`](#highlight.tags.heading) +* [`emphasis`](#highlight.tags.emphasis) +* [`strong`](#highlight.tags.strong) +* [`keyword`](#highlight.tags.keyword) +* [`atom`](#highlight.tags.atom) +* [`bool`](#highlight.tags.bool) +* [`url`](#highlight.tags.url) +* [`labelName`](#highlight.tags.labelName) +* [`inserted`](#highlight.tags.inserted) +* [`deleted`](#highlight.tags.deleted) +* [`literal`](#highlight.tags.literal) +* [`string`](#highlight.tags.string) +* [`number`](#highlight.tags.number) +* [`variableName`](#highlight.tags.variableName) +* [`typeName`](#highlight.tags.typeName) +* [`namespace`](#highlight.tags.namespace) +* [`className`](#highlight.tags.className) +* [`macroName`](#highlight.tags.macroName) +* [`propertyName`](#highlight.tags.propertyName) +* [`operator`](#highlight.tags.operator) +* [`comment`](#highlight.tags.comment) +* [`meta`](#highlight.tags.meta) +* [`punctuation`](#highlight.tags.punctuation) +* [`invalid`](#highlight.tags.invalid) + +In addition, these mappings are provided: + +* [`regexp`](#highlight.tags.regexp), + [`escape`](#highlight.tags.escape), and + [`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string) + are mapped to `"tok-string2"` +* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName2"` +* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName tok-local"` +* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName) + to `"tok-variableName tok-definition"` +* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName) + to `"tok-propertyName tok-definition"` +*/ +const classHighlighter = tagHighlighter([ + { tag: tags.link, class: "tok-link" }, + { tag: tags.heading, class: "tok-heading" }, + { tag: tags.emphasis, class: "tok-emphasis" }, + { tag: tags.strong, class: "tok-strong" }, + { tag: tags.keyword, class: "tok-keyword" }, + { tag: tags.atom, class: "tok-atom" }, + { tag: tags.bool, class: "tok-bool" }, + { tag: tags.url, class: "tok-url" }, + { tag: tags.labelName, class: "tok-labelName" }, + { tag: tags.inserted, class: "tok-inserted" }, + { tag: tags.deleted, class: "tok-deleted" }, + { tag: tags.literal, class: "tok-literal" }, + { tag: tags.string, class: "tok-string" }, + { tag: tags.number, class: "tok-number" }, + { tag: [tags.regexp, tags.escape, tags.special(tags.string)], class: "tok-string2" }, + { tag: tags.variableName, class: "tok-variableName" }, + { tag: tags.local(tags.variableName), class: "tok-variableName tok-local" }, + { tag: tags.definition(tags.variableName), class: "tok-variableName tok-definition" }, + { tag: tags.special(tags.variableName), class: "tok-variableName2" }, + { tag: tags.definition(tags.propertyName), class: "tok-propertyName tok-definition" }, + { tag: tags.typeName, class: "tok-typeName" }, + { tag: tags.namespace, class: "tok-namespace" }, + { tag: tags.className, class: "tok-className" }, + { tag: tags.macroName, class: "tok-macroName" }, + { tag: tags.propertyName, class: "tok-propertyName" }, + { tag: tags.operator, class: "tok-operator" }, + { tag: tags.comment, class: "tok-comment" }, + { tag: tags.meta, class: "tok-meta" }, + { tag: tags.invalid, class: "tok-invalid" }, + { tag: tags.punctuation, class: "tok-punctuation" } +]); + +export { Tag, classHighlighter, getStyleTags, highlightCode, highlightTree, styleTags, tagHighlighter, tags }; diff --git a/node_modules/@lezer/highlight/package.json b/node_modules/@lezer/highlight/package.json new file mode 100644 index 0000000000..1da0d5af78 --- /dev/null +++ b/node_modules/@lezer/highlight/package.json @@ -0,0 +1,31 @@ +{ + "name": "@lezer/highlight", + "version": "1.2.1", + "description": "Highlighting system for Lezer parse trees", + "main": "dist/index.cjs", + "type": "module", + "exports": { + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "module": "dist/index.js", + "types": "dist/index.d.ts", + "author": "Marijn Haverbeke ", + "license": "MIT", + "devDependencies": { + "@marijn/buildtool": "0.1.3", + "typescript": "^5.0.0" + }, + "dependencies": { + "@lezer/common": "^1.0.0" + }, + "files": ["dist"], + "repository": { + "type" : "git", + "url" : "https://github.com/lezer-parser/highlight.git" + }, + "scripts": { + "watch": "node build.js --watch", + "prepare": "node build.js" + } +} diff --git a/node_modules/@lezer/html/CHANGELOG.md b/node_modules/@lezer/html/CHANGELOG.md new file mode 100644 index 0000000000..7f0c2d6811 --- /dev/null +++ b/node_modules/@lezer/html/CHANGELOG.md @@ -0,0 +1,285 @@ +## 1.3.10 (2024-05-29) + +### Bug fixes + +Fix an issue that broke attribute reading when defining a nested language on a tag that isn't a `style`, `textearea`, or `script` tag. + +## 1.3.9 (2024-02-21) + +### Bug fixes + +When using the "selfClosing" dialect, fix parse errors for `
` (tags that implicitly self-close) and `` (special tags). + +## 1.3.8 (2023-12-28) + +### Bug fixes + +Add `bidiIsolate` node props for tags, comments, and attributes. + +Mark tags, attributes, and comments as isolating for bidirectional text. + +## 1.3.7 (2023-11-23) + +### Bug fixes + +Fix a bug that caused the parser to not properly recognize empty HTML comments. Don't emit nested parses for empty elements in configureNesting + +Fix an issue where `configureNesting` could emit empty overlay ranges for empty elements. + +## 1.3.6 (2023-07-12) + +### Bug fixes + +Improve parsing of multiple unfinished opening tags by disallowing less-than characters in attribute names. + +## 1.3.5 (2023-07-03) + +### Bug fixes + +Make the package work with new TS resolution styles. + +## 1.3.4 (2023-03-27) + +### Bug fixes + +Fix a bug that caused mixed parsing of non-style/script elements to attach the nested parse tree to the incorrect node. + +## 1.3.3 (2023-02-21) + +### Bug fixes + +Make sure build output is strictly ES6 again. + +## 1.3.2 (2023-02-16) + +### Bug fixes + +Fix a crash caused by nexted parsing of attributes returning invalid ranges for attributes missing their closing quote. + +## 1.3.1 (2023-02-11) + +### Bug fixes + +Always allow self-closing tags in `