完成 0.3.3 版本的开发打包

This commit is contained in:
锦恢 2024-04-22 01:20:50 +08:00
parent 03c4d1b715
commit a8ae1d6608
64 changed files with 2457 additions and 1584 deletions

View File

@ -1,7 +0,0 @@
module.exports = {
// ... 其他配置
ignorePatterns: ['**/*.d.ts'],
env: {
es6: true
}
};

0
deploy.bat Normal file
View File

View File

@ -1,6 +1,6 @@
<mxfile host="65bd71144e">
<diagram id="fareUikBvdjO0hJmng89" name="第 1 页">
<mxGraphModel dx="1355" dy="695" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
<diagram id="fareUikBvdjO0hJmng89" name="makeBitVertex 原理图">
<mxGraphModel dx="1529" dy="929" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
@ -566,203 +566,275 @@
<mxCell id="136" value="\[w&lt;br style=&quot;font-size: 18px;&quot;&gt;\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" parent="1" vertex="1">
<mxGeometry x="550" y="1460" width="50" height="60" as="geometry"/>
</mxCell>
<mxCell id="137" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1680" y="1000" as="sourcePoint"/>
<mxPoint x="1640" y="1158.82" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="138" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1640" y="1160" as="sourcePoint"/>
<mxPoint x="1680" y="1320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="139" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2040" y="1000" as="sourcePoint"/>
<mxPoint x="1680" y="1000" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="140" value="\[p_0=(x_0, y_0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" vertex="1" parent="1">
<mxGeometry x="1480" y="1120" width="160" height="30" as="geometry"/>
</mxCell>
<mxCell id="141" value="\[p_1=(x_1, y_1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" vertex="1" parent="1">
<mxGeometry x="2160" y="1130" width="160" height="30" as="geometry"/>
</mxCell>
<mxCell id="143" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2040" y="1320" as="sourcePoint"/>
<mxPoint x="1680" y="1320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="144" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2080" y="1160" as="sourcePoint"/>
<mxPoint x="2040" y="1318.8199999999997" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="145" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2040" y="1000" as="sourcePoint"/>
<mxPoint x="2080" y="1160" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="146" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2070" y="1360" as="sourcePoint"/>
<mxPoint x="1650" y="1360" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="147" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2120" y="1160" as="sourcePoint"/>
<mxPoint x="2070" y="1360" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="149" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1650" y="1360" as="sourcePoint"/>
<mxPoint x="1600" y="1160" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="150" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2120" y="1158.95" as="sourcePoint"/>
<mxPoint x="2040" y="1159" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="151" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1680" y="1160" as="sourcePoint"/>
<mxPoint x="1600" y="1160.05" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="152" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2000" y="1280" as="sourcePoint"/>
<mxPoint x="1720" y="1280" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="153" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1720" y="1280" as="sourcePoint"/>
<mxPoint x="1680" y="1158.95" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="154" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2040" y="1160" as="sourcePoint"/>
<mxPoint x="2000" y="1280" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="155" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1650" y="1360" as="sourcePoint"/>
<mxPoint x="1720" y="1280" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="156" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="2070" y="1360" as="sourcePoint"/>
<mxPoint x="2000" y="1275" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="157" value="\[(\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1670" y="1130" width="110" height="30" as="geometry"/>
</mxCell>
<mxCell id="158" value="\[(-\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1470" y="1175" width="120" height="30" as="geometry"/>
</mxCell>
<mxCell id="159" value="\[(\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1700" y="1240" width="110" height="30" as="geometry"/>
</mxCell>
<mxCell id="160" value="\[p_0=(x_0 + title, -1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" vertex="1" parent="1">
<mxGeometry x="1605" y="1370" width="190" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="ldzhMOmdS79g5s7hsVNb" name="第 2 页">
<mxGraphModel dx="1345" dy="451" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
<diagram id="ldzhMOmdS79g5s7hsVNb" name="makeVecVertex 原理图">
<mxGraphModel dx="-10" dy="250" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="0KlvA6460LBpeT4quUVe-1" value="\[p_0=(x_0,y_0)&lt;br&gt;\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
<mxGeometry x="120" y="500" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-2" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
<mxCell id="GijaLTcLDulYfw_Rey3C-1" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="120" y="520" as="sourcePoint"/>
<mxPoint x="160" y="400" as="targetPoint"/>
<mxPoint x="1160" y="600" as="sourcePoint"/>
<mxPoint x="1120" y="758.8199999999997" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-3" value="\[p_1=(x_1,y_1)&lt;br&gt;\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
<mxGeometry x="440" y="500" width="110" height="40" as="geometry"/>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-4" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
<mxGeometry x="100" y="810" width="20" height="20" as="geometry"/>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-5" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
<mxGeometry x="485" y="810" width="20" height="20" as="geometry"/>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-6" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
<mxGeometry x="100" y="690" width="20" height="20" as="geometry"/>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-7" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
<mxGeometry x="485" y="690" width="20" height="20" as="geometry"/>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-8" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
<mxCell id="GijaLTcLDulYfw_Rey3C-2" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="120" y="520" as="sourcePoint"/>
<mxPoint x="160" y="640" as="targetPoint"/>
<mxPoint x="1120" y="760" as="sourcePoint"/>
<mxPoint x="1160" y="920" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-9" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
<mxCell id="GijaLTcLDulYfw_Rey3C-3" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="160" y="400" as="sourcePoint"/>
<mxPoint x="400" y="400" as="targetPoint"/>
<mxPoint x="1520" y="600" as="sourcePoint"/>
<mxPoint x="1160" y="600" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-10" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
<mxCell id="GijaLTcLDulYfw_Rey3C-4" value="\[p_0=(x_0, y_0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
<mxGeometry x="970" y="715" width="160" height="30" as="geometry"/>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-5" value="\[p_1=(x_1, y_1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
<mxGeometry x="1540" y="715" width="160" height="30" as="geometry"/>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-6" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="160" y="640" as="sourcePoint"/>
<mxPoint x="400" y="640" as="targetPoint"/>
<mxPoint x="1520" y="920" as="sourcePoint"/>
<mxPoint x="1160" y="920" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0KlvA6460LBpeT4quUVe-11" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
<mxCell id="GijaLTcLDulYfw_Rey3C-7" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="400" y="400" as="sourcePoint"/>
<mxPoint x="440" y="520" as="targetPoint"/>
<mxPoint x="1560" y="760" as="sourcePoint"/>
<mxPoint x="1520" y="918.8199999999997" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="YzxP9u1fmLVgk9Jru_4W-1" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
<mxCell id="GijaLTcLDulYfw_Rey3C-8" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="-40" y="400" as="sourcePoint"/>
<mxPoint x="140" y="400" as="targetPoint"/>
<mxPoint x="1520" y="600" as="sourcePoint"/>
<mxPoint x="1560" y="760" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="YzxP9u1fmLVgk9Jru_4W-2" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
<mxCell id="GijaLTcLDulYfw_Rey3C-9" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="-40" y="640" as="sourcePoint"/>
<mxPoint x="120" y="639.9999999999999" as="targetPoint"/>
<mxPoint x="1550" y="960" as="sourcePoint"/>
<mxPoint x="1130" y="960" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="YzxP9u1fmLVgk9Jru_4W-3" value="" style="endArrow=classic;startArrow=classic;html=1;" edge="1" parent="1">
<mxCell id="GijaLTcLDulYfw_Rey3C-10" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="640" as="sourcePoint"/>
<mxPoint x="80" y="400" as="targetPoint"/>
<mxPoint x="1600" y="760" as="sourcePoint"/>
<mxPoint x="1550" y="960" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="YzxP9u1fmLVgk9Jru_4W-4" value="\[w&lt;br style=&quot;font-size: 18px;&quot;&gt;\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" vertex="1" parent="1">
<mxGeometry x="20" y="480" width="50" height="60" as="geometry"/>
</mxCell>
<mxCell id="YzxP9u1fmLVgk9Jru_4W-6" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
<mxCell id="GijaLTcLDulYfw_Rey3C-11" value="" style="endArrow=none;html=1;strokeColor=#3700CC;strokeWidth=2;fontColor=#F0B102;dashed=1;fillColor=#6a00ff;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="400" y="640.0000000000001" as="sourcePoint"/>
<mxPoint x="440" y="520" as="targetPoint"/>
<mxPoint x="1130" y="960" as="sourcePoint"/>
<mxPoint x="1080" y="760" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-12" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1600" y="758.9499999999998" as="sourcePoint"/>
<mxPoint x="1520" y="759" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-13" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1480" y="880" as="sourcePoint"/>
<mxPoint x="1200" y="880" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-14" value="" style="endArrow=none;html=1;strokeColor=#3700CC;strokeWidth=2;fontColor=#F0B102;dashed=1;fillColor=#6a00ff;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1200" y="880" as="sourcePoint"/>
<mxPoint x="1160" y="758.9499999999998" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-15" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1520" y="760" as="sourcePoint"/>
<mxPoint x="1480" y="880" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-16" value="" style="endArrow=none;html=1;strokeColor=#3700CC;strokeWidth=2;fontColor=#F0B102;dashed=1;fillColor=#6a00ff;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1130" y="960" as="sourcePoint"/>
<mxPoint x="1200" y="880" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-17" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1550" y="960" as="sourcePoint"/>
<mxPoint x="1480" y="875" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-18" value="\[(\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1145" y="745" width="110" height="30" as="geometry"/>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-19" value="\[(-\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="980" y="745" width="120" height="30" as="geometry"/>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-20" value="\[(\frac{w}{2},\frac{w}{2}&lt;br&gt;)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1160" y="840" width="150" height="40" as="geometry"/>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-21" value="\[a_0=(x_0 + bs, -1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
<mxGeometry x="1160" y="970" width="180" height="30" as="geometry"/>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-22" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1120" y="1019.3100000000004" as="sourcePoint"/>
<mxPoint x="1120" y="970" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-23" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1160" y="970" as="sourcePoint"/>
<mxPoint x="1160" y="1020" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-24" value="" style="endArrow=classic;startArrow=classic;html=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1120" y="989.3100000000004" as="sourcePoint"/>
<mxPoint x="1160" y="990" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="GijaLTcLDulYfw_Rey3C-25" value="\[bs&lt;br style=&quot;font-size: 18px;&quot;&gt;\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" parent="1" vertex="1">
<mxGeometry x="1120" y="980" width="50" height="60" as="geometry"/>
</mxCell>
<mxCell id="AR7EaJVa85OL3mO77pCV-26" value="" style="endArrow=none;html=1;strokeColor=#3700CC;strokeWidth=2;fontColor=#F0B102;dashed=1;fillColor=#6a00ff;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1160" y="759.9999999999998" as="sourcePoint"/>
<mxPoint x="1080" y="760.05" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-1" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="980" y="880.0000000000001" as="sourcePoint"/>
<mxPoint x="1060" y="880.0000000000001" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-2" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="980" y="960" as="sourcePoint"/>
<mxPoint x="1060" y="960" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-3" value="" style="endArrow=classic;startArrow=classic;html=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1020" y="960.58" as="sourcePoint"/>
<mxPoint x="1020" y="880" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-4" value="\[w&lt;br style=&quot;font-size: 18px;&quot;&gt;\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" parent="1" vertex="1">
<mxGeometry x="970" y="890" width="50" height="60" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-5" value="\[a_2=(x_0 + bs, 1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
<mxGeometry x="1145" y="570" width="180" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-6" value="\[a_3=(x_0 - bs, 1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
<mxGeometry x="1520" y="580" width="170" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-7" value="\[a_1=(x_1 - bs, -1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
<mxGeometry x="1450" y="970" width="180" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-8" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1550" y="560" as="sourcePoint"/>
<mxPoint x="1130" y="559.22" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-9" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1080" y="760" as="sourcePoint"/>
<mxPoint x="1130" y="560" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-10" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1160" y="760" as="sourcePoint"/>
<mxPoint x="1200" y="640" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-11" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1480" y="640" as="sourcePoint"/>
<mxPoint x="1200" y="640" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-12" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1550" y="560" as="sourcePoint"/>
<mxPoint x="1480" y="640" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-13" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1130" y="560" as="sourcePoint"/>
<mxPoint x="1200" y="640.0000000000001" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-14" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1520" y="760" as="sourcePoint"/>
<mxPoint x="1480" y="638.9499999999999" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-15" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1600" y="760" as="sourcePoint"/>
<mxPoint x="1550" y="560.0000000000001" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-16" value="\[b_0\]" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" parent="1" vertex="1">
<mxGeometry x="1120" y="820" width="40" height="40" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-18" value="\[(-\frac{w}{2},-\frac{w}{2}&lt;br&gt;)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1000" y="960" width="150" height="40" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-19" value="\[(\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1580" y="745" width="110" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-20" value="\[(-\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1420" y="745" width="120" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-21" value="\[(\frac{w}{2},\frac{w}{2}&lt;br&gt;)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1510" y="520" width="150" height="40" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-22" value="\[(-\frac{w}{2},-\frac{w}{2}&lt;br&gt;)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1360" y="640" width="150" height="40" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-23" value="\[(-\frac{w}{2},\frac{w}{2}&lt;br&gt;)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1370" y="840" width="150" height="40" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-24" value="\[(\frac{w}{2},-\frac{w}{2}&lt;br&gt;)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1520" y="940" width="150" height="40" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-25" value="\[(\frac{w}{2},-\frac{w}{2}&lt;br&gt;)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1160" y="640" width="150" height="40" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-26" value="\[(-\frac{w}{2},\frac{w}{2}&lt;br&gt;)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1040" y="520" width="150" height="40" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-27" value="6" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1225" y="745" width="30" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-28" value="7" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1250" y="810" width="30" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-29" value="1" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1400" y="810" width="30" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-30" value="2" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1420" y="745" width="30" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-31" value="3" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1400" y="680" width="30" height="30" as="geometry"/>
</mxCell>
<mxCell id="0AE3MlXHRA_X4uAlCJMS-32" value="5" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1250" y="680" width="30" height="30" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>

243
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,14 +10,14 @@
"dependencies": {
"core-js": "^3.8.3",
"element-plus": "^2.5.6",
"lodash.get": "^4.4.2",
"mitt": "^3.0.1",
"onml": "^2.1.0",
"stream": "^0.0.2",
"vue": "^3.2.13",
"vue-i18n": "^9.9.1",
"waveql": "^1.8.0",
"lodash.get": "^4.4.2",
"onml": "^2.1.0",
"w3c-keyname": "^2.2.8"
"w3c-keyname": "^2.2.8",
"waveql": "^1.8.0"
},
"devDependencies": {
"@babel/core": "^7.12.16",
@ -25,7 +25,6 @@
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"unplugin-auto-import": "^0.17.5",
"unplugin-vue-components": "^0.26.0"

42
public/icon.svg Normal file
View File

@ -0,0 +1,42 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
width="126px" height="126px" viewBox="-0.5 -0.5 126 126"
content="&lt;mxfile&gt;&lt;diagram id=&quot;E9SxX19eNgA6MUTyjjO6&quot; name=&quot;Icon-黑白&quot;&gt;7VnbktsoEP0aP0YlhG5+HF/GqVSS8pZrd2f3xcVIWGJXEiqEx3K+fsFCN8sXORnNuJL1g003TQN9DtDgEZzG+YKhNPxCfRyNDN3PR3A2MgzoOOJbKvaFwjDNQhEw4hcqUCtW5BtWSl1pt8THWcuQUxpxkraVHk0S7PGWDjFGd22zDY3avaYowB3FykNRV/sn8XmotMAe1xUfMQlC1bVrqAnHqDRWM8lC5NNdQwXnIzhllPKiFOdTHMnYlXHxJ7s5fqSf7OfpbvVp7cXpYv2hcPZ4S5NqCgwn/HVdw8L1C4q2Kl5qrnxfBnAXEo5XKfKkvBMcGcFJyONISEAUUZYWsG1IjkVXkw2JoimNKDs0h8YMGnAi9Bln9N8KA0ta0oQ3LDeHT2VZ1iQ0ET1PGN0mvuyg6JV5imrAFWLPAKlAvmDGcd6ghwrYAtMYc7YXJqrWtBX2JflLedegUsmPsMGiSokUfYPKdw2RKCiUbkDMfC/EYG/ERM104oLZwwXYLH1I2FyoOVYbuYaqAZ5jaFYXvVr76vDZ1+ETXsTmKDl/K5BtwIwutBUs5wELGPIJrmFWy2+4FeZobaSgVWmaq+wETGAokJx7B2koNCzrDtFw/0ejPn/eEo08X23Th+zzxPqbzBe7cGIbf/TZwAKx6adVXDrzrXI99Fy20G8J4fm9ZHzEXb17WlsnYgWHYu74eqxkdIjIVj+jZxwtaUY4oYmoeqac01jSrsw65YHpoyw8HKZSQBEJpKknYoZZm+el2wdlw2la+Eplv3EeyFxfw5FAgUk7LaIB8dYB4jhrlEUbmmKG1KBQMtySuUi23kumjLBiADA1B9quKW4jlmFDYHf4AOGJteNqVQvLccdD0QOA6/y4OZcTGdojikkkIzClMfGEvxVKMvHzZaUMVA7mdsAER2D6eIO2ER8CsOb+BU5gAIYKuvELB708RgzNAWNj7BqmZQNTh2b3THlTTJzuie6LW7wSKeMhDWiConmtbdws9DY8OCf8Sall+S9Zlsl/Ic7yRt1s3xCWmBExIbmXFrpETO6p9CqFwpVVirWrg1T6uoUOAB6a+w/yqaNOt4XmkcggHhye30e7e/FtnMnolnn4+hHGEQvwxZNZrSKJ20UKMhyJ4+Sl/TrzI4zS7309j2QiIj+nkKxqfsK1fvfH2zsh8wahPznCIR77XhuP3rnjiWtFP4juB48hnvJ+Bjzef+c6OVpriCSlLDcyi/M5SpmPVELRyriWkByk4+zmVqq8fpJylCt8P2F65xSHpmIWaN8wSClJeNbwvJSK+k4J7KNXGFuTbLR011H8bFLrenMw1mxzDAzD1R0dOJZpHVGzGOAZb6DHUKqpFemdcnFhjMfX5rEGWzdgs+22yAY7bg+rqoKl10Lzflt8s5++muuPH5bW+vf863LzT59z6h4e/K7seN/zgNV5DB/0wU+I9b+XBXj1X8Bw/h8=&lt;/diagram&gt;&lt;diagram id=&quot;2oZjiazD9LnPP1Vpl2Fo&quot; name=&quot;第 2 页&quot;&gt;5ZZdb4IwFEB/DY8m0DLQV5m6h7nEuGXPDVToVigpVXC/fkUuX+Lilui2RF+k515u29ObBgN7cbGQJI2WIqDcQGZQGPjeQAiZeKL/SrKviGU6qCKhZAGwFqzZB60TgW5ZQLNeohKCK5b2oS+ShPqqx4iUIu+nbQTvz5qSEGY0W7D2CaeDtFcWqKiiY+S2/IGyMKpnthzYcUzqZCicRSQQeQfhmYE9KYSqnuLCo7y0V3up3pt/EW0WJmmivvNCulw+b3YrwlZPycub9Tgd52oEVXaEb2HDsFi1rw1IsU0CWhaxDDzNI6boOiV+Gc31oWsWqZhDeMM49wQXUo8TkeikaaakeG/kIVuj4dLrdVCpaNFBsJUFFTFVcq9TIDqyXPAKnYVtGOftMWEMLOocUQMJtEbYFG/t6QcQ+AOZ6NdlmheS6Y57Lm2MBi4t2xm6bODFXeLzLnUVfQvQ8x5JllZXw4YVpfsji+Mj1QbC88OvyTwVuUgP20c97A572D7Rwva1OvjuBqxP/plz5/acO+YfO3dvwPngdrmidT1sP2QOsc73IJ59Ag==&lt;/diagram&gt;&lt;/mxfile&gt;">
<defs />
<g>
<rect x="2" y="2" width="120" height="120" rx="21.6" ry="21.6" fill="#2d323b" stroke="none"
pointer-events="all" />
<rect x="25.75" y="25.75" width="72.5" height="72.5" rx="36.25" ry="36.25" fill="#2d323b"
stroke="#cb81da" stroke-width="3" pointer-events="all" />
<ellipse cx="17" cy="107" rx="7.500000000000001" ry="7.500000000000001" fill="#cb81da"
stroke="#cb81da" stroke-width="2" pointer-events="all" />
<ellipse cx="107" cy="107" rx="7.500000000000001" ry="7.500000000000001" fill="#cb81da"
stroke="#cb81da" stroke-width="2" pointer-events="all" />
<ellipse cx="107" cy="17" rx="7.500000000000001" ry="7.500000000000001" fill="#cb81da"
stroke="#cb81da" stroke-width="2" pointer-events="all" />
<path d="M 85.4 65.95 L 92 65.95 M 59 61.34 L 65.6 61.34 M 59 70.55 L 65.6 70.55"
fill="none" stroke="#cb81da" stroke-width="2" stroke-miterlimit="10"
pointer-events="none" />
<path
d="M 65.6 56.74 L 75.5 56.74 C 80.97 56.74 85.4 60.86 85.4 65.95 C 85.4 71.03 80.97 75.16 75.5 75.16 L 65.6 75.16 Z"
fill="#cb81da" stroke="#cb81da" stroke-width="2" stroke-miterlimit="10"
pointer-events="none" />
<rect x="37" y="42" width="11" height="11" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)"
pointer-events="none" />
<rect x="37" y="64.72" width="11" height="11" fill="rgb(255, 255, 255)"
stroke="rgb(0, 0, 0)" pointer-events="none" />
<path d="M 59 70.55 L 48.01 70.6" fill="none" stroke="#cb81da" stroke-width="2"
stroke-miterlimit="10" pointer-events="none" />
<rect x="37" y="64.72" width="11" height="11" fill="#000000" stroke="#000000"
pointer-events="none" />
<rect x="37" y="42" width="11" height="11" fill="#000000" stroke="#000000"
pointer-events="none" />
<rect x="37" y="42" width="11" height="11" fill="#cb81da" stroke="#cb81da"
pointer-events="none" />
<rect x="37" y="64.72" width="11" height="11" fill="#cb81da" stroke="#cb81da"
pointer-events="none" />
<path d="M 48 48.14 L 53.51 48.09 L 53.51 61.31 L 59 61.34" fill="none" stroke="#cb81da"
stroke-width="2" stroke-miterlimit="10" pointer-events="none" />
<ellipse cx="17" cy="17" rx="7.500000000000001" ry="7.500000000000001" fill="#cb81da"
stroke="#cb81da" stroke-width="2" pointer-events="none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -1,8 +1,6 @@
@font-face {
font-family: "iconfont"; /* Project id 4440655 */
src: url('iconfont.woff2?t=1709378049768') format('woff2'),
url('iconfont.woff?t=1709378049768') format('woff'),
url('iconfont.ttf?t=1709378049768') format('truetype');
src: url('iconfont.woff2?t=1713691301672') format('woff2');
}
.iconfont {
@ -13,11 +11,35 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-ctrl:before {
content: "\e605";
}
.icon-shift:before {
content: "\e626";
}
.icon-mouse:before {
content: "\e69e";
}
.icon-left-right:before {
content: "\e61c";
}
.icon-up-down:before {
content: "\e61d";
}
.icon-help:before {
content: "\e87a";
}
.icon-parameter:before {
content: "\e6be";
}
.icon-task-:before {
.icon-task:before {
content: "\e602";
}
@ -29,11 +51,11 @@
content: "\e69d";
}
.icon-Function:before {
.icon-function:before {
content: "\e90e";
}
.icon-R:before {
.icon-real:before {
content: "\e6ec";
}
@ -41,7 +63,7 @@
content: "\e603";
}
.icon-String:before {
.icon-string:before {
content: "\e614";
}
@ -61,7 +83,7 @@
content: "\e657";
}
.icon-Collections:before {
.icon-collections:before {
content: "\e689";
}

Binary file not shown.

View File

@ -12,13 +12,25 @@
<link rel="stylesheet" href="vcd.css">
<link rel="stylesheet" href="iconfont.css">
<script src="vcd.js"></script>
<script>
window.readVcdFile = async () => {
const response = await fetch('test.vcd');
const blob = await response.blob();
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onload = event => {
const fileContent = event.target.result;
const unintarray = new Uint8Array(fileContent);
resolve(unintarray);
};
reader.readAsArrayBuffer(blob);
});
}
</script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>

View File

@ -192,7 +192,7 @@
--vscode-symbolIcon-fieldForeground: #75beff;
--vscode-symbolIcon-fileForeground: #cccccc;
--vscode-symbolIcon-folderForeground: #cccccc;
--vscode-symbolIcon-functionForeground: #b180d7;
--vscode-symbolicon-functionForeground: #b180d7;
--vscode-symbolIcon-interfaceForeground: #75beff;
--vscode-symbolIcon-keyForeground: #cccccc;
--vscode-symbolIcon-keywordForeground: #cccccc;
@ -205,9 +205,9 @@
--vscode-symbolIcon-operatorForeground: #cccccc;
--vscode-symbolIcon-packageForeground: #cccccc;
--vscode-symbolIcon-propertyForeground: #cccccc;
--vscode-symbolIcon-referenceForeground: #cccccc;
--vscode-symbolicon-realeferenceForeground: #cccccc;
--vscode-symbolIcon-snippetForeground: #cccccc;
--vscode-symbolIcon-stringForeground: #cccccc;
--vscode-symbolicon-stringForeground: #cccccc;
--vscode-symbolIcon-structForeground: #cccccc;
--vscode-symbolIcon-textForeground: #cccccc;
--vscode-symbolIcon-typeParameterForeground: #cccccc;
@ -565,7 +565,7 @@
--vscode-debugIcon-pauseForeground: #75beff;
--vscode-debugIcon-stopForeground: #f48771;
--vscode-debugIcon-disconnectForeground: #f48771;
--vscode-debugIcon-restartForeground: #89d185;
--vscode-debugicon-realestartForeground: #89d185;
--vscode-debugIcon-stepOverForeground: #75beff;
--vscode-debugIcon-stepIntoForeground: #75beff;
--vscode-debugIcon-stepOutForeground: #75beff;

View File

@ -4,13 +4,20 @@
--main-color: #CB81DA;
--main-dark-color: #2D323B;
--main-light-color: var(--main-color);
--sidebar-width: 280px;
--sidebar-width: 230px;
--right-nav-width: 60px;
--time-scale-height: 50px;
--sidebar-padding: 10px;
--vcd-render-padding: 24px;
--sidebar-item-margin: 5px;
--vcd-render-padding: 30px;
/* 需要满足如下公式 --time-scale-height + --sidebar-padding = --vcd-render-padding + canvas预留 高度 */
--render-scale-x: 1;
/* css 动画属性 */
--animation-7s: .7s cubic-bezier(0.23,1,0.32,1);
--animation-5s: .5s cubic-bezier(0.23,1,0.32,1);
--animation-3s: .35s cubic-bezier(0.23,1,0.32,1);
--gray-box-shadow-0: 0 0 8px 3px rgba(182, 181, 182, 0.9);
}
html, body {
@ -94,3 +101,17 @@ body::-webkit-scrollbar {
a {
color: var(--main-color);
}
.digital-ide-icon {
background-image: url(./icon.svg);
background-size: 100%;
height: 50px;
width: 50px;
}
.digital-ide-icon.big {
background-image: url(./icon.svg);
background-size: 100%;
height: 200px;
width: 200px;
}

View File

@ -14,9 +14,9 @@
<RightNav :topModules="VcdInfo.topModules"></RightNav>
</template>
<script>
import { onMounted, reactive } from 'vue';
import { getVcdStream, readVcdFile, numberOrString, gcd, normaliseUsingGCD, parseTimescale } from '@/hook/utils';
<script setup>
import { onMounted, reactive, watch } from 'vue';
import { getVcdStream, numberOrString, gcd, normaliseUsingGCD, parseTimescale } from '@/hook/utils';
import { emitter, globalLookup, globalSetting, signalValues } from '@/hook/global';
import { makeWaveView } from '@/hook/render';
@ -24,13 +24,14 @@ import Sidebar from '@/components/sidebar.vue';
import RightNav from '@/components/right-nav.vue';
import MainRender from '@/components/render';
export default {
components: {
RightNav,
Sidebar,
MainRender
// globalSetting localStorage
watch(
() => globalSetting,
() => {
localStorage.setItem('setting', JSON.stringify(globalSetting));
},
setup() {
{ deep: true }
);
const VcdInfo = reactive({
topModules: [],
@ -51,22 +52,27 @@ export default {
document.body.style.setProperty('--el-border', 'var(--sidebar)');
document.body.style.setProperty('--el-border-color-light', 'var(--sidebar)');
document.body.style.setProperty('--el-border-color-lighter', 'var(--sidebar)');
document.body.style.setProperty('--el-bg-color-overlay', 'transplant');
document.body.style.setProperty('--el-bg-color-overlay', 'var(--sidebar)');
document.body.style.setProperty('--el-color-info-light-9', 'var(--vscode-focusBorder)');
document.body.style.setProperty('--el-color-info', 'var(--foreground)');
document.body.style.setProperty('--el-color-info-light-8', 'var(--vscode-focusBorder)');
document.body.style.setProperty('--el-bg-color-overlay', 'transplant');
// document.body.style.setProperty('--el-color-white', 'var(--background)');
//
document.body.style.setProperty('--time-scale-height', '50px');
document.body.style.setProperty('--sidebar-padding', '10px');
document.body.style.setProperty('--vcd-render-padding', '24px');
document.body.style.setProperty('--vcd-render-padding', '30px');
document.body.style.setProperty('--sidebar-width', '230px');
// signal height
document.body.style.setProperty('--display-signal-info-height', globalSetting.displaySignalHeight + 'px');
const uint8array = await readVcdFile();
// localStorage
if (!localStorage.getItem('setting')) {
localStorage.setItem('setting', JSON.stringify(globalSetting));
}
// vcd
const uint8array = await window.readVcdFile();
const vcdstream = await getVcdStream();
let tgcd;
@ -117,7 +123,7 @@ export default {
makeWaveView();
console.log('duration time', globalLookup.time);
// console.log('duration time', globalLookup.time);
emitter.emit('meta-ready', null);
//
@ -133,13 +139,6 @@ export default {
}
});
return {
VcdInfo
}
}
}
</script>
<style>

View File

@ -1,18 +1,39 @@
<template>
<div class="about-wrapper">
<div class="usermanual">
<h2>{{ t('usermanual') }}</h2>
<div class="usermanual-item">
<div v-html="t('usermanual.left-right-scroll.title')"></div>
<div>{{ t('usermanual.left-right-scroll.caption') }}</div>
</div>
<div class="usermanual-item">
<div v-html="t('usermanual.up-down-scroll.title')"></div>
<div>{{ t('usermanual.up-down-scroll.caption') }}</div>
</div>
<div class="usermanual-item">
<div v-html="t('usermanual.xscale.title')"></div>
<div>{{ t('usermanual.xscale.caption') }}</div>
</div>
</div>
<br>
<hr>
<br>
<div class="icon-caption" @click="goto('https://github.com/Digital-EDA')">
<img src="../../assets/icon.png" height="200px" alt="">
<div class="digital-ide-icon big"/>
</div>
<div class="version-caption">
<span>{{ t('current-version') }} &ensp; <span class="version-wrapper">0.3.3</span></span>
</div>
<hr>
<br>
<div style="display: flex;justify-content: space-around;">
<div class="copyright-caption" v-html="t('copyright')"></div>
</div>
</div>
</template>
<script>
import { useI18n } from 'vue-i18n';
@ -35,15 +56,14 @@ export default {
<style>
.about-wrapper {
margin-top: 20px;
padding: 10px;
width: 600px;
margin-top: 10px;
width: 450px;
}
.version-caption {
display: flex;
width: 100% !important;
font-size: 20px;
font-size: 1.1rem;
padding: 10px;
margin: 10px;
align-items: center;
@ -53,7 +73,7 @@ export default {
.copyright-caption {
width: 50% !important;
line-height: 30px;
font-size: 20px;
font-size: 0.9rem;
padding: 10px;
margin: 10px;
align-items: center;
@ -73,4 +93,23 @@ export default {
padding: 5px;
}
.usermanual {
margin: 10px;
margin-top: 0;
padding: 10px;
padding-top: 0;
}
.usermanual-item {
display: flex;
justify-content: space-between;
padding: 5px;
margin: 5px;
font-size: 0.9rem;
}
.usermanual-item .iconfont {
font-size: 1.1rem !important;
color: var(--sidebar-text-item);
}
</style>

View File

@ -0,0 +1,24 @@
<template>
<el-tooltip
effect="dark"
:content="props.content"
:placement="props.placement"
raw-content
>
<span class="iconfont icon-help"></span>
</el-tooltip>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
content: {
type: String,
required: true
},
placement: {
type: String,
default: 'right'
}
});
</script>

View File

@ -12,7 +12,7 @@
<div class="vcd-function-option">
<div class="vcd-control-panel-wrapper">
<img class="vcd-control-panel-icon" src="../assets/icon.png" alt="">
<div class="vcd-control-panel-icon digital-ide-icon" />
</div>
<hr>
<div class="vcd-control-panel-wrapper"
@ -52,7 +52,7 @@ export default {
const controlPanel = reactive({
sections: [
{
iconClass: 'iconfont icon-Collections'
iconClass: 'iconfont icon-collections'
},
{
iconClass: 'iconfont icon-setting'

View File

@ -1,17 +1,128 @@
<template>
<div class="setting-wrapper">
<div class="setting-container">
<div class="setting-section">
<h2>{{ t('general-setting') }}</h2>
<div class="setting-option" style="width: 300px;">
<span class="option-title">{{ t('language-setting') }}</span>
<el-select name="language-setting" class="language-setting" v-model="locale">
<el-option
v-for="option in languageSetting.options"
:value="option.value"
:label="option.text"
:key="option.value">
</el-option>
</el-select>
</div>
<br>
<div class="setting-option">
<span class="option-title">
{{ t('prerender') }}
<help-icon placement="left"
:content="t('prerender-description')"
></help-icon>
</span>
<el-switch v-model="globalSetting.prerender" size="default"/>
</div>
<br>
<div class="setting-option">
<span class="option-title">
{{ t('render-animation') }}
</span>
<el-switch v-model="globalSetting.renderAnimation" size="default"/>
</div>
<br>
<div class="setting-option" style="width: 380px;">
<span class="option-title" style="width: 300px;">
{{ t('horizontal-scaling-ratio') }}
<help-icon placement="left"
:content="t('horizontal-scaling-ratio-description')"
></help-icon>
</span>
<el-slider v-model="globalSetting.HorizontalScalingRatio" show-stops :min="1" :max="5"/>
</div>
<br>
<div class="setting-option" style="width: 380px;">
<span class="option-title" style="width: 300px;">
{{ t('horizontal-roll-ratio') }}
<help-icon placement="left"
:content="t('horizontal-roll-ratio-description')"
></help-icon>
</span>
<el-slider v-model="globalSetting.HorizontalRollRatio" show-stops :min="1" :max="5"/>
</div>
<br>
<div class="setting-option" style="width: 380px;">
<span class="option-title" style="width: 300px;">
{{ t('vertical-roll-ratio') }}
<help-icon placement="left"
:content="t('vertical-roll-ratio-description')"
></help-icon>
</span>
<el-slider v-model="globalSetting.VerticalRollRario" show-stops :min="1" :max="5"/>
</div>
</div>
<hr>
<div class="setting-section">
<h2>{{ t('appearance-setting') }}</h2>
<div class="setting-option">
<span class="option-title" style="width: 150px;">{{ t('display-wave-height') }}</span>
<el-input-number v-model="globalSetting.displaySignalHeight" :min="1" :max="100" @change="safeModifySignalTrackHeight" size="default"/>
</div>
<br>
<div class="setting-option">
<span class="option-title" style="width: 150px;">{{ t('display-signal-info-scope') }}</span>
<el-checkbox-group v-model="globalSetting.displaySignalInfoScope" size="default">
<el-checkbox-button label="width" border>{{ t('display-signal-info-scope.width') }}</el-checkbox-button>
<el-checkbox-button label="parent" border>{{ t('display-signal-info-scope.parent') }}</el-checkbox-button>
</el-checkbox-group>
</div>
<br>
<div class="setting-option">
<span class="option-title">{{ t('wavecolor') }}</span>
<el-select
v-model="wavecolor.currentOptionIndex"
collapse-tags
collapse-tags-tooltip
placeholder="Select"
>
<el-option v-for="option in wavecolor.options" :key="option.value"
:label="option.label" :value="option.value" />
</el-select>
<div style="height: 20px; width: 20px;"></div>
<el-color-picker
v-model="wavecolor.colors[wavecolor.currentOptionIndex]"
show-alpha
:predefine="predefinedColors"
size="large"
/>
</div>
</div>
<hr>
<div class="setting-section">
<h2>{{ t('search-setting') }}</h2>
<div class="setting-option">
<span class="option-title">{{ t('search-case-sensitivity') }}</span>
<el-switch v-model="globalSetting.caseSensitivity" size="large"/>
<el-switch v-model="globalSetting.caseSensitivity" size="default"/>
</div>
<br>
<div class="setting-option">
<span class="option-title">{{ t('search-display-parent-only') }}</span>
<el-switch v-model="globalSetting.displayParentOnly" size="large"/>
<el-switch v-model="globalSetting.displayParentOnly" size="default"/>
</div>
<br>
@ -31,62 +142,84 @@
:label="name" :value="name" />
</el-select>
</div>
</div>
<hr>
<div class="setting-section">
<h2>{{ t('general-setting') }}</h2>
<div class="setting-option" style="width: 300px;">
<span class="option-title">{{ t('language-setting') }}</span>
<el-select name="language-setting" class="language-setting" v-model="locale">
<el-option
v-for="option in languageSetting.options"
:value="option.value"
:label="option.text"
:key="option.value">
</el-option>
</el-select>
</div>
<br>
<div class="setting-option" style="width: 380px;">
<span class="option-title" style="width: 300px;">{{ t('wheel-zoom-ratio') }}</span>
<el-slider v-model="languageSetting.wheelZoomRatio" show-stops :min="1" :max="5"/>
</div>
</div>
<hr>
<div class="setting-section">
<h2>{{ t('appearance-setting') }}</h2>
<div class="setting-option">
<span class="option-title">{{ t('display-wave-height') }}</span>
<el-input-number v-model="globalSetting.displaySignalHeight" :min="1" :max="100" @change="safeModifySignalTrackHeight" size="large"/>
</div>
<br>
<div class="setting-option">
<span class="option-title">{{ t('display-signal-info-scope') }}</span>
<el-checkbox-group v-model="globalSetting.displaySignalInfoScope" size="default">
<el-checkbox-button label="width" border>width </el-checkbox-button>
<el-checkbox-button label="parent" border>parent </el-checkbox-button>
</el-checkbox-group>
</div>
</div>
</div>
</template>
<script>
import { reactive } from 'vue';
<script setup>
import { reactive, defineComponent, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { globalSetting } from '@/hook/global';
import { debounceWrapper, scopes, variables } from '@/hook/utils';
import { globalSetting, globalLookup } from '@/hook/global';
import { debounceWrapper, scopes, variables, predefinedColors, webglColor2rgba, rgba2WebglColor } from '@/hook/utils';
import { gl_Colors } from '@/hook/wave-view/render-utils';
import HelpIcon from '../help-icon.vue';
defineComponent({ name: "dide-setting" });
export default {
name: 'dide-setting',
setup() {
const { t, locale } = useI18n();
locale.value = globalSetting.language;
watch(
() => locale.value,
() => {
globalSetting.language = locale.value;
localStorage.setItem('setting', JSON.stringify(globalSetting));
}
);
const wavecolor = reactive({
options: [
{
value: 0,
label: t('wavecolor.normal-bit')
},
{
value: 1,
label: t('wavecolor.normal-vec')
},
{
value: 2,
label: t('wavecolor.high-impedance')
},
{
value: 3,
label: t('wavecolor.unknown')
}
],
glColorMap: [2, 5, 4, 1],
currentOptionIndex: 0,
colors: [
webglColor2rgba(...gl_Colors.slice(2 * 4, 2 * 4 + 4)),
webglColor2rgba(...gl_Colors.slice(5 * 4, 5 * 4 + 4)),
webglColor2rgba(...gl_Colors.slice(4 * 4, 4 * 4 + 4)),
webglColor2rgba(...gl_Colors.slice(1 * 4, 1 * 4 + 4)),
],
reset() {}
});
watch(() => wavecolor.currentOptionIndex, () => {
console.log(wavecolor.currentOptionIndex);
});
watch(() => wavecolor.colors, () => {
console.log('enter');
const colorString = wavecolor.colors[wavecolor.currentOptionIndex];
const rgba = rgba2WebglColor(colorString);
if (rgba !== undefined) {
const currentOption = wavecolor.options[wavecolor.currentOptionIndex];
const waveRender = globalLookup.getWaveRender();
const glColorIndex = wavecolor.glColorMap[currentOption.value];
const colorUpdaters = [{ index: glColorIndex, rgba }];
if (glColorIndex === 2) { // value = 0 value = 1
colorUpdaters.push({ index: 3, rgba });
}
waveRender.updateGLColor(colorUpdaters, { updateMask: true });
}
}, { deep: true });
const languageSetting = reactive({
options: [
@ -103,30 +236,24 @@ export default {
function modifySignalTrackHeight() {
document.body.style.setProperty('--display-signal-info-height', globalSetting.displaySignalHeight + 'px');
const waveRender = globalLookup.getWaveRender();
waveRender.render();
}
const safeModifySignalTrackHeight = debounceWrapper(modifySignalTrackHeight, 200);
return {
t,
languageSetting,
globalSetting,
safeModifySignalTrackHeight,
locale,
scopes,
variables
}
}
}
</script>
<style>
.setting-wrapper {
width: 600px;
width: fit-content;
padding: 10px;
}
.setting-container {
overflow-y: scroll;
height: 99vh;
}
.setting-section {
padding: 10px;
margin: 10px;
@ -136,22 +263,43 @@ export default {
.setting-option {
margin: 5px;
padding: 10px 12px;
padding: 8px 12px;
height: 40px;
width: fit-content;
border-radius: .5em;
background-color: var(--background);
display: flex;
align-items: center;
font-size: 0.9rem;
}
.option-title {
min-width: 80px;
margin-right: 12px;
user-select: none;
}
.el-slider__button {
background-color: var(--background) !important;
}
.el-switch__core .el-switch__action {
background-color: var(--background) !important;
}
.el-slider__stop {
background-color: var(--sidebar-item-text) !important;
}
.icon-help {
cursor: pointer;
transition: var(--animation-3s);
-webkit-transition: var(--animation-3s);
}
.icon-help:hover {
color: var(--main-color);
transition: var(--animation-3s);
-webkit-transition: var(--animation-3s);
}
</style>

View File

@ -1,8 +1,10 @@
<template>
<div class="vcd-sidebar-wrapper">
<div class="display-signal-wrapper">
<div style="height: var(--time-scale-height);"></div>
<div class="display-signal-wrapper" :style="sideBarWrapperStyle">
<div class="display-signal-container" :style="sidedBarContainerStyle">
<div :style="timeScaleStyle"></div>
<div class="display-signal-item"
:style="sideBarItemStyle"
v-for="(signal, index) in globalLookup.currentWires" :key="index">
<div class="signal-color-vendor">
<span :class="makeSignalIconClass(signal)"></span>
@ -16,10 +18,12 @@
raw-content
>
<div class="signal-info-name">
{{ signal.name }}
</div></el-tooltip>
<span class="signal-parent-info" v-show="showParent">{{ signal.parent.name }}</span>
<span>{{ signal.name }}</span>
</div>
</el-tooltip>
<div class="signal-info-width">
<div class="signal-info-width" v-show="showWidth">
<div :class="signal.size > 1 ? 'signal-info-caption' : ''">
{{ makeSignalCaption(signal) }}
</div>
@ -41,23 +45,41 @@
</div>
</div>
</div>
</div>
<div class="add-signal-button" @click="addSignal">
<span class="iconfont icon-Collections"></span>
<span class="iconfont icon-collections"></span>
</div>
</div>
</template>
<script>
/* eslint-disable */
import { reactive } from 'vue';
<script setup>
import { reactive, computed, defineComponent } from 'vue';
import { useI18n } from 'vue-i18n';
import { emitter, globalLookup, globalSetting } from '@/hook/global';
import { emitter, globalLookup, globalSetting, globalStyle } from '@/hook/global';
import { makeIconClass } from '@/hook/utils';
export default {
name: 'sidebar',
setup() {
const { t } = useI18n();
defineComponent({ name: 'side-bar' });
const showWidth = computed(() => globalSetting.displaySignalInfoScope.includes('width'));
const showParent = computed(() => globalSetting.displaySignalInfoScope.includes('parent'));
const timeScaleStyle = computed(() => ({
height: `${globalStyle.timeScaleHeight}px`
}));
const sideBarWrapperStyle = computed(() => ({
padding: `${globalStyle.sideBarPadding}px`
}));
const sidedBarContainerStyle = computed(() => ({
transform: `translateY(${- globalStyle.yOffset}px)`,
transition: globalSetting.renderAnimation ? 'var(--animation-3s)' : 'unset'
}));
const sideBarItemStyle = computed(() => ({
margin: `${globalStyle.sideBarItemMargin}px`
}));
function addSignal() {
emitter.emit('right-nav', 0);
@ -96,16 +118,6 @@ export default {
return htmlString;
}
return {
t,
globalLookup,
makeSignalIconClass,
makeSignalCaption,
makeFullSignalNameDeps,
addSignal
}
}
}
</script>
<style>
@ -132,20 +144,20 @@ export default {
}
.display-signal-wrapper {
padding: var(--sidebar-padding);
background-color: var(--sidebar);
border: solid 1px var(--sidebar-border);
min-width: var(--sidebar-width);
height: calc(100vh - 90px);
box-shadow: 0 0 15px 1px rgb(16, 16, 16);
overflow: hidden;
}
.display-signal-item {
border-radius: .5em;
background-color: var(--background);
margin: 5px;
height: var(--display-signal-info-height);
display: flex;
cursor: pointer;
}
.display-signal-item::selection {
@ -182,6 +194,8 @@ export default {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: flex;
flex-direction: column;
}
.signal-info-tooltip-wrapper {
@ -223,4 +237,15 @@ export default {
cursor: none;
}
.signal-parent-info {
font-size: .8rem;
border-radius: .5em;
padding: 2px 5px;
color: var(--sidebar);
background-color: var(--main-color);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

View File

@ -56,8 +56,8 @@ export default {
}
const expandManage = reactive({
expanded: true,
expandTagClass: mods.length === 0 ? '' : 'expand-tag',
expanded: false,
expandTagClass: mods.length === 0 ? '' : 'collapse-tag',
click() {
this.expanded = !this.expanded;
if (this.expandTagClass) {

View File

@ -13,7 +13,12 @@
@blur="searchManage.displayResult = false"
/>
</div>
<div class="search-result-wrapper" v-if="searchManage.displayResult | searchManage.mouseOnResult">
<div
v-if="searchManage.displayResult | searchManage.mouseOnResult"
:style="searchResultWrapper"
class="search-result-wrapper"
id="search-result-wrapper"
>
<div class="search-result"
@mouseenter="searchManage.mouseOnResult = true"
@mouseleave="searchManage.mouseOnResult = false"
@ -25,7 +30,6 @@
@click="toggleRender(searchResult.module)">
<div v-html="searchResult.htmlString" class="search-result-item"></div>
</div>
</div>
<div v-else>
{{ t('search-nothing') }}
@ -36,27 +40,31 @@
</div>
</template>
<script>
import { reactive } from 'vue';
<script setup>
import { reactive, computed, defineComponent, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { globalSetting, globalLookup, emitter } from '@/hook/global';
import { debounceWrapper, makeSearchResultItem } from '@/hook/utils';
import { toggleRender } from '@/hook/render';
export default {
name: 'tree-view-search',
setup() {
const { t } = useI18n();
defineComponent({ name: 'search-box' });
const searchResultWrapper = computed(() => ({
right: '55px',
transition: 'var(--animation-3s)'
}));
const searchManage = reactive({
content: '',
displayResult: false,
mouseOnResult: false,
searchResult: []
searchResult: [],
searchResultEl: undefined,
searchResultLeft: -5,
});
function search() {
const searchString = searchManage.content.trim();
if (searchString.length === 0) {
@ -83,6 +91,13 @@ export default {
emitter.emit('signal-search', searchResultItem);
}
}
nextTick(() => {
searchManage.searchResultEl = document.getElementById('search-result-wrapper');
if (searchManage.searchResultEl) {
searchManage.searchResultLeft = 480 - searchManage.searchResultEl.offsetWidth;
}
})
}
emitter.on('signal-search', searchResultItem => {
@ -91,16 +106,6 @@ export default {
const safeSearch = debounceWrapper(search, 500);
return {
searchManage,
safeSearch,
globalLookup,
debounceWrapper,
t,
toggleRender
}
}
}
</script>
<style>

View File

@ -80,15 +80,15 @@ export default {
color: #C76B3C;
}
.icon-String {
.icon-string {
color: #8CC265;
}
.icon-R {
.icon-real {
color: #5fb4d8;
}
.icon-task- {
.icon-task {
color: orange;
}
@ -103,7 +103,7 @@ export default {
margin: 3px;
display: flex;
justify-content: space-between;
height: 25px;
height: 23px;
padding-left: 3px;
cursor: pointer;
align-items: center;
@ -124,6 +124,6 @@ export default {
border-radius: .5em;
background-color: var(--color-deepPurple);
padding: 3px;
font-size: 15px;
font-size: 12px;
}
</style>

View File

@ -1,5 +1,6 @@
import mitt from 'mitt';
import { reactive } from 'vue';
import WebGL2WaveRender from './wave-view/render-wave';
const emitter = mitt();
@ -35,8 +36,11 @@ const globalLookup = reactive({
tgcd: null,
// 其实就是 signalValues
chango: {},
// 初始化时会被定义
render: () => {},
waveRender: undefined,
pstate: undefined,
xScale: 1,
@ -60,25 +64,75 @@ const globalLookup = reactive({
childModule.parent = module;
}
}
},
/**
* @returns {WebGL2WaveRender}
*/
getWaveRender() {
return this.waveRender;
}
});
const globalStyle = reactive({
timeScaleHeight: 30,
sideBarPadding: 10,
sideBarItemMargin: 5,
vcdRenderPadding: 24,
yOffset: 0,
});
const globalSetting = reactive({
language: 'zh',
caseSensitivity: false,
displayParentOnly: false,
displaySignalHeight: 50,
searchMode: 'so', // so, mo, sm
searchScope: ['wire', 'reg', 'integer'],
displaySignalInfoScope: ['width', 'parent'],
wheelZoomRatio: 1,
minGridWidth: 300
displaySignalInfoScope: ['width'],
HorizontalScalingRatio: 1,
HorizontalRollRatio: 1,
VerticalRollRario: 1,
minGridWidth: 300,
prerender: true,
renderAnimation: false,
});
function loadSetting() {
const settingString = localStorage.getItem('setting')
try {
const setting = JSON.parse(settingString);
return setting;
} catch (error) {
return undefined;
}
}
const storedSetting = loadSetting();
if (storedSetting) {
for (const key of Reflect.ownKeys(storedSetting)) {
const value = storedSetting[key];
if (value !== undefined) {
globalSetting[key] = value;
}
}
}
// for (const key of Reflect.ownKeys(globalSetting)) {
// const value = localStorageGetItem(key);
// if (value !== undefined && value !== null) {
// globalSetting[key] = value;
// }
// }
const signalValues = {};
export {
emitter,
globalLookup,
globalSetting,
globalStyle,
signalValues
};

View File

@ -1,6 +1,7 @@
import { globalLookup, globalSetting, signalValues } from "./global";
import { domContainer, pluginRenderTimeGrid, pluginRenderValues, mountTree,
genOnWheel, genKeyHandler, keyBindo } from './wave-view';
genOnWheel, genKeyHandler, keyEvent } from './wave-view';
import { findCurrentSignalValue } from './utils';
let mainRenderEl = null;
@ -38,6 +39,7 @@ function makeWaveView(parentElement) {
if (!parentElement) {
parentElement = getMainRenderEl();
}
const container = domContainer({
elemento: mountTree.defaultElemento,
layers: mountTree.defaultLayers,
@ -55,7 +57,7 @@ function makeWaveView(parentElement) {
console.log('updater');
};
container.elo.container.addEventListener('wheel', genOnWheel(parentElement, container.pstate, globalLookup, keyBindo));
container.elo.container.addEventListener('wheel', genOnWheel(parentElement, container.pstate, globalLookup, keyEvent));
}

View File

@ -1,47 +0,0 @@
export interface RenderElements {
grid: HTMLDivElement
view: HTMLDivElement
values: HTMLDivElement
}
export interface ChangoItem {
kind: string
wave: Array<number | string>
lineVao: WebGLVertexArrayObject
maskVao: WebGLVertexArrayObject
}
export interface WireInfoItem {
kind: string
link: string
name: string
size: number
parent: WireInfoItem
type: string
}
export interface Pstate {
width: number
height: number
xScale: number
xOffset: number
yOffset: number
yStep: number
yDuty: number
}
export interface WebGLLocation {
colors: WebGLUniformLocation
shifts: WebGLUniformLocation
scale: WebGLUniformLocation
offset: WebGLUniformLocation
pos: number
widthShifts: WebGLUniformLocation
gl: WebGL2RenderingContext
}
export interface PerspectivePoint {
x: number
y: number
color: number
}

View File

@ -1 +0,0 @@
module.Render = {};

View File

@ -1,5 +1,3 @@
/* eslint-disable no-undef */
import { Stream } from "stream";
import { globalLookup } from "./global";
@ -12,22 +10,6 @@ async function getVcdStream() {
return ostream;
}
/**
* @returns {Promise<Uint8Array>}
*/
async function readVcdFile() {
const response = await fetch('test.vcd');
const blob = await response.blob();
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onload = event => {
const fileContent = event.target.result;
const unintarray = new Uint8Array(fileContent);
resolve(unintarray);
};
reader.readAsArrayBuffer(blob);
});
}
function debounceWrapper(fn, delay) {
let timer
@ -47,13 +29,13 @@ function makeIconClass(mod) {
case 'module': return 'icon-memory-chip';
case 'begin': return 'icon-brackets';
case 'fork': return 'icon-fork';
case 'function': return 'icon-Function';
case 'task': return 'icon-task-';
case 'function': return 'icon-function';
case 'task': return 'icon-task';
case 'event': return 'icon-prevent';
case 'integer': return 'icon-integer';
case 'parameter': return 'icon-parameter';
case 'real': return 'icon-R';
case 'real': return 'icon-real';
case 'realtime': return 'icon-wave-square';
case 'reg': return 'icon-register';
case 'supply0': return 'icon-wave-square';
@ -68,7 +50,7 @@ function makeIconClass(mod) {
case 'wand': return 'icon-wave-square';
case 'wire': return 'icon-wave-square';
case 'wor': return 'icon-wave-square';
case 'string': return 'icon-String';
case 'string': return 'icon-string';
default:
break;
}
@ -322,12 +304,57 @@ function isVariable(wire) {
return variables.has(wire.type);
}
function webglColor2rgba(r, g, b, a) {
const standRed = Math.floor(r * 255);
const standGreen = Math.floor(g * 255);
const standBlue = Math.floor(b * 255);
return `rgba(${standRed},${standGreen},${standBlue},${a})`;
}
/**
*
* @param {string} rgba
* @returns {{
* red: number,
* green: number,
* blue: number,
* alpha: number
* } | undefined}
*/
function rgba2WebglColor(rgba) {
const match = rgba.match(/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(\.\d+)?)\)$/);
if (match) {
return {
red: parseInt(match[1]) / 255,
green: parseInt(match[2]) / 255,
blue: parseInt(match[3]) / 255,
alpha: parseFloat(match[4])
};
} else {
return undefined;
}
}
const predefinedColors = [
'#ff4500',
'#ff8c00',
'#ffd700',
'#90ee90',
'#00ced1',
'#1e90ff',
'#c71585',
'rgba(255, 69, 0, 0.68)',
'rgb(255, 120, 0)',
'hsv(51, 100, 98)',
'hsva(120, 40, 94, 0.5)',
'hsl(181, 100%, 37%)',
'hsla(209, 100%, 56%, 0.73)',
'#c7158577'
];
export {
getVcdStream,
readVcdFile,
debounceWrapper,
makeSearchResultItem,
handleTimeScale,
@ -341,5 +368,8 @@ export {
gcd,
findCurrentSignalValue,
normaliseUsingGCD,
updateWireCurrentValue
updateWireCurrentValue,
predefinedColors,
webglColor2rgba,
rgba2WebglColor
};

View File

@ -1,7 +1,6 @@
'use strict';
const getX = require('./get-x.js');
const surferer = require('./surferer.js');
import getX from './get-x';
import surferer from './surferer';
const skipT = (wave, iStart, tLimit) => {
let iRes = iStart;
@ -102,6 +101,8 @@ const bracer = (lane, desc, pstate) => {
return res;
};
module.exports = bracer;
export default bracer;
/* eslint complexity: [1, 55] */

View File

@ -1,7 +1,9 @@
const WebGL2WaveRender = require('./gen-render-waves-gl.js');
const renderCursor = require('./render-cursor.js');
const genResizeHandler = require('./gen-resize-handler.js');
const mTree = require('./mount-tree.js');
import { globalLookup } from '../global';
import WebGL2WaveRender from './render-wave';
import renderCursor from './render-cursor';
import genResizeHandler from './gen-resize-handler';
import mTree from './mount-tree';
const setTime = (pstate, str) => {
// const { sidebarOffset, time, timescale, tgcd, xOffset } = pstate;
@ -118,10 +120,19 @@ const domContainer = (obj) => {
yOffset: -40, // [px]
yStep: 54, // = 24 // [px] wave lane height
yDuty: 0.6,
// for animation
oldXOffset: sidebarWidth,
oldYOffset: -40,
oldYStep: 54,
oldYDuty: 0.6,
sidebarWidth,
container
};
globalLookup.pstate = pstate;
return {
elo,
pstate,
@ -138,6 +149,7 @@ const domContainer = (obj) => {
tgcd: deso.tgcd,
timescale: deso.timescale,
xScale: deso.xScale || 8,
oldXScale: deso.xScale || 8,
numLanes: deso.currentWires.size,
t0: deso.t0,
time: deso.time
@ -157,16 +169,20 @@ const domContainer = (obj) => {
setTime(pstate, deso.timeOpt.value);
}
let waveRender = new WebGL2WaveRender(elo, deso, pstate, obj.renderPlugins);
const waveRender = new WebGL2WaveRender(elo, deso, pstate, obj.renderPlugins);
deso.render = waveRender.render.bind(waveRender);
deso.waveRender = waveRender;
globalLookup.waveRender = waveRender;
const resizeHandler = genResizeHandler(pstate);
// 通过 resize 完成 height 和 width 的初始化
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
// TODO : 使用更新的属性替换 contentRect
// 未来版本 contentRect 可能会被丢弃
let { width, height } = entry.contentRect;
console.log(width, height);
// height = height || 888;
// console.log('resizeObserver', width, height);
resizeHandler(width, height);
@ -183,6 +199,4 @@ const domContainer = (obj) => {
};
};
module.exports = domContainer;
/* eslint-env browser */
export default domContainer;

View File

@ -1,5 +1,3 @@
'use strict';
const formatTime = (t, expo) => {
const prefixes = ['T', 'G', 'M', 'k', '', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y'];
const ts1 = 14 - expo;
@ -8,4 +6,4 @@ const formatTime = (t, expo) => {
return (t * mult).toLocaleString() + ' ' + prefix + 's';
};
module.exports = formatTime;
export default formatTime;

View File

@ -1,4 +1,6 @@
'use strict';
const replacer = '...';
// '\u205D'
const format = (fmt, len) => {
len = BigInt(len);
@ -20,9 +22,9 @@ const format = (fmt, len) => {
return sign;
}
if (pos === 2) {
return sign + '\u205D';
return sign + replacer;
}
return sign + '\u205D' + txtOrig.slice(2 - pos);
return sign + replacer + txtOrig.slice(2 - pos);
};
}
if (Number(m.groups.elen) > 0) {
@ -38,9 +40,9 @@ const format = (fmt, len) => {
return txtRes;
}
if (pos === 1) {
return '\u205D';
return replacer;
}
return '\u205D' + txtRes.slice(1 - pos);
return replacer + txtRes.slice(1 - pos);
};
}
return (val, pos) => {
@ -49,9 +51,9 @@ const format = (fmt, len) => {
return txtOrig;
}
if (pos === 1) {
return '\u205D';
return replacer;
}
return '\u205D' + txtOrig.slice(1 - pos);
return replacer + txtOrig.slice(1 - pos);
};
}
} {
@ -66,7 +68,7 @@ const format = (fmt, len) => {
if (txtRes.length <= pos) {
return txtRes;
}
txtRes = txtRes.slice(0, pos - 1) + '\u205D';
txtRes = txtRes.slice(0, pos - 1) + replacer;
return txtRes;
};
}
@ -92,9 +94,9 @@ const format = (fmt, len) => {
return txtRes;
}
if (pos === 1) {
return '\u205D';
return replacer;
}
return '\u205D' + txtRes.slice(1 - pos);
return replacer + txtRes.slice(1 - pos);
};
}
return (val, pos) => {
@ -140,4 +142,4 @@ const format = (fmt, len) => {
return () => '?';
};
module.exports = format;
export default format;

View File

@ -1,12 +1,10 @@
'use strict';
const { keyName } = require('w3c-keyname');
const executeKeyHandler = (key, keyBindo, pstate, cm) => {
return (keyBindo[key] || keyBindo.nop).fn(pstate, cm);
const executeKeyHandler = (key, keyEvent, pstate, cm) => {
return (keyEvent[key] || keyEvent.nop).fn(pstate, cm);
};
const genKeyHandler = (div, pstate, deso, cm, keyBindo, plugins) => {
const genKeyHandler = (div, pstate, deso, cm, keyEvent, plugins) => {
return event => {
const modifier = (
@ -17,7 +15,7 @@ const genKeyHandler = (div, pstate, deso, cm, keyBindo, plugins) => {
// const key = modifier + event.key;
const key = modifier + keyName(event);
if (executeKeyHandler(key, keyBindo, pstate, cm)) {
if (executeKeyHandler(key, keyEvent, pstate, cm)) {
event.stopPropagation();
if (plugins != undefined) {
plugins.map(fn => fn(key, event));
@ -27,5 +25,7 @@ const genKeyHandler = (div, pstate, deso, cm, keyBindo, plugins) => {
};
};
exports.executeKeyHandler = executeKeyHandler;
exports.genKeyHandler = genKeyHandler;
export default {
executeKeyHandler,
genKeyHandler
};

View File

@ -1,13 +1,11 @@
'use strict';
const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
const genOnWheel = (element, pstate, deso, keyEvent, plugins) =>
event => {
const { deltaX, deltaY } = event;
if (event.ctrlKey) {
const key = (deltaY < 0)
? 'Ctrl+icon:scrollUp'
: ((deltaY > 0) ? 'Ctrl+icon:scrollDown' : 'nop');
if (keyBindo[key].fn(pstate)) {
if (keyEvent[key].fn(pstate)) {
if (plugins != undefined) {
plugins.map(fn => fn(key, event));
}
@ -16,7 +14,7 @@ const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
event.preventDefault();
} else if (event.shiftKey) {
const key = (deltaY < 0) ? 'Shift+icon:scrollUp' : ((deltaY > 0) ? 'Shift+icon:scrollDown' : 'nop');
if (keyBindo[key].fn(pstate)) {
if (keyEvent[key].fn(pstate)) {
if (plugins != undefined) {
plugins.map(fn => fn(key, event));
}
@ -24,8 +22,17 @@ const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
}
event.preventDefault();
} else if (deltaX !== 0 && deltaY === 0) {
const key = (deltaX < 0) ? 'icon:scrollLeft': 'icon:scrollRight';
if (keyBindo[key].fn(pstate)) {
const key = (deltaX < 0) ? 'scrollLeft': 'scrollRight';
if (keyEvent[key].fn(pstate)) {
if (plugins != undefined) {
plugins.map(fn => fn(key, event));
}
deso.render();
}
event.preventDefault();
} else if (deltaX === 0 && deltaY !== 0) {
const key = (deltaY < 0) ? 'scrollUp': 'scrollDown';
if (keyEvent[key].fn(pstate)) {
if (plugins != undefined) {
plugins.map(fn => fn(key, event));
}
@ -35,4 +42,4 @@ const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
}
};
module.exports = genOnWheel;
export default genOnWheel;

View File

@ -1,6 +1,4 @@
'use strict';
const xOffsetUpdate = require('./x-offset-update.js');
import xOffsetUpdate from './x-offset-update';
const genResizeHandler = pstate =>
(width, height) => {
@ -8,8 +6,6 @@ const genResizeHandler = pstate =>
pstate.width = width;
pstate.height = height;
console.log('time', time);
// Y
const yOffsetMax = (numLanes + 2) * 2 * yStep;
if (yOffsetMax < 0) {
@ -21,7 +17,7 @@ const genResizeHandler = pstate =>
const xScaleMin = pstate.xScaleMin = 0.001;
pstate.xScale = (xScale < xScaleMin) ? xScaleMin : xScale;
xOffsetUpdate(pstate, xOffset);
xOffsetUpdate(pstate, () => xOffset);
};
module.exports = genResizeHandler;
export default genResizeHandler;

View File

@ -1,5 +1,3 @@
'use strict';
const getElement = divName => {
if (typeof divName === 'string') {
const c = document.getElementById(divName);
@ -11,6 +9,6 @@ const getElement = divName => {
return divName;
};
module.exports = getElement;
export default getElement;
/* eslint-env browser */

View File

@ -1,6 +1,4 @@
'use strict';
const format = require('./format.js');
import format from './format';
const getLabel = (lane) => {
if (typeof lane !== 'object') {
@ -31,4 +29,4 @@ const getLabel = (lane) => {
};
};
module.exports = getLabel;
export default getLabel;

View File

@ -1,8 +1,6 @@
'use strict';
import lister from './lister';
const lister = require('./lister.js');
const getListing = async (readers) => {
async function getListing(readers) {
let listing = [];
const r = readers.find(reader => reader.ext === 'lst');
if (r) {
@ -21,6 +19,6 @@ const getListing = async (readers) => {
}
}
return listing;
};
}
module.exports = getListing;
export default getListing;

View File

@ -1,5 +1,3 @@
'use strict';
const getT = (x, pstate) => {
const {xOffset, xScale, tgcd } = pstate;
return Math.round((x / xScale) - (xOffset / xScale)) * tgcd;
@ -10,4 +8,4 @@ const getT = (x, pstate) => {
// (t / tgcd) * xScale / 2 + (xOffset * width / 2) = x;
};
module.exports = getT;
export default getT;

View File

@ -1,6 +1,4 @@
'use strict';
const getX = (pstate, time) =>
time * pstate.xScale + pstate.xOffset;
module.exports = getX;
export default getX;

View File

@ -1,5 +1,3 @@
'use strict';
// Fletcher Style checksum
const hash = str => {
@ -12,4 +10,4 @@ const hash = str => {
return (sum2 ^ sum1 ^ (sum2 >> 5) ^ (sum1 >> 5)) % 36;
};
module.exports = hash;
export default hash;

View File

@ -1,27 +1,28 @@
'use strict';
import getElement from './get-element';
import getListing from './get-listing';
import domContainer from './dom-container';
import pluginRenderValues from './plugin-render-values';
import pluginRenderTimeGrid from './plugin-render-time-grid';
import keyEvent from './keyEvent';
import mountTree from './mount-tree';
import genKeyHandler from './gen-key-handler';
import genOnWheel from './gen-on-wheel';
import xOffsetUpdate from './x-offset-update';
import getX from './get-x';
import getT from './get-t';
const getElement = require('./get-element.js');
const getListing = require('./get-listing.js');
const domContainer = require('./dom-container.js');
const pluginRenderValues = require('./plugin-render-values.js');
const pluginRenderTimeGrid = require('./plugin-render-time-grid.js');
const keyBindo = require('./key-bindo.js');
const mountTree = require('./mount-tree.js');
const genKeyHandler = require('./gen-key-handler.js');
const genOnWheel = require('./gen-on-wheel.js');
const xOffsetUpdate = require('./x-offset-update.js');
const getX = require('./get-x.js');
const getT = require('./get-t.js');
exports.getListing = getListing;
exports.getElement = getElement;
exports.domContainer = domContainer;
exports.pluginRenderValues = pluginRenderValues;
exports.pluginRenderTimeGrid = pluginRenderTimeGrid;
exports.keyBindo = keyBindo;
exports.mountTree = mountTree;
exports.genKeyHandler = genKeyHandler;
exports.genOnWheel = genOnWheel;
exports.xOffsetUpdate = xOffsetUpdate;
exports.getX = getX;
exports.getT = getT;
export {
getListing,
getElement,
domContainer,
pluginRenderValues,
pluginRenderTimeGrid,
keyEvent,
mountTree,
genKeyHandler,
genOnWheel,
xOffsetUpdate,
getX,
getT
};

View File

@ -1,86 +0,0 @@
'use strict';
const xOffsetUpdate = require('./x-offset-update.js');
const xScaleUpdate = require('./x-scale-update.js');
const yScroll = delta => (pstate, cm) => {
const info = cm.getScrollInfo();
cm.scrollTo(null, info.top + info.clientHeight * delta);
return false;
};
const pluso = {
desc: 'Zoom in time',
fn: pstate => xScaleUpdate(pstate, 10 / 9 * pstate.xScale)
};
const minuso = {
desc: 'Zoom out time',
fn: pstate => xScaleUpdate(pstate, 9 / 10 * pstate.xScale)
};
const fullo = {
desc: 'All of time',
fn: pstate => xScaleUpdate(pstate, pstate.xScaleMin)
};
const scroll = {
left: {
desc: 'Scroll into the past',
fn: pstate => xOffsetUpdate(pstate, pstate.xOffset + pstate.time)
},
right: {
desc: 'Scroll into the future',
fn: pstate => xOffsetUpdate(pstate, pstate.xOffset - pstate.time)
},
up: {
desc: 'scroll up',
fn: yScroll(-.1)
},
down: {
desc: 'scroll down',
fn: yScroll(.1)
}
};
const editable = {
desc: 'Toggle edit mode',
fn: (pstate, cm) => {
console.log('editable', pstate, cm);
}
};
module.exports = {
// Alt + <, >. left / right
'Alt+,': scroll.left,
'Alt+.': scroll.right,
// Alt + [ ] home / end
'Alt+[': { desc: 'Jump to beginning of time', fn: pstate => xOffsetUpdate(pstate, pstate.sidebarWidth) }, // Home
'Alt+]': { desc: 'Jump to end time', fn: pstate => xOffsetUpdate(pstate, pstate.width - pstate.xScale * pstate.time) }, // End
// ALT + - +
'Alt+=': pluso, // '+': pluso, '=': pluso,
'Alt+-': minuso, // '-': minuso, '_': minuso,
'Alt+0': fullo, // 'Shift+f': fullo, F: fullo, 'Shift+F': fullo,
'Alt+/': editable,
// wheel
'icon:scrollLeft': scroll.left,
'icon:scrollRight': scroll.right,
'Shift+icon:scrollUp': scroll.left,
'Shift+icon:scrollDown': scroll.right,
'Ctrl+icon:scrollUp': pluso,
'Ctrl+icon:scrollDown': minuso,
// CAN'T DO: Alt + e, d, f, l
// ArrowUp: scroll.up, 'Shift+ArrowUp': scroll.up,
// ArrowDown: scroll.down, 'Shift+ArrowDown': scroll.down,
// PageUp: {desc: 'scroll page up', fn: yScroll(-1)},
// PageDown: {desc: 'scroll page down', fn: yScroll(1)},
nop: { fn: () => false }
};

View File

@ -0,0 +1,102 @@
import { globalSetting } from '../global';
import xOffsetUpdate from './x-offset-update';
import yOffsetUpdate from './y-offset-update';
import xScaleUpdate from './x-scale-update';
const xScaleLevels = {
1: 10 / 9,
2: 10 / 7,
3: 10 / 6,
4: 10 / 5,
5: 10 / 4
};
const xOffsetLevel = {
1: 5,
2: 4,
3: 3,
4: 1,
5: 0.5
};
const yOffsetLevel = {
1: 20,
2: 40,
3: 80,
4: 160,
5: 320
};
const pluso = {
desc: 'Zoom in time',
fn: pstate => xScaleUpdate(pstate, () => pstate.xScale * xScaleLevels[globalSetting.HorizontalScalingRatio])
};
const minuso = {
desc: 'Zoom out time',
fn: pstate => xScaleUpdate(pstate, () => pstate.xScale / xScaleLevels[globalSetting.HorizontalScalingRatio])
};
const fullo = {
desc: 'All of time',
fn: pstate => xScaleUpdate(pstate, () => pstate.xScaleMin)
};
const scroll = {
left: {
desc: 'Scroll into the past',
fn: pstate => xOffsetUpdate(pstate, () => pstate.xOffset + pstate.time / xOffsetLevel[globalSetting.HorizontalRollRatio])
},
right: {
desc: 'Scroll into the future',
fn: pstate => xOffsetUpdate(pstate, () => pstate.xOffset - pstate.time / xOffsetLevel[globalSetting.HorizontalRollRatio])
},
up: {
desc: 'scroll up',
fn: pstate => yOffsetUpdate(pstate, () => pstate.yOffset - yOffsetLevel[globalSetting.VerticalRollRario])
},
down: {
desc: 'scroll down',
fn: pstate => yOffsetUpdate(pstate, () => pstate.yOffset + yOffsetLevel[globalSetting.VerticalRollRario])
}
};
const editable = {
desc: 'Toggle edit mode',
fn: (pstate, cm) => {
console.log('editable', pstate, cm);
}
};
export default {
// Alt + <, >. left / right
// 'Alt+,': scroll.left,
// 'Alt+.': scroll.right,
// // Alt + [ ] home / end
// 'Alt+[': { desc: 'Jump to beginning of time', fn: pstate => xOffsetUpdate(pstate, pstate.sidebarWidth) }, // Home
// 'Alt+]': { desc: 'Jump to end time', fn: pstate => xOffsetUpdate(pstate, pstate.width - pstate.xScale * pstate.time) }, // End
// // ALT + - +
// 'Alt+=': pluso, // '+': pluso, '=': pluso,
// 'Alt+-': minuso, // '-': minuso, '_': minuso,
// 'Alt+0': fullo, // 'Shift+f': fullo, F: fullo, 'Shift+F': fullo,
// wheel
scrollLeft: scroll.left,
scrollRight: scroll.right,
scrollUp: scroll.up,
scrollDown: scroll.down,
'Shift+icon:scrollUp': scroll.left,
'Shift+icon:scrollDown': scroll.right,
'Ctrl+icon:scrollUp': pluso,
'Ctrl+icon:scrollDown': minuso,
nop: { fn: () => false }
};

View File

@ -1,6 +1,4 @@
'use strict';
module.exports = () => {
export default () => {
const trace = {};
let tail = '';
return {

View File

@ -1,5 +1,3 @@
'use strict';
const defaultElemento = {
container: ['div', { class: 'vcd-container', id: 'vcd-container' }],
grid: ['div', { class: 'vcd-vline', id: 'vcd-vline' }],
@ -43,9 +41,9 @@ const createContainer = (els, layers) => {
return els.container;
};
exports.defaultElemento = defaultElemento;
exports.defaultLayers = defaultLayers;
exports.createElemento = createElemento;
exports.createContainer = createContainer;
/* eslint-env browser */
export default {
defaultElemento,
defaultLayers,
createElemento,
createContainer
};

View File

@ -1,7 +1,6 @@
'use strict';
import onml from 'onml';
const onml = require('onml');
const format = require('./format');
import format from './format';
const getElement = divName => {
if (typeof divName === 'string') {

View File

@ -1,10 +1,8 @@
'use strict';
import genSVG from 'onml/gen-svg.js';
import stringify from 'onml/stringify.js';
const genSVG = require('onml/gen-svg.js');
const stringify = require('onml/stringify.js');
const formatTime = require('./format-time.js');
const getT = require('./get-t.js');
import formatTime from './format-time.js';
import getT from './get-t.js';
const round10 = n =>
([
@ -66,4 +64,4 @@ const pluginRenderTimeGrid = (desc, pstate, els) => {
els.grid.innerHTML = stringify(ml);
};
module.exports = pluginRenderTimeGrid;
export default pluginRenderTimeGrid;

View File

@ -1,8 +1,6 @@
'use strict';
import renderValues from './render-values';
const renderValues = require('./render-values.js');
function pluginRenderValues(desc, pstate, els) {
export default function pluginRenderValues(desc, pstate, els) {
const gen = renderValues(desc, pstate);
for (let i = 0; i < 1e6; i++) {
const iter = gen.next();
@ -12,5 +10,3 @@ function pluginRenderValues(desc, pstate, els) {
}
}
}
module.exports = pluginRenderValues;

View File

@ -1,10 +1,8 @@
'use strict';
import genSVG from 'onml/gen-svg.js';
import stringify from 'onml/stringify.js';
const genSVG = require('onml/gen-svg.js');
const stringify = require('onml/stringify.js');
const formatTime = require('./format-time.js');
const { globalLookup } = require('../global');
import formatTime from './format-time';
import { globalLookup } from '../global';
const renderCursor = (cfg, pstate) => {
const { xmargin, fontWidth, fontHeight } = cfg;
@ -58,4 +56,4 @@ const renderCursor = (cfg, pstate) => {
return stringify(genSVG(2 * xmargin, height).concat(body));
};
module.exports = renderCursor;
export default renderCursor;

View File

@ -40,7 +40,7 @@ void main() {
vec2 shift = shifts[pos.y];
vec2 widthShift = widthShifts[pos.w];
gl_Position = vec4(
float(pos.x) * scale.x + offset.x + float(widthShift.x),
float(pos.x) * scale.x + offset.x + float(widthShift.x) + shift.y,
float(shift.x) * scale.y + offset.y + float(widthShift.y),
1, 1
);

View File

@ -28,11 +28,11 @@ const screenWidthPixel = window.screen.width * getRatio() / 100;
const gl_Colors = new Float32Array([
0, 0, 0, 0, // 0: 空
0, 0, 1, 1, // 1: 高阻态 Z
0, 0, 1, 1, // 1: 未知态 X
0.2, 0.847, 0.1, 1, // 2: value = 0 用于 width = 1 的信号
0.2, 0.847, 0.1, 1, // 3: value = 1 用于 width = 1 的信号
0.9, 0.2, 0.2, 1, // 4: 未知态 X
.5, 1, 1, 1, // 5: vec 用于 width > 1 的信号
0.9, 0.2, 0.2, 1, // 4: 高阻态 Z
0.486, 0.302, 1., 1, // 5: vec 用于 width > 1 的信号
1, 1, 0, 1, // 6: yellow
1, 0, 1, 1, // 7: strange purple
@ -41,23 +41,38 @@ const gl_Colors = new Float32Array([
0, 1, 1, .5, // 9: (h H) weak 1
1, 0, 0, .5, // 10: (w W) weak unknown
0, 0, 1, 0.1, // 11: 高阻态 Z 遮罩
0, 0, 1, 0.1, // 11: 未知态 X 遮罩
0.2, 0.847, 0.1, 0.1, // 12: value = 0 遮罩
0.2, 0.847, 0.1, 0.1, // 13: value = 1 遮罩
0.9, 0.2, 0.2, 0.1, // 14: 未知态 X 遮罩
.5, 1, 1, 0.1 // 15: vec 遮罩
0.9, 0.2, 0.2, 0.1, // 14: 高阻态 Z 遮罩
0.486, 0.302, 1., 0.1 // 15: vec 遮罩
]);
// 控制方向
// 特殊偏移量
// 第一列 Y 第二列 保留
const gl_Shifts = new Float32Array([ // 14
0, 0, // 0
1, -1, // 1
1, 0, // 1
1, 0, // 2
1, 1, // 3
-1, -1, // 4
1, 0, // 3
-1, 0, // 4
-1, 0, // 5
-1, 1 // 6
-1, 0 // 6
]);
// 为了满足 vec 类型的波形的开头和结尾的那个小小的内嵌的、不受scale影响的值
// 第一列 Y 第二列 X 在所有计算完成后的额外偏移量
const barShift = 0.005;
const gl_Shifts_for_bar = new Float32Array([
0, 0, // 0
1, barShift, // 1
1, -barShift, // 2
1, 0, // 3
-1, barShift, // 4
-1, -barShift, // 5
-1, 0 // 6
]);
const gl_Shifts_map = new Map();
@ -78,7 +93,6 @@ const gl_WidthShifts = new Float32Array([
widthShift, widthShift // 7
]);
export {
getRatio,
gl_Colors,
@ -88,5 +102,7 @@ export {
gl_WidthShifts,
gl_Shifts_map,
screenWidthPixel,
screenHeightPixel
screenHeightPixel,
gl_Shifts_for_bar,
barShift
};

View File

@ -1,15 +1,13 @@
'use strict';
import tt from 'onml/tt.js';
import genSVG from 'onml/gen-svg.js';
import stringify from 'onml/stringify.js';
const tt = require('onml/tt.js');
const genSVG = require('onml/gen-svg.js');
const stringify = require('onml/stringify.js');
// const getPco = require('./get-pco.js');
const water = require('./water.js');
const bracer = require('./bracer.js');
const vline = require('./vline.js');
const getX = require('./get-x.js');
const vlineStylo = require('./vline-stylo.js');
const getLabel = require('./get-label.js');
import water from './water.js';
import bracer from './bracer';
import vline from './vline';
import getX from './get-x';
import vlineStylo from './vline-stylo';
import getLabel from './get-label';
const defs = ['defs',
['linearGradient', { id: 'valid' },
@ -53,7 +51,7 @@ function* renderValues(desc, pstate) {
const ml = genSVG(width, height - topBarHeight - botBarHeight);
let ifirst = 0;
for (let i = 0; i < ilen; i += 1) {
for (let i = 0; i < ilen; ++ i) {
const lane = view[i];
if (lane && (lane.name || lane.kind)) {
if (i > iskip) {
@ -78,7 +76,7 @@ function* renderValues(desc, pstate) {
} else if (lane && lane.ref) {
const chango = desc.chango[lane.ref];
if (chango && chango.kind === 'vec') {
const mLane = ['g', tt(0, Math.round((i - (iskip - ifirst) + .8) * yStep))];
const mLane = ['g', tt(0, Math.round((i - (iskip - ifirst) + 0.1) * yStep))];
const { wave } = chango;
const jlen = wave.length;
@ -131,5 +129,5 @@ function* renderValues(desc, pstate) {
return stringify(ml);
}
module.exports = renderValues;
export default renderValues;
/* eslint complexity: [1, 55] */

View File

@ -1,10 +1,16 @@
'use strict';
import { ElLoading } from 'element-plus';
import { globalSetting, globalStyle } from '../global';
import i18n from '../../i18n';
const { t } = i18n.global;
import { gl_Colors, gl_Shifts, gl_Shifts_for_bar, gl_Shifts_map, gl_WidthShifts, barShift, getRatio, screenHeightPixel } from './render-utils.js';
import { vertexShader, fragmentShader } from './render-shader.js';
const { gl_Colors, gl_Shifts, gl_Shifts_map, gl_WidthShifts } = require('./render-utils.js');
const { vertexShader, fragmentShader } = require('./render-shader.js');
// const { ChangoItem } = require('./types.d.ts');
class WebGL2WaveRender {
/**
*
@ -43,6 +49,12 @@ class WebGL2WaveRender {
* @param { Array } plugins
*/
constructor(elements, globalLookup, pstate, plugins) {
const loading = ElLoading.service({
lock: true,
text: t('loading'),
background: 'rgba(0, 0, 0, 0.7)'
});
const canvas = document.createElement('canvas');
elements.view.replaceChildren(canvas);
@ -62,9 +74,10 @@ class WebGL2WaveRender {
const { lineVerticesMap, maskVerticesMap } = this.makeVertex();
this.lineVerticesMap = lineVerticesMap;
this.maskVerticesMap = maskVerticesMap;
this.initData();
this.animationHandler = undefined;
loading.close();
}
/**
@ -112,19 +125,42 @@ class WebGL2WaveRender {
const time = globalLookup.time;
const lineVerticesMap = new Map();
const maskVerticesMap = new Map();
if (globalSetting.prerender) {
for (const id of Reflect.ownKeys(globalLookup.chango)) {
const { lineVertices, maskVertices } = this.makeVertexByID(id);
lineVerticesMap.set(id, lineVertices);
maskVerticesMap.set(id, maskVertices);
}
}
return { lineVerticesMap, maskVerticesMap };
}
/**
*
* @param {string} id
* @returns {{
* lineVertices: Uint32Array
* maskVertices: Uint32Array
* }}
*/
makeVertexByID(id) {
const globalLookup = this.globalLookup;
const time = globalLookup.time;
const signalItem = globalLookup.chango[id];
const { kind, wave } = signalItem;
if (kind === 'bit') {
const { lineVertices, maskVertices } = this.makeBitVertex(wave, time);
lineVerticesMap.set(id, lineVertices);
maskVerticesMap.set(id, maskVertices);
return { lineVertices, maskVertices };
} else if (kind === 'vec') {
// const vertices = this.makeVecVertex(wave, time);
// lineVerticesMap.set(id, vertices);
const { lineVertices, maskVertices } = this.makeVecVertex(wave, time);
return { lineVertices, maskVertices };
}
return {
lineVertices: undefined,
maskVertices: undefined
}
return { lineVerticesMap, maskVerticesMap };
}
@ -198,12 +234,25 @@ class WebGL2WaveRender {
const r2 = [x1, gl_Shifts_map.get(y1), color, wsIndex];
const r3 = [x2, gl_Shifts_map.get(y1), color, wsIndex];
const r4 = [x2, gl_Shifts_map.get(y2), color, wsIndex];
return this.makeQuadVertices(r1, r2, r3, r4);
}
/**
*
* @param {number[]} p1
* @param {number[]} p2
* @param {number[]} p3
* @param {number[]} p4
* @returns {number[]}
*/
makeQuadVertices(p1, p2, p3, p4) {
return [
...r1, ...r2, ...r3,
...r1, ...r3, ...r4,
...p1, ...p2, ...p3,
...p1, ...p3, ...p4
]
}
/**
*
* @param {Array<string | number>} wave
@ -329,81 +378,114 @@ class WebGL2WaveRender {
}
if (debug) {
console.log(perspectivePoints);
console.log(pointNum);
console.log(lineVertices);
}
const Uint32lineVertices = new Uint32Array(lineVertices);
const Uint32maskVertices = new Uint32Array(maskVertices);
// if (debug) {
// console.log(perspectivePoints);
// console.log(pointNum);
// console.log(lineVertices);
// }
return {
lineVertices : Uint32lineVertices,
maskVertices : Uint32maskVertices
lineVertices : new Uint32Array(lineVertices),
maskVertices : new Uint32Array(maskVertices)
};
}
/**
*
* @param {Array<string | number>} wave
* @param { number } time
* @returns {Uint32Array}
* @returns {{
* lineVertices: Uint32Array
* maskVertices: Uint32Array
* }}
*/
makeVecVertex(wave, time) {
const vertices = [];
makeVecVertex(wave, time, debug = false) {
const lineVertices = [];
const maskVertices = [];
const length = wave.length;
for (let i = 0; i < length; ++ i) {
const [t1, val, msk] = wave[i];
const [t1, val, mask] = wave[i];
const t2 = (i === (length - 1)) ? time : wave[i + 1][0];
// t1(val) --- t2(val)
// 详见 设计图 ./design/webgl.drawio makeVecVertex原理 sheet
// 此处的 y 不是 y 的索引,详见 gl_Shifts_for_bar 的设计
const p0 = {x: t1, y: 0};
const p1 = {x: t2, y: 0};
const a0 = {x: t1, y: 4};
const a1 = {x: t2, y: 5};
const a2 = {x: t1, y: 1};
const a3 = {x: t2, y: 2};
if (msk) {
vertices.push(
t1, 0, 0,
t2, 0, 0,
t2, 0, 4,
t2, 4, 4,
t1, 6, 4,
t1, 0, 4,
t1, 3, 4,
t2, 1, 4,
t2, 0, 4
const color = mask ? 4 : 5;
const points = [ a1, p1, a3, a2, p0, a0 ];
const wsIndice = [ 1, 2, 3, 5, 6, 7 ];
for (let i = 0; i < 6; ++ i) {
const prePoint = points[i];
const nextPoint = points[(i + 1) % 6];
const preWsIndex = wsIndice[i];
const nextWsIndex = wsIndice[(i + 1) % 6];
const quadVertices = this.makeQuadVertices(
[prePoint.x, prePoint.y, color, preWsIndex],
[prePoint.x, prePoint.y, color, (preWsIndex + 4) % 8],
[nextPoint.x, nextPoint.y, color, (nextWsIndex + 4) % 8],
[nextPoint.x, nextPoint.y, color, nextWsIndex],
);
} else {
vertices.push(
t1, 0, 0,
t2, 0, 0,
t2, 0, 5,
t2, 4, 5,
t1, 6, 5,
t1, 0, 5,
t1, 3, 5,
t2, 1, 5,
t2, 0, 5
lineVertices.push(...quadVertices);
}
const maskTriangles = [
[3, 4, 5],
[5, 0, 3],
[0, 3, 2],
[0, 1, 2]
];
for (const triangleIndice of maskTriangles) {
const [i1, i2, i3] = triangleIndice;
const point1 = points[i1];
const point2 = points[i2];
const point3 = points[i3];
maskVertices.push(
point1.x, point1.y, color + 10, wsIndice[i1],
point2.x, point2.y, color + 10, wsIndice[i2],
point3.x, point3.y, color + 10, wsIndice[i3]
);
}
}
return new Uint32Array(vertices);
if (debug) {
console.log(lineVertices);
}
initData() {
return {
lineVertices: new Uint32Array(lineVertices),
maskVertices: new Uint32Array(maskVertices)
};
}
/**
*
* @param {string} id
* @returns
*/
initVertice(id) {
const webglLocation = this.webglLocation;
const gl = webglLocation.gl;
const globalLookup = this.globalLookup;
const lineVerticesMap = this.lineVerticesMap;
const maskVerticesMap = this.maskVerticesMap;
const signalItem = this.globalLookup.chango[id];
for (const id of Reflect.ownKeys(globalLookup.chango)) {
const signalItem = globalLookup.chango[id];
const lineVertices = lineVerticesMap.get(id);
if (lineVertices === undefined) {
// console.warn(`无法找到 link 为 ${id} 的顶点数据`);
continue;
if (this.lineVerticesMap.get(id) === undefined) {
const { lineVertices, maskVertices } = this.makeVertexByID(id);
this.lineVerticesMap.set(id, lineVertices);
this.maskVerticesMap.set(id, maskVertices);
}
const lineVertices = this.lineVerticesMap.get(id);
const maskVertices = this.maskVerticesMap.get(id);
// 创建并设置 绘制wave轮廓 主体轮廓的 缓冲区、vao、顶点设置
const lineVertexBuffer = gl.createBuffer();
@ -414,12 +496,6 @@ class WebGL2WaveRender {
gl.vertexAttribIPointer(webglLocation.pos, 4, gl.UNSIGNED_INT, 0, 0);
gl.enableVertexAttribArray(webglLocation.pos);
const maskVertices = maskVerticesMap.get(id);
if (maskVertices === undefined) {
continue;
}
// 创建并设置 绘制wave半透明遮罩层 主体轮廓的 缓冲区、vao、顶点设置
const maskVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, maskVertexBuffer);
@ -430,11 +506,59 @@ class WebGL2WaveRender {
gl.enableVertexAttribArray(webglLocation.pos);
}
initData() {
if (globalSetting.prerender) {
for (const id of Reflect.ownKeys(this.globalLookup.chango)) {
this.initVertice(id);
}
}
const webglLocation = this.webglLocation;
const gl = webglLocation.gl;
gl.uniform4fv(webglLocation.colors, gl_Colors);
gl.uniform2fv(webglLocation.widthShifts, gl_WidthShifts);
gl.uniform2fv(webglLocation.shifts, gl_Shifts);
}
/**
*
* @param {Array<{
* index: number
* rgba: {
* red: number,
* green: number,
* blue: number,
* alpha: number
* }
* }>} updaters
* @param {{
* updateMask: boolean
* }} config
*/
updateGLColor(updaters, config) {
const webglLocation = this.webglLocation;
const gl = webglLocation.gl;
for (const updater of updaters) {
const startIndex = updater.index * 4;
const rgba = updater.rgba;
gl_Colors[startIndex] = rgba.red;
gl_Colors[startIndex + 1] = rgba.green;
gl_Colors[startIndex + 2] = rgba.blue;
gl_Colors[startIndex + 3] = rgba.alpha;
if (config.updateMask) {
const maskIndex = (updater.index + 10) * 4;
gl_Colors[maskIndex] = rgba.red;
gl_Colors[maskIndex + 1] = rgba.green;
gl_Colors[maskIndex + 2] = rgba.blue;
}
}
gl.uniform4fv(webglLocation.colors, gl_Colors);
this.render();
}
render() {
if (this.animationHandler !== undefined) {
cancelAnimationFrame(this.animationHandler);
@ -448,76 +572,131 @@ class WebGL2WaveRender {
const maskVerticesMap = this.maskVerticesMap;
const elements = this.elements;
const timeScaleHeight = parseInt(document.body.style.getPropertyValue('--time-scale-height').match(/\d+/)[0]);
const sidebarPadding = parseInt(document.body.style.getPropertyValue('--sidebar-padding').match(/\d+/)[0]);
const vcdRenderPadding = parseInt(document.body.style.getPropertyValue('--vcd-render-padding').match(/\d+/)[0]);
const canvasPaddingTop = timeScaleHeight + sidebarPadding - vcdRenderPadding;
// 更新 yDuty & yStep
// yStep: scale 之后的单个 wave 的容器高度需要和 displaySignalHeight + sideBarItemMargin 一样
// yDuty: scale 之后的单个 wave 的 padding 必须等于 sideBarItemMargin也就是 (1 - yDuty) * yStep = 2 * margin
const sidebarItemMargin = globalStyle.sideBarItemMargin;
this.animationHandler = window.requestAnimationFrame(() => {
const { width, height, xScale, xOffset, yOffset, yStep, yDuty } = this.pstate;
const canvasHeight = height - canvasPaddingTop;
const canvasWidth = width;
const pstate = this.pstate;
const plugins = this.plugins;
pstate.yStep = globalSetting.displaySignalHeight + globalStyle.sideBarItemMargin;
pstate.yDuty = (1 - 2 * globalStyle.sideBarItemMargin / this.pstate.yStep) * 0.9;
document.body.style.setProperty('--vcd-render-padding', pstate.topBarHeight + 'px');
const canvasHeight = pstate.height - pstate.topBarHeight - pstate.botBarHeight;
const canvasWidth = pstate.width;
// 默认 1594
canvas.width = canvasWidth;
// 默认 1260
canvas.height = canvasHeight;
let startTime = undefined;
// 默认执行一个 300 ms 的动画
const animationDuration = 300;
let animationHandler = this.animationHandler = requestAnimationFrame(drawWaves);
function linearAnimation(delta, oldVal, newVal) {
return (1 - delta) * oldVal + delta * newVal;
}
function cubicBezierAnimation(delta, oldVal, newVal) {
delta = 3 * (1 - delta) * (1 - delta) * delta + 3 * (1 - delta) * delta * delta + delta * delta * delta;
return (1 - delta) * oldVal + delta * newVal;
}
function renderOneFrame(animationDelta) {
// 考虑设置线性动画的变量 xScale, xOffset, yOffset, yStep, yDuty
const xScale = cubicBezierAnimation(animationDelta, pstate.oldXScale, pstate.xScale);
const xOffset = cubicBezierAnimation(animationDelta, pstate.oldXOffset, pstate.xOffset);
const yOffset = cubicBezierAnimation(animationDelta, pstate.oldYOffset, pstate.yOffset);
const yStep = cubicBezierAnimation(animationDelta, pstate.oldYStep, pstate.yStep);
const yDuty = cubicBezierAnimation(animationDelta, pstate.oldYDuty, pstate.yDuty);
// 设置 glsl 变量
gl.uniform2f(webglLocation.scale,
2 * xScale / canvasWidth,
yStep * yDuty / canvasHeight
);
console.log(yStep, yDuty, canvasHeight);
const scaleX = 2 * xScale / canvasWidth;
const scaleY = yStep * yDuty / canvasHeight;
gl.uniform2f(webglLocation.scale, scaleX, scaleY);
// 设置 webgl 和 canvas 大小位置一致
gl.viewport(0, 0, canvasWidth, canvasHeight);
// 清楚颜色缓冲区,也就是删除上一次的渲染结果
gl.clear(gl.COLOR_BUFFER_BIT);
// 根据 globalLookup 当前激活的需要渲染的信号进行渲染
let index = 0;
for (const signal of globalLookup.currentWires) {
const wave = globalLookup.chango[signal.link].wave;
const id = signal.link;
const wave = globalLookup.chango[id].wave;
// this.makeBitVertex(wave, globalLookup.time, true);
const signalItem = globalLookup.chango[signal.link];
// this.makeVecVertex(wave, globalLookup.time, true);
const signalItem = globalLookup.chango[id];
if (!signalItem) {
return;
}
// TODO: 将此处的 offset 计算中的参数和 globalSetting 的数字形成关联
gl.uniform2f(webglLocation.offset,
(2 * xOffset / width) - 1,
(2 * yOffset - 2 * yStep * (index + .7)) / canvasHeight + 1
);
console.log('offset y', (2 * yOffset - 2 * yStep * (index + .7)) / canvasHeight + 1);
const offsetX = 2 * xOffset / canvasWidth - 1;
const offsetY = 2 * (yOffset - yStep * index) / canvasHeight + 1;
gl.uniform2f(webglLocation.offset, offsetX, offsetY);
// 根据 lineVao 进行绘制
const lineVertices = lineVerticesMap.get(signal.link);
const maskVertices = maskVerticesMap.get(signal.link);
if (lineVerticesMap.get(id) === undefined) {
this.initVertice(id);
}
const lineVertices = lineVerticesMap.get(id);
const maskVertices = maskVerticesMap.get(id);
if (signal.size === 1) {
// 如果是 width 为 1 的
gl.uniform2fv(webglLocation.shifts, gl_Shifts);
gl.bindVertexArray(signalItem.lineVao);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / 4);
``
gl.bindVertexArray(signalItem.maskVao);
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / 4);
} else {
// 如果是 width 大于 1 的
gl.drawArrays(gl.LINE_STRIP, 0, lineVertices.length / 4);
gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar);
gl.bindVertexArray(signalItem.lineVao);
gl.drawArrays(gl.TRIANGLES, 0, lineVertices.length / 4);
gl.bindVertexArray(signalItem.maskVao);
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / 4);
}
index ++;
}
this.plugins.map(fn => fn(globalLookup, this.pstate, elements));
this.animationHandler = undefined;
});
plugins.map(fn => fn(globalLookup, pstate, elements));
}
function drawWaves(now) {
if (startTime === undefined) {
startTime = now;
} else {
const pastTime = now - startTime;
const animationDelta = globalSetting.renderAnimation ? Math.min(pastTime / animationDuration, 1) : 1;
renderOneFrame(animationDelta);
// 达到 1 时说明线性动画时间到了,退出即可
if (animationDelta >= 1) {
cancelAnimationFrame(animationHandler);
// 更新状态变量
pstate.oldXOffset = pstate.xOffset;
pstate.oldYOffset = pstate.yOffset;
pstate.oldXScale = pstate.xScale;
pstate.oldYStep = pstate.yStep;
pstate.oldYDuty = pstate.yDuty;
return;
}
}
// 进入下一帧
requestAnimationFrame(drawWaves);
}
}
module.exports = WebGL2WaveRender;
}
export default WebGL2WaveRender;

View File

@ -1,6 +1,4 @@
'use strict';
function* sampler (wave) {
export default function* sampler(wave) {
let t1, v0, v1;
[t1, v1] = wave[0]; // initial state
let t = 0;
@ -18,5 +16,3 @@ function* sampler (wave) {
yield v1;
}
}
module.exports = sampler;

View File

@ -1,6 +1,4 @@
'use strict';
const getT = require('./get-t.js');
import getT from './get-t';
function* surferer(wave, pstate) {
const { sidebarWidth, width } = pstate;
@ -21,4 +19,4 @@ function* surferer (wave, pstate) {
}
}
module.exports = surferer;
export default surferer;

View File

@ -1,5 +1,3 @@
'use strict';
const vlineStylo = {
w: {h:0, l:100}, // w
r: {h:10, l:45}, // r
@ -11,4 +9,4 @@ const vlineStylo = {
v: {h:280, l:55} // v
};
module.exports = vlineStylo;
export default vlineStylo;

View File

@ -1,8 +1,7 @@
'use strict';
import onml from 'onml';
const getX = require('./get-x.js');
const onml = require('onml');
const vlineStylo = require('./vline-stylo.js');
import getX from './get-x.js';
import vlineStylo from './vline-stylo.js';
/* Zones
1 2 3
@ -12,7 +11,7 @@ const vlineStylo = require('./vline-stylo.js');
const vline = (lane, pstate, i) => {
const { width, height, timescale, yStep, yOffset, topBarHeight, botBarHeight } = pstate;
const y = (i + .7) * yStep - yOffset;
const y = i * yStep - yOffset;
const yMax = height - topBarHeight - botBarHeight;
return lane.vlines.map(vline => {
@ -54,4 +53,4 @@ const vline = (lane, pstate, i) => {
});
};
module.exports = vline;
export default vline;

View File

@ -1,12 +1,12 @@
'use strict';
// PC based pipeline view
const tt = require('onml/tt.js');
const getX = require('./get-x.js');
const surferer = require('./surferer.js');
const sampler = require('./sampler.js');
const hash = require('./hash.js');
import tt from 'onml/tt.js';
import getX from './get-x';
import surferer from './surferer';
import sampler from './sampler';
import hash from './hash';
const pushBrick = (listing, pco, v, name, label, t) => {
let pc = v;
@ -110,7 +110,7 @@ const water = (lane, desc, pstate) => {
}
// row header
mLane.push(['text', {class: 'pc', 'xml:space': 'preserve', y: Math.round(yStep * .7)},
mLane.push(['text', { class: 'pc', 'xml:space': 'preserve', y: Math.round(yStep) },
['tspan', { class: 'pc-addr' }, parseInt(pc, 10).toString(16).padStart(12, ' ')],
['tspan', { class: 'pc-opcode' }, pcd.op.padStart(9, ' ')],
' ',
@ -137,4 +137,4 @@ const water = (lane, desc, pstate) => {
};
module.exports = water;
export default water;

View File

@ -1,14 +1,11 @@
'use strict';
const xOffsetUpdate = (pstate, nextOffsetX) => {
const xOffsetUpdate = (pstate, nextOffsetXFn) => {
let nextOffsetX = nextOffsetXFn();
const { width, xOffset, xScale, time, sidebarWidth } = pstate;
// console.log('input offset', nextOffsetX);
// console.log('xScale', xScale);
const maxOffsetX = width - xScale * time + 2000; // maximum offset
const maxOffsetX = width + xScale * time * 1.0; // maximum offset
nextOffsetX = Math.min(nextOffsetX, maxOffsetX);
const minOffsetX = 0; // minimum offset
const minOffsetX = - width - xScale * time * 1.2; // minimum offset
nextOffsetX = Math.max(nextOffsetX, minOffsetX);
// console.log('max offset', maxOffsetX);
@ -19,8 +16,9 @@ const xOffsetUpdate = (pstate, nextOffsetX) => {
return false; // exit without scroll
}
pstate.oldXOffset = pstate.xOffset;
pstate.xOffset = nextOffsetX;
return true;
};
module.exports = xOffsetUpdate;
export default xOffsetUpdate;

View File

@ -1,8 +1,14 @@
'use strict';
import xOffsetUpdate from './x-offset-update';
const xOffsetUpdate = require('./x-offset-update.js');
const xScaleUpdate = (pstate, xScaleNext) => {
/**
*
* @param {{
* xScale: number
* }} pstate
* @returns
*/
function xScaleUpdate(pstate, xScaleNextFn) {
let xScaleNext = xScaleNextFn();
const { xOffset, xCursor, xScale, xScaleMin, xScaleMax } = pstate;
xScaleNext = (xScaleNext > xScaleMax) ? xScaleMax : xScaleNext;
@ -14,10 +20,12 @@ const xScaleUpdate = (pstate, xScaleNext) => {
if (xScaleNext === xScale) {
return false; // exit without scale change
}
pstate.oldXScale = pstate.xScale;
pstate.xScale = xScaleNext;
xOffsetUpdate(pstate, xCursor - (xCursor - xOffset) * xScaleNext / xScale);
xOffsetUpdate(pstate, () => xCursor - (xCursor - xOffset) * xScaleNext / xScale);
return true;
};
}
module.exports = xScaleUpdate;
export default xScaleUpdate;

View File

@ -0,0 +1,30 @@
import { globalStyle, globalLookup } from '../global';
const yOffsetUpdate = (pstate, nextOffsetYFn) => {
let nextOffsetY = nextOffsetYFn();
const { width, xOffset, xScale, time, sidebarWidth } = pstate;
const currentRenderHeight = globalLookup.currentWires.size * pstate.yStep;
const canvasHeight = pstate.height - pstate.topBarHeight - pstate.botBarHeight;
console.log(currentRenderHeight, canvasHeight);
const maxOffsetX = Math.max(-40, currentRenderHeight - canvasHeight); // maximum offset
nextOffsetY = Math.min(nextOffsetY, maxOffsetX);
const minOffsetX = -40; // minimum offset
nextOffsetY = Math.max(nextOffsetY, minOffsetX);
if (nextOffsetY === xOffset) {
return false; // exit without scroll
}
console.log('next offset y', nextOffsetY);
pstate.oldYOffset = pstate.yOffset;
pstate.yOffset = nextOffsetY;
// 这玩意儿初始设置 -40 的偏移,当作 padding-top
globalStyle.yOffset = nextOffsetY + 40;
return true;
};
export default yOffsetUpdate;

View File

@ -3,7 +3,13 @@
"signal": "Signals",
"search-signal": "Search Signal",
"language-setting": "Language",
"wheel-zoom-ratio": "Wheel Zoom Level",
"horizontal-scaling-ratio": "Horizontal Scaling Level",
"horizontal-scaling-ratio-description": "There are a total of 5 gear, the higher the gear, <br/>the higher the magnification when ctrl + mouse wheel zoomin",
"horizontal-roll-ratio": "Horizontal Roll Level",
"horizontal-roll-ratio-description": "There are 5 gear positions in total. The higher the gear position, <br/>the larger the step length of the left and right sliding waveform timeline",
"vertical-roll-ratio": "Vertical Roll Level",
"vertical-roll-ratio-description": "There are 5 gear positions in total. The higher the gear position, <br/>the larger the step length of the up and down sliding waveform timeline",
"search-setting": "Search",
"search-case-sensitivity": "Case Sensitivity",
@ -21,6 +27,31 @@
"appearance-setting": "Appearance",
"display-wave-height": "Height of Wave Track",
"display-signal-info-scope": "Info displayed in sidebar",
"display-signal-info-scope.width": "width",
"display-signal-info-scope.parent": "parent",
"wavecolor": "color of wave",
"wavecolor.normal-bit": "wave of one width",
"wavecolor.normal-vec": "wave of more than one width",
"wavecolor.high-impedance": "wave of high impedance",
"wavecolor.unknown": "wave of unknown",
"operation-setting": "Operation",
"render-setting": "Render",
"prerender": "prerender",
"prerender-description": "Prerendering will make rendering faster, but will take up extra memory <br/> If your computer has more than 10 GB of memory, we recommend you turn it on.",
"render-animation": "enable rendering animation",
"usermanual": "User Manual",
"usermanual.left-right-scroll.title": "<span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-up-down\"/>",
"usermanual.left-right-scroll.caption": "move up and down",
"usermanual.up-down-scroll.title": "<span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-left-right\"/> / <span class=\"iconfont icon-shift\"/> + <span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-up-down\"/>",
"usermanual.up-down-scroll.caption": "move left and right",
"usermanual.xscale.title": "<span class=\"iconfont icon-ctrl\"/> + <span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-up-down\"/>",
"usermanual.xscale.caption": "scale along x axis",
"loading": "loading",
"current-version": "current version",
"copyright": "The copyright of this software belongs to <a href=\"https://github.com/Digital-EDA\" target=\"_blank\">Digital-IDE</a> project team. Welcome to <a href=\"https://github.com/Digital-EDA/Digital-IDE\">Star</a>."

View File

@ -5,7 +5,7 @@ import zh from './zh.json';
const i18n = createI18n({
legacy: false,
locale: 'en',
locale: 'zh',
warnHtmlMessage: false,
messages: { en, zh }
});

View File

@ -3,7 +3,13 @@
"signal": "信号",
"search-signal": "搜索信号",
"language-setting": "语言",
"wheel-zoom-ratio": "滚轮缩放倍率",
"horizontal-scaling-ratio": "横向缩放速度",
"horizontal-scaling-ratio-description": "一共有5个挡位挡位越高<br/>ctrl + 鼠标滚轮缩放时的倍率越高",
"horizontal-roll-ratio": "横向滚动速度",
"horizontal-roll-ratio-description": "一共有5个挡位挡位越高<br/>左右滑动波形时间轴的步长越大",
"vertical-roll-ratio": "纵向滚动速度",
"vertical-roll-ratio-description": "一共有5个挡位挡位越高<br/>上下滑动波形时间轴的步长越大",
"search-setting": "搜索",
"search-case-sensitivity": "区分大小写",
@ -20,6 +26,31 @@
"appearance-setting": "外观",
"display-wave-height": "波形轨道的高度",
"display-signal-info-scope": "侧边栏展示信息",
"display-signal-info-scope.width": "位宽",
"display-signal-info-scope.parent": "所属模块名",
"wavecolor": "波形颜色",
"wavecolor.normal-bit": "单位宽波形",
"wavecolor.normal-vec": "多位宽波形",
"wavecolor.high-impedance": "高阻态波形",
"wavecolor.unknown": "未知态波形",
"operation-setting": "操作",
"render-setting": "渲染",
"prerender": "预渲染",
"prerender-description": "预渲染将使得渲染速度更快,但是会占用额外内存<br/>如果您的电脑内存大于10个G我们建议您开启。",
"render-animation": "开启渲染动画",
"usermanual": "使用说明",
"usermanual.left-right-scroll.title": "<span class=\"iconfont icon-mouse\"/><span class=\"iconfont icon-up-down\"/>",
"usermanual.left-right-scroll.caption": "上下移动",
"usermanual.up-down-scroll.title": "<span class=\"iconfont icon-mouse\"/><span class=\"iconfont icon-left-right\"/> / <span class=\"iconfont icon-shift\"/> + <span class=\"iconfont icon-mouse\"/><span class=\"iconfont icon-up-down\"/>",
"usermanual.up-down-scroll.caption": "左右移动",
"usermanual.xscale.title": "<span class=\"iconfont icon-ctrl\"/> + <span class=\"iconfont icon-mouse\"/><span class=\"iconfont icon-up-down\"/>",
"usermanual.xscale.caption": "横向缩放",
"loading": "加载中",
"current-version": "当前版本",
"copyright": "本软件版权归 <a href=\"https://github.com/Digital-EDA\" target=\"_blank\">Digital-IDE</a> 项目组所有,欢迎 <a href=\"https://github.com/Digital-EDA/Digital-IDE\">Star</a>。"

View File

@ -10,5 +10,9 @@ module.exports = defineConfig({
})
return definitions;
})
},
publicPath: './',
configureWebpack: {
devtool: false,
}
})

View File

@ -11,4 +11,5 @@ module.exports = {
resolvers: [ElementPlusResolver()],
}),
],
devtool: 'none',
}