desck 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +21 -0
- package/README.md +176 -0
- package/desck.cjs +2 -0
- package/elm.json +39 -0
- package/justfile +13 -0
- package/package.json +25 -0
- package/public/index.html +30 -0
- package/public/palette.json +16 -0
- package/public/projects/something.json +139 -0
- package/public/projects/template.json +69 -0
- package/public/script.js +490 -0
- package/public/style.css +471 -0
- package/public/svg/backface.svg +1 -0
- package/public/svg/courts.svg +30 -0
- package/public/svg/digits.svg +18 -0
- package/public/svg/suits.svg +43 -0
- package/server.cjs +316 -0
- package/settings.json +10 -0
- package/src/Card.elm +38 -0
- package/src/ColorPicker.elm +113 -0
- package/src/Deck.elm +571 -0
- package/src/DeckView.elm +415 -0
- package/src/Layout.elm +224 -0
- package/src/Main.elm +3743 -0
- package/src/Palette.elm +302 -0
- package/src/Project.elm +1029 -0
- package/src/Rect.elm +292 -0
- package/src/SaveFile.elm +422 -0
- package/src/Theme.elm +99 -0
- package/src/Util.elm +337 -0
- package/src/Vec.elm +196 -0
- package/src/Zone.elm +364 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="35" viewBox="0 0 6.614583 9.2604165">
|
|
2
|
+
<defs>
|
|
3
|
+
<symbol id="k"><path d="M3.5282462 8.2610797h.8528297l-1.2586997-3.438872-.96174 1.452634.007 1.986238h.67532v1.024345H.46289621v-1.024345h.78419999V.86561565l-.78419999.0033v-.895374H2.8778362v.925674h-.66638l-.014 3.60442705L4.3054259.86891565h-.7440397v-.895374h2.5903007v.895374h-.699L3.7170462 3.8392177l1.6994407 4.42331h.7352v1.024347H3.5287362v-1.025824z" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
4
|
+
<symbol id="q"><path d="M1.2453112 6.2050733H.46299121v-1.061029h.78231999s.006-.57172.0285-1.580274c.0485-2.149766.10244-2.483488.72797-3.07516804 1.23531-1.169313 3.3040107-.216569 3.2795407 1.54183604-.0358 2.481646-.01 4.847619-.0828 5.182817-.12949.5902-.14261.623459-.0897.731374.10832.216562 1.04277.310433 1.04277.249822v1.045144c-.71376.05506-1.01031-.01146-1.581441-.417245-.3563397.34222-1.4417397.685919-2.3050197.281607-.65651-.307473-1.15401-1.10168-1.01978-2.898884zm2.64422 1.852277c-.3877-.557311-1.04019-1.317885-1.65399-1.588032-.0383.640826.0172 1.178176.24365 1.467183.36031.460108.94279.565431 1.41034.120849m.3217-6.129653c-.28776-.810829-1.02706-1.08578604-1.5672-.578371-.33774.315614-.39169.647848-.399 2.452449-.004 1.11314-.004 1.581016-.004 1.581016 1.05148.339259 2.0343797 1.558829 2.0259897 1.542938l.0257-3.366391c.0204-.546222-.007-1.093179-.081-1.631641z" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
5
|
+
<symbol id="j"><path d="M3.2753964.94840148h.9697497c-.0246 1.92982402.008 3.22193702 0 5.27380202-.003.498174-.0121.847381-.07 1.106395-.33107 1.270495-2.1690501 1.277517-2.5341501.364006-.21226-.531408-.15579-.94456-.16555-1.479666H.46302603v.599037c.006 1.42866.48181 2.111947 1.58695997 2.381346 1.1363401.307464 2.4649901-.161491 2.9373711-1.134129.20388-.401624.25697-.532241.27124-1.848585.009-1.796148.006-3.365119 0-5.26220602h.89296v-.97486H3.2753964" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
6
|
+
<symbol id="0"><path d="M4.0630212-.02645835c-.8742 0-1.57681.793774-1.57681 1.77970605v5.754105c0 .985935.70298 1.779339 1.57681 1.779339h.5102797c.874171 0 1.578261-.793404 1.578261-1.779339v-5.754105c0-.98593205-.70446-1.77970605-1.578261-1.77970605zm.2638797.880615c.516131 0 .931131.39355905.931131.88578805v5.830232c0 .492228-.415.889482-.931131.889482-.5160897 0-.9325697-.397254-.9325697-.889482v-5.830232c0-.491859.41648-.88578805.9325697-.88578805M.46302121 9.2868747V-.02627535h.90812999V9.2868747Z" style="fill-opacity:1;stroke:none;stroke-width:.282219"/></symbol>
|
|
7
|
+
<symbol id="9"><path d="m.53031032 7.5042862.91052998-.270589c.34397.860269 1.03774 1.114946 1.77222 1.059794 1.3177296-.09847 1.7555306-1.479198 1.8540406-2.69965-.513451.510464-1.2847606.769583-1.9420506.743308-2.10108-.105508-2.63892998-1.681684-2.65832998-3.331531-.0574-1.391099.55610998-2.39870107 1.60855998-2.86141307.55764-.234315 1.83426-.234315 2.3949996.04332 1.287481.636686 1.721621 1.96901607 1.678381 4.36244507-.0432 2.393426-.49403 4.57936-2.9600306 4.731139-1.43718.08845-2.51133998-.855832-2.65831998-1.776818zm3.57660998-2.367232c.8289506-.496337 1.0747106-1.252111 1.0288006-1.904153-.11673-1.566191-.9923406-2.45533407-2.2631306-2.27913707-.70891.09995-1.09667.47159607-1.31927 1.16270407-.41069 1.278202.11051 2.773312 1.0862 3.117569.43898.15621 1.1176.111424 1.4674-.09698z" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
8
|
+
<symbol id="8"><path d="M.46404638 6.5588507c.0416-1.250265.46649-1.719249 1.30300002-2.373392-.66736-.512225-.94870002-1.267259-.89141002-1.909945C1.0130564.71925065 2.1424864-.05869535 3.3749064-.02543535c1.2334399.03474 2.2949899 1.07508395 2.3778499 2.20597405.072.983057-.20256 1.457587-.85799 1.974615.77786.698862 1.27471 1.157867 1.2563 2.389277-.0183 1.231416-1.00292 2.696766-2.7188899 2.741481-1.71595.04472-3.01079002-1.476807-2.96813002-2.727061m4.79016992.0044c.0733-1.132002-.86719-1.895531-1.9287699-1.906622-1.0336-.01183-1.95809.926888-1.95809 1.943206 0 1.091345 1.20274 1.684506 1.97957 1.687094.9442699.0044 1.8435099-.749123 1.9072899-1.723678m-.33966-4.049395c.0202-.952381-.8058199-1.63571805-1.6583399-1.60837105-.75805.02474-1.55978.63972905-1.56113 1.43652405 0 .997471.91255 1.495652 1.69176 1.514869.70725.01699 1.5116899-.622729 1.5277099-1.343022m0 0" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
9
|
+
<symbol id="7"><path d="M1.8828962 9.2868752c.60941-3.238217 1.25813-5.669696 2.9614207-8.30809205H1.3821762V2.1144862H.46301621V-.02645885H5.5269869l.62458 1.005242C4.4025059 3.4500662 3.3511262 6.4221382 2.9411462 9.2868752Z" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
10
|
+
<symbol id="6"><path d="M3.3980561-.02554746c-.23834.0054-.49074.03521-.70761.08537C1.4996262.33439154.58276616 1.1571395.46363616 3.0147736c-.003 1.399374.008 2.872415 0 2.887689-.0315 1.868922 1.24829004 3.384529 2.82809994 3.38441 1.5795901-.000222 2.8599601-1.515475 2.8597801-3.38441-.00006-1.868728-1.28036-3.383661-2.8597801-3.383883-.65577.0011-1.2913299.268637-1.8001999.75801.009-.0082.016-.01778.0246-.02588-.28122-1.84762 2.0609399-3.37602006 3.34532-1.614329h.96688c-.28954-1.24861406-1.39748-1.68550406-2.4302901-1.66193806zm-.10632 3.58516206c1.0930501-.000154 1.9792301 1.04879 1.9793201 2.342848-.00009 1.294067-.88627 2.34301-1.9793201 2.342854-1.09305.000156-1.9792399-1.048787-1.9793299-2.342854.00009-1.294058.8862799-2.343002 1.9793299-2.342848" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
11
|
+
<symbol id="5"><path d="M.46305956 6.8714564h.88453004c.16874.562137.54209 1.129083 1.0490599 1.287637 1.43223.353688 2.3536805-.487859 2.6570905-1.458012.36808-1.176761-.008-2.829166-.9942405-3.415694-.81701-.486379-2.0309599-.07614-2.5885099.964236l-.61945004-.398409.33256004-3.877673H5.2309v.91657H1.9515696l-.052 1.615453c.7059399-.52112 1.7908499-.515575 2.4964104-.150056 1.33628.670058 1.95714 2.193486 1.69769 3.988922-.35998 1.785827-1.15381 2.797755-2.9443105 2.942262-1.9915899.01884-2.69471994-1.425117-2.68625994-2.415236z" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
12
|
+
<symbol id="4"><path d="M3.3712212 9.2868742v-.823177h.7267v-1.357006H.46302121v-.957334L4.3962809-.02645985l.637271.0033V6.1493262h1.11801v.957368h-1.11801v1.357011h.59337v.823171zm.7267-7.052398-2.49724 3.914881h2.49724z" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
13
|
+
<symbol id="3"><path d="m.46302143 7.2453631.67470897-.527336c.585554 1.01328 1.2404251 1.680676 2.2422081 1.566111 1.5030237-.109749 2.1258107-1.784138 1.8113507-3.045756-.30421-1.131896-1.5487807-1.68325-2.5382687-1.079796-.222822.129992-.375002.208843-.474589.27628-.1067751-.183967-.3546311-.652759-.3546311-.652759L4.1201922.93397404H1.6006984V2.1431121H.63375743V-.02645896H5.5579882v.736122S4.2386622 2.1638051 3.8026502 2.9601661c1.073833.04176 1.93938.76495 2.250099 1.908307.1813.601988.100039 1.978896-.137277 2.572372-.396391.989266-1.479121 1.791912-2.4689267 1.8381-1.6618091.118623-2.54339807-1.118603-2.98352407-2.033582" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
14
|
+
<symbol id="2"><path d="m.46301901 9.2868751.0487-.58492c.153781-1.776595.56297999-2.375945 2.88395799-4.2306 1.1268131-.899028 1.4963121-1.342623 1.5480961-1.857245.147574-1.213869-1.0037691-1.592723-1.7536641-1.598272-.969031-.0087-1.980782.503405-1.670764 1.825797l-.96637799.304488C.33376801 1.9500111.55926701.82789708 1.57972.32991408c1.362755-.649295 3.1101801-.394758 3.9924811.628213.592989.68629002.728482 1.63600102.410379 2.37926902-.929389 1.898679-4.0820291 2.734074-4.3421411 4.930957h3.4843701v-1.223121h1.026755v2.241643z" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
15
|
+
<symbol id="a"><path d="M.46302051 9.2868747v-.796343h.75878009l1.616422-8.51699005h.920017l1.78059 8.51699005h.612733v.796343h-2.087872v-.796343h.563467l-.225015-1.305187h-2.106337l-.162701 1.305187h.563439v.796343zm3.75939809-3.031276-.915677-4.558559-.857674 4.558559z" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
16
|
+
<symbol id="x"><path d="M 0.61374917,3.6276481 H 2.6690765 L 3.3072917,0.38641634 3.9489381,3.6276481 H 6.0008339 L 4.3401022,5.6384647 4.9783172,8.874 3.3072917,6.8688792 1.6396972,8.874 2.2744811,5.6384647 Z" style="fill-opacity:1;stroke:none;stroke-width:.282223"/></symbol>
|
|
17
|
+
</defs>
|
|
18
|
+
</svg>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg
|
|
3
|
+
width="100"
|
|
4
|
+
height="100"
|
|
5
|
+
viewBox="0 0 100 100"
|
|
6
|
+
version="1.1"
|
|
7
|
+
id="svg1"
|
|
8
|
+
xml:space="preserve"
|
|
9
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
|
12
|
+
<defs id="defs">
|
|
13
|
+
|
|
14
|
+
<symbol id="spade">
|
|
15
|
+
<path
|
|
16
|
+
style="fill-opacity:1;stroke:none;"
|
|
17
|
+
d="M 50,3.6269531 C 36.82156,15.916891 26.066104,26.359248 12.394531,47.125 -1.38909,68.060941 18.325737,92.479162 47.046875,67.208984 c 3.531483,10.44427 -12.756737,24.233661 -14.339844,25.503907 -1.583106,1.270245 -2.020583,3.907873 2.048828,3.873046 L 50,96.609375 65.244141,96.585937 c 4.069411,0.03483 3.631934,-2.602801 2.048828,-3.873046 C 65.709862,91.442645 49.421642,77.653254 52.953125,67.208984 81.674263,92.479162 101.38909,68.060941 87.605469,47.125 73.933896,26.359248 63.17844,15.916891 50,3.6269531 Z"
|
|
18
|
+
/>
|
|
19
|
+
</symbol>
|
|
20
|
+
|
|
21
|
+
<symbol id="heart">
|
|
22
|
+
<path
|
|
23
|
+
style="fill-opacity:1;stroke:none;"
|
|
24
|
+
d="m 30.595703,12.669922 c -15.654354,-0.77967 -31.6954072,16.06956 -14.216797,38.40625 19.654251,25.117036 29.699949,37.588545 33.625,42.412109 3.925052,-4.823564 13.970749,-17.295073 33.625,-42.412109 C 110.26298,17.039312 59.06555,-4.2554933 50.003906,30.150391 46.888966,18.323368 38.795603,13.07832 30.595703,12.669922 Z"
|
|
25
|
+
transform="translate(-0.00400416,-3.2102795)"
|
|
26
|
+
/>
|
|
27
|
+
</symbol>
|
|
28
|
+
|
|
29
|
+
<symbol id="club">
|
|
30
|
+
<path
|
|
31
|
+
style="fill-opacity:1;stroke:none;"
|
|
32
|
+
d="m 50,2.6132813 c -2.814144,0.00573 -6.166239,1.0144902 -9.792969,3.3085937 -14.207095,8.986758 -10.653576,22.648479 -6.351562,30.179687 4.302014,7.531209 14.245645,15.710734 13.445312,17.105469 -1.830908,3.263961 -7.959037,-4.29145 -13.929687,-7.751953 -7.085105,-4.106424 -17.400428,-3.084618 -23.308594,7.041016 -5.3683608,9.200494 -3.6620104,19.76729 2.640625,25.308593 6.302635,5.541305 16.759237,5.735282 24.300781,-1.414062 4.050609,-3.839955 7.857319,-15.318531 10.115235,-7.625 2.257915,7.693531 -12.819951,25.668771 -14.660157,26.855469 -1.840205,1.186698 -2.155108,3.118579 1.513672,2.724609 C 37.049201,98.015329 46.89972,97.898062 50,97.869141 c 3.10028,0.02892 12.950799,0.146188 16.027344,0.476562 3.66878,0.39397 3.353877,-1.537911 1.513672,-2.724609 C 65.70081,94.434396 50.622944,76.459156 52.880859,68.765625 c 2.257916,-7.693531 6.064626,3.785045 10.115235,7.625 7.541544,7.149344 17.998146,6.955367 24.300781,1.414062 C 93.59951,72.263384 95.305861,61.696588 89.9375,52.496094 84.029334,42.37046 73.714011,41.348654 66.628906,45.455078 60.658256,48.915581 54.530127,56.470992 52.699219,53.207031 51.898886,51.812296 61.842517,43.632771 66.144531,36.101562 70.446545,28.570354 74.000064,14.908633 59.792969,5.921875 56.166239,3.6277715 52.814144,2.6190092 50,2.6132813 Z"
|
|
33
|
+
/>
|
|
34
|
+
</symbol>
|
|
35
|
+
|
|
36
|
+
<symbol id="diamond">
|
|
37
|
+
<path
|
|
38
|
+
style="fill-opacity:1;stroke:none;"
|
|
39
|
+
d="M 50,1 C 39.481746,18.484444 34.416583,27.953139 10,50 34.416583,72.046861 39.481746,81.515556 50,99 60.518254,81.515556 65.583417,72.046861 90,50 65.583417,27.953139 60.518254,18.484444 50,1 Z"
|
|
40
|
+
/>
|
|
41
|
+
</symbol>
|
|
42
|
+
</defs>
|
|
43
|
+
</svg>
|
package/server.cjs
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
const express = require("express");
|
|
2
|
+
const http = require("http");
|
|
3
|
+
const socketIo = require("socket.io");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
|
|
7
|
+
const app = express();
|
|
8
|
+
const server = http.createServer(app);
|
|
9
|
+
const io = socketIo(server, { maxHttpBufferSize: 1e8 });
|
|
10
|
+
|
|
11
|
+
const parseConfig = (args) => {
|
|
12
|
+
let flags = args.filter((a) => a.substr(0, 2) === "--");
|
|
13
|
+
args = args.filter((a) => a.substr(0, 2) !== "--");
|
|
14
|
+
let c = {
|
|
15
|
+
port: 3000,
|
|
16
|
+
mode: "dev",
|
|
17
|
+
formats: [],
|
|
18
|
+
symbols: false,
|
|
19
|
+
input: null,
|
|
20
|
+
output: null,
|
|
21
|
+
settings: null,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
c.port = 8000;
|
|
25
|
+
|
|
26
|
+
c.mode = flags.includes("--watch")
|
|
27
|
+
? "watch"
|
|
28
|
+
: flags.includes("--export")
|
|
29
|
+
? "export"
|
|
30
|
+
: "dev";
|
|
31
|
+
|
|
32
|
+
c.formats = [];
|
|
33
|
+
if (flags.includes("--svg")) c.formats.push("svg");
|
|
34
|
+
if (flags.includes("--png")) c.formats.push("png");
|
|
35
|
+
c.symbols = flags.includes("--symbols");
|
|
36
|
+
|
|
37
|
+
c.input = args[2]
|
|
38
|
+
? path.join(process.cwd(), args[2])
|
|
39
|
+
: path.join(__dirname, "public/projects");
|
|
40
|
+
|
|
41
|
+
c.output = args[3]
|
|
42
|
+
? path.join(process.cwd(), args[3])
|
|
43
|
+
: path.join(__dirname, "exports");
|
|
44
|
+
|
|
45
|
+
c.settings = JSON.parse(
|
|
46
|
+
fs.readFileSync(
|
|
47
|
+
args[4]
|
|
48
|
+
? path.join(process.cwd(), args[4])
|
|
49
|
+
: path.join(__dirname, "settings.json"),
|
|
50
|
+
),
|
|
51
|
+
);
|
|
52
|
+
return c;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
let config = parseConfig(process.argv);
|
|
56
|
+
console.log(config);
|
|
57
|
+
|
|
58
|
+
const verbose = !["watch", "export"].includes(config.mode);
|
|
59
|
+
|
|
60
|
+
const ensureDir = (dir) => {
|
|
61
|
+
if (!fs.existsSync(dir)) {
|
|
62
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const readFiles = (p) => {
|
|
67
|
+
const f = fs.statSync(p);
|
|
68
|
+
const files = f.isDirectory() ? fs.readdirSync(p) : [p];
|
|
69
|
+
return files
|
|
70
|
+
.filter((f) => path.extname(f) == ".json")
|
|
71
|
+
.map((f) => path.basename(f, ".json"));
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const outputFile = (f) => {
|
|
75
|
+
return path.join(config.output, f);
|
|
76
|
+
};
|
|
77
|
+
const inputFile = (f) => {
|
|
78
|
+
return path.join(config.input, f);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const logMessage = (kind, ...args) => {
|
|
82
|
+
args = args.length == 1 ? args[0] : args;
|
|
83
|
+
console.log(`\x1b[33m[${kind}]\x1b[0m`, args);
|
|
84
|
+
};
|
|
85
|
+
const logSuccess = (kind, ...args) => {
|
|
86
|
+
args = args.length == 1 ? args[0] : args;
|
|
87
|
+
console.log(`\x1b[32m[${kind}]\x1b[0m`, args);
|
|
88
|
+
};
|
|
89
|
+
const logError = (kind, ...args) => {
|
|
90
|
+
console.log(`\x1b[31m[${kind}]\x1b[0m`, args);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
ensureDir(config.output);
|
|
94
|
+
|
|
95
|
+
app.use(express.static(path.join(__dirname, "public")));
|
|
96
|
+
|
|
97
|
+
app.get("/", (_req, res) => {
|
|
98
|
+
res.sendFile(path.join(__dirname, "public/index.html"));
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
app.get("/up", (_req, res) => res.send("ok"));
|
|
102
|
+
|
|
103
|
+
app.get("/README.md", (_req, res) =>
|
|
104
|
+
res.sendFile(path.join(__dirname, "README.md")),
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
io.on("connection", (socket) => {
|
|
108
|
+
const readProjects = () => {
|
|
109
|
+
return readFiles(config.input);
|
|
110
|
+
};
|
|
111
|
+
if (verbose) {
|
|
112
|
+
logMessage("connect", "gui");
|
|
113
|
+
}
|
|
114
|
+
let files = readProjects();
|
|
115
|
+
// logMessage("files", files);
|
|
116
|
+
const emitList = () => {
|
|
117
|
+
const projects = readProjects();
|
|
118
|
+
socket.emit("files", projects);
|
|
119
|
+
};
|
|
120
|
+
emitList();
|
|
121
|
+
socket.on("save", (project) => {
|
|
122
|
+
logMessage("save", project.name);
|
|
123
|
+
fs.writeFileSync(
|
|
124
|
+
inputFile(`${project.name}.json`),
|
|
125
|
+
JSON.stringify(project, null, 4),
|
|
126
|
+
"utf-8",
|
|
127
|
+
);
|
|
128
|
+
socket.emit("saved");
|
|
129
|
+
emitList();
|
|
130
|
+
});
|
|
131
|
+
socket.onAny((message, data) => {
|
|
132
|
+
if (verbose) {
|
|
133
|
+
logMessage(message, data);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
socket.on("svg", (message) => {
|
|
138
|
+
logMessage("export", `${message.name}.svg`);
|
|
139
|
+
fs.writeFileSync(outputFile(`${message.name}.svg`), message.data);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
socket.on("import", (name) => {
|
|
143
|
+
const filepath = inputFile(`${name}.json`);
|
|
144
|
+
if (fs.existsSync(filepath)) {
|
|
145
|
+
if (verbose) {
|
|
146
|
+
logMessage("load", `${name}`);
|
|
147
|
+
}
|
|
148
|
+
const json = fs.readFileSync(filepath, "utf-8");
|
|
149
|
+
socket.emit("open", JSON.parse(json));
|
|
150
|
+
} else {
|
|
151
|
+
logError("load", `'${filepath}' does not exist`);
|
|
152
|
+
socket.emit("fail", `${filepath} does not exist!`);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
socket.on("disconnect", () => {
|
|
157
|
+
if (verbose) {
|
|
158
|
+
logMessage("disconnect", "gui");
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
server.listen(config.port, () => {
|
|
164
|
+
logMessage("start", `server running on http://localhost:${config.port}`);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const exportProject = async (browser, config, jsonData, format) => {
|
|
168
|
+
const page = await browser.newPage();
|
|
169
|
+
const hash = jsonData ? `#${btoa(jsonData)}` : "";
|
|
170
|
+
await page.goto(`http://localhost:${config.port}${hash}`, {
|
|
171
|
+
waitUntil: "networkidle0",
|
|
172
|
+
});
|
|
173
|
+
const svgs = await page.$$("#view");
|
|
174
|
+
if (svgs.length > 0) {
|
|
175
|
+
switch (format) {
|
|
176
|
+
case "symbols":
|
|
177
|
+
const symbolsData = await page.evaluate((settings) => {
|
|
178
|
+
const svg = window.exportSymbols(settings).data;
|
|
179
|
+
return svg;
|
|
180
|
+
}, config.settings);
|
|
181
|
+
await page.close();
|
|
182
|
+
return {
|
|
183
|
+
data: symbolsData,
|
|
184
|
+
format: "utf8",
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
case "svg":
|
|
188
|
+
const svgData = await page.evaluate((settings) => {
|
|
189
|
+
return window.exportImage(settings).data;
|
|
190
|
+
}, config.settings);
|
|
191
|
+
await page.close();
|
|
192
|
+
return {
|
|
193
|
+
data: svgData,
|
|
194
|
+
format: "utf8",
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
case "png":
|
|
198
|
+
const pngData = await page.evaluate(async (settings) => {
|
|
199
|
+
return await window.exportPNG(settings);
|
|
200
|
+
}, config.settings);
|
|
201
|
+
await page.close();
|
|
202
|
+
return {
|
|
203
|
+
data: pngData.replace(/^data:image\/png;base64,/, ""),
|
|
204
|
+
format: "base64",
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
logError("page", "#view was not rendered");
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const puppeteer = require("puppeteer");
|
|
213
|
+
|
|
214
|
+
const withBrowser = async (fun) => {
|
|
215
|
+
try {
|
|
216
|
+
const browser = await puppeteer.launch({
|
|
217
|
+
headless: true,
|
|
218
|
+
args: ["--no-sandbox"],
|
|
219
|
+
});
|
|
220
|
+
const result = await fun(browser);
|
|
221
|
+
await browser.close();
|
|
222
|
+
return result;
|
|
223
|
+
} catch (err) {
|
|
224
|
+
logError("export", err);
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const exportSingle = async (browser, name) => {
|
|
230
|
+
let results = [];
|
|
231
|
+
for (let format of config.formats) {
|
|
232
|
+
logMessage("export", `${name}.json`);
|
|
233
|
+
const inputPath = inputFile(`${name}.json`);
|
|
234
|
+
const jsonData = fs.readFileSync(inputPath);
|
|
235
|
+
const output = await exportProject(browser, config, jsonData, format);
|
|
236
|
+
if (output) {
|
|
237
|
+
const outputPath = outputFile(`${name}.${format}`);
|
|
238
|
+
fs.writeFileSync(outputPath, output.data, output.format);
|
|
239
|
+
results.push(outputPath);
|
|
240
|
+
} else {
|
|
241
|
+
throw new Error("Page failed to render project!");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return results;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const exportAll = async () => {
|
|
248
|
+
await withBrowser(async (browser) => {
|
|
249
|
+
let targets = [];
|
|
250
|
+
if (config.symbols) {
|
|
251
|
+
const output = await exportProject(browser, config, null, "symbols");
|
|
252
|
+
if (output) {
|
|
253
|
+
const outputPath = outputFile(`_symbols.svg`);
|
|
254
|
+
fs.writeFileSync(outputPath, output.data, output.format);
|
|
255
|
+
targets.push(outputPath);
|
|
256
|
+
} else {
|
|
257
|
+
throw new Error("Page failed to render symbols!");
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const files = readFiles(config.input);
|
|
262
|
+
logMessage("export", "all projects...");
|
|
263
|
+
logMessage("files", files);
|
|
264
|
+
for (let name of files) {
|
|
265
|
+
let results = await exportSingle(browser, name);
|
|
266
|
+
targets = targets.concat(results);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
switch (config.mode) {
|
|
272
|
+
case "dev":
|
|
273
|
+
{
|
|
274
|
+
const liveReload = (file) =>
|
|
275
|
+
fs.watchFile(file, (_curr, _prev) => io.emit("live-reload"), {
|
|
276
|
+
watchInterval: 200,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
liveReload("public/main.js");
|
|
280
|
+
liveReload("public/script.js");
|
|
281
|
+
}
|
|
282
|
+
break;
|
|
283
|
+
case "watch":
|
|
284
|
+
{
|
|
285
|
+
const f = fs.statSync(config.input);
|
|
286
|
+
if (!f.isDirectory) {
|
|
287
|
+
throw new Error("input to watch should be a directory!");
|
|
288
|
+
}
|
|
289
|
+
logMessage("watch", `${config.input} -> ${config.output}`);
|
|
290
|
+
const runExports = async (file) => {
|
|
291
|
+
await exportAll();
|
|
292
|
+
logMessage("export", file);
|
|
293
|
+
};
|
|
294
|
+
fs.readdirSync(config.input).map((file) =>
|
|
295
|
+
fs.watchFile(
|
|
296
|
+
inputFile(file),
|
|
297
|
+
async (_curr, _prev) => {
|
|
298
|
+
const name = path.basename(file, ".json");
|
|
299
|
+
await withBrowser(async (browser) => {
|
|
300
|
+
await exportSingle(browser, name);
|
|
301
|
+
});
|
|
302
|
+
},
|
|
303
|
+
{ watchInterval: 500 },
|
|
304
|
+
),
|
|
305
|
+
);
|
|
306
|
+
// runExports("");
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
case "export":
|
|
310
|
+
(async () => {
|
|
311
|
+
const files = await exportAll();
|
|
312
|
+
logSuccess("success", files);
|
|
313
|
+
process.exit(0);
|
|
314
|
+
})();
|
|
315
|
+
break;
|
|
316
|
+
}
|
package/settings.json
ADDED
package/src/Card.elm
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Card exposing (..)
|
|
2
|
+
|
|
3
|
+
import Deck exposing (CardModel, defaultModel)
|
|
4
|
+
import DeckView exposing (cardSize)
|
|
5
|
+
import Rect exposing (Rect, Rotation, angled, rect2)
|
|
6
|
+
import Vec exposing (Vec2)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
type alias Card =
|
|
10
|
+
{ model : CardModel
|
|
11
|
+
, rect : Rect
|
|
12
|
+
, rot : Rotation
|
|
13
|
+
, front : Bool
|
|
14
|
+
, highlight : Bool
|
|
15
|
+
, id : String
|
|
16
|
+
, z : Int
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
defaultCard : Card
|
|
21
|
+
defaultCard =
|
|
22
|
+
{ model = defaultModel
|
|
23
|
+
, front = True
|
|
24
|
+
, rect = rect2 (Vec2 0 0) cardSize
|
|
25
|
+
, rot = angled 0.0
|
|
26
|
+
, highlight = True
|
|
27
|
+
, id = ""
|
|
28
|
+
, z = 0
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
makeCard : Int -> CardModel -> Vec2 -> Card
|
|
33
|
+
makeCard index model pos =
|
|
34
|
+
{ defaultCard
|
|
35
|
+
| model = model
|
|
36
|
+
, rect = rect2 pos cardSize
|
|
37
|
+
, id = "c" ++ String.fromInt index
|
|
38
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
module ColorPicker exposing (..)
|
|
2
|
+
|
|
3
|
+
import Color as C
|
|
4
|
+
import Html as H exposing (Html)
|
|
5
|
+
import Html.Attributes as HA
|
|
6
|
+
import Html.Events as E
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
type alias Model =
|
|
10
|
+
{ h : Float
|
|
11
|
+
, s : Float
|
|
12
|
+
, l : Float
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
defaultModel : Model
|
|
17
|
+
defaultModel =
|
|
18
|
+
{ h = 0.0, s = 1.0, l = 0.5 }
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
fromColor : C.Color -> Model
|
|
22
|
+
fromColor c =
|
|
23
|
+
let
|
|
24
|
+
{ hue, saturation, lightness } =
|
|
25
|
+
C.toHsla c
|
|
26
|
+
in
|
|
27
|
+
{ h = hue, s = saturation, l = lightness }
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
type Msg
|
|
31
|
+
= UpdateHue String
|
|
32
|
+
| UpdateSat String
|
|
33
|
+
| UpdateVal String
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
update : Msg -> Model -> ( Model, C.Color )
|
|
37
|
+
update msg model =
|
|
38
|
+
let
|
|
39
|
+
parse s =
|
|
40
|
+
Maybe.withDefault 0.0 <| String.toFloat s
|
|
41
|
+
|
|
42
|
+
out m =
|
|
43
|
+
( m
|
|
44
|
+
, C.hsl m.h m.s m.l
|
|
45
|
+
)
|
|
46
|
+
in
|
|
47
|
+
case msg of
|
|
48
|
+
UpdateHue s ->
|
|
49
|
+
out { model | h = parse s }
|
|
50
|
+
|
|
51
|
+
UpdateSat s ->
|
|
52
|
+
out { model | s = parse s }
|
|
53
|
+
|
|
54
|
+
UpdateVal s ->
|
|
55
|
+
out { model | l = parse s }
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
hslString : Float -> Float -> Float -> String
|
|
59
|
+
hslString h s l =
|
|
60
|
+
"hsl(" ++ (String.fromFloat <| 360.0 * h) ++ ", " ++ (String.fromFloat <| 100.0 * s) ++ "%," ++ (String.fromFloat <| 100.0 * l) ++ "%)"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
view : Model -> Html Msg
|
|
64
|
+
view model =
|
|
65
|
+
H.div
|
|
66
|
+
[]
|
|
67
|
+
[ H.input
|
|
68
|
+
[ HA.type_ "range"
|
|
69
|
+
, HA.min "0"
|
|
70
|
+
, HA.max "1"
|
|
71
|
+
, HA.class "slider"
|
|
72
|
+
, HA.step "0.01"
|
|
73
|
+
, HA.class "hue-rainbow"
|
|
74
|
+
, HA.value <| String.fromFloat model.h
|
|
75
|
+
, E.onInput UpdateHue
|
|
76
|
+
]
|
|
77
|
+
[]
|
|
78
|
+
, H.input
|
|
79
|
+
[ HA.type_ "range"
|
|
80
|
+
, HA.min "0"
|
|
81
|
+
, HA.max "1"
|
|
82
|
+
, HA.class "slider"
|
|
83
|
+
, HA.step "0.01"
|
|
84
|
+
, HA.value <| String.fromFloat model.s
|
|
85
|
+
, HA.style "background" <|
|
|
86
|
+
"linear-gradient(90deg, "
|
|
87
|
+
++ hslString model.h 0.0 model.l
|
|
88
|
+
++ " 0%, "
|
|
89
|
+
++ hslString model.h 1.0 model.l
|
|
90
|
+
++ " 100%)"
|
|
91
|
+
, E.onInput UpdateSat
|
|
92
|
+
]
|
|
93
|
+
[]
|
|
94
|
+
, H.input
|
|
95
|
+
[ HA.type_ "range"
|
|
96
|
+
, HA.min "0"
|
|
97
|
+
, HA.max "1"
|
|
98
|
+
, HA.class "slider"
|
|
99
|
+
, HA.step "0.01"
|
|
100
|
+
, HA.value <| String.fromFloat model.l
|
|
101
|
+
, HA.style "background" <|
|
|
102
|
+
"linear-gradient(90deg, "
|
|
103
|
+
++ hslString model.h model.s 0.0
|
|
104
|
+
++ " 0%, "
|
|
105
|
+
++ hslString model.h model.s 1.0
|
|
106
|
+
++ " 100%)"
|
|
107
|
+
, E.onInput UpdateVal
|
|
108
|
+
]
|
|
109
|
+
[]
|
|
110
|
+
, H.input [ HA.type_ "color" ] []
|
|
111
|
+
|
|
112
|
+
-- , H.text <| asHsl model
|
|
113
|
+
]
|