<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>24&apos;s Blog</title>
    <description>后端与嵌入式、maya与游戏 | elmagnifico， Back-end engineer &amp; Embedded System Lover | 这里是elmagnifico的个人博客，君子之交淡如水。</description>
    <link>https://elmagnifico.tech/</link>
    <atom:link href="https://elmagnifico.tech/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Fri, 26 Jun 2026 06:35:33 +0000</pubDate>
    <lastBuildDate>Fri, 26 Jun 2026 06:35:33 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>一些思考和想法</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;受到一些游戏，小说等启发，记录一些我觉得有意思的设计，希望有朝一日可以把他们实现到我的游戏中。&lt;/p&gt;

&lt;h2 id=&quot;设定&quot;&gt;设定&lt;/h2&gt;

&lt;h3 id=&quot;无限流&quot;&gt;无限流&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;无限恐怖&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;原形来源于无限恐怖，两方对立，各自有各自的目标，可以合作，也可以冲突，但是大家都不知道对方的目的，在一定的时间内完成任务，由第三方扮演监督方和NPC，从而达成一个三方博弈的局面，成功达成目标的，可以拿走他们的奖励，退出比赛，失败则是死亡或者丢失xxx。&lt;/p&gt;

&lt;p&gt;同时也类似于现在的剧本杀，只是目前剧本杀只有2方，npc和玩家，这里引入另一方作为对抗，形成人斗的核心。&lt;/p&gt;

&lt;h3 id=&quot;代入感&quot;&gt;代入感&lt;/h3&gt;

&lt;p&gt;有点类似于上的玩家扮演NPC，其实就是一个RPG，但是玩家并不是只能从主角的角度进行游戏，而是可以进入到任何一个其中的角色进行游戏。一局内，可以扮演多个角色，最终让这种巧合达成一个结局，类似于疯狂的石头、疯狂的赛车、疯狂的外星人、无名之辈，这种类似的一环扣一环最终达成一个bad or happy ending。让玩家创造出一个环环相扣式的故事。当然这个结局可以是多种开放的。玩家体会到了每个角色的心路和情感，增强了代入感。&lt;/p&gt;

&lt;h3 id=&quot;多种可能&quot;&gt;多种可能&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Undertale&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;传说之下，没有玩过，但是被剧透了很多游戏相关的机制，简单说就是通过各种线索，让玩家在通过一个个boss或者关卡的时候，拥有不同的过关方式，而不是简单的杀死或者直接逃课类的通关，而是代入这个角色，了解角色的一切，进而做出人性的中善的操作。其实说的简单一点，就是让玩家去达成这个人物结局，而非编剧或者设定去决定，这种需要强编剧能力才能讲好一个故事。其实这种让玩家去了解boss，何尝不是一种设定，作者从一开始就算计好了，或者设计好了，是想让你从善的角度来解决问题的。&lt;/p&gt;

&lt;p&gt;我希望的是遇到问题，解决问题，解决问题有多种方式，甚至是解决出问题的人，出问题的社会，出问题的游戏。&lt;/p&gt;

&lt;h3 id=&quot;穿越&quot;&gt;穿越&lt;/h3&gt;

&lt;p&gt;基于时空线的，可以穿越到各个时空线去改变过去和未来，互相交织，互相影响。每次改变过去，都会造成游戏从被影响的那一刻重新开始，或者说是让游戏重新开了。当重开了n次以后，终于达成了最终的结局，抛出核心：错过即不在，珍惜当下。同时有一个黑色结局，无论达成了什么样的结果，我亦无悔，直面未来。&lt;/p&gt;

&lt;h3 id=&quot;我自己&quot;&gt;我自己&lt;/h3&gt;

&lt;p&gt;将我自己作为一个NPC代入进游戏，让玩家了解、互动，最终认识作者，认识我。从一个第三方的角度，体验别人与我的相处，与我的互动和认识。&lt;/p&gt;

&lt;p&gt;扩展：允许每个人设定自己，让自己成为一个npc，培养自己，让别人可以与自己认识，可以与自己交互，最终成为一个特立独行，一个我想成为的我。简单说就是让假我来扮演真我，或者是让真我来扮演假我。&lt;/p&gt;

&lt;h3 id=&quot;个体成为npc&quot;&gt;个体成为NPC&lt;/h3&gt;

&lt;p&gt;简单说就是允许玩家赋予自己作为NPC，通过一定的编程或者蓝图或者类似的东西，可以将自己的行为准则，行事方式录入到世界中作为一个NPC来行动，从而与其他玩家进行交互，变成一个有血有肉的人，每个人可以定义自己的风格，可以通过达成某些条件之后获得某一项东西。送出的物品，需要玩家本身拥有才能送出，否则无法进行复制，同时这样的NPC也需要一定的审核后才能成为真的NPC。而平常离线时，则角色自动转化成NPC执行对应的事件。&lt;/p&gt;

&lt;p&gt;NPC可以进行任务副本等等一切操作，甚至可以多个号联合在一起进行某些固定任务。&lt;/p&gt;

&lt;h3 id=&quot;随机固定属性&quot;&gt;随机固定属性&lt;/h3&gt;

&lt;p&gt;玩家的属性是固定的，并且是随机的，但是拥有一项别人所没有的东西，那就是学习能力。通过后天的学习，可以将某些属性修炼到逆天的程度。不存在可以修改出身的设定，并且账号是绑定的，完全无法出售的，必须是本人登录的，跟随你一辈子的东西。账号永久绑定一个人，身份证、实名、人脸认证、机器绑定、IP绑定。一旦任何一项发生了改变，那么一切都需要重新认证一次。账号交易行为不被许可，创建人物的行为会被收费。多少个角色就收费多少次，如同买游戏一样。&lt;/p&gt;

&lt;h2 id=&quot;loophero&quot;&gt;loophero&lt;/h2&gt;

&lt;p&gt;类似loophero，可以随便加入别人房间，一起loop，可以把控制权交给对方，允许房间内的人操作&lt;/p&gt;

&lt;p&gt;各种各样的冒险、事件、类似地下城的模式，加入以后可以共克难关，也能大佬带带&lt;/p&gt;

&lt;p&gt;游戏名：带佬呆呆，英文名 Die noob, Die lorn&lt;/p&gt;

&lt;h2 id=&quot;知识孤岛&quot;&gt;知识孤岛&lt;/h2&gt;

&lt;p&gt;让知识可以联系在一起的方式、方法&lt;/p&gt;

&lt;h4 id=&quot;双向链接&quot;&gt;双向链接&lt;/h4&gt;

&lt;p&gt;可以看到当前页面中联系到的其他一些知识文章或者信息&lt;/p&gt;

&lt;p&gt;修改markdown语法，增加双向链接的语法&lt;/p&gt;

&lt;p&gt;跳转后可以返回相同位置&lt;/p&gt;

&lt;h4 id=&quot;index&quot;&gt;index&lt;/h4&gt;

&lt;p&gt;可以通过本文关键字，搜索当前知识库中相同关键字的文章&lt;/p&gt;

&lt;h4 id=&quot;可以自主定义搜索域&quot;&gt;可以自主定义，搜索域&lt;/h4&gt;

&lt;p&gt;多个知识体系联合查询&lt;/p&gt;

&lt;h2 id=&quot;chatgpt-信息可信&quot;&gt;Chatgpt 信息可信&lt;/h2&gt;

&lt;p&gt;当AI甚至人为的营销信息爆炸的时候，如何保证信息可信？&lt;/p&gt;

&lt;p&gt;如何从爆炸信息中检索到关键且有用的信息，而不被带有偏差或者误导性质的信息带走&lt;/p&gt;

&lt;h2 id=&quot;水冷-桌机-被动散热&quot;&gt;水冷-桌机-被动散热&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;40*40*25= 0.04立方米=40升

热容积=40*4200=168000焦耳/度

7950x最大功率230W

168000/230*50=36521秒  常温水上升50度大概要10小时，还是满功耗的情况，实际不可能

换成二甲基硅油，比热容是1630，比例2.5766，换算以后就是3.88小时，也不是很难

3080Ti满功率是350W

CPU+GPU全功率工作，用水，最多需要14482秒，升高50度，大概也就是4小时

如果用硅油，只需要1.56小时就能升高50度
所以貌似用这种方式散热不太行，温度上升的比较明显了，还是需要散热
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;主板反扣，将散热器怼到水面中&lt;/p&gt;

&lt;p&gt;取消主板的所有前置，只有后置面，将后置面作为主面而非背面&lt;/p&gt;

&lt;p&gt;按钮，直接使用无线开关即可，不需要有线的&lt;/p&gt;

&lt;h2 id=&quot;自动开关窗&quot;&gt;自动开关窗&lt;/h2&gt;

&lt;p&gt;智能家居，自动开关窗，本质上风扇+防尘 新风空调之类的，但是风量更大，更符合常识&lt;/p&gt;

&lt;p&gt;已经有人实现并且做了，还有直接和窗户本体嵌入，一体化更好的&lt;/p&gt;

&lt;h2 id=&quot;下一代代码编辑器&quot;&gt;下一代代码编辑器&lt;/h2&gt;

&lt;p&gt;无论是哪种ide，本身都仅仅只有代码部分，而文档管理无论怎么修改都会和代码分割开来，而且文档会出现不同步，散乱在各种地方的情况&lt;/p&gt;

&lt;p&gt;这种情况下要维护代码和文档就变得异常困难了&lt;/p&gt;

&lt;p&gt;既然如此，为什么不把代码和文档混合在一起，形成一种新的格式呢&lt;/p&gt;

&lt;p&gt;比如：代码上方就是文档，包含图片，视频，音频，等等类型的文件，同时允许引用其他地方的文档进入&lt;/p&gt;

&lt;p&gt;超链接允许直接嵌入，显示时可以选择嵌入显示或者是跳转&lt;/p&gt;

&lt;p&gt;甚至对于图来说，最好上面就可以直接进行编辑&lt;/p&gt;

&lt;p&gt;代码的部分则更简单了，只要是同一个文件中的代码，他们就可以按照由上至下的逻辑进行拼接&lt;/p&gt;

&lt;p&gt;同一个页面内的代码，有一个页面属性，可以用来设置他的编译类型，从而在中间过程中生成他原来的代码逻辑，可以单独把代码抽离成普通的代码文件，同时也能把文档抽离成普通的文档文件&lt;/p&gt;

&lt;p&gt;这样就可以在写代码的时候，直接修改文档或者查看文档，这样就不会错过一些逻辑或者漏掉一些内容&lt;/p&gt;

&lt;p&gt;同理，如果文档可以写的再规范一些，代码甚至可以用AI辅助开发，这样AI生成的代码就更加有理有据了&lt;/p&gt;

&lt;p&gt;相当于我们在编译的环节中，又进行了一次编译，让代码不再仅仅是代码，而是真正的完整工程&lt;/p&gt;

&lt;h3 id=&quot;竞品&quot;&gt;竞品&lt;/h3&gt;

&lt;p&gt;swimm 有点类似，但是需要云端支持，结合了AI等内容，同时还具有代码扫描、审查类的功能&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://swimm.io/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;古人的尝试&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;http://www.mark-to-win.com/tutorial/176050.html&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;jupyter 就是把代码和markdown都写在一起了，同时代码还能运行&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://zhuanlan.zhihu.com/p/478098675&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;特性&quot;&gt;特性&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;开源、独立、不影响代码的独立性，不需要远程服务器，能看到代码即能看到文档&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;文档以markdown形式记录&lt;/li&gt;
  &lt;li&gt;文档支持各种各样的block，每个文档和对应的代码存在行或者文件的绑定关系&lt;/li&gt;
  &lt;li&gt;允许文档合并，block合并&lt;/li&gt;
  &lt;li&gt;文件名改动或者行或者函数等发生变动时，需要有提示绑定关系的变更&lt;/li&gt;
  &lt;li&gt;切换文件时自动切换文档，也允许主动显示当前代码的文档内容&lt;/li&gt;
  &lt;li&gt;所有标记性的东西，记录在文档中，不影响原始的code状态&lt;/li&gt;
  &lt;li&gt;标记性的内容可以独立做一个目录，每次从目录中进行搜索匹配即可&lt;/li&gt;
  &lt;li&gt;最好可以跟踪git 自动修改文件名产生的变更&lt;/li&gt;
  &lt;li&gt;允许打开第三方链接或者笔记中的block&lt;/li&gt;
  &lt;li&gt;可以支持更多的IDE&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;长远&quot;&gt;长远&lt;/h3&gt;

&lt;p&gt;为什么代码不可以和文档写在一起，甚至多种代码混在一起&lt;/p&gt;

&lt;p&gt;通过文件的标识，区分各种代码，代码的顺序可以唯一确定，但是查看的时候可以将各个代码块完全独立的移动&lt;/p&gt;

</description>
        <pubDate>Sat, 05 Apr 2025 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2025/04/05/thought/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2025/04/05/thought/</guid>
        
        <category>Game</category>
        
        
      </item>
    
      <item>
        <title>小米人在传感器Pro踩坑</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;前面看了小米人在传感器Pro的应用感觉还挺有意思的，没想到一试发现是个大坑&lt;/p&gt;

&lt;h2 id=&quot;小米人在传感器pro&quot;&gt;小米人在传感器Pro&lt;/h2&gt;

&lt;h3 id=&quot;标称覆盖&quot;&gt;标称覆盖&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409130031445.png&quot; alt=&quot;image-20240913003135155&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409130036898.png&quot; alt=&quot;image-20240913003641853&quot; /&gt;&lt;/p&gt;

&lt;p&gt;看似水平有110°，其实最有用的静态只有106°左右，垂直角度是60°，其实非常小了，同时限制了你能俯仰的角度大概就是30度左右，极限是60度，再大就会吃掉垂直角度。&lt;/p&gt;

&lt;p&gt;由于这个东西本身检测目标是人，所以他不能被直接遮挡在各种东西后面，他的检测空间最好相对干净一些，这就限制了他的安装高度，官方推荐是1.8m，大概就是人高，如果安装越高，就需要更大角度，但是角度大了，其实就变相缩小俯视角度下的覆盖面积。&lt;/p&gt;

&lt;h3 id=&quot;真实覆盖&quot;&gt;真实覆盖&lt;/h3&gt;

&lt;p&gt;图中一小格是0.5m*0.5m&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409130035342.png&quot; alt=&quot;image-20240913003539250&quot; /&gt;&lt;/p&gt;

&lt;p&gt;可以看到最远可以覆盖7m，静态范围只能4m，看似很大？实则很坑。&lt;/p&gt;

&lt;p&gt;7m的动态侦测，换句话说就是不稳定，移动可以检测到，但是稳定目标不行，别想做任何静态相关的自动化，不太能用。&lt;/p&gt;

&lt;p&gt;真正宣传和侧重的都是这个静态区域，但是由于角度问题，其实上图真正可以用的范围基本只有红圈内，雷达脚下1m，左右2m的范围内存在盲区，可用性很低&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409130047408.png&quot; alt=&quot;image-20240913004710349&quot; /&gt;&lt;/p&gt;

&lt;p&gt;为什么，因为角度问题，如果角度放的够低，会削减盲区，灯下不黑了，但是同样的远端就小了，而角度降低很容易被其他家具挡住导致更多的盲区。这样导致实际可以检测互动的区域其实只有6-8㎡，去掉一些固定家具，一些大型家具遮挡，实际可用的范围就更小了。&lt;/p&gt;

&lt;p&gt;对比他的价格，379，这个价格我都能买三四个小覆盖的毫米波雷达了，野生人在雷达我都能买六七个了，什么样的场景会覆盖不了。&lt;/p&gt;

&lt;p&gt;鬼影问题很严重，动态区域和静态区域来回走，就能造成好几个鬼影，鬼影消失的也非常慢。更别说走出了检测区，鬼影出现就更厉害了&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409130105568.png&quot; alt=&quot;image-20240913010523528&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;改进建议&quot;&gt;改进建议&lt;/h3&gt;

&lt;p&gt;目前看雷达的感应地图的精度太低了，可能和算力或者干扰有关系，0.5m*0.5m的地图如果是大客厅可能还可以，但是小一点的空间，这个精度太粗了，很多东西划不出来。&lt;/p&gt;

&lt;p&gt;这个0.5同时也导致了安装难度过高，你安装完以后需要人去核对地图，这个时候你就会发现怎么安装好像都没办法说用这个传感器卡住地图，不是偏左就是偏右了（其实还是检测精度不够）&lt;/p&gt;

&lt;p&gt;这个东西太大了，特别是配合上磁吸的安装座更大了，本来就装不高，还这么大，十分影响观感&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;优点还是有一些的，比如静态检测还是很稳定的，很少出现人消失误判的情况，静态区域的无人判断可以非常快&lt;/p&gt;

&lt;p&gt;这么久以来智能家居都缺少一点点AI，这个雷达的数据总算是迈出了一步，可以结合到AI了，不过问题还是太多了，这个数据太烂了，做识别和深挖都不够用的。智能家居缺少了一个总控，可以分析收集所有数据的总控端，这个环节补上了，可能才会有新的应用场景，据说小米已经在做了，快要释放到客户端了&lt;/p&gt;
</description>
        <pubDate>Fri, 13 Sep 2024 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2024/09/13/Xiaomi-Pro/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2024/09/13/Xiaomi-Pro/</guid>
        
        <category>米家</category>
        
        
      </item>
    
      <item>
        <title>PHP</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;传闻中天下第一的语言，试一下服务器部署，没想到这么困难，老古董还是有点难啊&lt;/p&gt;

&lt;h2 id=&quot;php&quot;&gt;PHP&lt;/h2&gt;

&lt;h3 id=&quot;部署&quot;&gt;部署&lt;/h3&gt;

&lt;p&gt;先安装PHP，2021 年开始，Ubuntu 官方不再支持 PHP 5.6 版本的维护和更新，因此如果需要在 Ubuntu 上安装 PHP 5.6，则需要使用第三方的 PPA（个人软件包归档）来进行安装&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php5.6
php -v
PHP 5.6.40-78+ubuntu24.04.1+deb.sury.org+1 (cli) 
Copyright (c) 1997-2016 The PHP Group
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;好像fpm不这么装也行，5.3.3以后集成了fpm，本身是用来管理的&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt-get install php5.6-fpm
systemctl status php5.6-fpm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;检查apache服务启动&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;systemctl status apache2.service 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;内网地址，可以看到页面了&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://10.10.2.24/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;替换一个PHP的index看下&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;我的第一个 PHP 页面&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello World!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;到这里已经可以正常显示启动了&lt;/p&gt;

&lt;h3 id=&quot;数据库&quot;&gt;数据库&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt install php5.6-mysql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker pull mysql:5.6
docker run --name user_database -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:5.6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 准备连接参数&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$servername&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;localhost&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$servername&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;127.0.0.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$username&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;123456&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$dbname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;user_database&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
&lt;span class=&quot;c1&quot;&gt;// 创建数据库连接&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$connect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mysqli_connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$servername&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$dbname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
&lt;span class=&quot;c1&quot;&gt;// 检查连接&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mysqli_connect_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;die&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;连接失败: &quot;&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mysqli_connect_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
&lt;span class=&quot;c1&quot;&gt;// 选择数据库&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mysqli_select_db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$dbname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;数据库连接成功&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;数据库连接失败&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
&lt;span class=&quot;c1&quot;&gt;// 关闭连接&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;mysqli_close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;测试是否可以连接到数据库，目前没有问题了&lt;/p&gt;

&lt;h3 id=&quot;apache2&quot;&gt;Apache2&lt;/h3&gt;

&lt;p&gt;Apache2和之前的不太一样，配置文件都改变了&lt;/p&gt;

&lt;p&gt;ports.conf中是apache监听的端口&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# If you just change the port or add more ports here, you will likely also&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# have to change the VirtualHost statement in&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# /etc/apache2/sites-enabled/000-default.conf&lt;/span&gt;

Listen 80

&amp;lt;IfModule ssl_module&amp;gt;
        Listen 443
&amp;lt;/IfModule&amp;gt;

&amp;lt;IfModule mod_gnutls.c&amp;gt;
        Listen 443
&amp;lt;/IfModule&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;默认apache的虚拟主机是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/apache2/sites-available/000-default.conf&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;VirtualHost &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;:80&amp;gt;
        &lt;span class=&quot;c&quot;&gt;# The ServerName directive sets the request scheme, hostname and port that&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# the server uses to identify itself. This is used when creating&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# redirection URLs. In the context of virtual hosts, the ServerName&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# specifies what hostname must appear in the request&apos;s Host: header to&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# match this virtual host. For the default virtual host (this file) this&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# value is not decisive as it is used as a last resort host regardless.&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# However, you must set it for any further virtual host explicitly.&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;#ServerName www.example.com&lt;/span&gt;

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        &lt;span class=&quot;c&quot;&gt;# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# error, crit, alert, emerg.&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# It is also possible to configure the loglevel for particular&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# modules, e.g.&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;#LogLevel info ssl:warn&lt;/span&gt;

        ErrorLog &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;APACHE_LOG_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/error.log
        CustomLog &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;APACHE_LOG_DIR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/access.log combined

        &lt;span class=&quot;c&quot;&gt;# For most configuration files from conf-available/, which are&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# enabled or disabled at a global level, it is possible to&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# include a line for only one particular virtual host. For example the&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# following line enables the CGI configuration for this host only&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# after it has been globally disabled with &quot;a2disconf&quot;.&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;#Include conf-available/serve-cgi-bin.conf&lt;/span&gt;
&amp;lt;/VirtualHost&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;类似nginx的config文件，设置域名和端口等等相关代理设置&lt;/p&gt;

&lt;p&gt;在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apache2.conf&lt;/code&gt;中的是apache的全局设置，比如是否支持SSL，映射目录是什么&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;一个奇怪的问题php里localhost和127.0.0.1竟然不一样，识别不了localhost，查了一下大概是由于php.ini中缺少了默认sock的方式，localhost是一种特殊传递数据的方式，并不会经过socket&lt;/p&gt;

&lt;h2 id=&quot;quote&quot;&gt;Quote&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.runoob.com/w3cnote/php-basic-summary.html?source=1&lt;/p&gt;

  &lt;p&gt;https://blog.csdn.net/m0_52985087/article/details/132132219&lt;/p&gt;

  &lt;p&gt;https://blog.csdn.net/weixin_71993565/article/details/140336762&lt;/p&gt;

  &lt;p&gt;https://blog.tag.gg/showinfo-13-35867-0.html&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Fri, 06 Sep 2024 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2024/09/06/PHP-Server/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2024/09/06/PHP-Server/</guid>
        
        <category>PHP</category>
        
        
      </item>
    
      <item>
        <title>再破吉尼斯世界纪录</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;再破一次吉尼斯世界记录，然而还不止于此。吉尼斯也会撞车，这谁敢信？不仅仅撞车，某一个类似的记录在连续一个月内被连破五次，这是巧合还是故意的？&lt;/p&gt;

&lt;h2 id=&quot;吉尼斯&quot;&gt;吉尼斯&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409060106844.png&quot; alt=&quot;image-20240906010618517&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Most Unmanned Aerial Vehicles (UAVs) airborne simutaneously&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;现在已经无法回查到4年前的那条记录了，应该是出现了冲突，所以所有此条记录都不存在了，只有曾经的官方新闻证明曾经破过。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Most remote controlled multirotors/drones airborne simultaneously&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;现在是使用这条记录进行平替，以前的描述和标准其实都有点太过轻松了，而且也有很多不合理的点，特别是大架次以后还要人数，这个就非常扯蛋，以前三五千人数也就算了，这都快破万了，人数已经很不靠谱了。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.guinnessworldrecords.cn/search?term=%2A&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;通过吉尼斯的查询入口，可以查到大部分记录，有一部分需要注册登录以后才能查询&lt;/p&gt;

&lt;p&gt;这次破的是：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;the largest image formed by multirotor/drones&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409060104122.png&quot; alt=&quot;image-20240906010421956&quot; /&gt;&lt;/p&gt;

&lt;p&gt;如果有相似团队或者个人挑战同一个记录，特别是商业目的的，吉尼斯会锁定这个词条大概一个月左右的时间，给予充分的宣传时间，如果是挑战不同记录，那就没啥错峰的操作了&lt;/p&gt;

&lt;p&gt;还好这次破纪录可以反向逆推，数没起飞的就行了，实际数量也可以直接参考地面站的数值，不需要弄一堆第三方志愿者来数飞机了，太傻了。&lt;/p&gt;

&lt;p&gt;四年前预言压力在网络上，大概极限是在7500左右，这次直接就破到了7598，刷新了最大架次，而事实证明这个数量还不是极限，还能再往上顶。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409060107128.png&quot; alt=&quot;image-20240906010741842&quot; /&gt;&lt;/p&gt;

&lt;p&gt;7598之后，就是7998，这也算是最短的记录了，破完第二天别人就又破了，起了个大早赶了个晚集&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409060113848.png&quot; alt=&quot;image-20240906011313776&quot; /&gt;&lt;/p&gt;

&lt;p&gt;再接着8100，很烦，本来这个东西在这个级别再比起来就没啥意思了，但总有人在卷，你就得更卷，所以下次就是五位数了&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409060114388.png&quot; alt=&quot;image-20240906011437255&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;迭代了2代产品，才勉强打过别人3年前出的产品，进步的速度肉眼可见的慢。&lt;/p&gt;

&lt;p&gt;拿着4年后的产品跟别人三年前的产品比较，确实有所进步，总算领先了那么一点点，但也仅此而已了&lt;/p&gt;
</description>
        <pubDate>Thu, 05 Sep 2024 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2024/09/05/UAVC-GuinnessWorldRecords2/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2024/09/05/UAVC-GuinnessWorldRecords2/</guid>
        
        <category>UAV</category>
        
        <category>GuinnessWorldRecords</category>
        
        
      </item>
    
      <item>
        <title>Git LFS与各种Git管理软件对比</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;之前选过一些资产管理软件，但是都不够好，当时遗漏了Git LFS，这里再补充测试一下&lt;/p&gt;

&lt;h2 id=&quot;git-lfs&quot;&gt;Git LFS&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/git-lfs.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/git-lfs/git-lfs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Git LFS的客户端和Git不同，但是可以使用相同的命令完成Git操作，其实LFS的底层原理挺简单，就是通过Git的时候进行回调，如果是LFS匹配的文件就进入到了LFS提交流程&lt;/p&gt;

&lt;p&gt;将所有stp结尾的文件，加入到追踪中&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git lfs track &quot;*.stp&quot;
git lfs track &quot;*.CATDrawing&quot;
git lfs track &quot;*.CATPart&quot;
git lfs track &quot;*.dxf&quot;
git lfs track &quot;*.igs&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;lfs文件追踪是加在.gitattributes文件中的&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git add .gitattributes
git commit -m &quot;track *.stp files using Git LFS&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;lfs文件追踪是加在.gitattributes文件中的&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git add .
git commit -m &quot;add stp&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;查看追踪文件&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git lfs track
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;下载包含lsf的仓库时也需要加上lfs的标签&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git lfs clone xxxx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;更新内容的脚本&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;unset &lt;/span&gt;http_proxy&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;unset &lt;/span&gt;https_proxy&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
git pull origin main
git add .&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33[34m&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;请输入更新内容，按回车键结束:&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33[0m&quot;&lt;/span&gt;
git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$REPLY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
git push origin main
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33[34m提交完成，按任意键退出&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33[0m&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; 1
&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;退出
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;克隆仓库的脚本&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;unset &lt;/span&gt;http_proxy&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;unset &lt;/span&gt;https_proxy&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33[34m&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;请输入仓库地址，中键复制，按回车键开始克隆:&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33[0m&quot;&lt;/span&gt;
git lfs clone &lt;span class=&quot;nv&quot;&gt;$REPLY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

git push origin main
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33[34m提交完成，按任意键退出&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33[0m&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; 1
&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;退出
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;创建新仓库脚本&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;unset http_proxy;
unset https_proxy;
git init --initial-branch=main

git lfs track &quot;*.stp&quot;
git lfs track &quot;*.CATDrawing&quot;
git lfs track &quot;*.CATPart&quot;
git lfs track &quot;*.dxf&quot;
git lfs track &quot;*.igs&quot;
git add .gitattributes
git commit -m &quot;track files using Git LFS&quot;

echo -e &quot;\033[34m&quot;
read -p &quot;请输入仓库地址，中键复制，按回车键开始上传:&quot;
echo -e &quot;\033[0m&quot;

git remote add origin $REPLY

git add .
git commit -m &quot;initial repository commit&quot;
git push origin main
echo -e &quot;\033[34m提交完成，按任意键退出\033[0m&quot;
read -n 1
echo 退出
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;迁移&quot;&gt;迁移&lt;/h3&gt;

&lt;p&gt;把原来git代码中大文件变成lfs中存储&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git lfs migrate import --include=&quot;*.stp&quot; --everything
git lfs migrate import --include=&quot;*.igs&quot; --everything
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;问题&quot;&gt;问题&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git push -u origin master
Remote &quot;origin&quot; does not support the LFS locking API. Consider disabling it with:
  $ git config lfs.https://e.coding.net/xxxx/gitlfs/gitlfs.git].git/info/lfs.locksverify false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可能会出现以上提示，这个是服务端不支持文件锁定，所以需要配置一下让服务端关闭即可&lt;/p&gt;

&lt;h3 id=&quot;测试&quot;&gt;测试&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240829225227600.png&quot; alt=&quot;image-20240829225227600&quot; /&gt;&lt;/p&gt;

&lt;p&gt;经过测试，1.11GB的文件，比较大的文件加入lfs以后，git add 命令会快很多&lt;/p&gt;

&lt;p&gt;上传和下载就取决于网络和服务端限制了，正常使用似乎问题不大。&lt;/p&gt;

&lt;p&gt;coding似乎5分钟左右就能完成2.28G的仓库上传，40秒不到就能把整个仓库完全拉下来，完全够用了&lt;/p&gt;

&lt;p&gt;大部分硬件仓库和结构仓库，不包含一些七七八八的东西的话，用Git lfs管理足够。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240830100229470.png&quot; alt=&quot;image-20240830100229470&quot; /&gt;&lt;/p&gt;

&lt;p&gt;配合SourceTree 给小白使用也非常简单&lt;/p&gt;

&lt;h2 id=&quot;自建lfs服务器&quot;&gt;自建LFS服务器&lt;/h2&gt;

&lt;p&gt;Git LFS，coding里是标配了20G空间，不占用原有代码空间，Gitee里只有1G基本等于没有，必须要私有部署才行&lt;/p&gt;

&lt;p&gt;GitLab也支持LFS，不过有一些要求&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Git LFS is supported in GitLab starting with version 8.2. (gitlab版本需要 &amp;gt;= 8.2)&lt;/li&gt;
  &lt;li&gt;Git LFS must be enabled under project settings  (必须在项目设置中开启LFS)&lt;/li&gt;
  &lt;li&gt;Users need to install Git LFS client version 1.0.1 and up （本地git lfs客户端版本 &amp;gt;= 1.0.1）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;开源的LFS存储服务器，据说Github也是基于这个二次开发的&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/git-lfs/lfs-test-server&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;修改&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.lfsconfig&lt;/code&gt;文件，增加lfs服务器地址&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  [lfs]
    url = &quot;http://localhost:8080/&quot;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;弹性LFS，使用一些对象存储或者是云盘实现LFS服务&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/zhxxch/git-lfs-one&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;gitea&quot;&gt;Gitea&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240830164326561.png&quot; alt=&quot;image-20240830164326561&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://gitee.com/gitea/gitea&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gitea更像是一个简化版的Gitlab，界面干净一些&lt;/p&gt;

&lt;p&gt;Gitea和其他DevOps的对比&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://docs.gitea.com/zh-cn/installation/comparison&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gitea整体非常轻量，适合小机器部署，功能自然也缺少了很多，如果人员很少，也没有规模化的一些需求，可以使用Gitea，否则还是Gitlab更好一些&lt;/p&gt;

&lt;h2 id=&quot;腾讯工蜂&quot;&gt;腾讯工蜂&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://code.tencent.com/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;通过Ugit发现了腾讯还专门有一个给游戏类使用的管理平台&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409141146190.png&quot; alt=&quot;image-20240914114636362&quot; /&gt;&lt;/p&gt;

&lt;p&gt;目前看起来和Coding重叠度非常高，但是给资源的角度非常大方，SaaS版本可以随便使用，LFS仓库给的非常大，可以说很离谱&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409141148694.png&quot; alt=&quot;image-20240914114819622&quot; /&gt;&lt;/p&gt;

&lt;p&gt;工蜂的内部界面非常像Gitlab&lt;/p&gt;

&lt;h2 id=&quot;svn&quot;&gt;SVN&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.visualsvn.com/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;如果只是普通的SVN本地管理是免费的，但是SVN的服务端是收费的&lt;/p&gt;

&lt;p&gt;VisualSVN Server&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.visualsvn.com/server/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240830170158664.png&quot; alt=&quot;image-20240830170158664&quot; /&gt;&lt;/p&gt;

&lt;p&gt;VisualSVN是按照用户数收费的，买断制，所以可以根据人员决定价格，服务器自己出就行了，不过一次性付费只有12个月的更新和维护时间，后续再更新需要再次付费。&lt;/p&gt;

&lt;p&gt;VisualSVN也有社区版本，社区版可以给15个人使用&lt;/p&gt;

&lt;h2 id=&quot;git-ui工具&quot;&gt;Git UI工具&lt;/h2&gt;

&lt;h3 id=&quot;ugit&quot;&gt;Ugit&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121721908.png&quot; alt=&quot;image-20240912172144786&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://ugit.qq.com/zh/index.html&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ugit是腾讯的自研Git客户端，本身分为专业版和美术版，美术版的交互类似SVN一些&lt;/p&gt;

&lt;p&gt;Ugit界面相比SourceTree更加简洁一些&lt;/p&gt;

&lt;p&gt;默认内置了LFS的模板，适合做大文件管理，内置了文件锁，可以防止文件被多个人更新&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409141159167.png&quot; alt=&quot;image-20240914115942100&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Ugit目前适配了私有部署的gitlab，如果此处提示无法登录，注意一下Gitlab的权限是否正常，是否开了代理，有时候代理会导致这里授权失败。&lt;/p&gt;

&lt;p&gt;授权以后，可以直接从克隆看到远端仓库，可以直接克隆，还是比较方便的，同时用户信息也自动帮你填好了，上手难度还是降低了一些的&lt;/p&gt;

&lt;p&gt;Ugit对比SourceTree，感觉Ugit确实更流畅一些，特别是文件比较多的时候，很明显的感觉，针对性优化确实有点意义&lt;/p&gt;

&lt;h3 id=&quot;gitkraken&quot;&gt;GitKraken&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.gitkraken.com/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121744488.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;GitKraken嵌入的比较多，更合适IDE里使用&lt;/p&gt;

&lt;h3 id=&quot;gitui&quot;&gt;gitui&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121811783.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/extrawurst/gitui&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;rust写的git ui客户端，主要还是服务VI VIM类的界面&lt;/p&gt;

&lt;h3 id=&quot;lazygit&quot;&gt;lazygit&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121810218.gif&quot; alt=&quot;interactive_rebase&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/jesseduffield/lazygit&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;和上面的gitui类似，也是服务mac、linux下的终端类界面&lt;/p&gt;

&lt;h3 id=&quot;smartgit&quot;&gt;SmartGit&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121811217.png&quot; alt=&quot;SmartGit Screenshot&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.syntevo.com/smartgit/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;付费Git客户端，界面类似SourceTree&lt;/p&gt;

&lt;h3 id=&quot;gitbutler&quot;&gt;GitButler&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121814707.png&quot; alt=&quot;image-20240912181436640&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://gitbutler.com/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;gitbutler，交互拉满，各种东西都可以通过拖拽实现，很符合直觉&lt;/p&gt;

&lt;p&gt;gitbutler是把修改内容和仓库文件进行了解耦，你修改的文件存在在workspace中，这次提交你可以提交或者融合到任何一个commit或者分支上去，具体怎么融合是他内部帮你处理好，不用自己写命令。&lt;/p&gt;

&lt;p&gt;这种适合增量、文件之间耦合关系很弱的开发模式，gitbutler是必须要走PR流程的，如果PR无法正常运行，那么整个流程就走不动了，它不支持你直接合并，这有点奇怪&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;大部分情况LFS+Gitlab可以解决多数问题&lt;/p&gt;

&lt;h2 id=&quot;quote&quot;&gt;Quote&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://coding.net/help/docs/admin/pay/newprice.html&lt;/p&gt;

  &lt;p&gt;https://coding.net/help/docs/repo/git/lfs.html&lt;/p&gt;

  &lt;p&gt;https://zhuanlan.zhihu.com/p/511750788&lt;/p&gt;

  &lt;p&gt;https://zhuanlan.zhihu.com/p/146683392&lt;/p&gt;

  &lt;p&gt;https://gitee.com/help/articles/4235#article-header4&lt;/p&gt;

  &lt;p&gt;https://forcemz.net/git/2017/04/16/Moses/&lt;/p&gt;

  &lt;p&gt;https://forcemz.net/git/2018/07/15/GitLFSRethinking/&lt;/p&gt;

  &lt;p&gt;https://cloud.tencent.com/developer/article/1010589&lt;/p&gt;

  &lt;p&gt;https://www.escapelife.site/posts/92ef32ff.html&lt;/p&gt;

  &lt;p&gt;https://juejin.cn/post/6844903791855140872&lt;/p&gt;

  &lt;p&gt;https://blog.inkroom.cn/2023/02/27/10J1G9S.html&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Wed, 28 Aug 2024 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2024/08/28/Git-LFS/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2024/08/28/Git-LFS/</guid>
        
        <category>Git</category>
        
        
      </item>
    
      <item>
        <title>东北见闻</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;记录一下东北见闻&lt;/p&gt;

&lt;h2 id=&quot;长春&quot;&gt;长春&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240819213804870.png&quot; alt=&quot;image-20240819213804870&quot; /&gt;&lt;/p&gt;

&lt;p&gt;长春是吉林的省会，很奇怪为什么不是吉林，吉林其实离长春很近，只有一百多公里。吉林历史上确实是吉林的省会，后来伪满洲大力发展长春，让长春成了省会的潜在竞争者，1953年长春成了直辖市，吉林还是省会，从1954年开始长春成为了吉林省会，自此就再也没变过了。&lt;/p&gt;

&lt;p&gt;长春比较有名的景点：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;伪满皇宫博物院，溥仪最后做皇帝时的皇宫&lt;/li&gt;
  &lt;li&gt;净月潭&lt;/li&gt;
  &lt;li&gt;长春电影制片厂&lt;/li&gt;
  &lt;li&gt;这有山，其实是个比较特殊的商业中心，假山坐在楼中&lt;/li&gt;
  &lt;li&gt;刘老根大舞台，欣赏不来&lt;/li&gt;
  &lt;li&gt;德云社，东北竟然也有相声社，第一次见&lt;/li&gt;
  &lt;li&gt;桂林路，网红、小吃一条街，有的东西大差不差&lt;/li&gt;
  &lt;li&gt;长春天主教堂，比较西式的建筑，国内还是满少见的&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240819215119517.png&quot; alt=&quot;image-20240819215119517&quot; /&gt;&lt;/p&gt;

&lt;p&gt;东北的衰败，来到长春，确实很明显，特别是还刚巧去了长春的老城区，人民广场附近。地图上看起来像是市中心，其实实际到了以后，有点黑灯瞎火。周围没有很多高楼，更多的是黑灯的老楼，像是很久都没有人住了。&lt;/p&gt;

&lt;p&gt;附近的门店也有很多关门很久很久了，人烟稀少。出租车司机说新城区人多一些，老城区基本没啥人了。到达的比较晚，也没啥吃饭的门店了，只有路边的烧烤，确实符合东北的风格，价格很低。&lt;/p&gt;

&lt;h2 id=&quot;延吉&quot;&gt;延吉&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240819220745267.png&quot; alt=&quot;image-20240819220745267&quot; /&gt;&lt;/p&gt;

&lt;p&gt;延吉城区比较小，繁华路段基本就集中在2-3公里的一条长街上。印象最深刻的就是打车贼便宜，5块的起步价，到哪里都是5块。可能正好处于旅游旺季，逆天的酒店价格，比深圳贵1.5倍左右。房价几千到一万多，在这样的小城市里也算是有点高的，招牌上基本都是中韩双语，路上遇到的人说韩语的也非常多。&lt;/p&gt;

&lt;p&gt;延吉的景点都比较一般，甚至说有点寒酸：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;水上市场，就是个早市&lt;/li&gt;
  &lt;li&gt;西市场，类似年代久远的百货商场，卖啥的都有，由于是旅游点之一，所以卫生、环境都还不错，相对人也比较多，不要好奇东市，菜市场而已&lt;/li&gt;
  &lt;li&gt;网红墙，妥妥的营销出来的景点，就是一堆广告牌，霓虹灯，深圳满大街都可以算是。人头攒动，摩肩接踵，过了这一片立马就消停了，属实迷惑，非要来的话可以接近23点再去，人少很多&lt;/li&gt;
  &lt;li&gt;帽儿山，比延吉市区高一头，可以俯瞰整个延吉，然而延吉没啥好看的&lt;/li&gt;
  &lt;li&gt;阿里郎广场，州政府对面，延边图书馆，跑道、街健、运动场，足球氛围拉满，挺不错的，深圳没几个这种地方，当地人多一些，旅客基本没有&lt;/li&gt;
  &lt;li&gt;延吉图们口岸，朝鲜，曾经在丹东见过对面破败的朝鲜，十年过去了，似乎也没什么变化&lt;/li&gt;
  &lt;li&gt;延边大学，双一流、211，进入校园需要提前预约&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;大概太阳下山后，中心老城区里非通行的广场上，摆摊、跳舞、烧烤、踢毽子、按摩，生活气氛浓郁。但总体都是老头老太太了，甚至还能看到营业的练歌房，老头老太太刚吼完出来，年轻人也不知道去了哪里。&lt;/p&gt;

&lt;p&gt;百货大楼、地下街、防空洞，旋转大门，这些曾经老旧的东西，在这里还能看到&lt;/p&gt;

&lt;p&gt;延吉作为距离长白山最近的城市，导致很多人去长白山玩，顺道被忽悠来延吉逛一逛，顺带带动了延吉的酒店。&lt;/p&gt;

&lt;h2 id=&quot;延边大学&quot;&gt;延边大学&lt;/h2&gt;

&lt;p&gt;延边大学从正门进入需要提前预约，预约也很简单，微信搜索延边大学小程序-校内通行信息登记系统即可，简单就能预约到了，扫人脸进门&lt;/p&gt;

&lt;p&gt;延边大学如果是从侧面进入是不需要预约信息的，跟学生一样走进去就行了&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240831220816978.png&quot; alt=&quot;image-20240831220816978&quot; /&gt;&lt;/p&gt;

&lt;p&gt;延边大学9.7号才开学，但是新生军训8.17已经提前开始了，操场上很多训练的方队。看了一下开学时间，延边大学也有小学期，暑假也是8月份才放的&lt;/p&gt;

&lt;p&gt;学校里自习桌还挺高级的，自带小米50w无线快充，挺高级的&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240831220837330.png&quot; alt=&quot;image-20240831220837330&quot; /&gt;&lt;/p&gt;

&lt;p&gt;学校里可以参观的比较少，一个博物馆，一个抗联馆，前者是类似校史馆，后者是红色文化宣传教育馆。人稍微多一点的是游泳馆，似乎是对外开放的，买票就能进，而且很大。&lt;/p&gt;

&lt;p&gt;学校食堂挺便宜的，都正常开放了，偏远角落还有一个咖啡文化馆，不过基本没啥人。&lt;/p&gt;

&lt;p&gt;总体来说学校不是特别大，一下午就足够逛完了，大部分地方都没啥看点，再加上学生没返校，路人很少，只能追忆一下以前的校园生活。&lt;/p&gt;

&lt;h2 id=&quot;长白山&quot;&gt;长白山&lt;/h2&gt;

&lt;p&gt;长白山分为西坡和北坡，无论是哪边，都需要在天气好的情况下去，否则有可能封山&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;北坡风景比较多，天池，瀑布，走路比较少，很快就能到达山顶&lt;/li&gt;
  &lt;li&gt;西坡无法直达山顶，需要徒步1440级台阶&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;长白山如果隔天去，可能会遇到买不到票，然后去咸鱼找黄牛，黄牛说要明天19点以后给票或者当天19点以后给（巨大坑点），一张票加个40左右。&lt;/p&gt;

&lt;p&gt;官方票务显示都没有票，但是真的等到了第二天大概18点以后，就会发现官方放票了。大多数票应该是提前被旅行社或者黄牛拿走了，导致官方一直显示是0，等时间到了，一放出来几千近万张票就来了，完全没必要加钱。&lt;/p&gt;

&lt;p&gt;冬季去西坡，夏季去北坡，从延吉出发去长白山还是挺远的，有个大概100多公里。长白山本身所在就是二道白河镇（基本就是为长白山旅游住宿的小镇），实际去北坡行程是先到到了二道白河镇，买了北坡门票，然后乘坐官方大巴上山，大概50分钟左右到达山腰吧。转乘15分钟的小车，可以到达山顶，观赏天池。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240828152805941.png&quot; alt=&quot;image-20240828152805941&quot; /&gt;&lt;/p&gt;

&lt;p&gt;山上观看天池的地方很小，人很多，除了看、拍照以外基本没有啥额外的娱乐活动了&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;山腰温度还行比正常低10-15度左右，山顶温度很低了，接近0度了，最好多带点衣服，风也很大&lt;/li&gt;
  &lt;li&gt;天池观赏非常看天气，大雾、多云建议都别去，大概率会关闭，如果不关闭天池也会像图里的，雾蒙蒙的，晴天风景完全不同&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240828152829256.png&quot; alt=&quot;image-20240828152829256&quot; /&gt;&lt;/p&gt;

&lt;p&gt;隐约可以看到对面这条小路，应该就是朝鲜了&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240828153018367.png&quot; alt=&quot;image-20240828153018367&quot; /&gt;&lt;/p&gt;

&lt;p&gt;山腰下来以后的其他景区，基本没啥看头，温泉只有一点点，没啥给你接触的机会；大瀑布不开放；岳桦栈道，也一般，纯走路没啥内容；小天池，还没村里的鱼塘大，去不去都那样；&lt;/p&gt;

&lt;p&gt;绿渊谭，也是个小水池+小瀑布，观赏性实在是太低了，至于其他的人造景区、人造园林，那就更没意思了。&lt;/p&gt;

&lt;p&gt;总的来说长白山也就天池值得一看，其他地方都太一般了，人工痕迹过重了，长白山大部门门票基本都是给了车票，全程都是景区内车接车送，当天景区内一共坐了6次车，在不同景点直接往返。&lt;/p&gt;

&lt;h2 id=&quot;图们&quot;&gt;图们&lt;/h2&gt;

&lt;p&gt;从延吉到图们不到30公里，一小时不到就能到了。图们，曾经可以去朝鲜，是和朝鲜贸易的口岸，不过目前已经被废弃了，除了看看，没啥可玩点了，想去到朝鲜从这里也是完全不可能的了。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240901235208851.png&quot; alt=&quot;image-20240901235208851&quot; /&gt;&lt;/p&gt;

&lt;p&gt;口岸界碑&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240901235659983.png&quot; alt=&quot;image-20240901235659983&quot; /&gt;&lt;/p&gt;

&lt;p&gt;25买个门票，就可以登上口岸顶&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240901235232715.png&quot; alt=&quot;image-20240901235232715&quot; /&gt;&lt;/p&gt;

&lt;p&gt;遥望对面的朝鲜，还是相当破败的，楼房里烧柴火，玻璃都没有，用塑料布当玻璃，正中大楼上还挂着将军一家的头像，很是嘲讽&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/image-20240901235302623.png&quot; alt=&quot;image-20240901235302623&quot; /&gt;&lt;/p&gt;

&lt;p&gt;图们口岸广场上玩门球的大爷和大妈，看了一场精彩的逆转，门球还挺少见的&lt;/p&gt;

&lt;h2 id=&quot;珲春&quot;&gt;珲春&lt;/h2&gt;

&lt;p&gt;珲春，一眼望三国，朝鲜+俄罗斯，珲春距离海参崴（曾经地理课本里经常出现的地方）很近了，可以直接从珲春出关进入俄罗斯，听说可以在俄罗斯打靶玩，目前还是免签的，很容易就可以到对面去看看了，不过除此以外珲春好像就没啥了&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;东北衰败，挺可惜的，人都没了，还谈什么振兴呢。看到了这样的小城市，再对比深圳的灯火通明。而小城市里的闲适、慵懒，在深圳怎么也找不到。如果不是为了欲，不是为了追求，为了卷，在小城市里&lt;em&gt;work-life balance&lt;/em&gt;也许是不错的选择，不过那样的生活有点没意思，一眼就能望到头。&lt;/p&gt;

&lt;p&gt;一路看下来，整体消费还是比较低的，深圳满街的咖啡奶茶店，在这里就很少，唯一常见的就是蜜雪冰城。&lt;/p&gt;

&lt;p&gt;快要接近8.20了，小小延吉，一个联名咖啡瞬间就没了，hhhh&lt;/p&gt;

&lt;p&gt;回到深圳以后，同比深圳12点还灯火通明，延吉8点就没啥人了，街边店铺都关了，人才是发展的动力啊&lt;/p&gt;
</description>
        <pubDate>Mon, 19 Aug 2024 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2024/08/19/Dongbei/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2024/08/19/Dongbei/</guid>
        
        <category>旅游</category>
        
        
      </item>
    
      <item>
        <title>在线画图工具</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;测评一下在线画图工具，看还有没有比Draw.io更好用的，能否有更好的替代品&lt;/p&gt;

&lt;h2 id=&quot;drawio&quot;&gt;Draw.io&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408062332210.png&quot; alt=&quot;image-20240806233222128&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://app.diagrams.net/&lt;/p&gt;

  &lt;p&gt;https://www.drawio.com/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;优点太多了&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;免费、开源&lt;/li&gt;
  &lt;li&gt;很多软件支持嵌入，比如VS code，obsidian等&lt;/li&gt;
  &lt;li&gt;支持本地部署&lt;/li&gt;
  &lt;li&gt;模板众多、素材丰富&lt;/li&gt;
  &lt;li&gt;导出格式多&lt;/li&gt;
  &lt;li&gt;存储方式可以关联多种网盘&lt;/li&gt;
  &lt;li&gt;支持在线，也支持客户端离线使用&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;问题&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;风格有点老，不够好看&lt;/li&gt;
  &lt;li&gt;图片大了还是有点卡&lt;/li&gt;
  &lt;li&gt;打开和加载速度还是有点慢&lt;/li&gt;
  &lt;li&gt;缺少文件历史，必须要配合其他软件一起用&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;本地部署&quot;&gt;本地部署&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 创建 Draw.io 数据存放目录&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; /docker/Drawio &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /docker/Drawio

&lt;span class=&quot;c&quot;&gt;# 使用 Docker-Cli 运行 Drawio 容器&lt;/span&gt;
docker run &lt;span class=&quot;nt&quot;&gt;-dit&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;drawio &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 8080:8080 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; drawiojs:/usr/local/tomcat/webapps/draw/js/ &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;always jgraph/drawio
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;访问路径，测试&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http://服务器IP地址:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;确认没问题，再套上caddy，自动SSL就行了&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;draw.xxxx.com {
    reverse_proxy 127.0.0.1:8080
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://app.diagrams.net/?lang=es
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;改进入语言需要加一个后缀，否则改不掉&lt;/p&gt;

&lt;h3 id=&quot;配置修改&quot;&gt;配置修改&lt;/h3&gt;

&lt;p&gt;如果要修改服务器默认配置可以通过修改&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Preconfig.js&lt;/code&gt;文件实现&lt;/p&gt;

&lt;p&gt;先把原配置复制出来&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker cp drawio:/usr/local/tomcat/webapps/draw/js/PreConfig.js ./
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408091939607.png&quot; alt=&quot;image-20240809193901354&quot; /&gt;&lt;/p&gt;

&lt;p&gt;添加默认中文&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;urlParams[&apos;lang&apos;] = &apos;zh&apos;; //设置默认中文
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;同样的如果想修改默认配置，也可以通过添加属性来实现&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;window.DRAWIO_CONFIG = {&quot;language&quot;:&quot;zh&quot;,&quot;configVersion&quot;:null,&quot;customFonts&quot;:[],&quot;libraries&quot;:&quot;general;uml;er;bpmn;flowchart;basic;arrows2&quot;,&quot;customLibraries&quot;:[&quot;L.scratchpad&quot;],&quot;plugins&quot;:[],&quot;recentColors&quot;:[],&quot;formatWidth&quot;:240,&quot;createTarget&quot;:false,&quot;pageFormat&quot;:{&quot;x&quot;:0,&quot;y&quot;:0,&quot;width&quot;:827,&quot;height&quot;:1169},&quot;search&quot;:true,&quot;showStartScreen&quot;:false,&quot;gridColor&quot;:&quot;#d0d0d0&quot;,&quot;darkGridColor&quot;:&quot;#424242&quot;,&quot;autosave&quot;:false,&quot;resizeImages&quot;:null,&quot;openCounter&quot;:4,&quot;version&quot;:18,&quot;unit&quot;:1,&quot;isRulerOn&quot;:false,&quot;ui&quot;:&quot;&quot;,&quot;darkMode&quot;:false,&quot;pages&quot;:true,&quot;defaultGridEnabled&quot;:false,&quot;defaultPageVisible&quot;:false};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;如果需要修改默认导出的url，可以修改BASE_URL&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;window.DRAWIO_BASE_URL = &apos;https://xx.com&apos;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;反向复制回去&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker cp ./PreConfig.js drawio:/usr/local/tomcat/webapps/draw/js/PreConfig.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;客户端修改&quot;&gt;客户端修改&lt;/h3&gt;

&lt;p&gt;默认配置可以随便修改，这种只会修改个人的配置，根据浏览器缓存绑定，并不会修改服务端&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.drawio.com/doc/faq/configure-diagram-editor&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;language&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;zh&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;configVersion&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;customFonts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;libraries&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;general;uml;er;bpmn;flowchart;basic;arrows2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;customLibraries&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;L.scratchpad&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;plugins&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;recentColors&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;formatWidth&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;createTarget&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;pageFormat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;827&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1169&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;search&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;showStartScreen&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;gridColor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#d0d0d0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;darkGridColor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#424242&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;autosave&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;resizeImages&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;openCounter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;unit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;isRulerOn&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ui&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;darkMode&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;pages&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;defaultGridEnabled&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;defaultPageVisible&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;比如上面的就是默认中文，关闭默认的网格显示，关闭页面视图，这样看起来就无限大了&lt;/p&gt;

&lt;h3 id=&quot;私有化存储&quot;&gt;私有化存储&lt;/h3&gt;

&lt;p&gt;Draw.io有一些私有化存储的方案&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;dropbox&lt;/li&gt;
  &lt;li&gt;github&lt;/li&gt;
  &lt;li&gt;trello&lt;/li&gt;
  &lt;li&gt;google drive&lt;/li&gt;
  &lt;li&gt;one drive&lt;/li&gt;
  &lt;li&gt;gitlab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;不过这种都是个人存储，团队私有化的话，比较适合使用gitlab作为存储库，还有一种MinIO作为存储端，这种是DIY的方案&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/mathcoder23/drawio-minio-oss?tab=readme-ov-file&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;gitlab联动&quot;&gt;Gitlab联动&lt;/h4&gt;

&lt;p&gt;与Gitlab联动还挺麻烦的，首先需要Gitlab注册一个应用程序&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409112028247.png&quot; alt=&quot;image-20240911202801102&quot; /&gt;&lt;/p&gt;

&lt;p&gt;注意，这里的程序id和secret需要复制下来，后续使用，此处需要给出对应的3个API接口访问权限才行，回调地址中需要填写你的drawio的地址并且加上&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/gitlab&lt;/code&gt;的回调路径才行&lt;/p&gt;

&lt;p&gt;用前面方式创建的drawio的docker，如果只通过ProConfig，是无法适配的，总是会出现报错或者CSP问题，所以最好重新配置启动docker&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;drawio2   &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 8080:8080   &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;DRAWIO_BASE_URL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;https://你的drawio &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;DRAWIO_GITLAB_ID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;你的appid   &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;DRAWIO_GITLAB_SECRET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;你的secret   &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;DRAWIO_GITLAB_URL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;https://你的gitlab   &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;DRAWIO_CSP_HEADER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; script-src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; https://code.jquery.com &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;unsafe-inline&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; connect-src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; https://你的gitlab; img-src * data:; media-src * data:; font-src * about:; style-src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;unsafe-inline&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; https://fonts.googleapis.com; frame-src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; https://你的gitlab;&quot;&lt;/span&gt;   jgraph/drawio
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;修改&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PreConfig.js&lt;/code&gt;，开启Gitlab&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	    &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;; script-src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; https://code.jquery.com &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;unsafe-inline&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;; connect-src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; https://你的gitlab; img-src * data:; media-src * data:; font-src * about:; style-src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;unsafe-inline&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; https://fonts.googleapis.com; frame-src &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; https://你的gitlab;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	    &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;http-equiv&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Content-Security-Policy&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 	    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insertBefore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ignore&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})();&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRAWIO_BASE_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://你的drawio&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRAWIO_SERVER_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRAWIO_BASE_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRAWIO_VIEWER_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRAWIO_LIGHTBOX_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRAW_MATH_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;math/es5&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRAWIO_CONFIG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;zh&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;configVersion&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;customFonts&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;libraries&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;general;uml;er;bpmn;flowchart;basic;arrows2&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;customLibraries&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;L.scratchpad&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;recentColors&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[],&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;formatWidth&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;createTarget&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;pageFormat&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;827&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1169&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;showStartScreen&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;gridColor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#d0d0d0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;darkGridColor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#424242&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;autosave&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;resizeImages&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;openCounter&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;isRulerOn&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ui&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;darkMode&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;defaultGridEnabled&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;defaultPageVisible&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;urlParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;manual&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Disable Real-Time&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;urlParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//dropbox&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;urlParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;gh&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//github&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;urlParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//trello&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;urlParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;gapi&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Google Drive&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;urlParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;od&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//OneDrive&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRAWIO_GITLAB_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://你的gitlab&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRAWIO_GITLAB_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;你的appid&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;nx&quot;&gt;urlParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;zh&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//设置默认中文&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;注意此处需要去掉&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;urlParams[&apos;gl&apos;]&lt;/code&gt; 如果有&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;window.DRAWIO_CSP_HEADER&lt;/code&gt;属性也要去掉&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;理论上此时就已经可以访问了，启动时会提示GiLab&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121005059.png&quot; alt=&quot;image-20240912100512016&quot; /&gt;&lt;/p&gt;

&lt;p&gt;创建绘图以后会出现授权跳转&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121002974.png&quot; alt=&quot;image-20240912100257933&quot; /&gt;&lt;/p&gt;

&lt;p&gt;然后就可以直接存储到代码仓库中了，并且地址每次保存其实就是一个commit更新&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121115329.png&quot; alt=&quot;image-20240912111500231&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;常见问题&quot;&gt;常见问题&lt;/h4&gt;

&lt;p&gt;如果出现400错误&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121018093.png&quot; alt=&quot;image-20240912101643125&quot; /&gt;&lt;/p&gt;

&lt;p&gt;细看这个跳转链接，和issue中报错的其实是一样的&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://draw.你的.com/gitlab?code=e0303bc6cc574f0aba111db163e8831288026e28264ec334f093d22123c4430b&amp;amp;state=cId%3D你的id%26domain%3Ddraw.你的.com%26token%3D16rlbhnmkrmi3nnfnitokrltab7u0mcgd494phdgd5ba38ghhr4i
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;这里看起来更像是链接转义时有问题，正确的应该是类似下面的，但是这里有一个&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt; state=cID=&lt;/code&gt;这里很奇怪，感觉是漏了一个&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://draw.你的.com/gitlab?code=e0303bc6cc574f0aba111db163e8831288026e28264ec334f093d22123c4430b&amp;amp;state=cId=你的id&amp;amp;domain=draw.你的.com&amp;amp;token=16rlbhnmkrmi3nnfnitokrltab7u0mcgd494phdgd5ba38ghhr4i
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;出现这个问题是因为只在PreConfig中设置了GitLab相关内容，但是实际程序跑起来不知道为什么没有应用这里的配置，导致实际不生效，所以要通过docker的环境变量去配置&lt;/p&gt;

&lt;p&gt;还有一种方式，在docker启动时直接指定参数&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run -d --name=drawio2   -p 8016:8080   -e DRAWIO_BASE_URL=https://draw.你的.com:8016   -e DRAWIO_GITLAB_ID=你的id   -e DRAWIO_GITLAB_SECRET=你的secret -e DRAWIO_GITLAB_URL=https://gitlab.你的.com   -e DRAWIO_CSP_HEADER=&quot;default-src \&apos;self\&apos;; script-src \&apos;self\&apos; \&apos;unsafe-inline\&apos;; connect-src \&apos;self\&apos; https://gitlab.你的.com; img-src * data:; media-src * data:; font-src * about:; style-src \&apos;self\&apos; \&apos;unsafe-inline\&apos;;&quot;   jgraph/drawio
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在授权时会遇到没有权限访问的情况了，这个是CSP有问题&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202409121018668.png&quot; alt=&quot;image-20240912100225961&quot; /&gt;&lt;/p&gt;

&lt;p&gt;简单说就是跨域还是有问题，好几个issue基本都是类似的问题&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Refused to connect to &apos;https://gitlab.你的.com/api/v4/user&apos; because it violates the following Content Security Policy directive: &quot;connect-src &apos;self&apos; https://*.dropboxapi.com https://api.trello.com https://api.github.com https://raw.githubusercontent.com https://*.googleapis.com https://*.googleusercontent.com https://graph.microsoft.com https://*.1drv.com https://*.sharepoint.com https://gitlab.com https://*.google.com https://fonts.gstatic.com https://fonts.googleapis.com&quot;.
mxXmlRequest.send	@	app.min.js:211
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;上面是一个博主写的CSP替换头，这个头其实不正确，就会导致一直报CSP问题，替换成下面的头即可&lt;/p&gt;

&lt;div class=&quot;language-dockerfile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DRAWIO_CSP_HEADER=default-src \&apos;self\&apos;; script-src \&apos;self\&apos; https://code.jquery.com \&apos;unsafe-inline\&apos;; connect-src \&apos;self\&apos; http://MY_SERVER_URL; img-src * data:; media-src * data:; font-src * about:; style-src \&apos;self\&apos; \&apos;unsafe-inline\&apos; https://fonts.googleapis.com; frame-src \&apos;self\&apos; http://MY_SERVER_URL;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;还有一种情况是你的PreConfig有问题，注意上面的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s.setAttribute&lt;/code&gt;这个属性里会有你的gitlab地址，很多人用了错误的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;content&lt;/code&gt;导致只要PreConfig应用了就会出错的情况&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(function() {
  try {
	    var s = document.createElement(&apos;meta&apos;);
	    s.setAttribute(&apos;content&apos;, &apos;src \&apos;self\&apos;; script-src \&apos;self\&apos; https://code.jquery.com \&apos;unsafe-inline\&apos;; connect-src \&apos;self\&apos; https://你的gitlab; img-src * data:; media-src * data:; font-src * about:; style-src \&apos;self\&apos; \&apos;unsafe-inline\&apos; https://fonts.googleapis.com; frame-src \&apos;self\&apos; https://你的gitlab;&apos;);
	    s.setAttribute(&apos;http-equiv&apos;, &apos;Content-Security-Policy&apos;);
 	    var t = document.getElementsByTagName(&apos;meta&apos;)[0];
      t.parentNode.insertBefore(s, t);
  } catch (e) {} // ignore
})();
window.DRAWIO_BASE_URL = &apos;https://你的drawio&apos;;
window.DRAWIO_SERVER_URL = window.DRAWIO_BASE_URL + &apos;/&apos;;
window.DRAWIO_VIEWER_URL = &apos;&apos;;
window.DRAWIO_LIGHTBOX_URL = &apos;&apos;;
window.DRAW_MATH_URL = &apos;math/es5&apos;;
window.DRAWIO_CONFIG = null;
urlParams[&apos;sync&apos;] = &apos;manual&apos;; //Disable Real-Time
urlParams[&apos;db&apos;] = &apos;0&apos;; //dropbox
urlParams[&apos;gh&apos;] = &apos;0&apos;; //github
urlParams[&apos;tr&apos;] = &apos;0&apos;; //trello
urlParams[&apos;gapi&apos;] = &apos;0&apos;; //Google Drive
urlParams[&apos;od&apos;] = &apos;0&apos;; //OneDrive
window.DRAWIO_GITLAB_URL = &apos;https://你的gitlab&apos;; 
window.DRAWIO_GITLAB_ID = &apos;你的appid&apos;; 

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;国内&quot;&gt;国内&lt;/h2&gt;

&lt;p&gt;国内的基本没有免费，除了钱还是钱&lt;/p&gt;

&lt;h3 id=&quot;pddon&quot;&gt;PDDON&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408062326202.png&quot; alt=&quot;image-20240806232659144&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://pddon.com/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;国产画图工具，但是加载速度是真的慢，基本不具有可用性&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;访问困难&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;mindmaster&quot;&gt;MindMaster&lt;/h3&gt;

&lt;p&gt;亿图图示，国内的在线制图，除了广告，就是弹窗，收费、收费、VIP，单用户1080的天价，打扰了&lt;/p&gt;

&lt;p&gt;水平拉连接点会出现bug&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408062223543.png&quot; alt=&quot;image-20240806222308467&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;processon&quot;&gt;ProcessOn&lt;/h3&gt;

&lt;p&gt;国内的在线制图，问题和MindMaster基本一样，除了广告就是弹窗VIP，免费版本只能在线创建9个图&lt;/p&gt;

&lt;p&gt;技术上比MindMaster好一点，界面也清爽一些，剩下的差不多，价格也便宜一些，不过我期望的是免费，这里就不提了。&lt;/p&gt;

&lt;h2 id=&quot;国外&quot;&gt;国外&lt;/h2&gt;

&lt;p&gt;国外的在线画图，都有一个统一的问题，国内访问困难&lt;/p&gt;

&lt;h3 id=&quot;excalidraw&quot;&gt;Excalidraw&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408062236524.png&quot; alt=&quot;image-20240806223602427&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://excalidraw.com/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Excalidraw 准确说不像是个画图工具，更像画板工具，自由度很高，可以随便画&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;支持多人合作&lt;/li&gt;
  &lt;li&gt;支持自定义素材&lt;/li&gt;
  &lt;li&gt;免费限制很小&lt;/li&gt;
  &lt;li&gt;开源&lt;/li&gt;
  &lt;li&gt;界面好看&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;问题也比较明显，素材库每个人都不一样，没法对齐每个人的，免费功能还是有限&lt;/p&gt;

&lt;p&gt;素材种手绘的样式比较多，很可爱，如果要正式场景下就有点难顶，素材库每次导入就是导入所有，而不能部分，有些别扭&lt;/p&gt;

&lt;p&gt;私有化部署+修改存储方案&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/alswl/excalidraw-collaboration&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;plant-uml&quot;&gt;Plant UML&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://plantuml.com/zh/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;用代码画图，有一套完整的语法，早期我自己也用，后来发现想让别人理解太难了，可惜，画图而已，不想浪费生命，还是拖拽更好一些&lt;/p&gt;

&lt;h3 id=&quot;visio&quot;&gt;Visio&lt;/h3&gt;

&lt;p&gt;老牌工具，没啥大问题，但是安装麻烦，体积太大，跟不上时代了&lt;/p&gt;

&lt;h3 id=&quot;onemodel&quot;&gt;OneModel&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408062313304.png&quot; alt=&quot;image-20240806231322248&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.onemodel.app/diagrams/my-diagrams&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;国外的制图网址，免费版限制很少，可以无限量画，只对工作空间人数有限制&lt;/p&gt;

&lt;p&gt;图样的参数相对比较少，可用素材也比较少，素材风格相对比较统一&lt;/p&gt;

&lt;h3 id=&quot;tldraw&quot;&gt;Tldraw&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408062317841.png&quot; alt=&quot;image-20240806231733749&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.tldraw.com/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;开源、免费的白板，支持多人共享，类似Excalidraw，但是没有素材库，也完全没有收费的版本&lt;/p&gt;

&lt;h3 id=&quot;figma&quot;&gt;Figma&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408062309368.png&quot; alt=&quot;image-20240806230940263&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.figma.com/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Figma更像UI规范的工具，画图也可以，整体简洁清爽，不过还是一样收费才能无限图，否则只能1个图文件&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;能打的画图工具太少了，wolai中也不支持draw.io嵌入，但是wolai已经有意向在之后加入draw.io了&lt;/p&gt;

&lt;h2 id=&quot;quote&quot;&gt;Quote&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://blog.alswl.com/2022/10/self-hosted-excalidraw/&lt;/p&gt;

  &lt;p&gt;https://www.cnblogs.com/wuhanjiayou/p/18145848/Drawio&lt;/p&gt;

  &lt;p&gt;https://www.erballoon.vip/2024/01/14/dockerbszxhtdrawio/&lt;/p&gt;

  &lt;p&gt;https://musicfe.com/drawio/&lt;/p&gt;

  &lt;p&gt;https://www.xubiaosunny.top/post/self-hosted_drawio_and_add_pravate_gitlab_storage_yfzk.html&lt;/p&gt;

  &lt;p&gt;https://github.com/jgraph/docker-drawio/tree/dev/self-contained#gitlab&lt;/p&gt;

  &lt;p&gt;https://blog.csdn.net/qq_28800347/article/details/136523271&lt;/p&gt;

  &lt;p&gt;https://github.com/jgraph/docker-drawio/discussions/30&lt;/p&gt;
&lt;/blockquote&gt;

</description>
        <pubDate>Tue, 06 Aug 2024 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2024/08/06/Draw.io/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2024/08/06/Draw.io/</guid>
        
        <category>Software</category>
        
        
      </item>
    
      <item>
        <title>Trilium体验</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;去年选择了wolai作为团队知识管理工具，之前已经使用过了obsidian，但是对非程序员不够好用，其次没有完善的权限管理，做共享比较麻烦，给出去就是源码，无法做后续管控，wolai基本都能解决这些问题。&lt;/p&gt;

&lt;p&gt;但是也有一些不够好的点，性能上对比Typora或者一般的编辑软件确实弱了一些，文档书写为了普适性，更适合一般人用，而没有更专业的模式，或者说更适合程序员使用的模式，这点不够好。&lt;/p&gt;

&lt;p&gt;其次wolai价格不便宜，偶尔还是有一些小bug&lt;/p&gt;

&lt;p&gt;Trilium的效果有点出乎意料&lt;/p&gt;

&lt;h2 id=&quot;trilium&quot;&gt;Trilium&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052209625.png&quot; alt=&quot;image-20240805220947547&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/zadam/trilium&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;无意间发现了Trilium，这不就是一个obsidian+git+vps+图床+drawio的一个应用嘛，是不是可以取代wolai&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052210548.png&quot; alt=&quot;image-20240805221040465&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052211031.png&quot; alt=&quot;image-20240805221103952&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;特点&quot;&gt;特点&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;树状结构文件，支持任意嵌套和引用（克隆）&lt;/li&gt;
  &lt;li&gt;markdown格式，图 ，表，公式&lt;/li&gt;
  &lt;li&gt;code支持高亮&lt;/li&gt;
  &lt;li&gt;版本控制&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;可视化文档链接关系&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;支持各种图制作和嵌入，画板&lt;/li&gt;
  &lt;li&gt;在线制图工具嵌入，drawio&lt;/li&gt;
  &lt;li&gt;嵌入脚本&lt;/li&gt;
  &lt;li&gt;公开分享&lt;/li&gt;
  &lt;li&gt;支持导入和导出，支持剪藏&lt;/li&gt;
  &lt;li&gt;数据备份&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;试用&quot;&gt;试用&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052209145.png&quot; alt=&quot;image-20240805220923061&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/zadam/trilium/releases/tag/v0.63.7&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;建议先从windows开始，比较简单，解压就能用了&lt;/p&gt;

&lt;h4 id=&quot;语言包&quot;&gt;语言包&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/Nriver/trilium-translation/releases&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;默认Trilium是英文的，而且没有其他语系可以切换&lt;/p&gt;

&lt;p&gt;如果已经打开过原版，需要删除缓存才能切换到中文版&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;你运行过原版的Trilium程序，系统里有英文版的缓存，请关闭trilium， Windows系统删除这个目录&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Users\用户名\AppData\Roaming\Trilium Notes&lt;/code&gt;, Linux系统删除这个目录&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.config/Trilium Notes/&lt;/code&gt; 。再启动Trilium就是中文的了。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;trilium-data，最好也一并删除了，这样可以快速初始化中文数据库&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052222107.png&quot; alt=&quot;image-20240805222234053&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052224795.png&quot; alt=&quot;image-20240805222435755&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这个前置块按钮和wolai好像&lt;/p&gt;

&lt;p&gt;不过这个markdown好像不标准，没有一级标题，只有二级到六级，wolai是没有五六级，咋就是不完美呢&lt;/p&gt;

&lt;h4 id=&quot;主题&quot;&gt;主题&lt;/h4&gt;

&lt;p&gt;仔细用了一下trilium这个默认主题也太难看了&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052233380.png&quot; alt=&quot;image-20240805223356287&quot; /&gt;&lt;/p&gt;

&lt;p&gt;特别是把原本的文章转过来，默认的这个markdown渲染，这都什么玩意&lt;/p&gt;

&lt;p&gt;修改主题，使用SinkeyTheme，总算是舒服一点了&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/sinkey100/trilium-theme/blob/main/README_CN.md&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052238260.png&quot; alt=&quot;image-20240805223848171&quot; /&gt;&lt;/p&gt;

&lt;p&gt;难受的点就是目录里的这个123456是什么鬼啊，很不想要&lt;/p&gt;

&lt;h4 id=&quot;转换blog&quot;&gt;转换blog&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.ankia.top/3LdIi2f30Pan&lt;/p&gt;

  &lt;p&gt;https://github.com/dvai/Ankia-Theme&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;使用Ankia的博客主题，直接开启分享就可以看到效果了&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052247723.png&quot; alt=&quot;image-20240805224742680&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052246309.png&quot; alt=&quot;image-20240805224646201&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这渲染出来的效果还不错哎&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052248243.png&quot; alt=&quot;image-20240805224826120&quot; /&gt;&lt;/p&gt;

&lt;p&gt;已有文章拖进去，立马就能看到了&lt;/p&gt;

&lt;h4 id=&quot;集成drawio&quot;&gt;集成draw.io&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.shmaur.com/drawioInstall.html&lt;/p&gt;

  &lt;p&gt;https://github.com/SiriusXT/trilium-drawio&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408052303342.gif&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;p&gt;这简直跟VS Code一样了，直接集成各种JS应用&lt;/p&gt;

&lt;h4 id=&quot;更多探索&quot;&gt;更多探索&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/Nriver/awesome-trilium&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这里有更多主题、插件等等介绍&lt;/p&gt;

&lt;h3 id=&quot;问题&quot;&gt;问题&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;不支持多人协作&lt;/li&gt;
  &lt;li&gt;多端同步也比较困难&lt;/li&gt;
  &lt;li&gt;分享无法带权限管理，只有密码或者公开&lt;/li&gt;
  &lt;li&gt;历史功能有点难用，不知道是什么逻辑记录历史的&lt;/li&gt;
  &lt;li&gt;书写体验有点拉跨，远逊于Typora、Obsidian等&lt;/li&gt;
  &lt;li&gt;Markdown格式不标准，这个很奇怪&lt;/li&gt;
  &lt;li&gt;插件、主题各种资源相对比较少一些&lt;/li&gt;
  &lt;li&gt;图片不能直接右键复制&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;其他&quot;&gt;其他&lt;/h2&gt;

&lt;p&gt;dokuwiki，作为wiki好像也打不过Trilium&lt;/p&gt;

&lt;p&gt;Joplin，缺少树型结构，文档编辑类似论坛发文章的东西，没有什么亮点&lt;/p&gt;

&lt;p&gt;tiddlywiki，无markdown，论坛式的，虽然支持双链、图片，但是交互逻辑过于老气了&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Trilium通过小小的DIY，已经超出预期了，有点心动的感觉，唯一的缺点在于编辑方式比Typora差太多了&lt;/p&gt;

&lt;h2 id=&quot;quote&quot;&gt;Quote&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://sspai.com/post/85515&lt;/p&gt;

  &lt;p&gt;https://post.smzdm.com/p/avp2w9m4/&lt;/p&gt;

  &lt;p&gt;https://www.ankia.top/sfDk7s6iFuno&lt;/p&gt;

  &lt;p&gt;https://post.smzdm.com/p/ao95lw4n/&lt;/p&gt;

  &lt;p&gt;https://www.ankia.top/&lt;/p&gt;
&lt;/blockquote&gt;

</description>
        <pubDate>Mon, 05 Aug 2024 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2024/08/05/Trilium/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2024/08/05/Trilium/</guid>
        
        <category>Trilium</category>
        
        
      </item>
    
      <item>
        <title>VS Code插件入门二</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;第二步，通过API实现一点点小功能&lt;/p&gt;

&lt;h2 id=&quot;vs-code插件入门&quot;&gt;VS Code插件入门&lt;/h2&gt;

&lt;p&gt;VS Code的API目录，可以先按照大类查找，然后再找下面具体的接口&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://code.visualstudio.com/api/references/vscode-api&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;VS Code的API例子在下面的地址中，相关的接口可以直接看一下例子里是怎么用的，效果怎样&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://github.com/microsoft/vscode-extension-samples&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;具体使用进入到对应的例子目录下，然后安装包，就可以启动了&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;npm install
F5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;获取文件路径&quot;&gt;获取文件路径&lt;/h3&gt;

&lt;p&gt;首先是通过插件获取到当前打开文件路径在哪里&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeTextEditor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407312204783.png&quot; alt=&quot;image-20240731220418647&quot; /&gt;&lt;/p&gt;

&lt;p&gt;试了一下，切换文件，显示没有问题，如果没有打开路径倒是会报错，需要异常处理一下&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeTextEditor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;cant find active text editor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeTextEditor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;还有一种路径，可能是需要当前打开的工程路径，可以通过下面这种方式获取&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;workspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;workspaceFolders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fsPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;创建一个新的显示区域&quot;&gt;创建一个新的显示区域&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407312242893.png&quot; alt=&quot;workbench-contribution&quot; /&gt;&lt;/p&gt;

&lt;p&gt;在创建新的显示区域之前，先要知道一下VS Code本身有哪些区域可以用来自定义&lt;/p&gt;

&lt;p&gt;最左侧的是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tree View Container&lt;/code&gt;，这个就比较像快捷菜单&lt;/p&gt;

&lt;p&gt;接着就是左侧的树型大纲视图，这里一般以大纲或者目录的形式显示一些辅助信息&lt;/p&gt;

&lt;p&gt;最底下的就是状态栏，可以添加一些当前工程或者插件的状态信息，比如进度条等&lt;/p&gt;

&lt;p&gt;最右侧较大范围的就是Webview&lt;/p&gt;

&lt;p&gt;Webview，页面视图，简单理解就是HTML中的一个&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iframe&lt;/code&gt;，可以嵌入一个页面进来，但是这个嵌入的页面是个相对安全的沙河，只有从外部控制Webview的内容，而Webview反向控制就比较困难。&lt;/p&gt;

&lt;p&gt;所以一般可以通过Webview调用markdown、gpt、copilot等等第三方的交换界面&lt;/p&gt;

&lt;p&gt;Webview在VS Code中，可以反向hook editor event，比如撤销、重做、保存，这样就让你在VS Code中实现一个某种编辑器成为可能。&lt;/p&gt;

&lt;p&gt;Webview一般有三种用法：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Webview Panels，一般的显示渲染结果的窗口&lt;/li&gt;
  &lt;li&gt;custom editor，一个自定义的编辑器&lt;/li&gt;
  &lt;li&gt;Webview views，大纲视图的二次开发&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这里参考&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vscode-extension-samples\webview-sample&lt;/code&gt;的例子，看他是如何让小猫在webview中写代码的&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408010009071.png&quot; alt=&quot;image-20240801000910003&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export function activate(context: vscode.ExtensionContext) {
	context.subscriptions.push(
		vscode.commands.registerCommand(&apos;catCoding.start&apos;, () =&amp;gt; {
			CatCodingPanel.createOrShow(context.extensionUri);
		})
	);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;注册命令主要就是调用了这个CatCodingPanel的实例化&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407312358060.png&quot; alt=&quot;image-20240731235837019&quot; /&gt;&lt;/p&gt;

&lt;p&gt;先缩起来看一下，CatCodingPanel这个类主要的几个方法，很明显的是CatCodingPanel使用的是vs的内部pannel对象&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vscode.WebviewPanel&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;		&lt;span class=&quot;c1&quot;&gt;// Otherwise, create a new panel.&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;panel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createWebviewPanel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;CatCodingPanel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;viewType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Cat Coding&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;column&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ViewColumn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;One&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;getWebviewOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extensionUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;停在接口上，就能很清晰看到4个参数的作用&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;function window.createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | {
    readonly viewColumn: vscode.ViewColumn;
    readonly preserveFocus?: boolean;
}, options?: vscode.WebviewPanelOptions &amp;amp; vscode.WebviewOptions): vscode.WebviewPanel
Create and show a new webview panel.

@param viewType — Identifies the type of the webview panel.

@param title — Title of the panel.

@param showOptions — Where to show the webview in the editor. If preserveFocus is set, the new webview will not take focus.

@param options — Settings for the new panel.

@return — New webview panel.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;发现这个函数好像根本没有说具体内容是怎么显示出来的&lt;/p&gt;

&lt;p&gt;那就看一下构造函数的内容&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	&lt;span class=&quot;kr&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;panel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;WebviewPanel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;extensionUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_panel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;panel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_extensionUri&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;extensionUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Set the webview&apos;s initial html content&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Listen for when the panel is disposed&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// This happens when the user closes the panel or when the panel is closed programmatically&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_panel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;onDidDispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_disposables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Update the content based on view changes&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_panel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;onDidChangeViewState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_panel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;visible&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
				&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
			&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_disposables&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Handle messages from the webview&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_panel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;webview&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;onDidReceiveMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
						&lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;showErrorMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
						&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
			&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_disposables&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可以看到显示内容是靠update初始化的，最终调用到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_getHtmlForWebview&lt;/code&gt;，这个里面基本上就是封装了一个HTML页面&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408010031149.png&quot; alt=&quot;image-20240801003101086&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onDidChangeViewState&lt;/code&gt;就可以认为是页面改动触发的刷新，比如分屏显示，缩小或者放大webview大小&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onDidReceiveMessage&lt;/code&gt;添加了一个事件回调，收到某些命令时进行弹窗显示&lt;/p&gt;

&lt;h4 id=&quot;webview的生命周期&quot;&gt;Webview的生命周期&lt;/h4&gt;

&lt;p&gt;Webview是有一个生命周期的，并且Webview的句柄是需要你自己保存的，否则这个东西就没人可以控制了。&lt;/p&gt;

&lt;p&gt;而Webview同样也需要正确释放，否则就会造成额外的错误&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;constructor&lt;/li&gt;
  &lt;li&gt;dispose&lt;/li&gt;
  &lt;li&gt;revive/reveal 从后台切到前台显示，获得焦点&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;debug&quot;&gt;Debug&lt;/h4&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Developer: Toggle Developer Tools&lt;/code&gt;可以看到这个webview的界面，就能清楚的看到这里其实嵌入式了iframe&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408012203571.png&quot; alt=&quot;image-20240801220306490&quot; /&gt;&lt;/p&gt;

&lt;p&gt;内部的网页就是cat coding&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202408012203284.png&quot; alt=&quot;image-20240801220330253&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;加载本地资源&quot;&gt;加载本地资源&lt;/h4&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getWebviewOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extensionUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;WebviewOptions&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// Enable javascript in the webview&lt;/span&gt;
		&lt;span class=&quot;na&quot;&gt;enableScripts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// And restrict the webview to only loading content from our extension&apos;s `media` directory.&lt;/span&gt;
		&lt;span class=&quot;na&quot;&gt;localResourceRoots&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;joinPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extensionUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;需要注意在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getWebviewOptions&lt;/code&gt;中的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localResourceRoots&lt;/code&gt;中会限制可以读取的资源路径，比如这里就限制必须是在插件路径的media文件夹内才可以&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
		&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scriptPathOnDisk1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;joinPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_extensionUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;giphy.gif&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;//const scriptPathOnDisk1 = vscode.Uri.joinPath(this._extensionUri, &apos;media&apos;, &apos;cat.gif&apos;);&lt;/span&gt;

		&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scriptUri1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;webview&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;asWebviewUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;scriptPathOnDisk1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;如果后续读取使用的是非media路径，webview会显示不了对应的gif&lt;/p&gt;

&lt;h4 id=&quot;通信&quot;&gt;通信&lt;/h4&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;	&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;subscriptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;catCoding.doRefactor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CatCodingPanel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentPanel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;nx&quot;&gt;CatCodingPanel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentPanel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doRefactor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;	
	&lt;span class=&quot;kr&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doRefactor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// Send a message to the webview webview.&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// You can send any JSON serializable data.&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_panel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;webview&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;refactor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;插件可以通过&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postMessage&lt;/code&gt;发送消息给实例化的webview，进而实现一些控制&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;c1&quot;&gt;// Handle messages sent from the extension to the webview&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The json data that the extension sent&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;refactor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;currentCount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ceil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentCount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textContent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;media/main.js&lt;/code&gt;中可以看到对应事件的响应代码&lt;/p&gt;

&lt;p&gt;反过来，webview也可以通过vs插件接口发送消息给插件&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nx&quot;&gt;setInterval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textContent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; `&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Update state&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Alert the extension when the cat introduces a bug&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.001&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Send a message back to the extension&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;postMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;na&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;🐛  on line &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentCount&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;media/main.js&lt;/code&gt;中可以看到webview加载的本地js直接调用了vs的api，进行post信息&lt;/p&gt;

&lt;h3 id=&quot;显示markdown&quot;&gt;显示markdown&lt;/h3&gt;

&lt;p&gt;非常简单直接使用内置的markdown命令实现显示当前激活文档的markdown渲染视图&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vscode.commands.executeCommand(&quot;markdown.showPreviewToSide&quot;, vscode.window.activeTextEditor.document.uri.path);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;不过这种方式只能显示一个markdown，而且具体markdown能显示啥，不能显示啥，或者说markdown的扩展，就不是我能控制的了&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;第二步ok&lt;/p&gt;

&lt;h2 id=&quot;quote&quot;&gt;Quote&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://liiked.github.io/VS-Code-Extension-Doc-ZH/#/&lt;/p&gt;

  &lt;p&gt;https://code.visualstudio.com/api&lt;/p&gt;

  &lt;p&gt;https://stackoverflow.com/questions/39569993/vs-code-extension-get-full-path&lt;/p&gt;

  &lt;p&gt;https://zhuanlan.zhihu.com/p/693769416&lt;/p&gt;

  &lt;p&gt;https://www.cnblogs.com/liuxianan/p/vscode-plugin-webview.html&lt;/p&gt;

  &lt;p&gt;https://code.visualstudio.com/api/extension-guides/webview&lt;/p&gt;
&lt;/blockquote&gt;

</description>
        <pubDate>Wed, 31 Jul 2024 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2024/07/31/VSCode-Plugin2/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2024/07/31/VSCode-Plugin2/</guid>
        
        <category>VS Code</category>
        
        
      </item>
    
      <item>
        <title>VS Code插件入门一</title>
        <description>&lt;h2 id=&quot;foreword&quot;&gt;Foreword&lt;/h2&gt;

&lt;p&gt;一直有一个插件或者工具的想法，只是有初步的一些点，但还不确定具体能做到什么程度，先拿VS Code的插件来实验一下是否可行&lt;/p&gt;

&lt;h2 id=&quot;vs-code插件入门&quot;&gt;VS Code插件入门&lt;/h2&gt;

&lt;p&gt;VS Code本身是基于Electron的，所以插件的开发基础自然也就是nodejs+js&lt;/p&gt;

&lt;p&gt;先搞懂VS Code的基础架构和插件接口，就可以考虑实现一个小demo看看效果&lt;/p&gt;

&lt;p&gt;基于插件入门的文档，预备阶段需要一些TS知识就先跳过，写的时候再学也可以&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://liiked.github.io/VS-Code-Extension-Doc-ZH/#/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;看了一下插件API可以实现的功能，以下两点大概是我目前最在意的&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;在UI中添加自定义组件和视图——&lt;a href=&quot;https://liiked.github.io/VS-Code-Extension-Doc-ZH/#/extension-capabilities/extending-workbench&quot;&gt;扩展工作台&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;创建Webview，使用HTML/CSS/JS显示自定义网页——&lt;a href=&quot;https://liiked.github.io/VS-Code-Extension-Doc-ZH/#/extension-guides/webview&quot;&gt;Webview指南&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;构建插件&quot;&gt;构建插件&lt;/h3&gt;

&lt;p&gt;来一次&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hello World&lt;/code&gt;准是没错的&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://code.visualstudio.com/api/get-started/your-first-extension&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;准备&quot;&gt;准备&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Node.js&lt;/li&gt;
  &lt;li&gt;Git&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;首先安装好代码生成&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;npm install --global yo generator-code
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;最好挂上代理，这个包有点难拉&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407302215810.png&quot; alt=&quot;image-20240730221515733&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;hello-world&quot;&gt;Hello World&lt;/h3&gt;

&lt;p&gt;调用脚手架生成代码&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yo code
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407302216890.png&quot; alt=&quot;image-20240730221621854&quot; /&gt;&lt;/p&gt;

&lt;p&gt;回答一系列问题以后，hellow就生成了，然后根据提示打开一个新的VS Code&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407302217771.png&quot; alt=&quot;image-20240730221718705&quot; /&gt;&lt;/p&gt;

&lt;p&gt;提示安装一下插件测试器，并且提示刚才构建的插件过于老了，没关系先玩玩看&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407302228315.png&quot; alt=&quot;image-20240730222854237&quot; /&gt;&lt;/p&gt;

&lt;p&gt;自动打开刚才新建的工程，但是此工程实际上可能跑不起来，需要先修改两个内容&lt;/p&gt;

&lt;p&gt;直接F5，启动调试，可以看到新起了一个VS Code，尝试看是否有&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hello World&lt;/code&gt;命令，测试应该是没有的&lt;/p&gt;

&lt;p&gt;此时查看测试VS Code的版本号，发现是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.90.2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407302230780.png&quot; alt=&quot;image-20240730223024752&quot; /&gt;&lt;/p&gt;

&lt;p&gt;核对一下package.json中的包代码，发现不一致&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;engines&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;vscode&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^1.90.2&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;@types/vscode&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^1.90.2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;将依赖的包版本修改为对应的VS版本后重启&lt;/p&gt;

&lt;p&gt;如果是热修改，VS Code也支持热重启，在调试启动的VS Code使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+R&lt;/code&gt;就会重新加载修改后的插件，立马就能验证插件了&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407302232805.png&quot; alt=&quot;image-20240730223204740&quot; /&gt;&lt;/p&gt;

&lt;p&gt;已经有&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hello World&lt;/code&gt;命令，并且消息提示正常&lt;/p&gt;

&lt;p&gt;主工程的VS Code中可以看到对应的log提示&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.elmagnifico.tech/static/upload/elmagnifico/202407302342736.png&quot; alt=&quot;image-20240730234212706&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;代码解析&quot;&gt;代码解析&lt;/h3&gt;

&lt;p&gt;工程结构，相对比较简单&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.
├── .vscode
│   ├── launch.json     // 插件加载和调试的配置
│   └── tasks.json      // 配置TypeScript编译任务
├── node_modules        // nodejs需要引用的各种模块
├── test                // 单元测试相关内容
├── .vscode-test.mjs    // 单元测试相关内容
├── .gitignore          
├── .vscodeignore       // vscode工程的忽略文件
├── .eslintrc.json      // 应该是es编译器相关配置
├── jsconfig.json       // js相关配置
├── .gitignore          
├── README.md
├── extension.ts        // 插件源代码
├── package.json        // 插件配置清单
├── tsconfig.json       // TypeScript配置
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;node_modules/@types/vscode/index.d.ts 中有所有的API接口&lt;/li&gt;
  &lt;li&gt;前面安装的插件&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vscode.extension-test-runner&lt;/code&gt;是为了配合工程中的test单元测试使用的&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;其他文件基本都是配置或者环境相关文件，主要实现还是在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extension.js&lt;/code&gt;中&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// The module &apos;vscode&apos; contains the VS Code extensibility API&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Import the module and reference it with the alias vscode in your code below&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// This method is called when your extension is activated&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Your extension is activated the very first time the command is executed&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**
 * @param {vscode.ExtensionContext} context
 */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;activate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// Use the console to output diagnostic information (console.log) and errors (console.error)&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// This line of code will only be executed once when your extension is activated&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Congratulations, your extension &quot;hellow&quot; is now active!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// The command has been defined in the package.json file&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Now provide the implementation of the command with  registerCommand&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// The commandId parameter must match the command field in package.json&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;disposable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;hellow.helloWorld&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// The code you place here will be executed every time your command is executed&lt;/span&gt;

		&lt;span class=&quot;c1&quot;&gt;// Display a message box to the user&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;vscode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;showInformationMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Hello World from hellow!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

	&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;subscriptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;disposable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// This method is called when your extension is deactivated&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;deactivate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;activate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;deactivate&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;插件注册流程也比较简单，就是激活和反激活，在这两个时间可以做一些注册命令或者安装或者清理环境之类的工作&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;activate
deactivate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;整个插件模块可以暴露的接口，也是可以自定义设计的&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;module.exports = {
	activate,
	deactivate
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;主要就是调用了两个接口，一个注册命令，一个显示消息&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vscode.commands.registerCommand
vscode.window.showInformationMessage
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;简单理解为向VS Code的上下文中注册了这个接口&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;context.subscriptions.push
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package.json&lt;/code&gt;需要重点说明一下，这里面描述了入口是谁，并且插件的版本和他对vscode的版本的要求，这里都是最低版本要求，同时插件的命令也在这里进行了说明&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hellow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;displayName&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hellow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0.0.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;engines&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;vscode&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^1.90.2&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;categories&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Other&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;activationEvents&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;./extension.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;contributes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;commands&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;command&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;hellow.helloWorld&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;lint&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;eslint .&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;pretest&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;npm run lint&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;vscode-test&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;@types/vscode&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^1.90.2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;@types/mocha&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^10.0.7&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;@types/node&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;20.x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;eslint&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^8.57.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;typescript&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^5.4.5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;@vscode/test-cli&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^0.0.9&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;@vscode/test-electron&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^2.4.0&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;第一步ok&lt;/p&gt;

&lt;h2 id=&quot;quote&quot;&gt;Quote&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://liiked.github.io/VS-Code-Extension-Doc-ZH/#/&lt;/p&gt;

  &lt;p&gt;https://code.visualstudio.com/api&lt;/p&gt;
&lt;/blockquote&gt;

</description>
        <pubDate>Tue, 30 Jul 2024 00:00:00 +0000</pubDate>
        <link>https://elmagnifico.tech/2024/07/30/VSCode-Plugin1/</link>
        <guid isPermaLink="true">https://elmagnifico.tech/2024/07/30/VSCode-Plugin1/</guid>
        
        <category>VS Code</category>
        
        
      </item>
    
  </channel>
</rss>
