From fb69ea41723ae7f0121ecf970f32f6a97df8753c Mon Sep 17 00:00:00 2001 From: xqz_admin Date: Mon, 23 Jun 2025 10:46:41 +0800 Subject: [PATCH] =?UTF-8?q?1.2.1=E6=9B=B4=E6=96=B0,=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E8=AF=B7=E7=9C=8Breadme.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 6148 bytes Echo_Z/__pycache__/settings.cpython-39.pyc | Bin 2460 -> 2469 bytes Echo_Z/settings.py | 1 + README.md | 12 +- api/__pycache__/admin.cpython-39.pyc | Bin 190 -> 190 bytes api/__pycache__/models.cpython-39.pyc | Bin 187 -> 187 bytes api/__pycache__/urls.cpython-39.pyc | Bin 248 -> 465 bytes api/__pycache__/views.cpython-39.pyc | Bin 0 -> 1745 bytes api/urls.py | 7 +- api/views.py | 45 ++++- comment/__init__.py | 0 comment/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 153 bytes comment/__pycache__/admin.cpython-39.pyc | Bin 0 -> 519 bytes comment/__pycache__/apps.cpython-39.pyc | Bin 0 -> 463 bytes comment/__pycache__/models.cpython-39.pyc | Bin 0 -> 1030 bytes comment/admin.py | 7 + comment/apps.py | 7 + comment/migrations/0001_initial.py | 27 +++ .../migrations/0002_comment_archives_id.py | 18 ++ ...03_comment_qq_alter_comment_archives_id.py | 23 +++ comment/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-39.pyc | Bin 0 -> 898 bytes .../0002_comment_archives_id.cpython-39.pyc | Bin 0 -> 626 bytes ...q_alter_comment_archives_id.cpython-39.pyc | Bin 0 -> 725 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 164 bytes comment/models.py | 16 ++ comment/tests.py | 3 + comment/views.py | 4 + db.sqlite3 | Bin 139264 -> 151552 bytes home/.DS_Store | Bin 0 -> 6148 bytes home/__pycache__/admin.cpython-39.pyc | Bin 605 -> 841 bytes home/__pycache__/apps.cpython-39.pyc | Bin 460 -> 454 bytes home/__pycache__/models.cpython-39.pyc | Bin 1082 -> 1634 bytes home/__pycache__/views.cpython-39.pyc | Bin 1020 -> 1627 bytes home/admin.py | 14 +- home/apps.py | 2 +- home/migrations/0005_articleslike.py | 25 +++ .../0005_articleslike.cpython-39.pyc | Bin 0 -> 874 bytes home/models.py | 12 +- home/static/aaa.js | 12 ++ home/static/archives.css | 25 +++ home/static/marked.min.js | 6 + home/templates/archives.html | 158 +++++++++++++++++- home/templates/bottom.html | 40 +---- home/templates/index.html | 36 ++++ home/views.py | 35 +++- requirements.txt | 15 ++ 47 files changed, 491 insertions(+), 59 deletions(-) create mode 100644 .DS_Store create mode 100644 api/__pycache__/views.cpython-39.pyc create mode 100644 comment/__init__.py create mode 100644 comment/__pycache__/__init__.cpython-39.pyc create mode 100644 comment/__pycache__/admin.cpython-39.pyc create mode 100644 comment/__pycache__/apps.cpython-39.pyc create mode 100644 comment/__pycache__/models.cpython-39.pyc create mode 100644 comment/admin.py create mode 100644 comment/apps.py create mode 100644 comment/migrations/0001_initial.py create mode 100644 comment/migrations/0002_comment_archives_id.py create mode 100644 comment/migrations/0003_comment_qq_alter_comment_archives_id.py create mode 100644 comment/migrations/__init__.py create mode 100644 comment/migrations/__pycache__/0001_initial.cpython-39.pyc create mode 100644 comment/migrations/__pycache__/0002_comment_archives_id.cpython-39.pyc create mode 100644 comment/migrations/__pycache__/0003_comment_qq_alter_comment_archives_id.cpython-39.pyc create mode 100644 comment/migrations/__pycache__/__init__.cpython-39.pyc create mode 100644 comment/models.py create mode 100644 comment/tests.py create mode 100644 comment/views.py create mode 100644 home/.DS_Store create mode 100644 home/migrations/0005_articleslike.py create mode 100644 home/migrations/__pycache__/0005_articleslike.cpython-39.pyc create mode 100644 home/static/aaa.js create mode 100644 home/static/marked.min.js create mode 100644 requirements.txt diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..21bf08d1869d3463fede6447d27e4f1c8605c362 GIT binary patch literal 6148 zcmeH~J#ND=422&P4*{}x%&4UY$PI)bJwY!Jv literal 0 HcmV?d00001 diff --git a/Echo_Z/__pycache__/settings.cpython-39.pyc b/Echo_Z/__pycache__/settings.cpython-39.pyc index 4faaecd1e3ca712ba606dff064bcdf4df4f81a77..8723b0b937da3d06ad7641087c74ee491504ea18 100644 GIT binary patch delta 67 zcmbOuyi}Msk(ZZ?0SG2-iO5*CkvEZvk!x~3lPKpc_T>EB+|<01%`Hr=%#1vnx!4{v Vv8e)87O77D%#p;%J2{Ng4FG5w5;gz; delta 57 zcmZ1~JV%%}k(ZZ?0R*-MXH4J7o5;k-IXRz6baO9LD>EbaW?{C+Ol&GZ=^~ZMe>jpD Kc_znmx&Z)$=MB^V diff --git a/Echo_Z/settings.py b/Echo_Z/settings.py index b1abd50..b962349 100644 --- a/Echo_Z/settings.py +++ b/Echo_Z/settings.py @@ -34,6 +34,7 @@ INSTALLED_APPS = [ 'simpleui', 'home', 'api', + 'comment', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', diff --git a/README.md b/README.md index 9e6e8fe..32e3957 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,12 @@ # 目录结构描述 ├── ReadMe.md // 帮助文档 - ├── home // 首页app + ├── home // 文章相关app ├── api // 项目api + ├── comment // 评论app + └── Echo-Z // 项目配置等目录 # 使用说明 @@ -35,3 +37,11 @@ python manage.py runserver 9999 ###### 1.2.0 2025年6月19日 完成文章的基础管理、文章的列表显示、文章的详细信息的功能编写,功能有待完善 + +###### 1.2.1 + 2025年6月23日 + 新增 + 1.文章详情页上一篇、下一篇功能 + 2.文章详情页评论列表显示 + 3.文章详情页评论发布 + 4.文章详情页点赞与取消点赞 diff --git a/api/__pycache__/admin.cpython-39.pyc b/api/__pycache__/admin.cpython-39.pyc index 98c6b4a0d2bbfcba2c462cae6dd5ca5da07ebe7b..b2f0163043899ec017af8f40c12cfe9056d364e2 100644 GIT binary patch delta 53 zcmdnTxQ~%Lk(ZZ?0SH1*hD_vklZ)a@$x6&i&(}-N&nqd)Oe$gm%B^H5Vg^!0%oFqd E0du(x(EtDd delta 53 zcmdnTxQ~%Lk(ZZ?0SIPQ1yAI5le@*2l9ia3p0AgjpI1_pnN-9Clv~MA!~&#>SSIHC F0|0{G4oCn1 diff --git a/api/__pycache__/models.cpython-39.pyc b/api/__pycache__/models.cpython-39.pyc index b2043fba755fa5651840a06f715c027aef8bee20..9b01b34ac6e9f7d5ba4d9fe1fc4e06c5ece51df7 100644 GIT binary patch delta 19 ZcmdnZxSNqXk(ZZ?0SLHGhD_w%001f(1bhGh delta 19 ZcmdnZxSNqXk(ZZ?0SIPQ1yAJO001lM1iSzM diff --git a/api/__pycache__/urls.cpython-39.pyc b/api/__pycache__/urls.cpython-39.pyc index db4cb2686f1f4447a2dc916301f080c705c549ab..572e273336f6474a813c0e44dd45f02c60bb5a30 100644 GIT binary patch delta 323 zcmeytc#&BuoQVaQ@nEZ>xD!)SVD?0@fV4%im*#=>M{yy{y2V{ulv9vc hQj%JfSG124@5U>Bk@rGGGF79Dul3VWPIQaymm4OA2!^gC@&MkRnaS zTdavGxtV!D21`L=Nrs;$>%@N=qTHoLIY4enYEfSCN`@kKpwc4t$)${594tU44}&3c@9*xfz5 zO5{C->;3}{_Hq9Mzof5-L;eCMs@e~n1jJZfs`{$kUG>dZGuqp05_pb(|6%-RK*%2$ z>^>d@U%=7}FoFo0lY%6KqR(<#u!I#};~E2d*mp=*bWcg|;5k%DdelZ@ zWTeRo*<&_PvJ_I;_E*MCPo$n!rItNz+u!J_+{E_AZnj^U`*~hnNMR3m@e?UBB~zpP z)isAo&T2r0V>o(PNHea4hU>$$DhgQ|aOqvkzyI!ZkTNW7{UECmtOv04LokL+=!DJ5 z#9MGdmvrs1B{lvcSd#e$@s?EZEB}(s*&sfS++%Vx8u&3J>vy~gT}u=;rd zRA?KdN&?%eg*SU=(kN`zdS!KCxgMQM6++zeY=~@0Z7j<~(pmj$xUS-ws5fBOU-x1x zN5{#y9+gjzS}VG@s~S$v+!3w<X}o)YKtl`jY|?f0)4(qytU z2bwZrd0j(Wex5y+V(<|4b$^}x79jN+++u@YvK*LN$%m_(fT>$(-UgF&w#VTi+7Yrc zZ{nYu=~$+ZhnPEnSfhXl>rzhJOuY;K3oW8Tw=Mn%fuNV(PMhqC>As6S5El~=gP1tT z5acAhD|*T2oRdi)_&vhNFqrd60L1Ve*?A)PjUhePVP8?WL)`|`qpqjt2n=BULS3h+ z)H-RD@&aB_4Rg^@@8EVMMcqO3Iv5*m7*mHBa&1ON-M}<YfnR{)_!zMNX6`4*zRH|Bd6CJ5=SJ~g+57Z=*;DVqC9hCo10iz> zYWV=Nju7=BdRso!M;KybJ0c0|(kbM9fOq;m-1N)TUC8u%2X07{u9%F', api_views.add_comment), + path('link//', api_views.like), + path('unlink//', api_views.un_like), + path('check_like//', api_views.check_like), ] \ No newline at end of file diff --git a/api/views.py b/api/views.py index 91ea44a..f48a03a 100644 --- a/api/views.py +++ b/api/views.py @@ -1,3 +1,46 @@ -from django.shortcuts import render +from datetime import datetime +from django.shortcuts import render,HttpResponse +from django.http import JsonResponse,HttpResponseNotAllowed,HttpResponseRedirect,JsonResponse +from django.views.decorators.http import require_http_methods + +from comment.models import comment +from home.models import * # Create your views here. + +@require_http_methods(["POST"]) +def add_comment(request, id): + create_comment = comment.objects.create(comment_Content=request.POST.get("comment"),comment_User=request.POST.get("username"), comment_Time=datetime.now(), archives_Id=id, qq=request.POST.get("qqNum")) + create_comment.save() + return HttpResponseRedirect("/archives/"+id) + +@require_http_methods(["POST"]) +def check_like(request, id, uuid): + articles_likes = ArticlesLike.objects.filter(articles_id=id,uuid=uuid) + if articles_likes: + return JsonResponse({"liked":True}) + else: + return JsonResponse({"liked":False}) + +@require_http_methods(["POST"]) +def like(request, id, uuid): + article_stat = 0 + if not ArticlesLike.objects.filter(articles_id=id, uuid=uuid): + ArticlesLike.objects.create(articles_id=id, uuid=uuid) + article = Articles.objects.get(id=id) + article.stat += 1 + article_stat = article.stat + article.save() + return JsonResponse({"success":True,"new_count": article_stat}) + +@require_http_methods(["POST"]) +def un_like(request,id, uuid): + article_stat = 0 + if ArticlesLike.objects.filter(articles_id=id, uuid=uuid): + ArticlesLike.objects.filter(articles_id=id, uuid=uuid).delete() + article = Articles.objects.get(id=id) + article.stat -= 1 + article_stat = article.stat + article.save() + + return JsonResponse({"success":True,"new_count": article_stat}) diff --git a/comment/__init__.py b/comment/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/comment/__pycache__/__init__.cpython-39.pyc b/comment/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7019d898d4963f712ab264997424b1e8e36cd5d GIT binary patch literal 153 zcmYe~<>g`kf>$R(GC=fW5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HWerR!OQL%nh zMrmSRm63jOeoCr-L1jrsex81DW^O@FYH6mvYjQ?@d=yYFH#aq}L_a=0GcU6wK3=b& V@)n0pZhlH>PO2Tq+|NMF008M@B_RL+ literal 0 HcmV?d00001 diff --git a/comment/__pycache__/admin.cpython-39.pyc b/comment/__pycache__/admin.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4076ffa7e0f1ce9712953a70ff0748642d89374e GIT binary patch literal 519 zcmYjNu};G<5Vhl^jY?V;ej-aFF(HAVs6vQ=E|kTKWn!yw6(=E1kjh#<1laf)KENvz zI};PEsF+7ZSI2n7n5}car-}Q*Bs6Pz@qC=5rI1Or zYO=COjM7yuTa{d;S;;8WI>|}5gK@R0eV}m*HcoWtb$Ax{=}0Vju_(tW$f?ys?aFkt uZ6CvoGB-7Wqz!AifYCtY;MS$PjdVP_88^|Wdw#YNc#Z*?9=HfcB*cG&h=^tY literal 0 HcmV?d00001 diff --git a/comment/__pycache__/apps.cpython-39.pyc b/comment/__pycache__/apps.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bdca114b673f4cf1748891c87956f16dcfa53321 GIT binary patch literal 463 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 literal 0 HcmV?d00001 diff --git a/comment/models.py b/comment/models.py new file mode 100644 index 0000000..fe2f76a --- /dev/null +++ b/comment/models.py @@ -0,0 +1,16 @@ +from django.db import models + +# Create your models here. +class comment(models.Model): + comment_Content = models.TextField(verbose_name="评论内容") + comment_User = models.CharField(max_length=100,verbose_name="评论者") + comment_Time = models.DateTimeField(verbose_name="评论时间") + archives_Id = models.IntegerField(default=0, verbose_name="文章id") + qq = models.IntegerField(default=1000, verbose_name="评论者qq号") + + def __str__(self): + return self.comment_content + + class Meta: + verbose_name = "评论" + verbose_name_plural = "评论管理" \ No newline at end of file diff --git a/comment/tests.py b/comment/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/comment/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/comment/views.py b/comment/views.py new file mode 100644 index 0000000..27cdb63 --- /dev/null +++ b/comment/views.py @@ -0,0 +1,4 @@ +from django.shortcuts import render + +# Create your views here. + diff --git a/db.sqlite3 b/db.sqlite3 index 8a0c581511538f55f8e6a4c85d94bcb1370ca6ea..286058524ac5481750944506b7a540e0447c9ec7 100644 GIT binary patch delta 5498 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 delta 2133 zcmY+FU5Fdk7030lyV|wcy|&{z#97;EXlj~xocYj5nl()_qmLO$Gn$b!qc1R%8EN!A z9~zCMk!V?~;6k&Z#9fM@FZDwpeFzw3DeKUdrtVYQKOX zGA|cLh1tZY(ljqtBa)^;(|)a5p_wqH3P#Q8rIhH@h>a5#qeymIwTmo5WD9tAR-dV{ ziJjGxijJ{U*D96GDc4a1!Vs%$L}^-Ngp%_J%=g*`4wrg0D%nS>47Ll`9J(i0)PhWl zVoR6%wmE5==``uq@2wjwHSeMC7}P0%CsY$&!0-J#uNT{F**#%j#cCz3QU^0b5H#0(V1Bj`vT z)y7g@p>s%;H0Y^nkvYrE#I;_n#CPM;fQeJ7Vwy}$`?9RUrqUSOw1MoB4co-H=7pgH7iG2`sIO+jS%Y}BDy zI3~pU=pZhX+!!ISP`QZH%~FCdW9Wp9p^2F-s)9()Y=Ug(rqO(Q2N@M9G`cfG9kSK2 zrtw6$UuYNAVYP^jBZD-`GfXO8uAmO0!6R)9)nODyaR`n=F!mfA+rh(UcHrpM2oc5+ zxF`|O?P4quD}ezzLB*$J+4Zzzil9Qf+41S4Z3ag?M(duBVWYHY?}{j4Q* zVg%u&i)KBEGE=xoyQ5w<$3O&OvXVXIRk~fwDh-MY$1n~eaKnN*cfe!|ol>u42u6ga z3>ovDTduKWv)S zWwd9=p)a*^=sx%grcAMXgjM{ijM8je@CTI=5!j48UH>??I zik)(iaU?1XQL+(3yHUjAX*g>UTr$_kc`DV+v1X)Kbu+~p{3E_HF(y$^ti5K{24o|xX zYZM}K#70bszy%)Z{cnic~2Z=%b2$bT4B{O@f9f)AJTzXcCJGWL+}Q0mva>?+>iWko?YL(>jQ_t0La$6TjmzJ`Pt^(<^1;M;oXn@(wWfP;3jAS zdO63yf`07ZJpH7G|69Tf?XjOd=i&c9b?{=4^e?{q^}zYXUmp7}9h|=LDY*64X|F$> z32j~RfnS1egIBjc-+F(`-nz1!pW9kXgf@K7A`5dnaB=ag?ZEb_;Bh-mu6Y>0gsrbH zKDiKxfn)gEst2J9NATXo0QLo>Ry_E%7mnaJE(Y)~U^2MjyMP}@GM55G=BPto3wVK- zpYZ~p{`-&j9^Uyr`eZ_n$CJgeYDFM~I64{{-htuct*`kve9ye_EVi+Dh6Ww+l6f_84h*_zHXoWdYj!B=x8wZc>7q4|BNd=;as-E5`>< bio9ZT?AOFO(CLUf9mt;n(}hL_{#$`7BYqXB literal 0 HcmV?d00001 diff --git a/home/__pycache__/admin.cpython-39.pyc b/home/__pycache__/admin.cpython-39.pyc index 21325e577e7c4fbbb1ac838f30ea10062aaeaabc..69620bd325aac5ac0af0de22d0ebb4f79dfb9979 100644 GIT binary patch delta 433 zcmZutJ5B>J5cSyJjmc+4A|jfIf+Er)QBu*6iiSi;q(E*^l(Ar81ClqXQ-lkkG%2B_ z;}nQ1SmFRQoPn7okti5zp5Dx}$It%MA8|5jG^&E)y?=T0DxZ?h{G2Kj2)USm1z;|7 zITQ|_mD4Y9Do~+*6sR5CMhmq78<$$8)FO;Yqt040Sh*0X`Ql4b2+;^9**y_B7<21y z02L>1t7DkQ#0vIhlm;z%c}?a2M|g9GzzGW|tVFPiQlqpHDjTCF2T^GD{4^Wqt~kr? zT(7htLv6HfUS$~cY?h&~imnjDL0a)O8tUr|4Tgkao1w|jS{};XJ>MqYqAU!7k-vV+ y?jYS-e#8DzFy38f#nky=HXcH?|9~zpZIn+7^^L^#e4B=M6aIp_G|IqE&A<=N=2g=G delta 196 zcmX@fc9(@Ok(ZZ?0SG3a56;-ZIFU~#!UD)kVMt-jVaR2SVq^rdnR1wNnWLB)8B!S+ zu%t3CWOQdpVNPLbVMt*~Wz1r2W^QJTVoPBSX3%7N2{KHR@fK@hN^WKzkin5yRFavT zlUh9a52Mt^wdRb{>_8R8AWJ!zSr}QEK(L4f$o11?pS+JrNw$a?$hpN)l$xGdT#{OJ ei_14ZB{jzpWL^==WKm`{E;gV79wr_Z4n_dtBP)jh diff --git a/home/__pycache__/apps.cpython-39.pyc b/home/__pycache__/apps.cpython-39.pyc index 5b97444e8e0dcc93d51291dfca1f7fd83f7012dd..b2497b52466d3ac9b7123da4d3ccc60b161c01fd 100644 GIT binary patch delta 35 pcmX@Ze2kelk(ZZ?0SKO)3dvY8k#|2A8<6vCTKn_W3nt$A006uQ4Lkq< delta 41 vcmX@ce1@4fk(ZZ?0SJsY2WPCC$h%*F2grFgt^N7x1<%(ld_JLV;2xlB5w!D{UjF4NARu5-A2jFHMl@K|*0!J6oG}YjAe=B0|8H zRu6*9h}kDuNZP-_i|_3wm|_R!%glT8e(dM%H{*A~w2Q@@gzIPX z-nylR<{7vWUaU>tl9F*D4_IT?+rfg z_xJaX-oJ^&99#xn+=ffVNRD;ptl5Fy2w&Z1~ zi0|@+s}Z#75Nm$Ncby1g)pOi6p1z`|Wt3RAEYIhbRmF=Zqe$?$)DSggVvhRZMG}*Q zoN@NXy3KEP9GCH`xT~y8RmgRk4hKvb7$_-`4&zxWqLP_v4xWBJ{QP$C>O=q87sPdVu*)?x zui`$oD9?3C{DPU4@_2!TrsLZ|2EA#fg#Iw;r+0&wyDgqa=YL;CHmX03+oNs_P=P1B zdwc@#NL&p9?DrI2#=?nq0%{fyBhuAlEe%J}s^|C#?D-4^w)6JzpRusSB;`CyLM`=9 zo&&jSC^RIGh#FvmDVu6yZPm3n%QozX54sENemZ2W*=3H)l~Lr_SEQpwM{Hc%>axIf N7Kv~|LM^D3%3q}LwD$l2 delta 335 zcmaFFvx|c-k(ZZ?0SMwQ1ZPMvPvnzfRGO%*$d5QxGHnWJ^}{2u(&mO~zZSC7C5TsXzuxacWLl5kwV8 zDIbuy#U3ADTv8MtF9PHgGXV((#wr1ryY!%vewuCkHZ%FbYggV~&yH z2MGv)2!y#{7T@GM%o-kknk=_CQ?e5C()0CFl8Qj)-(vO6Pf5)wV#cNkB+p@!o1ape OlWNBZU!vX-Vk5Cu@ diff --git a/home/__pycache__/views.cpython-39.pyc b/home/__pycache__/views.cpython-39.pyc index 03b57168b7821f150831e6452ad1ee653583ebd1..59b6c653d7c4cfab5d5d22c8b0a046199a90f5bf 100644 GIT binary patch literal 1627 zcmZuxOOG2x5T5RN+GFo}^VozS@w!b!)`$x^AOs3T;j#x<5E= zC0-H;v}Yu=2k(&+*Zh_~ArS@T$Tdiaug3Q71~H@hx~rzDrn(-TwcAYx&zJW;>wg_O z&L6~Fd^nhQLHag8ID(bVkfm(MQ_hIzrMpL~TY5u3^&#_w|DBTtA`l_gP(&X)N#iN3 zorK#!$&rxCw(c1-`AF)?c%)^*EV~H^^YL&fMay?T7C5$Fy`e+n?pfGzl`GiQPw zI0c*YioNfA{>I#`+yRjX@<9P81Vw_M1aq(Ag1z7@8kKj-m~*&oniax^)H`+&qQ7gS zOqsl2N}U9j7sC3cFr|ceUmKO>1_3IW87Zu%O=heIPRyDGPV``>Z-(Xa3?m~Sm?XB* zd&(3!+}UuvKajc6*3HUNAQx$ zvBI+KS4Uk1^Xzu_6D^hQru}I)n!VZ0$3k`|4^4kO>gr-RDdn{2evtRay|mjO4`uhL zkYDJX$wTYcv6DxA9pJDgk66S#cJ@9Cq7GBn@GYl^)=wK73b(Gx4b+ROGC(B+JEn?o z&l$LazvXbJha4}wQ->{eeCW8xY!L|5VG*K^sF}J;bsE7Qb#m1nxW1!`6WE1MA958%iqnn$LISjeVP+caSl<3Ejx4vyw_-rB61 z-%@9Fb`w??{VDZz!qT7+y% zM+~yj!FWfbx+b3*U1vbK_?*UcA?yrsW0X4GSk-aGt2)UPRqg6R+;r`zW$NUvfVVHhEfTF+6eA-y@j+Y+5 z2Lyl+umTuKcIq!h$0S`NXX8$s!=Ak-cG3~a;j1{|P^-7;!c^NVuat>=#|r5@Ti8m$ z=N)5pnpqcQTBTM=CyY(46A;OxQ30(Ttmk%KK{G+t)K(qXXsWS?{>&nSGhNW^lq$2v z@wBR(*Xp9SI)F7A8`UdlPz*grGXdlLv~7VnjVeT*3$)r>C}Wf0s!;9YDq1+2ek1xm z1eed_4@PMdC;1|+kDkUEa2vOWHgD?K6!W%Hiz0rT<;`{y=gnNj`-S>q*4snp^?hK` z<`Eb|Cp5%|3Hs-`^urm|4`DXLny!Zc2kY?ci>I9VPm>{K)>=|KX8G)ULPQ3M@A34uT)5(+>Y>Sjjega4kW_{t3wLF@)J3I4s-mp%mW#Bq@`(fxPx`4-ssj9%>kV~rkBtylz-6(UV?RgY8P zQQp@_Czpd@0ss6F8gBR|7(M|rFnx>LgPJbD>w^Z^_|>2ejU9V~Koj?x;6Mx7I|Q+d z*ntk5g3}rY7IfhZOuZv8y<=gn7R(^Av&vch&j{(+VH$HaGdDMPnKD_3e#CRi$|6jq zau<&_?ubpUh=BXcimcq|*~-O;l=dZO1qap6q==au(oH^8PR^xZk=WwOeZu8>nsb^k ztkIsN7a&c1XxT)w_jY^qc~<~ZX#n3~WmL!x?kl@21ss5mn?f^s_GACs`_Y?^d#}Fl z?QZXXeOdLEJ*5#(f+DOgmGwzv=}z3ymk*=Y7(UKBeUcQ-qEfP`XDPelSlP*H%qh@uyU^C`AFwh@a8zTmkeSX#B0s_v|6#U)Oaq1@{t zSj4_9>l(^kNeUitIY!P>$d24rn(?E7`DDloc(XFU?|KigwYleqB}=yEy*_64vLPy! zc)5tPh?l~<*$-3dds0&&o[o.length-1])||6!==c[0]&&2!==c[0])){a=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]=i+o?(i=c,[4,new Promise((function(n){var e=new MessageChannel;e.port1.onmessage=function(){return n()},e.port2.postMessage(null)}))]):[3,3]):[3,4];case 2:t.sent(),t.label=3;case 3:return++a,[3,1];case 4:return[2,e]}}))}))}function u(n){return n.then(void 0,(function(){})),n}function l(n){return parseInt(n)}function s(n){return parseFloat(n)}function d(n,e){return"number"==typeof n&&isNaN(n)?e:n}function f(n){return n.reduce((function(n,e){return n+(e?1:0)}),0)}function m(n,e){if(void 0===e&&(e=1),Math.abs(e)>=1)return Math.round(n/e)*e;var t=1/e;return Math.round(n*t)/t}function v(n,e){var t=n[0]>>>16,r=65535&n[0],o=n[1]>>>16,i=65535&n[1],a=e[0]>>>16,c=65535&e[0],u=e[1]>>>16,l=0,s=0,d=0,f=0;d+=(f+=i+(65535&e[1]))>>>16,f&=65535,s+=(d+=o+u)>>>16,d&=65535,l+=(s+=r+c)>>>16,s&=65535,l+=t+a,l&=65535,n[0]=l<<16|s,n[1]=d<<16|f}function h(n,e){var t=n[0]>>>16,r=65535&n[0],o=n[1]>>>16,i=65535&n[1],a=e[0]>>>16,c=65535&e[0],u=e[1]>>>16,l=65535&e[1],s=0,d=0,f=0,m=0;f+=(m+=i*l)>>>16,m&=65535,d+=(f+=o*l)>>>16,f&=65535,d+=(f+=i*u)>>>16,f&=65535,s+=(d+=r*l)>>>16,d&=65535,s+=(d+=o*u)>>>16,d&=65535,s+=(d+=i*c)>>>16,d&=65535,s+=t*l+r*u+o*c+i*a,s&=65535,n[0]=s<<16|d,n[1]=f<<16|m}function p(n,e){var t=n[0];32===(e%=64)?(n[0]=n[1],n[1]=t):e<32?(n[0]=t<>>32-e,n[1]=n[1]<>>32-e):(e-=32,n[0]=n[1]<>>32-e,n[1]=t<>>32-e)}function b(n,e){0!==(e%=64)&&(e<32?(n[0]=n[1]>>>32-e,n[1]=n[1]<>>1];y(n,e),h(n,g),e[1]=n[0]>>>1,y(n,e),h(n,w),e[1]=n[0]>>>1,y(n,e)}var k=[2277735313,289559509],V=[1291169091,658871167],S=[0,5],W=[0,1390208809],x=[0,944331445];function Z(n,e){var t=function(n){for(var e=new Uint8Array(n.length),t=0;t127)return(new TextEncoder).encode(n);e[t]=r}return e}(n);e=e||0;var r,o=[0,t.length],i=o[1]%16,a=o[1]-i,c=[0,e],u=[0,e],l=[0,0],s=[0,0];for(r=0;r>>0).toString(16)).slice(-8)+("00000000"+(c[1]>>>0).toString(16)).slice(-8)+("00000000"+(u[0]>>>0).toString(16)).slice(-8)+("00000000"+(u[1]>>>0).toString(16)).slice(-8)}function R(n){return"function"!=typeof n}function M(n,r,o,i){var l=Object.keys(n).filter((function(n){return!function(n,e){for(var t=0,r=n.length;t=4}function I(){var n=window,e=navigator;return f(["msWriteProfilerMark"in n,"MSStream"in n,"msLaunchUri"in e,"msSaveBlob"in e])>=3&&!F()}function Y(){var n=window,e=navigator;return f(["webkitPersistentStorage"in e,"webkitTemporaryStorage"in e,0===(e.vendor||"").indexOf("Google"),"webkitResolveLocalFileSystemURL"in n,"BatteryManager"in n,"webkitMediaStream"in n,"webkitSpeechGrammar"in n])>=5}function j(){var n=window;return f(["ApplePayError"in n,"CSSPrimitiveValue"in n,"Counter"in n,0===navigator.vendor.indexOf("Apple"),"RGBColor"in n,"WebKitMediaKeys"in n])>=4}function X(){var n=window,e=n.HTMLElement,t=n.Document;return f(["safari"in n,!("ongestureend"in n),!("TouchEvent"in n),!("orientation"in n),e&&!("autocapitalize"in e.prototype),t&&"pointerLockElement"in t.prototype])>=4}function C(){var n,e=window;return n=e.print,/^function\s.*?\{\s*\[native code]\s*}$/.test(String(n))&&"[object WebPageNamespace]"===String(e.browser)}function P(){var n,e,t=window;return f(["buildID"in navigator,"MozAppearance"in(null!==(e=null===(n=document.documentElement)||void 0===n?void 0:n.style)&&void 0!==e?e:{}),"onmozfullscreenchange"in t,"mozInnerScreenX"in t,"CSSMozDocumentRule"in t,"CanvasCaptureMediaStream"in t])>=4}function E(){var n=window,e=navigator,t=n.CSS,r=n.HTMLButtonElement;return f([!("getStorageUpdates"in e),r&&"popover"in r.prototype,"CSSCounterStyleRule"in n,t.supports("font-size-adjust: ex-height 0.5"),t.supports("text-transform: full-width")])>=4}function H(){var n=document;return n.fullscreenElement||n.msFullscreenElement||n.mozFullScreenElement||n.webkitFullscreenElement||null}function A(){var n=Y(),e=P(),t=window,r=navigator,o="connection";return n?f([!("SharedWorker"in t),r[o]&&"ontypechange"in r[o],!("sinkId"in new Audio)])>=2:!!e&&f(["onorientationchange"in t,"orientation"in t,/android/i.test(r.appVersion)])>=2}function N(){var n=navigator,e=window,t=Audio.prototype,r=e.visualViewport;return f(["srLatency"in t,"srChannelCount"in t,"devicePosture"in n,r&&"segments"in r,"getTextInformation"in Image.prototype])>=3}function J(){var n=window,e=n.OfflineAudioContext||n.webkitOfflineAudioContext;if(!e)return-2;if(j()&&!X()&&!function(){var n=window;return f(["DOMRectList"in n,"RTCPeerConnectionIceEvent"in n,"SVGGeometryElement"in n,"ontransitioncancel"in n])>=3}())return-1;var t=new e(1,5e3,44100),r=t.createOscillator();r.type="triangle",r.frequency.value=1e4;var o=t.createDynamicsCompressor();o.threshold.value=-50,o.knee.value=40,o.ratio.value=12,o.attack.value=0,o.release.value=.25,r.connect(o),o.connect(t.destination),r.start(0);var a=function(n){var e=3,t=500,r=500,o=5e3,a=function(){};return[new Promise((function(c,l){var s=!1,d=0,f=0;n.oncomplete=function(n){return c(n.renderedBuffer)};var m=function(){setTimeout((function(){return l(T("timeout"))}),Math.min(r,f+o-Date.now()))},v=function(){try{var r=n.startRendering();switch(i(r)&&u(r),n.state){case"running":f=Date.now(),s&&m();break;case"suspended":document.hidden||d++,s&&d>=e?l(T("suspended")):setTimeout(v,t)}}catch(o){l(o)}};v(),a=function(){s||(s=!0,f>0&&m())}})),a]}(t),c=a[0],l=a[1],s=u(c.then((function(n){return function(n){for(var e=0,t=0;t.6*t.length}))).sort(),[2,i]}var c}))}))},fontPreferences:function(){return function(n,e){void 0===e&&(e=4e3);return D((function(t,o){var i=o.document,a=i.body,c=a.style;c.width="".concat(e,"px"),c.webkitTextSizeAdjust=c.textSizeAdjust="none",Y()?a.style.zoom="".concat(1/o.devicePixelRatio):j()&&(a.style.zoom="reset");var u=i.createElement("div");return u.textContent=r([],Array(e/20<<0),!0).map((function(){return"word"})).join(" "),a.appendChild(u),n(i,a)}),'')}((function(n,e){for(var t={},r={},o=0,i=Object.keys(vn);o=3)?-4:J();var n,e},screenFrame:function(){var n=this;if(j()&&E()&&C())return function(){return Promise.resolve(void 0)};var r=nn();return function(){return e(n,void 0,void 0,(function(){var n,e;return t(this,(function(t){switch(t.label){case 0:return[4,r()];case 1:return n=t.sent(),[2,[(e=function(n){return null===n?null:m(n,10)})(n[0]),e(n[1]),e(n[2]),e(n[3])]]}}))}))}},canvas:function(){return U(j()&&E()&&C())},osCpu:function(){return navigator.oscpu},languages:function(){var n,e=navigator,t=[],r=e.language||e.userLanguage||e.browserLanguage||e.systemLanguage;if(void 0!==r&&t.push([r]),Array.isArray(e.languages))Y()&&f([!("MediaSettingsRange"in(n=window)),"RTCEncodedAudioFrame"in n,""+n.Intl=="[object Intl]",""+n.Reflect=="[object Reflect]"])>=3||t.push(e.languages);else if("string"==typeof e.languages){var o=e.languages;o&&t.push(o.split(","))}return t},colorDepth:function(){return window.screen.colorDepth},deviceMemory:function(){return d(s(navigator.deviceMemory),void 0)},screenResolution:function(){if(!(j()&&E()&&C()))return K()},hardwareConcurrency:function(){return d(l(navigator.hardwareConcurrency),void 0)},timezone:function(){var n,e=null===(n=window.Intl)||void 0===n?void 0:n.DateTimeFormat;if(e){var t=(new e).resolvedOptions().timeZone;if(t)return t}var r,o=(r=(new Date).getFullYear(),-Math.max(s(new Date(r,0,1).getTimezoneOffset()),s(new Date(r,6,1).getTimezoneOffset())));return"UTC".concat(o>=0?"+":"").concat(o)},sessionStorage:function(){try{return!!window.sessionStorage}catch(n){return!0}},localStorage:function(){try{return!!window.localStorage}catch(n){return!0}},indexedDB:function(){if(!F()&&!I())try{return!!window.indexedDB}catch(n){return!0}},openDatabase:function(){return!!window.openDatabase},cpuClass:function(){return navigator.cpuClass},platform:function(){var n=navigator.platform;return"MacIntel"===n&&j()&&!X()?function(){if("iPad"===navigator.platform)return!0;var n=screen,e=n.width/n.height;return f(["MediaSource"in window,!!Element.prototype.webkitRequestFullscreen,e>.65&&e<1.53])>=2}()?"iPad":"iPhone":n},plugins:function(){var n=navigator.plugins;if(n){for(var e=[],t=0;t .comment-input { + width: 49.5%; + height: 30px; + border: 1px solid #eee; + border-radius: 6px; + margin-bottom: 10px; + padding: 15px; +} + + .submit-btn { background-color: #3498db; color: #fff; diff --git a/home/static/marked.min.js b/home/static/marked.min.js new file mode 100644 index 0000000..717c9fc --- /dev/null +++ b/home/static/marked.min.js @@ -0,0 +1,6 @@ +/** + * marked v15.0.7 - a markdown parser + * Copyright (c) 2011-2025, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).marked={})}(this,(function(e){"use strict";function t(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}function n(t){e.defaults=t}e.defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};const s={exec:()=>null};function r(e,t=""){let n="string"==typeof e?e:e.source;const s={replace:(e,t)=>{let r="string"==typeof t?t:t.source;return r=r.replace(i.caret,"$1"),n=n.replace(e,r),s},getRegex:()=>new RegExp(n,t)};return s}const i={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceTabs:/^\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] /,listReplaceTask:/^\[[ xX]\] +/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,unescapeTest:/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:e=>new RegExp(`^( {0,3}${e})((?:[\t ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),hrRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),fencesBeginRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}(?:\`\`\`|~~~)`),headingBeginRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}#`),htmlBeginRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}<(?:[a-z].*>|!--)`,"i")},l=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,o=/(?:[*+-]|\d{1,9}[.)])/,a=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,c=r(a).replace(/bull/g,o).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),h=r(a).replace(/bull/g,o).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),p=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,u=/(?!\s*\])(?:\\.|[^\[\]\\])+/,g=r(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",u).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),k=r(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,o).getRegex(),d="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",f=/|$))/,x=r("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ \t]*)+\\n|$))","i").replace("comment",f).replace("tag",d).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),b=r(p).replace("hr",l).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",d).getRegex(),w={blockquote:r(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",b).getRegex(),code:/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,def:g,fences:/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,hr:l,html:x,lheading:c,list:k,newline:/^(?:[ \t]*(?:\n|$))+/,paragraph:b,table:s,text:/^[^\n]+/},m=r("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",l).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3}\t)[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",d).getRegex(),y={...w,lheading:h,table:m,paragraph:r(p).replace("hr",l).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",m).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",d).getRegex()},$={...w,html:r("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",f).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:s,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:r(p).replace("hr",l).replace("heading"," *#{1,6} *[^\n]").replace("lheading",c).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},R=/^( {2,}|\\)\n(?!\s*$)/,S=/[\p{P}\p{S}]/u,T=/[\s\p{P}\p{S}]/u,z=/[^\s\p{P}\p{S}]/u,A=r(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,T).getRegex(),_=/(?!~)[\p{P}\p{S}]/u,P=/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/,I=r(P,"u").replace(/punct/g,S).getRegex(),L=r(P,"u").replace(/punct/g,_).getRegex(),B="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",C=r(B,"gu").replace(/notPunctSpace/g,z).replace(/punctSpace/g,T).replace(/punct/g,S).getRegex(),q=r(B,"gu").replace(/notPunctSpace/g,/(?:[^\s\p{P}\p{S}]|~)/u).replace(/punctSpace/g,/(?!~)[\s\p{P}\p{S}]/u).replace(/punct/g,_).getRegex(),E=r("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,z).replace(/punctSpace/g,T).replace(/punct/g,S).getRegex(),Z=r(/\\(punct)/,"gu").replace(/punct/g,S).getRegex(),v=r(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),D=r(f).replace("(?:--\x3e|$)","--\x3e").getRegex(),M=r("^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment",D).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),O=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,Q=r(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label",O).replace("href",/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),j=r(/^!?\[(label)\]\[(ref)\]/).replace("label",O).replace("ref",u).getRegex(),N=r(/^!?\[(ref)\](?:\[\])?/).replace("ref",u).getRegex(),G={_backpedal:s,anyPunctuation:Z,autolink:v,blockSkip:/\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g,br:R,code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,del:s,emStrongLDelim:I,emStrongRDelimAst:C,emStrongRDelimUnd:E,escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,link:Q,nolink:N,punctuation:A,reflink:j,reflinkSearch:r("reflink|nolink(?!\\()","g").replace("reflink",j).replace("nolink",N).getRegex(),tag:M,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\":">",'"':""","'":"'"},V=e=>K[e];function W(e,t){if(t){if(i.escapeTest.test(e))return e.replace(i.escapeReplace,V)}else if(i.escapeTestNoEncode.test(e))return e.replace(i.escapeReplaceNoEncode,V);return e}function Y(e){try{e=encodeURI(e).replace(i.percentDecode,"%")}catch{return null}return e}function ee(e,t){const n=e.replace(i.findPipe,((e,t,n)=>{let s=!1,r=t;for(;--r>=0&&"\\"===n[r];)s=!s;return s?"|":" |"})).split(i.splitPipe);let s=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),t)if(n.length>t)n.splice(t);else for(;n.length0)return{type:"space",raw:t[0]}}code(e){const t=this.rules.block.code.exec(e);if(t){const e=t[0].replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?e:te(e,"\n")}}}fences(e){const t=this.rules.block.fences.exec(e);if(t){const e=t[0],n=function(e,t,n){const s=e.match(n.other.indentCodeCompensation);if(null===s)return t;const r=s[1];return t.split("\n").map((e=>{const t=e.match(n.other.beginningSpace);if(null===t)return e;const[s]=t;return s.length>=r.length?e.slice(r.length):e})).join("\n")}(e,t[3]||"",this.rules);return{type:"code",raw:e,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):t[2],text:n}}}heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].trim();if(this.rules.other.endingHash.test(e)){const t=te(e,"#");this.options.pedantic?e=t.trim():t&&!this.rules.other.endingSpaceChar.test(t)||(e=t.trim())}return{type:"heading",raw:t[0],depth:t[1].length,text:e,tokens:this.lexer.inline(e)}}}hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:te(t[0],"\n")}}blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){let e=te(t[0],"\n").split("\n"),n="",s="";const r=[];for(;e.length>0;){let t=!1;const i=[];let l;for(l=0;l1,r={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=s?n:"[*+-]");const i=this.rules.other.listItemRegex(n);let l=!1;for(;e;){let n=!1,s="",o="";if(!(t=i.exec(e)))break;if(this.rules.block.hr.test(e))break;s=t[0],e=e.substring(s.length);let a=t[2].split("\n",1)[0].replace(this.rules.other.listReplaceTabs,(e=>" ".repeat(3*e.length))),c=e.split("\n",1)[0],h=!a.trim(),p=0;if(this.options.pedantic?(p=2,o=a.trimStart()):h?p=t[1].length+1:(p=t[2].search(this.rules.other.nonSpaceChar),p=p>4?1:p,o=a.slice(p),p+=t[1].length),h&&this.rules.other.blankLine.test(c)&&(s+=c+"\n",e=e.substring(c.length+1),n=!0),!n){const t=this.rules.other.nextBulletRegex(p),n=this.rules.other.hrRegex(p),r=this.rules.other.fencesBeginRegex(p),i=this.rules.other.headingBeginRegex(p),l=this.rules.other.htmlBeginRegex(p);for(;e;){const u=e.split("\n",1)[0];let g;if(c=u,this.options.pedantic?(c=c.replace(this.rules.other.listReplaceNesting," "),g=c):g=c.replace(this.rules.other.tabCharGlobal," "),r.test(c))break;if(i.test(c))break;if(l.test(c))break;if(t.test(c))break;if(n.test(c))break;if(g.search(this.rules.other.nonSpaceChar)>=p||!c.trim())o+="\n"+g.slice(p);else{if(h)break;if(a.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4)break;if(r.test(a))break;if(i.test(a))break;if(n.test(a))break;o+="\n"+c}h||c.trim()||(h=!0),s+=u+"\n",e=e.substring(u.length+1),a=g.slice(p)}}r.loose||(l?r.loose=!0:this.rules.other.doubleBlankLine.test(s)&&(l=!0));let u,g=null;this.options.gfm&&(g=this.rules.other.listIsTask.exec(o),g&&(u="[ ] "!==g[0],o=o.replace(this.rules.other.listReplaceTask,""))),r.items.push({type:"list_item",raw:s,task:!!g,checked:u,loose:!1,text:o,tokens:[]}),r.raw+=s}const o=r.items.at(-1);if(!o)return;o.raw=o.raw.trimEnd(),o.text=o.text.trimEnd(),r.raw=r.raw.trimEnd();for(let e=0;e"space"===e.type)),n=t.length>0&&t.some((e=>this.rules.other.anyLine.test(e.raw)));r.loose=n}if(r.loose)for(let e=0;e({text:e,tokens:this.lexer.inline(e),header:!1,align:i.align[t]}))));return i}}lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type:"heading",raw:t[0],depth:"="===t[2].charAt(0)?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t){const e="\n"===t[1].charAt(t[1].length-1)?t[1].slice(0,-1):t[1];return{type:"paragraph",raw:t[0],text:e,tokens:this.lexer.inline(e)}}}text(e){const t=this.rules.block.text.exec(e);if(t)return{type:"text",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){const t=this.rules.inline.escape.exec(e);if(t)return{type:"escape",raw:t[0],text:t[1]}}tag(e){const t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){const t=this.rules.inline.link.exec(e);if(t){const e=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(e)){if(!this.rules.other.endAngleBracket.test(e))return;const t=te(e.slice(0,-1),"\\");if((e.length-t.length)%2==0)return}else{const e=function(e,t){if(-1===e.indexOf(t[1]))return-1;let n=0;for(let s=0;s-1){const n=(0===t[0].indexOf("!")?5:4)+t[1].length+e;t[2]=t[2].substring(0,e),t[0]=t[0].substring(0,n).trim(),t[3]=""}}let n=t[2],s="";if(this.options.pedantic){const e=this.rules.other.pedanticHrefTitle.exec(n);e&&(n=e[1],s=e[3])}else s=t[3]?t[3].slice(1,-1):"";return n=n.trim(),this.rules.other.startAngleBracket.test(n)&&(n=this.options.pedantic&&!this.rules.other.endAngleBracket.test(e)?n.slice(1):n.slice(1,-1)),ne(t,{href:n?n.replace(this.rules.inline.anyPunctuation,"$1"):n,title:s?s.replace(this.rules.inline.anyPunctuation,"$1"):s},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){const e=t[(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," ").toLowerCase()];if(!e){const e=n[0].charAt(0);return{type:"text",raw:e,text:e}}return ne(n,e,n[0],this.lexer,this.rules)}}emStrong(e,t,n=""){let s=this.rules.inline.emStrongLDelim.exec(e);if(!s)return;if(s[3]&&n.match(this.rules.other.unicodeAlphaNumeric))return;if(!(s[1]||s[2]||"")||!n||this.rules.inline.punctuation.exec(n)){const n=[...s[0]].length-1;let r,i,l=n,o=0;const a="*"===s[0][0]?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(a.lastIndex=0,t=t.slice(-1*e.length+n);null!=(s=a.exec(t));){if(r=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!r)continue;if(i=[...r].length,s[3]||s[4]){l+=i;continue}if((s[5]||s[6])&&n%3&&!((n+i)%3)){o+=i;continue}if(l-=i,l>0)continue;i=Math.min(i,i+l+o);const t=[...s[0]][0].length,a=e.slice(0,n+s.index+t+i);if(Math.min(n,i)%2){const e=a.slice(1,-1);return{type:"em",raw:a,text:e,tokens:this.lexer.inlineTokens(e)}}const c=a.slice(2,-2);return{type:"strong",raw:a,text:c,tokens:this.lexer.inlineTokens(c)}}}}codespan(e){const t=this.rules.inline.code.exec(e);if(t){let e=t[2].replace(this.rules.other.newLineCharGlobal," ");const n=this.rules.other.nonSpaceChar.test(e),s=this.rules.other.startingSpaceChar.test(e)&&this.rules.other.endingSpaceChar.test(e);return n&&s&&(e=e.substring(1,e.length-1)),{type:"codespan",raw:t[0],text:e}}}br(e){const t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}}del(e){const t=this.rules.inline.del.exec(e);if(t)return{type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2])}}autolink(e){const t=this.rules.inline.autolink.exec(e);if(t){let e,n;return"@"===t[2]?(e=t[1],n="mailto:"+e):(e=t[1],n=e),{type:"link",raw:t[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let e,n;if("@"===t[2])e=t[0],n="mailto:"+e;else{let s;do{s=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??""}while(s!==t[0]);e=t[0],n="www."===t[1]?"http://"+t[0]:t[0]}return{type:"link",raw:t[0],text:e,href:n,tokens:[{type:"text",raw:e,text:e}]}}}inlineText(e){const t=this.rules.inline.text.exec(e);if(t){const e=this.lexer.state.inRawBlock;return{type:"text",raw:t[0],text:t[0],escaped:e}}}}class re{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.tokens=[],this.tokens.links=Object.create(null),this.options=t||e.defaults,this.options.tokenizer=this.options.tokenizer||new se,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};const n={other:i,block:U.normal,inline:J.normal};this.options.pedantic?(n.block=U.pedantic,n.inline=J.pedantic):this.options.gfm&&(n.block=U.gfm,this.options.breaks?n.inline=J.breaks:n.inline=J.gfm),this.tokenizer.rules=n}static get rules(){return{block:U,inline:J}}static lex(e,t){return new re(t).lex(e)}static lexInline(e,t){return new re(t).inlineTokens(e)}lex(e){e=e.replace(i.carriageReturn,"\n"),this.blockTokens(e,this.tokens);for(let e=0;e!!(s=n.call({lexer:this},e,t))&&(e=e.substring(s.raw.length),t.push(s),!0))))continue;if(s=this.tokenizer.space(e)){e=e.substring(s.raw.length);const n=t.at(-1);1===s.raw.length&&void 0!==n?n.raw+="\n":t.push(s);continue}if(s=this.tokenizer.code(e)){e=e.substring(s.raw.length);const n=t.at(-1);"paragraph"===n?.type||"text"===n?.type?(n.raw+="\n"+s.raw,n.text+="\n"+s.text,this.inlineQueue.at(-1).src=n.text):t.push(s);continue}if(s=this.tokenizer.fences(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.heading(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.hr(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.blockquote(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.list(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.html(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.def(e)){e=e.substring(s.raw.length);const n=t.at(-1);"paragraph"===n?.type||"text"===n?.type?(n.raw+="\n"+s.raw,n.text+="\n"+s.raw,this.inlineQueue.at(-1).src=n.text):this.tokens.links[s.tag]||(this.tokens.links[s.tag]={href:s.href,title:s.title});continue}if(s=this.tokenizer.table(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.lheading(e)){e=e.substring(s.raw.length),t.push(s);continue}let r=e;if(this.options.extensions?.startBlock){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startBlock.forEach((e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))})),t<1/0&&t>=0&&(r=e.substring(0,t+1))}if(this.state.top&&(s=this.tokenizer.paragraph(r))){const i=t.at(-1);n&&"paragraph"===i?.type?(i.raw+="\n"+s.raw,i.text+="\n"+s.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):t.push(s),n=r.length!==e.length,e=e.substring(s.raw.length)}else if(s=this.tokenizer.text(e)){e=e.substring(s.raw.length);const n=t.at(-1);"text"===n?.type?(n.raw+="\n"+s.raw,n.text+="\n"+s.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=n.text):t.push(s)}else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let n=e,s=null;if(this.tokens.links){const e=Object.keys(this.tokens.links);if(e.length>0)for(;null!=(s=this.tokenizer.rules.inline.reflinkSearch.exec(n));)e.includes(s[0].slice(s[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,s.index)+"["+"a".repeat(s[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(s=this.tokenizer.rules.inline.blockSkip.exec(n));)n=n.slice(0,s.index)+"["+"a".repeat(s[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(s=this.tokenizer.rules.inline.anyPunctuation.exec(n));)n=n.slice(0,s.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);let r=!1,i="";for(;e;){let s;if(r||(i=""),r=!1,this.options.extensions?.inline?.some((n=>!!(s=n.call({lexer:this},e,t))&&(e=e.substring(s.raw.length),t.push(s),!0))))continue;if(s=this.tokenizer.escape(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.tag(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.link(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(s.raw.length);const n=t.at(-1);"text"===s.type&&"text"===n?.type?(n.raw+=s.raw,n.text+=s.text):t.push(s);continue}if(s=this.tokenizer.emStrong(e,n,i)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.codespan(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.br(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.del(e)){e=e.substring(s.raw.length),t.push(s);continue}if(s=this.tokenizer.autolink(e)){e=e.substring(s.raw.length),t.push(s);continue}if(!this.state.inLink&&(s=this.tokenizer.url(e))){e=e.substring(s.raw.length),t.push(s);continue}let l=e;if(this.options.extensions?.startInline){let t=1/0;const n=e.slice(1);let s;this.options.extensions.startInline.forEach((e=>{s=e.call({lexer:this},n),"number"==typeof s&&s>=0&&(t=Math.min(t,s))})),t<1/0&&t>=0&&(l=e.substring(0,t+1))}if(s=this.tokenizer.inlineText(l)){e=e.substring(s.raw.length),"_"!==s.raw.slice(-1)&&(i=s.raw.slice(-1)),r=!0;const n=t.at(-1);"text"===n?.type?(n.raw+=s.raw,n.text+=s.text):t.push(s)}else if(e){const t="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(t);break}throw new Error(t)}}return t}}class ie{options;parser;constructor(t){this.options=t||e.defaults}space(e){return""}code({text:e,lang:t,escaped:n}){const s=(t||"").match(i.notSpaceStart)?.[0],r=e.replace(i.endingNewline,"")+"\n";return s?'
'+(n?r:W(r,!0))+"
\n":"
"+(n?r:W(r,!0))+"
\n"}blockquote({tokens:e}){return`
\n${this.parser.parse(e)}
\n`}html({text:e}){return e}heading({tokens:e,depth:t}){return`${this.parser.parseInline(e)}\n`}hr(e){return"
\n"}list(e){const t=e.ordered,n=e.start;let s="";for(let t=0;t\n"+s+"\n"}listitem(e){let t="";if(e.task){const n=this.checkbox({checked:!!e.checked});e.loose?"paragraph"===e.tokens[0]?.type?(e.tokens[0].text=n+" "+e.tokens[0].text,e.tokens[0].tokens&&e.tokens[0].tokens.length>0&&"text"===e.tokens[0].tokens[0].type&&(e.tokens[0].tokens[0].text=n+" "+W(e.tokens[0].tokens[0].text),e.tokens[0].tokens[0].escaped=!0)):e.tokens.unshift({type:"text",raw:n+" ",text:n+" ",escaped:!0}):t+=n+" "}return t+=this.parser.parse(e.tokens,!!e.loose),`
  • ${t}
  • \n`}checkbox({checked:e}){return"'}paragraph({tokens:e}){return`

    ${this.parser.parseInline(e)}

    \n`}table(e){let t="",n="";for(let t=0;t${s}`),"\n\n"+t+"\n"+s+"
    \n"}tablerow({text:e}){return`\n${e}\n`}tablecell(e){const t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`\n`}strong({tokens:e}){return`${this.parser.parseInline(e)}`}em({tokens:e}){return`${this.parser.parseInline(e)}`}codespan({text:e}){return`${W(e,!0)}`}br(e){return"
    "}del({tokens:e}){return`${this.parser.parseInline(e)}`}link({href:e,title:t,tokens:n}){const s=this.parser.parseInline(n),r=Y(e);if(null===r)return s;let i='
    ",i}image({href:e,title:t,text:n}){const s=Y(e);if(null===s)return W(n);let r=`${n}{const r=e[s].flat(1/0);n=n.concat(this.walkTokens(r,t))})):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach((e=>{const n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach((e=>{if(!e.name)throw new Error("extension name required");if("renderer"in e){const n=t.renderers[e.name];t.renderers[e.name]=n?function(...t){let s=e.renderer.apply(this,t);return!1===s&&(s=n.apply(this,t)),s}:e.renderer}if("tokenizer"in e){if(!e.level||"block"!==e.level&&"inline"!==e.level)throw new Error("extension level must be 'block' or 'inline'");const n=t[e.level];n?n.unshift(e.tokenizer):t[e.level]=[e.tokenizer],e.start&&("block"===e.level?t.startBlock?t.startBlock.push(e.start):t.startBlock=[e.start]:"inline"===e.level&&(t.startInline?t.startInline.push(e.start):t.startInline=[e.start]))}"childTokens"in e&&e.childTokens&&(t.childTokens[e.name]=e.childTokens)})),n.extensions=t),e.renderer){const t=this.defaults.renderer||new ie(this.defaults);for(const n in e.renderer){if(!(n in t))throw new Error(`renderer '${n}' does not exist`);if(["options","parser"].includes(n))continue;const s=n,r=e.renderer[s],i=t[s];t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n||""}}n.renderer=t}if(e.tokenizer){const t=this.defaults.tokenizer||new se(this.defaults);for(const n in e.tokenizer){if(!(n in t))throw new Error(`tokenizer '${n}' does not exist`);if(["options","rules","lexer"].includes(n))continue;const s=n,r=e.tokenizer[s],i=t[s];t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n}}n.tokenizer=t}if(e.hooks){const t=this.defaults.hooks||new ae;for(const n in e.hooks){if(!(n in t))throw new Error(`hook '${n}' does not exist`);if(["options","block"].includes(n))continue;const s=n,r=e.hooks[s],i=t[s];ae.passThroughHooks.has(n)?t[s]=e=>{if(this.defaults.async)return Promise.resolve(r.call(t,e)).then((e=>i.call(t,e)));const n=r.call(t,e);return i.call(t,n)}:t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n}}n.hooks=t}if(e.walkTokens){const t=this.defaults.walkTokens,s=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(s.call(this,e)),t&&(n=n.concat(t.call(this,e))),n}}this.defaults={...this.defaults,...n}})),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return re.lex(e,t??this.defaults)}parser(e,t){return oe.parse(e,t??this.defaults)}parseMarkdown(e){return(t,n)=>{const s={...n},r={...this.defaults,...s},i=this.onError(!!r.silent,!!r.async);if(!0===this.defaults.async&&!1===s.async)return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(null==t)return i(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof t)return i(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(t)+", string expected"));r.hooks&&(r.hooks.options=r,r.hooks.block=e);const l=r.hooks?r.hooks.provideLexer():e?re.lex:re.lexInline,o=r.hooks?r.hooks.provideParser():e?oe.parse:oe.parseInline;if(r.async)return Promise.resolve(r.hooks?r.hooks.preprocess(t):t).then((e=>l(e,r))).then((e=>r.hooks?r.hooks.processAllTokens(e):e)).then((e=>r.walkTokens?Promise.all(this.walkTokens(e,r.walkTokens)).then((()=>e)):e)).then((e=>o(e,r))).then((e=>r.hooks?r.hooks.postprocess(e):e)).catch(i);try{r.hooks&&(t=r.hooks.preprocess(t));let e=l(t,r);r.hooks&&(e=r.hooks.processAllTokens(e)),r.walkTokens&&this.walkTokens(e,r.walkTokens);let n=o(e,r);return r.hooks&&(n=r.hooks.postprocess(n)),n}catch(e){return i(e)}}}onError(e,t){return n=>{if(n.message+="\nPlease report this to https://github.com/markedjs/marked.",e){const e="

    An error occurred:

    "+W(n.message+"",!0)+"
    ";return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}}const he=new ce;function pe(e,t){return he.parse(e,t)}pe.options=pe.setOptions=function(e){return he.setOptions(e),pe.defaults=he.defaults,n(pe.defaults),pe},pe.getDefaults=t,pe.defaults=e.defaults,pe.use=function(...e){return he.use(...e),pe.defaults=he.defaults,n(pe.defaults),pe},pe.walkTokens=function(e,t){return he.walkTokens(e,t)},pe.parseInline=he.parseInline,pe.Parser=oe,pe.parser=oe.parse,pe.Renderer=ie,pe.TextRenderer=le,pe.Lexer=re,pe.lexer=re.lex,pe.Tokenizer=se,pe.Hooks=ae,pe.parse=pe;const ue=pe.options,ge=pe.setOptions,ke=pe.use,de=pe.walkTokens,fe=pe.parseInline,xe=pe,be=oe.parse,we=re.lex;e.Hooks=ae,e.Lexer=re,e.Marked=ce,e.Parser=oe,e.Renderer=ie,e.TextRenderer=le,e.Tokenizer=se,e.getDefaults=t,e.lexer=we,e.marked=pe,e.options=ue,e.parse=xe,e.parseInline=fe,e.parser=be,e.setOptions=ge,e.use=ke,e.walkTokens=de})); \ No newline at end of file diff --git a/home/templates/archives.html b/home/templates/archives.html index 5fe23c3..0175edd 100644 --- a/home/templates/archives.html +++ b/home/templates/archives.html @@ -2,8 +2,12 @@ {% load static %} {#文章详情#} +{% block sitename %} + {{ title }}-我的个人博客 +{% endblock %} {% block stylesheethref %} - + + {% endblock %} {% block content %}
    @@ -13,24 +17,21 @@

    {{ title }}

    +
    {{ title }}封面图
    @@ -39,6 +40,145 @@
    {{ content|safe }}
    +
    +
    +
    + + + +
    +

    {{ stat }}

    +
    +
    + +
    + +
    +

    评论

    +
    +
    + {% csrf_token %} +
    + + + +
    + +
    +
    +
    + {% for comment in comments %} +
    +
    + 用户头像 +
    +
    +
    + {{ comment.comment_User }} + {{ comment.comment_Time|timesince }} +
    +

    {{ comment.comment_Content }}

    + {% if comment.replies.all %} +
    + {% for reply in comment.replies.all %} +
    +
    + 用户头像 +
    +
    +
    + {{ reply.user.username }} + {{ reply.created_at|timesince }}前 +
    +

    {{ reply.content }}

    +
    +
    + {% endfor %} +
    + {% endif %} +
    +
    + {% empty %} +
    暂无评论,快来抢沙发吧~
    + {% endfor %} +
    +
    +{% endblock %} + +{% block script %} + const no_active_path = "M512 928c-28.928 0-57.92-12.672-86.624-41.376L106.272 564C68.064 516.352 32 471.328 32 384c0-141.152 114.848-256 256-256 53.088 0 104 16.096 147.296 46.592 14.432 10.176 17.92 30.144 7.712 44.608-10.176 14.432-30.08 17.92-44.608 7.712C366.016 204.064 327.808 192 288 192c-105.888 0-192 86.112-192 192 0 61.408 20.288 90.112 59.168 138.688l315.584 318.816C486.72 857.472 499.616 863.808 512 864c12.704.192 24.928-6.176 41.376-22.624l316.672-319.904C896.064 493.28 928 445.696 928 384c0-105.888-86.112-192-192-192-48.064 0-94.08 17.856-129.536 50.272l-134.08 134.112c-12.512 12.512-32.736 12.512-45.248 0s-12.512-32.736 0-45.248L562.24 196c48.32-44.192 109.664-68 173.76-68 141.152 0 256 114.848 256 256 0 82.368-41.152 144.288-75.68 181.696l-317.568 320.8C569.952 915.328 540.96 928 512 928z" + const active_path = "M736 128c-65.952 0-128.576 25.024-176.384 70.464-4.576 4.32-28.672 28.736-47.328 47.68L464.96 199.04C417.12 153.216 354.272 128 288 128 146.848 128 32 242.848 32 384c0 82.432 41.184 144.288 76.48 182.496l316.896 320.128C450.464 911.68 478.304 928 512 928s61.568-16.32 86.752-41.504l316.736-320 2.208-2.464C955.904 516.384 992 471.392 992 384c0-141.152-114.848-256-256-256z" + const path = document.getElementById('link_svg'); + + const fpPromise = import('{% static "aaa.js" %}').then(FingerprintJS => FingerprintJS.load()); + fpPromise.then(fp => fp.get()).then(result => {localStorage.setItem("uuid",result.visitorId)}); + + document.addEventListener('DOMContentLoaded', function() { + const likeBtn = document.getElementsByClassName('dz')[0]; + if (!likeBtn) return; + fetch(`/api/check_like/{{ id }}/${localStorage.getItem("uuid")}`,{ + method: 'POST', + headers: { + 'X-CSRFToken': '{{ csrf_token }}' + }, + credentials: 'include' + }).then(response => response.json()).then(data => { + if (data.liked) { + path.setAttribute('d', active_path) + likeBtn.classList.add('active'); + } + }); + const dz_icon = document.getElementsByClassName('dz-icon')[0]; + dz_icon.addEventListener('click', function() { + if (likeBtn.classList.contains('active')) { + fetch(`/api/unlink/{{ id }}/${localStorage.getItem("uuid")}`,{ + method: 'POST', + headers: { + 'X-CSRFToken': '{{ csrf_token }}' + }, + credentials: 'include' + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + likeBtn.classList.remove('active'); + path.setAttribute('d', no_active_path) + document.getElementById('likeCount').textContent = data.new_count; + } + }); + } else { + fetch(`/api/link/{{ id }}/${localStorage.getItem("uuid")}`, { + method: 'POST', + headers: { + 'X-CSRFToken': '{{ csrf_token }}' + }, + credentials: 'include' + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + likeBtn.classList.add('active'); + path.setAttribute('d', active_path) + document.getElementById('likeCount').textContent = data.new_count; + } + }); + } + }) + }); + {% endblock %} \ No newline at end of file diff --git a/home/templates/bottom.html b/home/templates/bottom.html index a57515f..2910a96 100644 --- a/home/templates/bottom.html +++ b/home/templates/bottom.html @@ -4,7 +4,9 @@ - 我的个人博客 + {% block sitename %} + 我的个人博客 + {% endblock %} {% block stylesheethref %} {% endblock %} @@ -92,40 +94,8 @@ \ No newline at end of file diff --git a/home/templates/index.html b/home/templates/index.html index e677d9e..07d813a 100644 --- a/home/templates/index.html +++ b/home/templates/index.html @@ -34,4 +34,40 @@ {% endfor %} +{% endblock %} +{% block script %} + document.addEventListener('DOMContentLoaded', function() { + // 搜索功能 + const searchBtn = document.querySelector('.search-box button'); + const searchInput = document.querySelector('.search-box input'); + + searchBtn.addEventListener('click', function() { + const query = searchInput.value.trim(); + if (query) { + alert('搜索: ' + query); + // 实际应用中这里应该是跳转到搜索页面或执行搜索操作 + } + }); + + searchInput.addEventListener('keypress', function(e) { + if (e.key === 'Enter') { + const query = searchInput.value.trim(); + if (query) { + alert('搜索: ' + query); + // 实际应用中这里应该是跳转到搜索页面或执行搜索操作 + } + } + }); + + // 文章卡片交互 + const articleCards = document.querySelectorAll('.article-card'); + articleCards.forEach(card => { + card.addEventListener('click', function(e) { + if (!e.target.closest('.read-more')) { + const id = this.querySelector('.article-id').textContent; + window.open(`/archives/${id}`) + } + }); + }); + }); {% endblock %} \ No newline at end of file diff --git a/home/views.py b/home/views.py index 10a5d31..50f9e9f 100644 --- a/home/views.py +++ b/home/views.py @@ -1,11 +1,12 @@ from django.shortcuts import render, HttpResponse -from . import models +from home.models import * +from comment.models import comment # Create your views here. def index(request): - artchle = models.articles.objects.all() + artchle = Articles.objects.all() + artchles = {"artchles": []} - print(artchle) for i in artchle: a = { "id":i.id, @@ -17,13 +18,19 @@ def index(request): } artchles["artchles"].append(a) return render(request, 'index.html', context=artchles) - # return HttpResponse("Hello, world. You're at the polls index.") def archives(request, id): - i = models.articles.objects.get(id=id) + i = Articles.objects.get(id=id) i.read += 1 i.save() + previous_article = Articles.objects.filter(id__lt=id).order_by('-id').first() + previous_id = previous_article.id if previous_article else id + previous_id_title = previous_article.title if previous_article else "暂无上一篇" + next_article = Articles.objects.filter(id__gt=id).order_by('id').first() + next_id = next_article.id if next_article else id + next_id_title = next_article.title if next_article else "暂无下一篇" + comments = comment.objects.filter(archives_Id=id).order_by("-comment_Time").all() a = { "id": i.id, "title": i.title, @@ -32,6 +39,22 @@ def archives(request, id): "stat": i.stat, "read": i.read, "content": i.content, - "author": i.author + "author": i.author, + "previous":{ + "id": previous_id, + "title": previous_id_title, + },"next":{ + "id": next_id, + "title": next_id_title, + },"comments": [] } + for c in comments: + com = { + "id": c.id, + "comment_Content": c.comment_Content, + "comment_User": c.comment_User, + "comment_Time": c.comment_Time, + "qq": c.qq, + } + a["comments"].append(com) return render(request, 'archives.html', a) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6b240b0 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,15 @@ +asgiref==3.8.1 +diff-match-patch==20241021 +Django==4.2.23 +django-import-export==4.3.7 +django-mdeditor==0.1.20 +django-simpleui==2025.5.262 +docutils==0.21.2 +importlib_metadata==8.7.0 +Markdown==3.8 +pillow==11.2.1 +Pygments==2.19.1 +sqlparse==0.5.3 +tablib==3.8.0 +typing_extensions==4.14.0 +zipp==3.23.0