From ef32e31e597d350a9d9d85f333dbf1f60887590b Mon Sep 17 00:00:00 2001 From: ZF sun <34314687@qq.com> Date: Thu, 15 Jan 2026 14:31:09 +0800 Subject: [PATCH] =?UTF-8?q?Merge:=20=E5=90=88=E5=B9=B6=E7=94=B5=E5=AD=90?= =?UTF-8?q?=E5=90=8D=E7=89=87=E5=8F=8A=E6=96=B0=E7=BB=84=E4=BB=B6=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E8=A7=86=E9=A2=91=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/upgrade_add_channel_fields.sql | 35 ++ .../shop/view/enterprise/channel/edit.html | 465 +++++++++++++++ .../shop/view/enterprise/channel/lists.html | 228 +++++++ .../shop/view/public/img/channel.png | Bin 0 -> 24973 bytes src/app/api/controller/Member.php | 17 +- .../component/controller/WechatChannel.php | 17 + .../view/wechat_channel/css/design.css | 315 ++++++++++ .../component/view/wechat_channel/design.html | 110 ++++ .../view/wechat_channel/js/design.js | 563 ++++++++++++++++++ src/app/shop/view/diy/heat_map.html | 7 + src/app/shop/view/diy/icon_img_view.html | 6 + src/app/shop/view/diy/icon_style.html | 7 + src/app/shop/view/diy/iconfont_component.html | 2 +- src/public/static/js/Sortable.min.js | 2 + 14 files changed, 1772 insertions(+), 2 deletions(-) create mode 100644 src/addon/personnel/data/upgrade_add_channel_fields.sql create mode 100644 src/addon/personnel/shop/view/enterprise/channel/edit.html create mode 100644 src/addon/personnel/shop/view/enterprise/channel/lists.html create mode 100644 src/addon/personnel/shop/view/public/img/channel.png create mode 100644 src/app/component/controller/WechatChannel.php create mode 100644 src/app/component/view/wechat_channel/css/design.css create mode 100644 src/app/component/view/wechat_channel/design.html create mode 100644 src/app/component/view/wechat_channel/js/design.js create mode 100644 src/public/static/js/Sortable.min.js diff --git a/src/addon/personnel/data/upgrade_add_channel_fields.sql b/src/addon/personnel/data/upgrade_add_channel_fields.sql new file mode 100644 index 000000000..4291589a5 --- /dev/null +++ b/src/addon/personnel/data/upgrade_add_channel_fields.sql @@ -0,0 +1,35 @@ +-- 升级脚本:为 personnel_channel 表添加新字段并优化表结构 +-- 执行时间: 2026-01-10 + +-- 1. 为 lucky_personnel_channel 表添加新字段 +ALTER TABLE `lucky_personnel_channel` +ADD COLUMN `feed_token` varchar(255) NOT NULL DEFAULT '' COMMENT '视频号视频的标识' AFTER `feed_id`, +ADD COLUMN `view_count` int unsigned NOT NULL DEFAULT 0 COMMENT '视频观看次数' AFTER `cover_url`, +ADD COLUMN `show_view_count` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否显示视频观看次数:0-不显示,1-显示' AFTER `view_count`, +ADD COLUMN `show_follow` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否显示关注按钮:0-不显示,1-显示' AFTER `show_view_count`; + +-- 2. 优化现有字段长度和类型 +ALTER TABLE `lucky_personnel_channel` +MODIFY COLUMN `channel_type` varchar(30) NOT NULL DEFAULT 'wechat' COMMENT '视频号类型:wechat-微信视频号,douyin-抖音,kuaishou-快手,redbook-小红书,bilibili-B站', +MODIFY COLUMN `channel_name` varchar(200) NOT NULL DEFAULT '' COMMENT '视频号名称', +MODIFY COLUMN `avatar_image_type` varchar(20) NOT NULL DEFAULT 'upload' COMMENT '头像类型:upload-上传图片,url-URL', +MODIFY COLUMN `avatar_url` varchar(500) NOT NULL DEFAULT '' COMMENT '头像URL', +MODIFY COLUMN `video_title` varchar(500) NOT NULL DEFAULT '' COMMENT '视频标题', +MODIFY COLUMN `feed_id` varchar(500) NOT NULL DEFAULT '' COMMENT '视频号内容ID', +MODIFY COLUMN `cover_image_type` varchar(20) NOT NULL DEFAULT 'upload' COMMENT '封面类型:upload-上传图片,url-URL', +MODIFY COLUMN `cover_url` varchar(500) NOT NULL DEFAULT '' COMMENT '封面URL', +MODIFY COLUMN `sort` int NOT NULL DEFAULT 0 COMMENT '排序,数值越小越靠前', +MODIFY COLUMN `is_show` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否显示:0-隐藏,1-显示', +MODIFY COLUMN `channel_id` int unsigned NOT NULL AUTO_INCREMENT, +MODIFY COLUMN `site_id` int unsigned NOT NULL DEFAULT 0 COMMENT '站点ID', +MODIFY COLUMN `create_time` int unsigned NOT NULL DEFAULT 0 COMMENT '创建时间'; + +-- 3. 添加索引优化查询性能 +ALTER TABLE `lucky_personnel_channel` +ADD INDEX `idx_site_id` (`site_id`), +ADD INDEX `idx_channel_type` (`channel_type`), +ADD INDEX `idx_is_show` (`is_show`), +ADD INDEX `idx_sort` (`sort`); + +-- 4. 修改表引擎为 InnoDB 和字符集为 utf8mb4 +ALTER TABLE `lucky_personnel_channel` ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/src/addon/personnel/shop/view/enterprise/channel/edit.html b/src/addon/personnel/shop/view/enterprise/channel/edit.html new file mode 100644 index 000000000..4747d7391 --- /dev/null +++ b/src/addon/personnel/shop/view/enterprise/channel/edit.html @@ -0,0 +1,465 @@ + + + + + + +
不同视频平台的唯一标识获取方式可能不同,请根据具体平台说明获取
+微信视频号,要填写FeedID的值;
+ +不同视频平台的唯一标识获取方式可能不同,请根据具体平台说明获取
+微信视频号,要填写视频的FeedToken值;仅内嵌小程序非同主体视频号视频时使用。
+ +点击上传
+点击上传
+3gyBn0CPYClL{271K?W%TEJHyqOin04@>tD<yx`xRw6oVH zQsmNuU4XFbm*7kZ9wjzjFe)nXGqwLzq@8PHv2g|i4go^iK^Tjj_roi>q-r;6*RDHW zyGpfoje7mgGqo#K>i6hQf?1xL0z!_Cjt&kE0`W#hMj#LA@X%0OYwOU^FzlV2oPu5B zsKCg^>i72b0ZXB7PfzdI*f %`5#7ASA|m1< z+Yj^bu3WTa |NriAY zZj|smD64_noM?szE#$_ij$Q>8pnKWTU0ky@+2AUG@s<=X_)oC30&^`b_#>3$$VG|* zxn?0CCl??igF0|&6P#;re;(2j1`xym5E6hpM 110r?#kB}Z z>IRGJ1`2Bi3Tj50I;T(zGl4P^^MN77Y$j$lCs4usM~t*UPPD=VdLZI6W4n<0|5(CK zBb-J150-YYYx+~tf?`3vpyatToS4oFV?0IpId_Z6mqVCPUVi$NzQ12^VNtQ4e~_u^ z<>=V>!s4PUSMNAGKgi6;%F8Vl7T$!z(c*BdINW@cb@Tc7H*Xb@;p5x9e&eC#D|WA5 zvv2+S1H63ew{4RW6xgtC?Vin>4y@m}Z^Op@OO|fmEqYWyaMQv?BK!gyR<0D=xl4wD zVF?Mbz>K}c|J_MTipQ=m0^}qD sk@i{u3Bm z+-GJM8$b}pVuNfFbMS^bCr5`7TK>O1#vj`|HT{nl?BWF}Xl!z*lc2*{^kSojFuh68 zdA5VvW^OhqnUl|7ybO;BGcH=NIT7;Fp$>VRQ3tWmV r>I=xCxe)z~IJUl8n`HiEqQ%z0% zsnZv3-*vin^LAiJXmLrIoBM;hx`u$j;Fqsnzk8oaH&2L!XdxM17_1W+iQwPg(&E7# zAOTw{geT!zxM0!2%^P>GS-xxa%Izzbi7Z>ZZN-YkybDQ*`QUVz7*`V1{u3Bm+?T#_ zXLtW^mH~5*QDZwf*fTNEJ<;DiITr(1+A}%W`zd<9f!?X1UZj3s*Z+>G0l1*_ehI7t z DoCo15od+k2|YXHT9maB=ava`pD1Lkjx(mhK)t5|Z){ANof{ z#V5adw`$c6u%atgiY;5dXW^o4d-uzEd;8tEao51W)WyYfyU1ZXJ7;w@o%_z7ws)N_ z=$UzXhOAs6Dj}h{a`leKe&JAf`jno{4SRh(^Z2;uXU~~~t%fLfHctNgTUvh9H|8Uy zT!_Q5m>rYodUdNT(x^1_V!oeYrnhd!1D%^^_LAUuNXd}kpP=@ile8UOeRBud%&;5n zMKIj+DbV4F?fML3D3DAag7JO?69Z5Pc6)kqfMAwpK`>O4-vyyEmJTAV4R=isc1-uT zPY(b(kUW%(_f1caOivF_PY kV~1err$GBQh|MNVPfkovj!jRDPLB^yj}Fd! zI_mm@vp+pKGCcv!j-!Quaj>n^Qxm`0-0`6)q|Hwl3jp I6coIqq}-HLe3Vq+_05NJR<;$)EK5j8cu=o+0UE3VxXH+PC@J|! zNU%_L0XaE8o|FqYmVzIT7l7Cmn{Xl~;w2{&z~f;T7dqp`NkJh%Ow5DPm2_qn>hDfk zI3sWeNJ;s~DB#rCOceKYC0_fGc%$aEW6f))s-%0x{%3A#? YX+H~S z=aP2DR*duvcegZrtY~PjY3!)`*!iKUv!S`GvAMgcwe>^$$J#ao)omYZ+L~%0ZEdJ- zuCHkNQ1P*$s $mGZ 5{wn(ADc6;PWS+*I+Twf^nvNayT0o93K*A5w2tym4>Lita89 zuSkAa`sz-7#_jqn_lE3%dN}0OmD1-H`A;o+8gr&5N5Dh=%+i8-u^Wj5#$q~0Xhy<^ z#|se?36Ox-hvy|B<{={D!sB_!$oR-e5jT&59N5K+&L{Jt)5S1+v1wt<_<*Ab8DVm= zg^ 7;)fs`Lp`_B>9{s+=RJcfj1qkUCX z`Kc~$g=RLzSMHWs+g9APufB7y-rlL~RZ?MTZgGA_L0)Q6ep+EcMnP_BZr0oMjO6sB z*pCvjtx^gt2c=q+)tlv%J}Rnp9FUw04yit2kcFF9%&@AMc1bDy(sHJyl`M;^xmM g3-`do6BWOAk)V)_;q{&vCDZ3`B+uiDlwysmBO#-8;%#veZ( z8Xxb7OKEcq?C=Qf^ayEx5L|2To_X=w{$=XR7M@U)y`d<7Q%BQ5RK$4wvJ1WspASt= zbeGo*9Mu?9Juz_X_|Q4Sq2p(V&KeF#ADxbk5A!m($V-_fyEg6UrW{R)lGD=FMk)>0 zbd9!?n@QsGym-@`+1@*{d!FPp-^XxSn(~!1OZGK^*4>-h4()B-v!zLTTf?5^wFlRC z?Ab9M8#^^QItj-A2S`hW-KZcFLirk$o!+V)#vAu4t=J&Sx0s2V zkA$3?6s`P|leWFH_Y+Gy1je?vyf(j7-LzNq?0~uBc<7U{hanSTPo{4=G(B)Ht}iPu z$|@_$EGf(=Dat6!e^;EJR#KW-`YvfoWY6?&@iCDD;|FENWmG3*R0aiCj9sy=($TBr z*wuadPQSh1SaRC ;Wj_sT@q!ft zt2U1ukRBG37?nCUs;oVxtUb77&5)@%xW7$mRxR5!doJD^3Wyr<^dAd}o4)6CWv9lX zrP|xqp53`oZ~snXm7{k}jUMIYln+i!^c0i~F557;Y4_k}v0-tAA#nvr`?wcQ-o2Of z^xoSQ2S<+H8NBH~5&3E|@abf1%Cw#5{avhPN6E{Bw-*QQC=1?E?6)D GyY?{1U};x8R4$Xx2ydR zw|r*Q1(z^z{txqP{$S(TZ0A#Idbh_d$Xe_e4#!SGCP)IEBoV;W{%;}eBm`z7eWevy zd4`vprOq{ v7TaVSRm5 zZ*PB3SMNY^`9OZrU_r@HZvIeS{zy?tSNzlQ(vlF@({J`}=~Ot?dcmUm^6hp5<5r7{ zokj*WyXN_r#HvTNb>#GHh>UxNLpcp^9LUqF}L_2$S;rCra+=6x*s6-cl@e(eqMS z8FzfuSar?hSl_3!$KN6C%;288s%e&ib2%U|d$&Vy*0j!gw!dv+cSL4a9pDMh ngo7|=o ~)? z2n#ko>Hq&~X+PyHF)9BdhUM~0cStPRDkrd2cKMFwjEjj$cp z!>zhcwd!}cCU2eaP^Gkl}_bT4!MV#;RXz!%R2hTzrL+=}U-#Tey zrh4guoVk&r#0CKoHkuv0OuK~^tX)87aaInDPo=CD_`taoJUPS*a&YXqBn$FL+4E^Q za~XJZ82R#PIo_|> 6YrAK{z z{hgiNz}x<@iNVR~p($jZ3Y)DOMW&a=GlCS;+=X*I*JZhFinG{!UxD_HIPS&~5?>>> z(vY1M;rpt>_gBZC%y-_Fb!~akL$%^Z>&xTLRwUSzgr3Ux*UAeyTO4)P{`3+z8%1O` zYM|}2nD(2b#fBhCA=1z7($_83r^K5}T7l1wB6!iCv_pou*+|GoM=MNABfMb28cIq5 zYAQiyre(}bOCe=sSjxq@o{e=C9ql64`H%{;v#(~LU&6w?Vm`|X*hNmpM?Y^d2{8v8 z4q^HH`72qNm$R}ir=&o*gs#w )reJCr_Qf zdCT6*`(boUoUDwR)ukH=2`_AHZfR(q3J;Hc@-!hf?un}E$>89~M?U@!9|h{^nMFjz zKK2WYi;ovStc49) zih}g;$M?e@yF>>*NR06}(U7*aGI|yr=yb#6w%Ms$Cfaw5wVW+adR#tr-$eP6>MrH2 z{Hh{+$9D)G FnriY-r5M%Jh5Wzjx<}WdiaWS00xZx3n;OcuLzLBK+0J=m<*M{=WXf zfq@ye!hcAH2m7W+2FqiNv%Qy;#hxgC;#d)Ju_ns6GTN%*g?&Yscy;8yswjzy5aoQk z<>@z9RYYEFetA1L;(DC*!m5Df1p$ZCAD&EimJYQNd3l$y=K1OA@rkJ~W{>|8(h@8Z z1-UT&ycI0WYq>bL2=eb RY(itS5HOMC49DE?`zp^;f;c2;3=epq<;?c26*-=(=f z@Q93x5)+l9q7W26q_uOW;+i#w7A+Fx;@nJ6zl@CZJ7M0Sb&K1Fd4Nm^*n!ejx-~Sg5@i_MK&}q*;BDzxqzNK6UR`# z7hKSh{_f769)z>q-Q6AS?e!l%WTvM-^7P%c^*E4r?J^BjrE6A}K59xgGSZ6%1_wJj zfaLvsV4C|8(hd$HmKIn$GSD|Q(pUY)|M~6Jbx(|{g7iznEGol|tAftdCft7GEcN2< z!VhtB1&$jE+(auwjcO8XTQVP~2bj3(FjR-`tngp=;--+L1eNy%#(Xc1iiC616XTPE ze=pL4n@UZ!cplwyCdSpQ^Vf58iO|!pV41%%HvUCWaByAy2MbH9kkH_y=LtD^xq1es zW*4vc2l~Hw`TW5CW5mSlU{S@z6=h_U(lgS4*qPZGcJ>ZcHP!c=9NxZvdqL0O#mm 5^kPz(RQq$T*tv%v-SJAv8wd4|1$|2p@0 z0!TaFpO^VgRb6G<=1m904r-jdaOvh |w6 KHA91&%0EPVwzoBOiMDSQd`_wdWciXXVjwKvZ15 z? J$_^@NVTrRB{%d!*FW&KMb9xp&WPo5&Gj#Qnxr zdT_&M!Ka|^@$VPb{x|sdS=#ab?DUi)Qj*J;EY?xdyk&hqBp~ti+v3XF&X&%Rww}?p zp5gYMp^jd_U^}$XGtko6+uYvM(KFQ5H`3fTker#` zwzIPbnLzI81(Jh-9vB!H85u!* Ms;4^B zlMr#Y|4l6IS0 d*tF(Ub`dT$zY*9C#vLl&CCtVosnpC30{1%OBGb?os_B?H^=m2Ro;yhMq)+tXZ>i zvGBqLY-|#T 7`|***UqDr6mYy5lc&(jpxZGLfqp#3a)%=o?3c-e+G^fq;z}9nD `Oca=t z|72|jxXo1L!c-KCD98lZm=~>Fw0!lVN zQ$R=OxQ3dVIx4EFs>;gB^70DirY09nuWnqW$j>Hm;he(*&)7p^Mvitt;0Cv~c7U0! zt*Nc9t{EL29T?~zM(3d*)& YXY)H6Xmta*9EL|D2y*6@xUHI;rXoY;YT`$g)zqDCj5_zfqxoylHv62{7)YAU7 zG3{pyi3x1^?Vb?nZ0v_D2_zLHCg$blSRo;LKw_up!EL*CuHCSE^Ts8D{9Np8oD10a zIXOAlSXt+@u+C>=U|^=Dp=V>B&&SC{N5e=$LPv~e!{d=P%y_~@f%Lce+qt3UOt1dL zrC0w#(vI0&ySjSK+AUkQa&vPtF|jOLx>iN?%mw{RqN0Z-j~qRGSWaAA?$AN$efz`@ z9FW|%PvXD RW@c1WRX5bu0coohbTIcgmxL=HNK46GPRo5ggfE z(yFPc0cn+#lw@V)4j($We(h#K?ybTc(gqhC9qc2-w&@1>CjdQxv=GoXH?_P;P6jJG z2u2p-T1bJk{Xp6g+q1hJwWzDZwpK #Kd$nAfh87VVn8fIZu!voBKeC*%cjsrl0(8bdN&<{m<#@T3^3*^XAQSXV322 zw|DWPg)Gc0EX?y+=Ckwg2yk-?2nZ|^6k5#7E6Bqu$j2|dYSlVX(S4f7wI6tTRa8|q zHZ@n()Yey518HlHo&eJ3lJVr?xd4UaT;+6p0dxXqDduaCF`l4czBZ5j4n3Rud^SI3 zhFdtC(&8P5w@65kP)p+|rGT+G>Q70l3be&Yd+gXT85vn1?V8ma8R_}hSyozGyWhPX zCMKf)`c)S2v#qTYV%q-x!MfU-lHy|67(itZtS!W}!$U UR9KNWw=>I)Wxc3i^|x`;g^=@c&sXR-jU~av^?6XCh_*iH1E`i z>t{r8X@OeP(^C_J?SBhPix;FI7pA1-r=$=@AvBx$0+b6WDHcLyQZhagQhi0W9smF! z07*naR3;MqJQ9-MK#Zn%Bn5KP0dMhG1w1_-!Avz$JToOZKNSV|+rktm;1j7R5D%P^ zQUEr|k>4}?vb2Bfil~8iZ(ezMc|}Bo1EQiL6A}^<6BEP3BSJ&N{QLt#!ot11AKkfq z*U`z@&E3P+&cWEk?6IGJSp{&lrK+YTzo4+NsJOVKoM34)akP2lU}-svNjQqB1^j6j zT2S+tQF2_O cMO*W@ZP_No26J z!(eGghAN(@<~&@Q=^^^YgeliftSm_XLzF?~>xVJctE%2OR>xXZhUt|)xdRlfdv-0% zO7zY#qN>0n< D=_h#N=N(dyG76g#`0^1<<)71{{tB z1@mm?TVTZDC~!FP9|px2phO#Cne&O*he98iiHUf~e(T#W(*FLW?VcX%E6B}`j){$r zkB89o#fulo$;l~iQZh2KfQw*08-SXv?R9kx9~zq4IyyVMyE{6&ptPp04qW2Q%*^zR z^xV9>{KBHzsw%|N%Ijp~<`t9k72|o{Q3*YuUSdwkcZHJsE)B026L&NlTL?3|J0piV zE&X<4ibLxU?&DavA4hzch(-cOC5fXt@)b*~h6S{Wii%Q4qz)d~zkKN$dRiV1wj~?Z z?_RlV*O3Ey&CRXt?Var?X))>T?d|L9>+kP}$QJ$&^>t5;4i`r&q`L{G*{;cV-d7rM zuKKA>^E1n;myXwDDKj4KseI>O{p4y**tv?J)Aezd{$?WXr>HA~))qck_rg}}q3*)V z(qs-=G%s#bRVQcxX{Y{T_jqQlFEKIuZZRn}^|MOKr v_eRDDL_~Vg)o98OIFItsw=CV1*oW=RZ~5q zs(MC6?d&n76KrfN@g#g?zsDlvU!?uUil~vE#t-$`IeBSmX<1naQ7bDeYieq%t7;%q z0lsflb$NMtMP*e*MP(T# 8PfJ+0<49o zwy%47bht1|`mGad-UI18SNZaAgW4#=w)}`#CzaEiaEZ5gtD q4-9{i_K$IoM|(chR;Q OCz11Bpk=&3MSF>c+M0&eii-L?DY-Hcu^I`PJ|mx|@Q&R}cW&fdyaq?K z1xGH5qd178L@g~i##GXXdrT%j>mIAl&O*s6C`d?%@7udaNMIQw9nX9w;dN_v3G%I5 zyL!97zkhRcTU%R47iwy;m5=@X1ll4KQBxyBss7@x?onqv*k2fIQUBbgwIKYhzk%67 ziqqS0Db7nP0@jrJu6%N5m*c5rFKmS?LpPQt-KvPUDT%QzioaD9s+{e{`NoMp{u(|r z#9(@I?5}o@1t35LcU1d?{?yde@bDn=u*-4mX_ymV0`>+61#4+(D=R4z;fQcQEL*m0 z(bm#Fe*C!BZ=#L;2@VcH8%Lh9IX*TqGBO04dAYg7I8M@Emi7;|v_M)2NvkR=fvat8 z?J)M6o0}UN8i1nJ)m6pC#XwrfgUtoTLgr&*BQP1b3I;YeH@B#$C?_Z9{rmTMnVHkm z6E$*RX_->-LZ?aT_u?sb5R>gEr;}#jQsP{3W{H@&h??#W%|)#If@D-HU_i_;cE&N5 z!hl%X*_c)p5iFpUmzNhme0YzjsF2|Dd32m~G#tW$YuH#8iEI(m)YQz)$!~85(sp9E zXZvPlpdXxM)IA;^j&j`h^fu9JCziB_2VQ#Vx)_OTZ^Egp#og1QE%RGZ5xl)3OtR?V zmJIi0g^w2(hsl;cu`dcblka;x*Z*8zknXcPB2iaKVlEM<`JJ1d`io;)Ji6EzB1u*C zGw72pM<=mIMNUtC^-+>=&DGY{1`7%Lq@bW6A|fItCMNo>U=?=k*a1f&Ohpg>OkkX# zWl`T%KWW)=~S^Uquw^{*rC)JRWlWqA(DJ+PlZ!s6m0NHa4t^73*E3JNL_GB;v$ z1)_dvXsEBRudJ$q%7uksTywHe$uB6ZE-QmCu14Wx77 qZB?CPV69f0+#T)o|RvkPbp{}m( dn-$eQc_ZKb8;X$&CbpS zrDtTMzkByKEj2YA{N{`d@PUESkXE5w1tu2)!z&O0-sb1$r>CX8e*GptD+^g%A+42; zqsqZ?72&uFaojmL&MX{fCXO`|$DE5}&ce-Cz|qL#Xk>9zGT;e+3Mm|=G>RiQ5`_i) zC~3jUswgWdK|m`bEq!3$-t8hH++2(3Xn0v!maJH@opZsmBS&Pg>1DXMKu`<3#f&Y+ z+dh=L1HHhm{H_J!%m+eAw(Fw}=$~2$XShffhg^uY z6MKG}IL}Wp&t3AJv((%BQc1UVKGNk^-h{ubfP3X54<_xez2!6O9y6(H>LEYw9Uns; z%slz^_csg=51%-3;{Qk5?c2A1hqTb_@bD1wMCd69^T#mKk`QtJS`qa}TH4Xxiju;# zwAAdZOc1cK*;(0nd3nIz+?-rwayUI57z^YCKN$&VtHGBph7?RLW_4i`s%7Wo)K^ta zO^()|GR@;!R>-$CpJ#JE_of1#&4v6Th1{D9dAAhsY CP!Jy<-+yIkL16G;pNf$dMh-FJ9{;kme;jFty2jDhf_!Vf zadK9su-FC7U~jd-HnCTMAa5QR9hn^Hm>BGz8XcP+pO_vULo#FI2*xL-Mn)my>*E98 zzxHtq$59Y6zX3HJ;~_x-+FHkTz9ZV&a|aXZs(tw$52V8rXy3+%2PPoynjD||_;K{_ z1oGrmBr}Gd@x<8Z=-BAU_!!h5gA ?8|KGUC)7PYj$Nc+c-7I`M)VCN(Z&yit>SDTueK79Cq zOy_iVLIjH$tsi;A9ad*@d~Bk>eG-|c9P8}v8Xg@Rn;0KJeuF;L-P=1cH8ngkVt( d!0X=-i(pSq(1ajqf#k1tGs) S@CoOiT=QGk`ocxTmm_WEBA|gUe z{6nO@e*M}n(*CKI7VOW| c+P>JxY@9M;=~D^ACNCUqP@M{!^7iC zdVe-4@*gZMGO{PJm-=B{`m8ecRxyJA|LxXBK6};W-<-6V+UMT#!QqJM=&8xbNNA`i z$Vl-tG?Y|SWM3XwQ&V&K^5yT77E${z(*BvGof_;!?8X#2{rBle#Y%pAneyz2_;Or) z;vU0*CcItl(*p^k=l3G*S4PjbNjur!0lvUY3872hIH_-4r+yC7l9Eyg3bP$Lw0!Mq z-o5*ltyso;@W9g5tGR!X_8((uCooI mee0H%x`wv8rZ%L |&-$C%s;aBX zN=uOi#^vRML&I}lCruEnWPEgFyr%`exsk?}&Y+~;7wOPcPeNK(Omb&nQeS&laY^yb zn>Xd< TCR^7Q@ZNG%-j(uteB-QqbtL;9hp`s=yCnt}J zit0>jK0ZE^U&u_~Mux|bzD*2Qf9UW}=t)fN3{31z&hGGy>wB5g*3mxa9EZMoj-R$R z1a_OCLjwL1(yD1(K-Dz@T|-~){grNG%b~EPh$<>77-?55 GWGUDuf{m>yH(OnBkNJ!B8wA &x=-d4%a@Y-|Kt$jr?AMcUt)v?IN( z7>0XVkhH65u&-xiczC#}ZMdalxTAZxy$eB0$52bhV1Ivm2eKL&lfl6u_)^hF9DX8L z$ bSO^SG)S0h%hR$5qrcG&EFZh0t0`O3KI=GSj#IKIj|t5PCJz)jQJFGu+k* z-5Y9dA3-0w+R@Q5dya!&J;zU5>mBZHCg_lW@4U 4hap~wrw337ZV>J6UPF2 zA|iyeA|l)1C{XyfzO0m#H<(@q2m9f(Qd3h&h&Vod8NwfnpP#h-9Un3DwKqcA+xnrm zv%ROM=R?!S=C)R_Ij!w&Ev?88-8y@E`hQHYwMV_(UA--Jy 4G~8_-7Dnp#_0 zq0NpCtY&+AI}9C-9}smlHFf1<>gX@vk-M|NPE{2&RRw%mADV^6zuC90&K~F+@=(Vv ztZ!|d9W8CGbNlvRoM~4_Ut0q~hXj0^wEVw2NJ;r9DTIKuN-AfdOK@g{-$;DfZA|TO zbpu5mJ9dn4%ZCJyr=p@DCMJdykH=F|Qjidn;_;+-5 (`m5z7!) zvFyW#hR)8;4s^`{L155hDIr6s)6v%2(NGC#OLKExZcaHW#YM&CW#ttWmFUq>vBSm1 zMeVzyiv5Nb=&5uR{wOOe$;e16paL#2q(_e)ovEj)N;nFd?V2N>_pP<1y`i!bE+QX4 zVtuPYe_#k+aaC3IOwVS|bnZERqqXMFkJSVn67c7emY0HD5Qk$trgREjF4EeGEQ;yq z?CAQcfPOG_f%XWbWnr4PW5*(4Ar^57;dN_yHg8(AWFhyaO#+)X@e)Y8b?a7aY4=yZ zELT@oPz {QRW- zSX+jnv8EK#hN|L*x|+tu4-NI@jmS>`8XCWlkKd4)-SzeLg{6&k^$qp)4HbnA^|erh zwAR>wNh6ZO+L>w1!^1=QTLRvjtURPj00mh{p-AbN0@zzjzIqTe_+{Uav=;3fbgaJa z1Jbwp#s;)+zjdr(rsjV-Q%D d@9cAm> r%#`f5V4Ws`TmHr{wjWc($-ZJVyG=I zKv0%fU0GRMT~b>TQJA0o^5v_v^z_vC?+c5N-}HQ6uqRs7R8|$c2Uq13AkVZY&Z(}d zs;w@D*7EamUcP*pnVFT5o}QDFTa8vGh@qk3u}?)&Q4vYO2i_*8C?l(g{DM|S@u=dl zqq4{3_sYn~96o$lT3SXL5gDv9CeYM3`&Lp`>=smAR8mt@h4!tcwko%_Bq}!->03rd zW@>6Gq}A2cKXRtf4zyNNQeIPCSzDTiDUhH~z@JN6aF6+cw6gM=b#-;c#l=`WQdVA8 z{tbbUM_*rGN=oWW(#~CmOvq!T-LPQ;C>fipSC}JudU|sjMrPhiN|5Iz#Kpyt5V8Lv z?e9t2%HkXh6-C*QmKS7|mmtrDswgi6%@?DOkHPMKRQ|A(6% 4XC zbI%l$ivQ+J(bkGVZv-6@@NLra{O-Wxxhcr`a5x58c?~#)=&0zYPoKoc1LB{2P2y4U z_xFcuA1Nv6k6YU1%a@Cbi|^gLcmEtYa^#4Qj}Pz@+Kh{fjfG5HTy%8QyLa!QC#a?6 z`P1<8leQ!;9Yax0T5)cAaZXxcPA2ku*+S%3vn6oFE-JzRn?H(T^cT0e*~QuK3v;s2 z){t_f9Z2WYEG#T2$j^raQuw-6RaE3;Wq*SlmdYU+8EJWGNl4L6IeF}^ES8a*5mi-H z7>r--Qt@Yf%gMs}hJJJ*)&~M$^FN{xJ#41`Ihn<%_CSXOeFDBsTJGN+csv(MT6%eT z_4M>~2RjERC&&A!IH7WXR$N?M+}zw;U0opq4y~!F>3>C9VPWB&J9lo~x>W>~EnBwi z+O_M-l`GJiGb)4+a&Wj85*!XfLd1&y15Wu{`1whjpZN|$UdCGt`57tsX({>dUw@9Y zH~Hx)fIJLoNQ#vp^=J3yLknqWnvs&1fo0z1r$hSwH)N*fXQd&?&B)Ksok?>tlAgw% zJ9AQ2>c}i45geJDO2|lx%SawZ(;3JDj) IOfV{Lf2q1&t4N{o)Cigw0 zuk+I1AbrbvpP!qFetI5?+&P)=0IQRepP!AUdHLDz^N^E8wKuCzz@JQ7a&lfEt(=@% zVnV`&^A{W(?17L#Cp$a4yLazG<`ybeR#qk^CZ?#EnVErGOGQQXU3b+SRL9A#Y@41QE*R%T`84#`boO!NI}AMDt01k@j~aZFcHw3|Xnk zC|;+&dH(WM;;YnGuTx*YNqdu$o|2OOHYMY2O3JIZ$ld&$ zCHeWA GW@cs~At8Q#egOf2&6_vF zr$FP-AjBq+QCC+d#3@G=jv5=A1q1{T pKyrO{4TJV+}0hO)ft(zmjNi<(a?#v!sM)Pvf6GdkTLN5}rcl z*|R6epYZUceG<>b4kd{mcrGpf{E&2#gxrf=``%kxK8XttH82iS(g{>h3szJQRnZ7m zQG2YSV6S)F)>= rI z;^sNb&LOdOt%RiHp)ETPu3Ud;&89 l=0{XAHcx)$iOgzixW&wxxlMrLME{9h-}%Z<^{{Gu3i3 z(s?1Y;^m4BPuFa{zjA|_@Ur8)f-*Go4hsp1OG--cEmLL{HWb ZC mFy1Rq`jR>ppaJbi57??T(6VedL!Uw7kg3Vk9f~#g<*& zVUg3#EzKP*{iW5@)gSxw%Tn&Sr`&W%arEdfD)qc(ZDel30Rxzs&eY7<#MFp}jw&QL zC^s*sJTGUuw0yd u )cb#(+OuTBxz{H z-@P04G(ILWA|^T#K};l;iH?elij0VIcZ+m#jC8ygVP_X^XBTE~A7o+q%+)y}*f&U4 zBXXx)w46qq`pI}zt$3}I&s5Z0PHWt}s((TInDpVjr_|trzxSG<`b|@<>n0~0tPOlE zFFZEa54&U=gNyefrEHxJ+_+oS)Oz%!fxmxH$=i2Bon6m7y`On_COq&edX?N+S(Wt2OG@E@ z!)B38%iC3vPyA$*n%|}dD5~}qm)Kcd(l<6VHwRN;XlQI`Xk S 3``mI|Q)b%KLKeSLk1a7@rc)HhZqbQm@v1p^C(km~DMVI^}@0 js>jD<`*=to1eaJe#Y*qzMGw;yS=r) zo1LG#1K_c%UC84Hi3zdsu`$RE0kj}X--WP<_|WjUkkHuBu$bV`=+N-!_$P4P*m%-x zwdDg2Ei)xEYkj9Xjom%cW|tH$Uw85g7# PFk^btl%a%Ts7XM4MlzyM&W5y05k$k@op*wDbpz`)QTCpRY-MOIFBL1A8ZTTN|k zc}ZDuPJZ_FTh@t*iBDoe5e3fb6Yy=)F8KXH0;J`{;pXkxD-E4VNJw~s1TF-b$-|z+ z|5?Bv9vvNpOlxZ^ nT~t)$;^HD9t^}+@dAPvV)(z+< zDXE5S0>BeS`8-oHH=XM+e+I(gU*hK{ZG2P+hPX%skn#8N_Vn`bdHnFPpO0U_WB-81 zLBRpxkzrw>K_S8ZA;AF%LI8mwAwdX&Ar16@{0I(2(#MY;`#gH|(ChI-PiXM5%RRSi zmt3z~*qiCvnd;uu*ReP*YjIxnve5|}i*x7HBp1wQRF>YmX8A%hU5#s|Cok!$+%VC0 zwl;9NX5wRe!^iIWBY^ESe;50>h@j|*u&C&0Kr|ToSg`WZVbL+ckx}t+@tWq=JZG+~ zH+rOCZK>#JC3)NBV|%-OfWM)Oi;S_w@X%0rcw}TmWLH;LM0mKr@1wk|^xm!}=bMTq zx(BG|QBu#NqNJtF&C4|a(`syh%zy%6fwxAerKKdNrlFRRl?LkO -M)R7h{z5E+aR-j%a(1MHf`OwVe|U+8#iy>=IH3)>-!MCcLWc; zy}TYg@_qo#K613Xf7QbIve_;D)3@|aTs^H~t}bPITG{Np`c;#YXVs-QtzDrmw|Dgt zL4y+tR{HAZ=hdzn>o{D#;ACy=b;sKKj j$^5`rfyL?uCU0hlauB15MyhXlP(? zXn16lo#TBLnX{t09*k!!RBk!x*xWs4da0^s;I8juS$z}#h?uVK?ttKshK9z>%*?>R zz(?L*O%3%~>969VeU9v3MbAJ@H;;;T9@X;~&oP#Qb+xm%PkR2`5ZN@OprQb)3w*_l zZE;b4^T(Qj?xwD`2KmFAER0S@M} 3dqpY zP}9>=(^FH?QPVJ9wZ8i3p{Iw3>jMur4-YptHx~~#m$1Oc9(Qj#SQ^=1G`e<9`|4Ts zODB|!RV4M)B@MKtjZZ0@QkB-#Ry?C}Xy4Y=MrTwl4NjQpYFQcT+_gMscS+y a;wjcZWZPL83R_7w`o>N (_3T z5I>@LRC)c{EjxCIYHDh4+qMIsqO7)K`<}IHw#rH$lap22v~k {sS$6qI!ClAdgvHEDwc{hsu6_;d4(M_M)U^ z`xbtF(gyl^VF&>Dcm_W9cCx*BQSZdfYgg=TZ{M@O>*4OAZ(uNwfqnjbPG)8{W@dI2 zY|Km;SeY5;Gchl?WM%ch-R1s$N0l#uElwOW z*E(u&?6AJtAp=cu6CG)(eOs9r<{c8 z>0T;pY8f6LZSUxK_{ayMuauOO2M-=Vpw-#g5$ONO#86vZNvx~Ao|%z~ii#ZQN<~BA z;9v)q7L4i<=_5c|a!Rs*zyNTJX=teo4E4*(N*WvMKQ`8Pb~JT$G $pTR-`-_ZWE+TL{q;7M2!1|k`Rx{v{W0-yEtEF~mVAP+SGUm9DeiS5Fp>8JP? zkk;4R4TFytz}45=-Ql+NRpXPVRb?+*n%i8v;^c7m%-OTl^X4-#u`@C-e-#W2Y-VO= z_njQETi7b+bQ w>WqD*>(oP#Rle%!CYj zJp$6c{=z+;G1Rk{FiZ)Mho E^NM>FM3GyA4FWb?e4Wn;X}xFJHTI$; q!&6G?@&_b#Z&Huwt>`SuI7A^P0xz zH81LET{Ss%&G6*ii-v$Z7Y%P;G_be6 `7- zM{)1&joUUa=jCMNW@q5zWaL@E$i>FM&Ca-hg^rhP9zO>&A3HrS>{>uC%t 2luQ#t}5l_>Hfgg5p+n d%gjzR}Kp+VtZ19Z1 zV`gjoM|Sp)-AXF^&rX#me`Ir1W-C>xt;*I;Do4%MBsJNpsZ@4nv)Rd3CE1 e)Hg4`=IH; zTMr&Q05KjQc71)_ZnyhaypP^KFlgqQZq{~nHc|(w6?47Zsn)^vvdO_}YJU}_uZq%J zN$D*o_m)%pDy9Z1Ci_Yy%$As&dayZkFJ^x0U{9kGOp!ZCV??!-_Xtc25AOpFQ+fh> zq0j;+hKH@Npd19rAi0fii{jgp8)$#&>5s~K668F^_&jh`6(9u2%PRqf$CU#&3$F9E z*J=w3VQvAvd3oTPkxE%!UMXmd! aE8)Fte<5}P{s$;qG^+y7vI0I<}$58`YjK%<%4efpr~j0PH5#|?;eQ1_Z~dB zzqj|`&4(+&wKk=tFSs?}Sr7Q{_S)7bd=ZMn;}F?ODGa{O^x(n6-PiBm-`juV{u>}| zi$o%!P{`-=Su9qM%X#o{Pa$D+wq5V(xIr1L G0-sh`Pz6^CtDeFNQk8^bjK8cr+#hdKh_sCF zEG$G-5+4V)m4)yYT*(z2uB^72I8Em@H+K&YQ!6VP`uoNi3@(|%xP18<4o7(HVs&G~ zt(#3fmtL!_t!=5VYj17sD=E2l{aV|#tHc&!&ubTJ8ymWtn|o?&h~SX=`VLU9t7|6^ z>OkYBrmm}3Td!ViYia3iXy_~@oPl4>+q-uMvHSP7-`I)m-M_b_T;NjT=@XL$xU8 zH+@#gJdaRXU0qXGRapaDRc+ir<$6`s)#@u(OUtS?vc<65?6+y%M!8)nSd#J`M%CUM zJL|4xNF`p93M}F|tC+vEz|nH4Y5_wBxK+-vsKXa7oTrX-S67znWV2SyqFE)h>BIrZ z5U^>(P77=f%erIfcEG)NFZTM*-Q9clc7Wa8nN*occl4cpSEX+Cy1^&*tnz(+qQ&0H zS?rqPY{l-z?t)gJ`Mu4}&9$|)Kp+5!bvm6It#*#j1K(6FXU(y@*_2j`lH|9sg3GLc zjp4U3gUjqyJ7*2zt~q8yPX4-!zwVx2cg?Rt{0-mYcEoTeymV*N7h2IzQG5D&>ct|~ z-rnm#J)mJqPhh#Bt#~emPj2xQ&+8+e`g$sHxYC*$;_U4F$OvU{aH6rHb7X|fVsXi& zsiLA99Ilwy+}nL?xVwAkMtyr<-x!O<8yll`v=7Y8%#DvvGMSv3>LxOoMj}yrx<{%i z8+cp+2;f1>(NQXcF+-!V`})R Od^g!z*Mry$~hXyW3`K{c{aJP=N5Z%xba$*T*%f) zcv=b1qFMA v{Hy5ZW4c($V6&4_m^>f4O00E=z M)rEP+?(Uttu?WyGr6;i5(3U?h!=oxM*~;P VbXV6vUfu=p7J$FF_zXOI9E+|awiUP7=7!&4aTpbDi`Hw? zd#!p%FR@$AVzGooqD;}IDU_*^k#S&S 4 z+KjQ=VXwttT;yv7T;2SPex9wFrArwT%K2%Ph^-ZKr1Q*KCRHk!k&AdL5mO`KXe3;t zV&1BgENdkzX6=eu2h3|y2OtZ$$Vem{iAE!l=z2J^WHI-X8EtgYxWy_CYHl$luaRfZ zcaP9#1?%BxFa(-J!{IPs6@UuzSdevFEEbhYRZ&qvCXL6oA}e0oM%WjP_-}8nMmGbI z@JcxBUk`cwD|VmP=Ji~fiGHm$)Rhiqz_Md`4qJdoO`ml+N6Y1&9v$29?e zIu_f!9SLnE#YF6dLyK@ymR5Ow6U6Zs0N3G92LW(JMFWv|tD&J|U|{0n#qtXmDtmiI z^71a?ab @o<5P8YEgc;LEiGL`!{p0FAp0e>we^BX zxad+%OUtdHAyP+YKY+irwWqId1e_d)yVQKM@51>iJf3j+p^dHw5sLr|1*02lZmZs+ z64?!Mhf!(QE|`@ G1bdX}Z(vy|MaMf#YGM^y=#O3{o~F4V{bTA9FMw<$#|wV11w z@(l`sNg=SP7Tg9EVotr%XET9|429N0>l>la`s!N9zZ$YT>@*hh%D_bZqF7*d-{LLQ z-WvA!0=~eiKe!rNUkAZ3!m7oxg!~r_8jV(8Uq3cF5{-t%A|{VZrc#EwyIb4Zng{z^ z26~AjBfU#YDuZ5b&`T{#swK0^Y*H!|LON}NGSomBtXp8+lJf_9ZZ+QOtncq_>h7xJ zb7|4&MmQ9RB*jE5H?(DE!thDUFGE(L^74vsxRP_{0N5o31*J$tfX9^<7uTLU2YfOC z@O<%N)%o+4AaX7&ECV~w6_%erUjdFn+JIACx^$(mupBf1Eei`koAUVnQgBpZ0f@=V zPCvAvpf6zoFKnxRn_jLL^FU^6QH!lwsZk+Pi{~{GU;>>&tXE15N{LY=1qSMRg+!;2 zXyuD~xfoh9I4lOptcA>)WrGS@(uG!6mUT)Me@4b-$Y-YI9J-WE6;2L|nByWgNy?*+ z4|Y~nRgCs`T&=EL )3hdSG9 zOG+-}7vx>InBR20sJ7}tb924NW%f8tZih+0XR74$UiXp{GC1ry7P*B_Z&%I_$zW)k z0OTWsZ9QE#W@n~Cq2OA;0}GhaGw90+ExzmwSSc`k(h!Ub;v~Z_@kk}n81M`nG5{EC zVT&&X1DI2Wv;kCubK>#{U=I#nVFqU|OSC~M@iU)(X#HMi!aU9ukHf#>*2#nt-jqtn z(kycHGQLqhZ;HD q*$XQ+JosCbs) zU-6igQb6n?nikU4YoBmF7Rj|t(6K`G65T$ zN-g48 DvtfWS0{*aqeu*GW$WK^;@O;#}`DravFH4d;3FtP-2Bl{rJa#*534?4d z$m(`MN)ZpZLB%{nAz;GrEOG$7@hvxQ9JPooonsgjBCUk4UF3nC>IIHc$ddACA{J?m zJ~}%!%$n%sGsxg |Gt_yL z&zKN#rxs=zQUP1WpO(+Dj1r+yDgvgL2+V33xI&PeLJkK67kF!jpyg%AX0tC@mzOM7 zJF*9E;smTprP9P7I* _2xR#letcV4fmBDA;P80c^9>27XqxyqU* zx!n#YP!F;l>gllMhL&&^43DyOZZo&&O2)BA-^FKpiEeoY{?#Q`o?FQUEvC#1kR5{- zD;TsGv>3D)v{=EQ#h}HY#R>*3RxoHWXfbFpXfe$(XfbFpXt9Dpdlt(VUwrY*TMXK7 zpzIj5Siw9k=4rp-&_0HE`yYazAMW$|Q3ZOOdOuzVZ>M&l3fRrt--r5 B|F*J^Rf&Pq Ej3588 z-~a9>Uz_Y_(9^;l1XM;-iRg~r<{B=^?mF62n5TULwDF-F*9{R7>3|RSp$v^d6CMQR zgy;~nL@l!`4qqd+6p)F%X~bolC$gUF%d~kM)jrGYesmuC`S%0R+dsxU?N mdjV1Ol;GZ0`^L>Ql_qJ{7bn4nI5rv^k=$tWg-|X^(;S zF@z`!hH$!oiS9`C3aoa#ngb)0 ^lY5P%0YYu1=-Ftj8h2^wQ6CP)Ep^uT(0hAxks`|0BZw_dW zQV;E?b>7o;CF*o(0W*Axqw_pEr~UI?$M^mf)IWK5XXm|t!*beZ3y;%Ns@$ITXmFfs zC+2CN2yFt-w7>;Wv=2dtn!~; )Ho;F8}p7!IIz&P!5V@IwnEw)di85tu# zdnlmMXtT4kQmNEnFn})_3 _NzggjDS;f=aW4xdQJIEFB?A-w6F_JsF}8$lZEGFZ_p&1^?m}^509=9 zXLR7 Pm9pD!MoxPOZ6b(;hyLTonHgbDhk0ZcO;bO9e~y=)HKXph? a@rq8c#-#$V*c$rfj|5J%W0qSKJDQofAmR-G-%=bg&Bzws?V|2 &wX+3!F9KMdOA?igl$iX!ddihfiK zmT_b7)mf4HW;}bGh+9zWQ3z%k>E#K+<0H53lI}3e6HD>4pdX^?N3DlFu>&(!yi+0g zVJv>kS3Q*RN4v@UwD0^~QrLg~i|@Ys!+-b okfBflB0kmL0fcAI4{~Uuh=Yu(! z(bZv!k{$;q_GWtHvwfTPS)omz>9Vo Ep~tBQhv`eDrbDTnobJ$vt^k zmYYh+F$5>k4+Y7bcIW-njoLo~IqkRK|MaWLj{U;G=`Y`yXOA)2v1gAlXkR5yi S97*RglJu=4B$ z2n*yr3N5Dj3zPj6LW@Mm|MS1U!+QF86d)`Tq@kh3G=Gt@pDJk4X)TzRK0o&HYpgs& z0g?h?Q<+uDFwI}2?5}!4dkAetgp4eWfcXiF*}ksu42X$df=Z1ZO!F5n`zuXsCbSu2 z2+U8v{MB!M@#%j8`}be|8nb6GL_HuQGTCPki)sE+WIsL7rkpK$3?ah^%vFd16)-!Y zr9?x<4SMLH=X*@^mm>SAf)+i7Kn?&5eCO0)!t7}cQ4diPJ#^5}Vw%5r*-sC&sWF5e zMyVA}%$~tg0;0!F#?Zkue<`w`9%!=;Bh0?KJ#pM%n!gm;PY<*i!w9pl#ZJ;6m`X22 c_E*dPAFA`@`4P`d{r~^~07*qoM6N<$g6a#b`Tzg` literal 0 HcmV?d00001 diff --git a/src/app/api/controller/Member.php b/src/app/api/controller/Member.php index e1fa312c1..f2f5038a6 100644 --- a/src/app/api/controller/Member.php +++ b/src/app/api/controller/Member.php @@ -576,6 +576,8 @@ class Member extends BaseApi $Personnelmodel = new PersonnelModel(); $set = $Personnelmodel->getPersonnelSet($this->site_id, $this->app_module)[ 'data' ][ 'value' ]; + //视频号数据 + $channel_list = model('personnel_channel')->getList(['site_id'=>$this->site_id, 'is_show'=>1],'*','sort asc createtime desc'); //视频文件 $video_list = model('personnel_video')->getList(['site_id'=>$this->site_id],'*','createtime desc'); //企业文件 @@ -583,7 +585,20 @@ class Member extends BaseApi //电子名片diy $config = $Personnelmodel->getPersonnelSet($this->site_id, $this->app_module)[ 'data' ][ 'value' ]; $config['value'] = json_decode($config['value'],true); - return $this->response(['code'=>'0','data'=>$list,'message'=>'操作成功','shop'=>$shop_info_result,'set'=>$set,'video_list'=>$video_list,'file_list'=>$file_list,'diy'=>$config['value']]); + return $this->response(['code'=>'0','data'=>$list,'message'=>'操作成功','shop'=>$shop_info_result,'set'=>$set,'channel_list'=>$channel_list, 'video_list'=>$video_list,'file_list'=>$file_list,'diy'=>$config['value']]); + } + /** + * 视频号观看次数+1 + */ + public function incrementChannelViewCount() + { + $id = $this->params[ 'channel_id' ] ?? 0; + if (empty($id)) { + return $this->response($this->error('', '未传视频号id!')); + } + $cur_view_count = model('personnel_channel')->getValue(['channel_id'=>$id], 'view_count', 0); + $res = model('personnel_channel')->update(['view_count'=>$cur_view_count+1],['channel_id'=>$id]); + return $this->response(['code'=>'0','message'=>'操作成功', 'data'=>$res, 'channel_id'=>$id, 'pre_view_count'=>$cur_view_count]); } //留言 public function message() diff --git a/src/app/component/controller/WechatChannel.php b/src/app/component/controller/WechatChannel.php new file mode 100644 index 000000000..f967745cc --- /dev/null +++ b/src/app/component/controller/WechatChannel.php @@ -0,0 +1,17 @@ +fetch("wechat_channel/design.html"); + } +} \ No newline at end of file diff --git a/src/app/component/view/wechat_channel/css/design.css b/src/app/component/view/wechat_channel/css/design.css new file mode 100644 index 000000000..654f3e318 --- /dev/null +++ b/src/app/component/view/wechat_channel/css/design.css @@ -0,0 +1,315 @@ +.wechat_channel-box .preview-draggable { + padding: 15px; +} + +.wechat_channel-box .video-list-wrap { + position: relative; +} + +.wechat_channel-box .video-list { + display: grid; + grid-template-columns: repeat(var(--row-count, 2), 1fr); + gap: 8px; + padding: 16px 16px 0px; +} + +.wechat_channel-box .video-item { + position: relative; + width: 100%; +} + +.wechat_channel-box .video-wrap { + position: relative; +} + +.wechat_channel-box .video-wrap .channel-preview { + position: relative; + width: 100%; + overflow: hidden; + border-radius: 5px; +} + +.wechat_channel-box .video-item .channel-preview img { + display: block; + width: 100%; + object-fit: cover; + border-radius: 5px; +} + +.wechat_channel-box .video-item .channel-preview { + position: relative; + width: 100%; + overflow: hidden; + border-radius: 5px; +} + +.wechat_channel-box .video-item .play-btn { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 40px; + height: 40px; + background: rgba(0, 0, 0, 0.6); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + z-index: 10; +} + +.wechat_channel-box .video-item .play-btn::before { + content: ''; + width: 0; + height: 0; + border-style: solid; + border-width: 10px 0 10px 16px; + border-color: transparent transparent transparent #fff; + margin-left: 2px; +} + +.wechat_channel-box .video-item .view-count { + position: absolute; + right: 2px; + font-size: 12px; + color: #fff; + padding: 4px 4px; + /* border-radius: 16px; */ + margin-bottom: 0; + z-index: 10; + text-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5); +} + +.wechat_channel-box .video-item .channel-info { + position: relative; + padding: 8px; + background: #fff; + border-radius: 0 0 8px 8px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + margin-top: -4px; +} + +.wechat_channel-box .video-item .channel-avatar { + display: none; +} + +.wechat_channel-box .video-item .channel-text { + flex: 1; + overflow: hidden; +} + +.wechat_channel-box .video-item .channel-name { + display: none; +} + +.wechat_channel-box .video-item .video-title { + font-size: 13px; + font-weight: 500; + color: #333; + overflow: hidden; + margin-bottom: 3px; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-box-orient: vertical; + word-break: break-all; + word-wrap: break-word; + white-space: normal; +} + +/* 1行标题 */ +.wechat_channel-box .video-item .video-title.title-max-lines-1 { + -webkit-line-clamp: 1; +} + +/* 2行标题 */ +.wechat_channel-box .video-item .video-title.title-max-lines-2 { + -webkit-line-clamp: 2; + margin-bottom: 4px; +} + +/* 3行标题 */ +.wechat_channel-box .video-item .video-title.title-max-lines-3 { + -webkit-line-clamp: 3; + margin-bottom: 4px; +} + +.wechat_channel-box .video-item .bottom-text { + font-size: 14px; + color: #666; + margin-top: 8px; + line-height: 1.4; + font-style: normal; +} + +.wechat_channel-box .video-item .video-placeholder { + height: 200px; + background: #f5f5f5; + display: flex; + align-items: center; + justify-content: center; + border: 1px dashed #ddd; + border-radius: 5px; +} + +.wechat_channel-box .video-item .placeholder-text { + color: #999; + font-size: 14px; +} + +/* 轮播样式 */ +.wechat_channel-box .video-carousel-wrap { + position: relative; + width: 100%; + overflow: hidden; +} + +.wechat_channel-box .video-carousel { + position: relative; + width: 100%; + overflow: hidden; +} + +.wechat_channel-box .carousel-item { + position: absolute; + top: 0; + left: 0; + width: 100%; + opacity: 0; + transition: opacity 0.5s ease-in-out; + z-index: 1; +} + +.wechat_channel-box .carousel-item.active { + position: relative; + opacity: 1; + z-index: 2; +} + +.wechat_channel-box .carousel-indicators { + position: relative; + margin-top: 8px; + margin-bottom: 8px; + margin-left: auto; + margin-right: auto; + width: fit-content; + display: flex; + gap: 8px; + z-index: 10; +} + +.wechat_channel-box .carousel-indicators .indicator { + width: 8px; + height: 8px; + border-radius: 50%; + background-color: rgba(255, 255, 255, 0.5); + cursor: pointer; + transition: background-color 0.3s ease; +} + +.wechat_channel-box .carousel-indicators .indicator.active { + background-color: #000000; + transform: scale(1.2); +} + +/* 轮播模式下的视频项样式 */ +.wechat_channel-box .video-carousel-wrap .video-item { + width: 100%; + max-width: 100%; +} + +/* 轮播模式下的通道预览样式 */ +.wechat_channel-box .video-carousel-wrap .channel-preview { + width: 100%; +} + +/* 16:9比例下的固定高度 */ +/* 一行显示1个 */ +.wechat_channel-box[data-ratio="16:9"] { + --image-height: 212px; +} +/* 一行显示2个 */ +.wechat_channel-box[data-ratio="16:9"][data-row-count="2"] { + --image-height: 104px; +} +/* 一行显示3个 */ +.wechat_channel-box[data-ratio="16:9"][data-row-count="3"] { + --image-height: 65px; +} +/* 一行显示4个 */ +.wechat_channel-box[data-ratio="16:9"][data-row-count="4"] { + --image-height: 47px; +} + +/* 3:4比例下的固定高度 */ +/* 一行显示1个 */ +.wechat_channel-box[data-ratio="3:4"] { + --image-height: 408px; +} +/* 一行显示2个 */ +.wechat_channel-box[data-ratio="3:4"][data-row-count="2"] { + --image-height: 200px; +} +/* 一行显示3个 */ +.wechat_channel-box[data-ratio="3:4"][data-row-count="3"] { + --image-height: 130px; +} +/* 一行显示4个 */ +.wechat_channel-box[data-ratio="3:4"][data-row-count="4"] { + --image-height: 96px; +} + +.wechat_channel-box .video-item .channel-preview img { + height: var(--image-height); +} + +.wechat_channel-box .video-item .view-count { + top: calc(var(--image-height) - 32px); +} + +.wechat_channel-box .edit-attribute .attr-wrap .restore-wrap .video-add-box .img-block { + width: 200px !important; + height: 125px !important; + margin-bottom: 30px; + margin-right: 0; + position: relative; +} + +.wechat_channel-box .edit-attribute .attr-wrap .restore-wrap .video-add-box .img-block>div { + line-height: 125px; + height: 125px !important; + width: 100%; + text-align: center; +} + +.wechat_channel-box .edit-attribute .attr-wrap .restore-wrap .video-add-box .img-block video { + width: 100% !important; + height: 125px !important; +} + +.wechat_channel-box .edit-attribute .attr-wrap .restore-wrap .video-add-box .img-block span { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.wechat_channel-box .video-zhezhao { + position: absolute; + background: #fff; + width: 61%; + height: 125px; + top: 1px; + right: 32px; + text-align: center; + line-height: 105px; + display: none; +} + +.wechat_channel-box .video-zhezhao span { + position: absolute; + top: 35px; + left: 80px; + color: #909399; +} + +/* .wechat_channel-box .layui-form-label + .layui-input-block {margin-left: 0 !important;} */ \ No newline at end of file diff --git a/src/app/component/view/wechat_channel/design.html b/src/app/component/view/wechat_channel/design.html new file mode 100644 index 000000000..68c8e001f --- /dev/null +++ b/src/app/component/view/wechat_channel/design.html @@ -0,0 +1,110 @@ + + + + + + \ No newline at end of file diff --git a/src/app/component/view/wechat_channel/js/design.js b/src/app/component/view/wechat_channel/js/design.js new file mode 100644 index 000000000..7d3cc8832 --- /dev/null +++ b/src/app/component/view/wechat_channel/js/design.js @@ -0,0 +1,563 @@ +Vue.component("wechat_channel-edit", { + template: `++ + ++++++++++++ +
+++++
+ ++{{ item.videoTitle || '视频标题' }}+{{ item.viewCount }}次观看+++请配置视频号信息++ ++++请添加视频号+++ + + + + ++++++++ +
+++++
+ ++{{ item.videoTitle || '视频标题' }}+{{ item.viewCount }}次观看+++请配置视频号信息+++请添加视频号++ + + + + + + + + + + + + + +`, + data: function () { + return { + data: this.$parent.data + }; + }, + + + created: function () { + if (!this.$parent.data.verify) this.$parent.data.verify = []; + this.$parent.data.verify.push(this.verify);//加载验证方法 + + this.$parent.data.ignore = ['textColor', 'componentBgColor', 'elementBgColor', 'elementAngle'];//加载忽略内容 -- 其他设置中的属性设置 + this.$parent.data.ignoreLoad = true; // 等待忽略数组赋值后加载 + }, + mounted: function () { + console.log("wechat_channel-edit", this.data) + + // 初始化数据结构 + if (!this.data.list) { + this.data.list = []; + } + + if (!this.data.rowCount) { + this.data.rowCount = 2; + } + + if (!this.data.showStyle) { + this.data.showStyle = 'fixed'; + } + + if (!this.data.aspectRatio) { + this.data.aspectRatio = '16:9'; + } + + if (!this.data.titleLineClamp) { + this.data.titleLineClamp = 1; + } + + if (this.data.showPlayBtn === undefined) { + this.data.showPlayBtn = true; + } + + // 初始化轮播幻灯片索引 + if (this.data.currentSlide === undefined) { + this.data.currentSlide = 0; + } + + // 初始化分组列表 + this.updateGroupedList(); + + // 初始化列表项 + this.data.list.forEach((item, index) => { + if (!item.avatarImageType) { + item.avatarImageType = 'url'; + } else if (item.avatarUrl && item.avatarImageType == 'upload') { + var val = '++ +容器设置
+ + ++ ++ + ++ +++ ++ + ++ +++ ++ + ++ + +++ ++ + ++ +++ +++ ++++视频列表
+ + +++ + + ++++ ++++ + +视频 {{ index + 1 }}
+ ++ ++ + ++ +++ ++ + ++ +++ ++ + ++ +++ ++ + ++ + +++ ++ + ++ +++ ++ + +++++++ + x ++ ++点击上传
++ ++ + ++ +++ ++ + ++ +++ ++ + ++ + +++ ++ + ++ +++ ++++++++ + x ++ ++点击上传
+推荐使用 200x200 像素的图片+'; + $("#avatarImg_" + index).html(val); + } + + if (!item.coverImageType) { + item.coverImageType = 'url'; + } else if (item.coverUrl && item.coverImageType == 'upload') { + var val = '
'; + $("#coverImg_" + index).html(val); + } + + if (item.showViewCount === undefined) { + item.showViewCount = true; + } + }); + + layui.use(['form'], () => { + var form = layui.form; + form.render(); + + // 头像类型切换 + form.on('radio(avatarType)', (data) => { + const elem = data.elem; + const type = elem.value; + const index = elem.dataset.index; + + if (index !== undefined && this.data.list[index]) { + this.data.list[index].avatarImageType = type; + + this.$nextTick(() => { + if (type == 'upload' && this.data.list[index].avatarUrl) { + var val = '
'; + $("#avatarImg_" + index).html(val); + } + }); + } + }); + + // 封面类型切换 + form.on('radio(coverImageType)', (data) => { + const elem = data.elem; + const type = elem.value; + const index = elem.dataset.index; + + if (index !== undefined && this.data.list[index]) { + this.data.list[index].coverImageType = type; + + this.$nextTick(() => { + if (type == 'upload' && this.data.list[index].coverUrl) { + var val = '
'; + $("#coverImg_" + index).html(val); + } + }); + } + }); + + // 封面比例切换 + form.on('radio(aspectRatio)', (data) => { + const elem = data.elem; + const ratio = elem.value; + this.data.aspectRatio = ratio; + }); + + // 标题最多行数切换 + form.on('select(titleLineClamp)', (data) => { + const lines = parseInt(data.value); + this.data.titleLineClamp = lines; + }); + + // 每行显示数量切换 + form.on('select(rowCount)', (data) => { + const count = parseInt(data.value); + this.data.rowCount = count; + // 更新分组列表 + this.updateGroupedList(); + // 重新初始化轮播功能,确保根据新的rowCount重新分组 + this.initCarousel(); + }); + + // 显示风格切换 + form.on('select(showStyle)', (data) => { + const style = data.value; + this.data.showStyle = style; + // 更新分组列表 + this.updateGroupedList(); + // 重新初始化轮播功能 + this.initCarousel(); + }); + + // 显示播放按钮切换 + form.on('switch(showPlayBtn)', (data) => { + const elem = data.elem; + const checked = elem.checked; + this.data.showPlayBtn = checked; + }); + + // 显示观看次数切换 + form.on('switch', (data) => { + const elem = data.elem; + const checked = elem.checked; + // 查找对应的视频号索引 + const videoItem = elem.closest('.video-item-edit'); + if (videoItem) { + const index = videoItem.dataset.index; + if (index !== undefined && this.data.list[index]) { + this.data.list[index].showViewCount = checked; + this.$forceUpdate(); + } + } + }); + }); + + // 初始化拖拽排序 + this.initSortable(); + + // 初始化轮播自动切换 + this.initCarousel(); + }, + methods: { + verify: function () { + var res = { code: true, message: "" }; + // 微信视频号组件暂不需要强制验证 + return res; + }, + + // 上传封面图片 + uploadCover: function (index) { + + // 从媒体库中选择 + openAlbum((data) => { + const imgUrl = data[0].pic_path; + var val = '
'; + $("#coverImg_" + index).html(val); + + if (this.data.list[index]) { + this.data.list[index].coverUrl = imgUrl; + } + }, 1); + }, + + // 上传头像图片 + uploadAvatar: function (index) { + + // 从媒体库中选择 + openAlbum((data) => { + const imgUrl = data[0].pic_path; + var val = '
'; + $("#avatarImg_" + index).html(val); + + if (this.data.list[index]) { + this.data.list[index].avatarUrl = imgUrl; + } + }, 1); + }, + + // 添加视频号 + addVideoItem: function () { + this.data.list.push({ + "channelType": "wechat", + "channelName": "", + "finderUserName": "", + "avatarImageType": "url", + "avatarUrl": "", + "videoTitle": "", + "coverImageType": "url", + "coverUrl": "", + "feedId": "", + "feedToken": "", + "viewCount": 0, + "showViewCount": true, + "embedMode": false + }); + this.$forceUpdate(); + this.$parent.$forceUpdate(); + + // 重新渲染表单并绑定事件 + this.$nextTick(() => { + layui.use(['form'], () => { + var form = layui.form; + form.render(); + + // 重新绑定头像类型切换事件 + form.on('radio(avatarType)', (data) => { + const elem = data.elem; + const type = elem.value; + const index = elem.dataset.index; + + if (index !== undefined && this.data.list[index]) { + this.data.list[index].avatarImageType = type; + this.$forceUpdate(); + + this.$nextTick(() => { + if (type == 'upload' && this.data.list[index].avatarUrl) { + var val = '
'; + $("#avatarImg_" + index).html(val); + } + }); + } + }); + + // 重新绑定封面类型切换事件 + form.on('radio(coverImageType)', (data) => { + const elem = data.elem; + const type = elem.value; + const index = elem.dataset.index; + + if (index !== undefined && this.data.list[index]) { + this.data.list[index].coverImageType = type; + this.$forceUpdate(); + + this.$nextTick(() => { + if (type == 'upload' && this.data.list[index].coverUrl) { + var val = '
'; + $("#coverImg_" + index).html(val); + } + }); + } + }); + }); + + // 重新初始化拖拽排序 + this.initSortable(); + }); + }, + + // 删除视频号 + removeVideoItem: function (index) { + this.data.list.splice(index, 1); + this.$forceUpdate(); + this.$parent.$forceUpdate(); + + // 重新初始化拖拽排序 + this.$nextTick(() => { + this.initSortable(); + }); + }, + + // 初始化拖拽排序 + initSortable: function () { + // 检查Sortable库是否已加载 + if (typeof Sortable !== 'undefined') { + const videoList = document.getElementById('videoListEdit'); + if (videoList) { + // 销毁现有实例 + if (this.sortableInstance) { + this.sortableInstance.destroy(); + } + + // 创建新的Sortable实例 + this.sortableInstance = new Sortable(videoList, { + handle: '.drag-handle', + animation: 150, + onEnd: (evt) => { + // 获取拖拽前后的索引 + const oldIndex = evt.oldIndex; + const newIndex = evt.newIndex; + + // 重新排序数组 + if (oldIndex !== newIndex) { + const [movedItem] = this.data.list.splice(oldIndex, 1); + this.data.list.splice(newIndex, 0, movedItem); + + // 强制更新视图 + this.$forceUpdate(); + this.$parent.$forceUpdate(); + + // 重新渲染表单 + layui.use(['form'], () => { + var form = layui.form; + form.render(); + }); + } + } + }); + } + } else { + // 如果Sortable库未加载,尝试动态加载 + const script = document.createElement('script'); + script.src = 'https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.0/Sortable.min.js'; + script.onload = () => { + this.initSortable(); + }; + document.head.appendChild(script); + } + }, + + // 更新分组列表 + updateGroupedList: function () { + const list = this.data.list || []; + const rowCount = this.data.rowCount || 2; + const groups = []; + + for (let i = 0; i < list.length; i += rowCount) { + groups.push(list.slice(i, i + rowCount)); + } + + this.data.groupedList = groups; + console.log("groupedList", this.data.groupedList); + }, + + // 初始化轮播自动切换 + initCarousel: function () { + // 清除现有的轮播定时器 + if (this.carouselTimer) { + clearInterval(this.carouselTimer); + } + + // 更新分组列表 + this.updateGroupedList(); + + // 只有当显示风格为carousel且有多个分组时才启动轮播 + if (this.data.showStyle === 'carousel' && this.data.groupedList && this.data.groupedList.length > 1) { + this.carouselTimer = setInterval(() => { + this.data.currentSlide = (this.data.currentSlide + 1) % this.data.groupedList.length; + }, 3000); // 每3秒切换一次 + } + } + }, +}); \ No newline at end of file diff --git a/src/app/shop/view/diy/heat_map.html b/src/app/shop/view/diy/heat_map.html index 70e1bdbac..5499d954b 100644 --- a/src/app/shop/view/diy/heat_map.html +++ b/src/app/shop/view/diy/heat_map.html @@ -105,6 +105,10 @@ text-align: right; } + .heat-map-wrap .manage-wrap .list-wrap .item div { + + } + .heat-map-wrap .manage-wrap .list-wrap .item div span { cursor: pointer; } @@ -115,6 +119,8 @@ } + +
+ {include file="diy/iconfont_component"/} diff --git a/src/app/shop/view/diy/icon_style.html b/src/app/shop/view/diy/icon_style.html index be43b3a4f..22599245e 100644 --- a/src/app/shop/view/diy/icon_style.html +++ b/src/app/shop/view/diy/icon_style.html @@ -1,3 +1,6 @@ + + + + +@@ -124,6 +130,7 @@+ + {include file="diy/iconfont_component"/} diff --git a/src/app/shop/view/diy/iconfont_component.html b/src/app/shop/view/diy/iconfont_component.html index 6dc24d7cd..3c7adc6ce 100644 --- a/src/app/shop/view/diy/iconfont_component.html +++ b/src/app/shop/view/diy/iconfont_component.html @@ -65,7 +65,7 @@ }, iconStyle(){ if (!this.value) return {}; - + // console.log(this.value) var style = { fontSize: this.value.fontSize + '%' } diff --git a/src/public/static/js/Sortable.min.js b/src/public/static/js/Sortable.min.js new file mode 100644 index 000000000..17bb16c73 --- /dev/null +++ b/src/public/static/js/Sortable.min.js @@ -0,0 +1,2 @@ +/*! Sortable 1.15.0 - MIT | git://github.com/SortableJS/Sortable.git */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function M(o){for(var t=1;t@@ -163,6 +168,8 @@t.length)&&(e=t.length);for(var n=0,o=new Array(e);n "===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function N(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\s+/g;function I(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function P(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=P(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i =n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[j]._onDragOver(o)}}var i,r,a}function Yt(t){q&&q.parentNode[j]._isOutsideThisEl(t.target)}function Bt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[j]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return It(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Bt.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in K.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in Pt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Mt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Et.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function Ft(t,e,n,o,i,r,a,l){var s,c,u=t[j],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||k(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function jt(t){t.draggable=!1}function Ht(){Ct=!1}function Lt(t){return setTimeout(t,0)}function Kt(t){return clearTimeout(t)}Bt.prototype={constructor:Bt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(gt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,q):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){Tt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&Tt.push(o)}}(o),!q&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=N(l,t.draggable,o,!1))&&l.animated||J===l)){if(nt=B(l),it=B(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return U({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),z("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=N(s,t.trim(),o,!1))return U({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),z("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!N(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!q&&n.parentNode===r&&(o=k(n),$=r,V=(q=n).parentNode,Q=q.nextSibling,J=n,at=a.group,st={target:Bt.dragged=q,clientX:(e||t).clientX,clientY:(e||t).clientY},ht=st.clientX-o.left,ft=st.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,q.style["will-change"]="all",o=function(){z("delayEnded",i,{evt:t}),Bt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(q.draggable=!0),i._triggerDragStart(t,e),U({sortable:i,name:"choose",originalEvent:t}),I(q,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(q,t.trim(),jt)}),h(l,"dragover",Xt),h(l,"mousemove",Xt),h(l,"touchmove",Xt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,q.draggable=!0),z("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Bt.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){q&&jt(q),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._disableDelayedDrag),f(t,"touchend",this._disableDelayedDrag),f(t,"touchcancel",this._disableDelayedDrag),f(t,"mousemove",this._delayedDragTouchMoveHandler),f(t,"touchmove",this._delayedDragTouchMoveHandler),f(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(q,"dragend",this),h($,"dragstart",this._onDragStart));try{document.selection?Lt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;yt=!1,$&&q?(z("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Yt),n=this.options,t||I(q,n.dragClass,!1),I(q,n.ghostClass,!0),Bt.active=this,t&&this._appendGhost(),U({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ct){this._lastX=ct.clientX,this._lastY=ct.clientY,kt();for(var t=document.elementFromPoint(ct.clientX,ct.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ct.clientX,ct.clientY))!==e;)e=t;if(q.parentNode[j]._isOutsideThisEl(t),e)do{if(e[j])if(e[j]._onDragOver({clientX:ct.clientX,clientY:ct.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Rt()}},_onTouchMove:function(t){if(st){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=Z&&v(Z,!0),a=Z&&r&&r.a,l=Z&&r&&r.d,e=Ot&&bt&&E(bt),a=(i.clientX-st.clientX+o.x)/(a||1)+(e?e[0]-_t[0]:0)/(a||1),l=(i.clientY-st.clientY+o.y)/(l||1)+(e?e[1]-_t[1]:0)/(l||1);if(!Bt.active&&!yt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY)) n.right+10||t.clientX<=n.right&&t.clientY>n.bottom&&t.clientX>=n.left:t.clientX>n.right&&t.clientY>n.top||t.clientX<=n.right&&t.clientY>n.bottom+10}(n,r,this)&&!g.animated){if(g===q)return O(!1);if((l=g&&a===n.target?g:l)&&(w=k(l)),!1!==Ft($,a,q,o,l,w,n,!!l))return x(),g&&g.nextSibling?a.insertBefore(q,g.nextSibling):a.appendChild(q),V=a,A(),O(!0)}else if(g&&function(t,e,n){n=k(X(n.el,0,n.options,!0));return e?t.clientX