quickdbd-cli 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1 @@
1
+ {"bold": {" ": 0.2368, "!": 0.3379, "\"": 0.5518, "#": 0.6489, "$": 0.6548, "%": 1.0156, "&": 0.6719, "'": 0.3389, "(": 0.377, ")": 0.377, "*": 0.5591, "+": 0.6787, ",": 0.334, "-": 0.4678, ".": 0.334, "/": 0.3882, "0": 0.6743, "1": 0.4312, "2": 0.6299, "3": 0.6455, "4": 0.6763, "5": 0.6221, "6": 0.6494, "7": 0.5815, "8": 0.6509, "9": 0.6494, ":": 0.334, ";": 0.3428, "<": 0.6787, "=": 0.6787, ">": 0.6787, "?": 0.5596, "@": 1.0161, "A": 0.7466, "B": 0.6616, "C": 0.7397, "D": 0.7222, "E": 0.6074, "F": 0.5869, "G": 0.7505, "H": 0.7471, "I": 0.2808, "J": 0.5845, "K": 0.7192, "L": 0.5654, "M": 0.9316, "N": 0.7622, "O": 0.7705, "P": 0.6479, "Q": 0.7769, "R": 0.6567, "S": 0.6548, "T": 0.6675, "U": 0.7319, "V": 0.7466, "W": 1.0376, "X": 0.7383, "Y": 0.731, "Z": 0.6641, "[": 0.377, "\\": 0.3882, "]": 0.377, "^": 0.4868, "_": 0.4761, "`": 0.3652, "a": 0.5806, "b": 0.6304, "c": 0.5884, "d": 0.6304, "e": 0.5957, "f": 0.3979, "g": 0.6318, "h": 0.6226, "i": 0.271, "j": 0.271, "k": 0.5801, "l": 0.271, "m": 0.9126, "n": 0.6226, "o": 0.6133, "p": 0.6304, "q": 0.6304, "r": 0.4072, "s": 0.5601, "t": 0.3662, "u": 0.6226, "v": 0.5996, "w": 0.8501, "x": 0.5801, "y": 0.6021, "z": 0.5728, "{": 0.4688, "|": 0.3716, "}": 0.4688, "~": 0.6787, " ": 0.2368, "¡": 0.3379, "¢": 0.5884, "£": 0.6387, "¤": 0.7617, "¥": 0.5703, "¦": 0.3389, "§": 0.5684, "¨": 0.6226, "©": 0.9141, "ª": 0.4639, "«": 0.6602, "¬": 0.6787, "®": 0.6621, "¯": 0.439, "°": 0.4595, "±": 0.6787, "²": 0.46, "³": 0.4717, "´": 0.3652, "µ": 0.6279, "¶": 0.5986, "·": 0.334, "¸": 0.3643, "¹": 0.333, "º": 0.4897, "»": 0.6602, "¼": 0.8457, "½": 0.8813, "¾": 0.9199, "¿": 0.5596, "À": 0.7466, "Á": 0.7466, "Â": 0.7466, "Ã": 0.7466, "Ä": 0.7466, "Å": 0.7466, "Æ": 1.0225, "Ç": 0.7397, "È": 0.6074, "É": 0.6074, "Ê": 0.6074, "Ë": 0.6074, "Ì": 0.2808, "Í": 0.2808, "Î": 0.2808, "Ï": 0.2808, "Ð": 0.7598, "Ñ": 0.7622, "Ò": 0.7705, "Ó": 0.7705, "Ô": 0.7705, "Õ": 0.7705, "Ö": 0.7705, "×": 0.6787, "Ø": 0.7705, "Ù": 0.7319, "Ú": 0.7319, "Û": 0.7319, "Ü": 0.7319, "Ý": 0.731, "Þ": 0.6689, "ß": 0.6572, "à": 0.5806, "á": 0.5806, "â": 0.5806, "ã": 0.5806, "ä": 0.5806, "å": 0.5806, "æ": 0.9102, "ç": 0.5884, "è": 0.5957, "é": 0.5957, "ê": 0.5957, "ë": 0.5957, "ì": 0.271, "í": 0.271, "î": 0.271, "ï": 0.271, "ð": 0.5991, "ñ": 0.6226, "ò": 0.6133, "ó": 0.6133, "ô": 0.6133, "õ": 0.6133, "ö": 0.6133, "÷": 0.6787, "ø": 0.6133, "ù": 0.6226, "ú": 0.6226, "û": 0.6226, "ü": 0.6226, "ý": 0.6021, "þ": 0.6304, "ÿ": 0.6021, "Ā": 0.7466, "ā": 0.5806, "Ă": 0.7466, "ă": 0.5806, "Ą": 0.7466, "ą": 0.5806, "Ć": 0.7397, "ć": 0.5884, "Ĉ": 0.7397, "ĉ": 0.5884, "Ċ": 0.7397, "ċ": 0.5884, "Č": 0.7397, "č": 0.5884, "Ď": 0.7222, "ď": 0.7544, "Đ": 0.7598, "đ": 0.6304, "Ē": 0.6074, "ē": 0.5957, "Ĕ": 0.6074, "ĕ": 0.5957, "Ė": 0.6074, "ė": 0.5957, "Ę": 0.6074, "ę": 0.5957, "Ě": 0.6074, "ě": 0.5957, "Ĝ": 0.7505, "ĝ": 0.6318, "Ğ": 0.7505, "ğ": 0.6318, "Ġ": 0.7505, "ġ": 0.6318, "Ģ": 0.7505, "ģ": 0.6318, "Ĥ": 0.7471, "ĥ": 0.6226, "Ħ": 0.8071, "ħ": 0.6226, "Ĩ": 0.2808, "ĩ": 0.271, "Ī": 0.2808, "ī": 0.271, "Ĭ": 0.2808, "ĭ": 0.271, "Į": 0.2808, "į": 0.271, "İ": 0.2808, "ı": 0.271, "IJ": 0.8647, "ij": 0.5425, "Ĵ": 0.5845, "ĵ": 0.271, "Ķ": 0.7192, "ķ": 0.5801, "ĸ": 0.5864, "Ĺ": 0.5654, "ĺ": 0.271, "Ļ": 0.5654, "ļ": 0.271, "Ľ": 0.5654, "ľ": 0.395, "Ŀ": 0.5776, "ŀ": 0.4492, "Ł": 0.6055, "ł": 0.271, "Ń": 0.7622, "ń": 0.6226, "Ņ": 0.7622, "ņ": 0.6226, "Ň": 0.7622, "ň": 0.6226, "Ŋ": 0.7622, "ŋ": 0.6226, "Ō": 0.7705, "ō": 0.6133, "Ŏ": 0.7705, "ŏ": 0.6133, "Ő": 0.7705, "ő": 0.6133, "Œ": 1.0176, "œ": 0.9878, "Ŕ": 0.6567, "ŕ": 0.4072, "Ŗ": 0.6567, "ŗ": 0.4072, "Ř": 0.6567, "ř": 0.4072, "Ś": 0.6548, "ś": 0.5601, "Ŝ": 0.6548, "ŝ": 0.5601, "Ş": 0.6548, "ş": 0.5601, "Š": 0.6548, "š": 0.5601, "Ţ": 0.6675, "ţ": 0.3662, "Ť": 0.6675, "ť": 0.4414, "Ŧ": 0.6675, "ŧ": 0.3662, "Ũ": 0.7319, "ũ": 0.6226, "Ū": 0.7319, "ū": 0.6226, "Ŭ": 0.7319, "ŭ": 0.6226, "Ů": 0.7319, "ů": 0.6226, "Ű": 0.7319, "ű": 0.6226, "Ų": 0.7319, "ų": 0.6226, "Ŵ": 1.0376, "ŵ": 0.8501, "Ŷ": 0.731, "ŷ": 0.6021, "Ÿ": 0.731, "Ź": 0.6641, "ź": 0.5728, "Ż": 0.6641, "ż": 0.5728, "Ž": 0.6641, "ž": 0.5728, "ſ": 0.3447}, "regular": {" ": 0.2812, "!": 0.2876, "\"": 0.4658, "#": 0.6333, "$": 0.6416, "%": 0.9819, "&": 0.644, "'": 0.2998, "(": 0.3647, ")": 0.3647, "*": 0.501, "+": 0.6616, ",": 0.2881, "-": 0.46, ".": 0.2881, "/": 0.3604, "0": 0.6309, "1": 0.4067, "2": 0.6099, "3": 0.6177, "4": 0.646, "5": 0.5933, "6": 0.6201, "7": 0.5659, "8": 0.6187, "9": 0.6201, ":": 0.2881, ";": 0.3018, "<": 0.6616, "=": 0.6616, ">": 0.6616, "?": 0.5112, "@": 0.9658, "A": 0.6899, "B": 0.6543, "C": 0.7305, "D": 0.7217, "E": 0.6011, "F": 0.5903, "G": 0.7461, "H": 0.7432, "I": 0.2686, "J": 0.5708, "K": 0.6719, "L": 0.5654, "M": 0.9033, "N": 0.7534, "O": 0.7646, "P": 0.6387, "Q": 0.7646, "R": 0.6436, "S": 0.6416, "T": 0.6455, "U": 0.7441, "V": 0.6899, "W": 0.9854, "X": 0.6821, "Y": 0.6787, "Z": 0.6289, "[": 0.3647, "\\": 0.3604, "]": 0.3647, "^": 0.4712, "_": 0.4561, "`": 0.3228, "a": 0.5615, "b": 0.6123, "c": 0.5713, "d": 0.6123, "e": 0.583, "f": 0.3701, "g": 0.6133, "h": 0.5913, "i": 0.2422, "j": 0.2422, "k": 0.5488, "l": 0.2422, "m": 0.876, "n": 0.5908, "o": 0.5996, "p": 0.6123, "q": 0.6123, "r": 0.3765, "s": 0.5278, "t": 0.3271, "u": 0.5913, "v": 0.562, "w": 0.8184, "x": 0.5459, "y": 0.562, "z": 0.5522, "{": 0.4263, "|": 0.3325, "}": 0.4263, "~": 0.6616, " ": 0.2812, "¡": 0.2876, "¢": 0.5713, "£": 0.6108, "¤": 0.7246, "¥": 0.5498, "¦": 0.27, "§": 0.5684, "¨": 0.5908, "©": 0.9141, "ª": 0.4536, "«": 0.5825, "¬": 0.6616, "®": 0.666, "¯": 0.4775, "°": 0.4556, "±": 0.6616, "²": 0.4419, "³": 0.4458, "´": 0.3228, "µ": 0.5859, "¶": 0.6025, "·": 0.2881, "¸": 0.2681, "¹": 0.3042, "º": 0.4824, "»": 0.5825, "¼": 0.8022, "½": 0.8472, "¾": 0.8818, "¿": 0.5112, "À": 0.6899, "Á": 0.6899, "Â": 0.6899, "Ã": 0.6899, "Ä": 0.6899, "Å": 0.6899, "Æ": 0.9937, "Ç": 0.7305, "È": 0.6011, "É": 0.6011, "Ê": 0.6011, "Ë": 0.6011, "Ì": 0.2686, "Í": 0.2686, "Î": 0.2686, "Ï": 0.2686, "Ð": 0.7349, "Ñ": 0.7534, "Ò": 0.7646, "Ó": 0.7646, "Ô": 0.7646, "Õ": 0.7646, "Ö": 0.7646, "×": 0.6616, "Ø": 0.7646, "Ù": 0.7441, "Ú": 0.7441, "Û": 0.7441, "Ü": 0.7441, "Ý": 0.6787, "Þ": 0.6357, "ß": 0.6162, "à": 0.5615, "á": 0.5615, "â": 0.5615, "ã": 0.5615, "ä": 0.5615, "å": 0.5615, "æ": 0.9175, "ç": 0.5713, "è": 0.583, "é": 0.583, "ê": 0.583, "ë": 0.583, "ì": 0.2422, "í": 0.2422, "î": 0.2422, "ï": 0.2422, "ð": 0.5825, "ñ": 0.5908, "ò": 0.5996, "ó": 0.5996, "ô": 0.5996, "õ": 0.5996, "ö": 0.5996, "÷": 0.6616, "ø": 0.5996, "ù": 0.5913, "ú": 0.5913, "û": 0.5913, "ü": 0.5913, "ý": 0.562, "þ": 0.6123, "ÿ": 0.562, "Ā": 0.6899, "ā": 0.5615, "Ă": 0.6899, "ă": 0.5615, "Ą": 0.6899, "ą": 0.5615, "Ć": 0.7305, "ć": 0.5713, "Ĉ": 0.7305, "ĉ": 0.5713, "Ċ": 0.7305, "ċ": 0.5713, "Č": 0.7305, "č": 0.5713, "Ď": 0.7217, "ď": 0.71, "Đ": 0.7349, "đ": 0.6123, "Ē": 0.6011, "ē": 0.583, "Ĕ": 0.6011, "ĕ": 0.583, "Ė": 0.6011, "ė": 0.583, "Ę": 0.6011, "ę": 0.583, "Ě": 0.6011, "ě": 0.583, "Ĝ": 0.7461, "ĝ": 0.6133, "Ğ": 0.7461, "ğ": 0.6133, "Ġ": 0.7461, "ġ": 0.6133, "Ģ": 0.7461, "ģ": 0.6133, "Ĥ": 0.7432, "ĥ": 0.5913, "Ħ": 0.7764, "ħ": 0.5913, "Ĩ": 0.2686, "ĩ": 0.2422, "Ī": 0.2686, "ī": 0.2422, "Ĭ": 0.2686, "ĭ": 0.2422, "Į": 0.2686, "į": 0.2422, "İ": 0.2686, "ı": 0.2422, "IJ": 0.8394, "ij": 0.4844, "Ĵ": 0.5708, "ĵ": 0.2422, "Ķ": 0.6719, "ķ": 0.5488, "ĸ": 0.5254, "Ĺ": 0.5654, "ĺ": 0.2422, "Ļ": 0.5654, "ļ": 0.2422, "Ľ": 0.5654, "ľ": 0.3398, "Ŀ": 0.5625, "ŀ": 0.3594, "Ł": 0.5947, "ł": 0.2422, "Ń": 0.7534, "ń": 0.5908, "Ņ": 0.7534, "ņ": 0.5908, "Ň": 0.7534, "ň": 0.5908, "Ŋ": 0.7534, "ŋ": 0.5908, "Ō": 0.7646, "ō": 0.5996, "Ŏ": 0.7646, "ŏ": 0.5996, "Ő": 0.7646, "ő": 0.5996, "Œ": 1.0049, "œ": 0.9995, "Ŕ": 0.6436, "ŕ": 0.3765, "Ŗ": 0.6436, "ŗ": 0.3765, "Ř": 0.6436, "ř": 0.3765, "Ś": 0.6416, "ś": 0.5278, "Ŝ": 0.6416, "ŝ": 0.5278, "Ş": 0.6416, "ş": 0.5278, "Š": 0.6416, "š": 0.5278, "Ţ": 0.6455, "ţ": 0.3271, "Ť": 0.6455, "ť": 0.376, "Ŧ": 0.6455, "ŧ": 0.3271, "Ũ": 0.7441, "ũ": 0.5913, "Ū": 0.7441, "ū": 0.5913, "Ŭ": 0.7441, "ŭ": 0.5913, "Ů": 0.7441, "ů": 0.5913, "Ű": 0.7441, "ű": 0.5913, "Ų": 0.7441, "ų": 0.5913, "Ŵ": 0.9854, "ŵ": 0.8184, "Ŷ": 0.6787, "ŷ": 0.562, "Ÿ": 0.6787, "Ź": 0.6289, "ź": 0.5522, "Ż": 0.6289, "ż": 0.5522, "Ž": 0.6289, "ž": 0.5522, "ſ": 0.3145}}
@@ -0,0 +1,230 @@
1
+ /* qdbd renderer: pure functions, model + positions -> SVG markup.
2
+ * Runs in the browser (viewer) and inside V8 from Python (CLI export), so the page,
3
+ * the SVG and the PNG are drawn by the same code. No DOM access here. */
4
+ (function (root) {
5
+ "use strict";
6
+
7
+ var C = {
8
+ bg: "#f4f5f4",
9
+ header: "#2b5797",
10
+ headerText: "#ffffff",
11
+ body: "#ffffff",
12
+ border: "#dfe3e8",
13
+ text: "#333333",
14
+ pk: "#2b5797",
15
+ fk: "#222222",
16
+ type: "#9a9a9a",
17
+ key: "#b0b0b0",
18
+ badgeBg: "#eef1f5",
19
+ badgeText: "#7a8899",
20
+ edge: "#b8bcc2",
21
+ };
22
+ var FONT = "Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif";
23
+
24
+ function esc(s) {
25
+ return String(s == null ? "" : s)
26
+ .replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
27
+ .replace(/"/g, "&quot;").replace(/'/g, "&#39;");
28
+ }
29
+
30
+ function n(v) { return Math.round(v * 100) / 100; }
31
+
32
+ function relatedColumns(model) {
33
+ var set = {};
34
+ model.rels.forEach(function (r) {
35
+ set[r.a.t + "\u0000" + r.a.c] = true;
36
+ set[r.b.t + "\u0000" + r.b.c] = true;
37
+ });
38
+ return set;
39
+ }
40
+
41
+ /* Visible columns of each table for a collapse mode: "full" | "keys" | "header". */
42
+ function geometry(model, mode) {
43
+ var st = model.style, rel = mode === "keys" ? relatedColumns(model) : null, out = {};
44
+ model.tables.forEach(function (t) {
45
+ var cols = [];
46
+ if (mode !== "header") {
47
+ t.cols.forEach(function (c) {
48
+ if (mode === "full" || c.pk || c.fk || rel[t.id + "\u0000" + c.id]) cols.push(c);
49
+ });
50
+ }
51
+ var rows = {};
52
+ cols.forEach(function (c, i) { rows[c.id] = i; });
53
+ out[t.id] = {
54
+ cols: cols,
55
+ rows: rows,
56
+ w: t.w,
57
+ h: st.headerH + cols.length * st.rowH + (cols.length ? st.bottomPad : 0),
58
+ };
59
+ });
60
+ return out;
61
+ }
62
+
63
+ function keyIcon(x, cy) {
64
+ return '<g stroke="' + C.key + '" stroke-width="1.5" fill="none">' +
65
+ '<circle cx="' + n(x + 3.5) + '" cy="' + n(cy) + '" r="3"/>' +
66
+ '<path d="M' + n(x + 6.5) + " " + n(cy) + "h7m-2 0v3m-2.5-3v2" + '"/></g>';
67
+ }
68
+
69
+ function renderTable(model, t, g, p) {
70
+ var st = model.style, w = g.w, h = g.h, out = [];
71
+ out.push('<g class="t" data-id="' + esc(t.id) + '" transform="translate(' + n(p[0]) + "," + n(p[1]) + ')">');
72
+ out.push('<rect class="tb" width="' + w + '" height="' + h + '" rx="2" fill="' + C.body + '" stroke="' + C.border + '"/>');
73
+ out.push('<path class="th" d="M0 2a2 2 0 0 1 2-2h' + (w - 4) + "a2 2 0 0 1 2 2v" + (st.headerH - 2) + "h-" + w + 'z" fill="' + C.header + '"/>');
74
+ out.push('<text x="' + st.padX + '" y="' + n(st.headerH / 2 + st.headerSize * 0.36) + '" fill="' + C.headerText +
75
+ '" font-family="' + FONT + '" font-size="' + st.headerSize + '">' + esc(t.name) + "</text>");
76
+ g.cols.forEach(function (c, i) {
77
+ var y = st.headerH + i * st.rowH, cy = y + st.rowH / 2, base = n(cy + st.rowSize * 0.36);
78
+ var weight = c.pk || c.fk ? ' font-weight="bold"' : "";
79
+ var color = c.pk ? C.pk : c.fk ? C.fk : C.text;
80
+ out.push('<g class="r" data-c="' + esc(c.id) + '">');
81
+ out.push('<rect class="rb" y="' + y + '" width="' + w + '" height="' + st.rowH + '" fill="' + C.body + '" fill-opacity="0"/>');
82
+ out.push('<text x="' + st.padX + '" y="' + base + '" fill="' + color + '" font-family="' + FONT + '" font-size="' +
83
+ st.rowSize + '"' + weight + ">" + esc(c.name) + "</text>");
84
+ var bx = st.padX + c.nameW + 6;
85
+ c.badges.forEach(function (b) {
86
+ var bh = st.badgeSize + 5;
87
+ out.push('<rect x="' + n(bx) + '" y="' + n(cy - bh / 2) + '" width="' + n(b.w) + '" height="' + bh + '" rx="3" fill="' + C.badgeBg + '"/>');
88
+ out.push('<text x="' + n(bx + st.badgePad) + '" y="' + n(cy + st.badgeSize * 0.36) + '" fill="' + C.badgeText +
89
+ '" font-family="' + FONT + '" font-size="' + st.badgeSize + '">' + esc(b.t) + "</text>");
90
+ bx += b.w + st.badgeGap;
91
+ });
92
+ if (c.pk) out.push(keyIcon(w - st.padX - c.typeW - st.keyW + 1, cy));
93
+ out.push('<text x="' + (w - st.padX) + '" y="' + base + '" text-anchor="end" fill="' + C.type + '" font-family="' + FONT +
94
+ '" font-size="' + st.rowSize + '">' + esc(c.type) + "</text>");
95
+ out.push("</g>");
96
+ });
97
+ out.push("</g>");
98
+ return out.join("");
99
+ }
100
+
101
+ function anchorY(model, g, p, colId) {
102
+ var st = model.style, i = g.rows[colId];
103
+ if (i === undefined) return p[1] + st.headerH / 2;
104
+ return p[1] + st.headerH + i * st.rowH + st.rowH / 2;
105
+ }
106
+
107
+ /* Pick sides: facing sides when tables are apart horizontally, both right when stacked. */
108
+ function edgeGeom(model, geo, pos, r) {
109
+ var ga = geo[r.a.t], gb = geo[r.b.t], pa = pos[r.a.t], pb = pos[r.b.t];
110
+ if (!ga || !gb || !pa || !pb) return null;
111
+ var ya = anchorY(model, ga, pa, r.a.c), yb = anchorY(model, gb, pb, r.b.c);
112
+ var da, db;
113
+ var overlap = pa[0] < pb[0] + gb.w + 30 && pb[0] < pa[0] + ga.w + 30;
114
+ if (r.a.t === r.b.t || overlap) { da = 1; db = 1; }
115
+ else if (pa[0] + ga.w / 2 < pb[0] + gb.w / 2) { da = 1; db = -1; }
116
+ else { da = -1; db = 1; }
117
+ var xa = da > 0 ? pa[0] + ga.w : pa[0], xb = db > 0 ? pb[0] + gb.w : pb[0];
118
+ var off;
119
+ if (da === db) off = 40 + Math.min(160, Math.abs(ya - yb) * 0.25) + Math.max(0, (da > 0 ? Math.max(xa, xb) - Math.min(xa, xb) : 0));
120
+ else off = Math.max(40, Math.abs(xb - xa) / 2);
121
+ var offA = off, offB = off;
122
+ if (da === db && da > 0) { offA = off - (Math.max(xa, xb) - xa); offB = off - (Math.max(xa, xb) - xb); offA = Math.max(offA, 40); offB = Math.max(offB, 40); }
123
+ var d = "M" + n(xa) + " " + n(ya) + "C" + n(xa + da * offA) + " " + n(ya) + " " + n(xb + db * offB) + " " + n(yb) + " " + n(xb) + " " + n(yb);
124
+ return { d: d, xa: xa, ya: ya, da: da, xb: xb, yb: yb, db: db };
125
+ }
126
+
127
+ function marker(card, x, y, dir) {
128
+ var s = [], st = ' stroke="' + C.edge + '" stroke-width="1.2" fill="none"';
129
+ function bar(o) { s.push('<path d="M' + n(x + dir * o) + " " + n(y - 6) + "v12" + '"' + st + "/>"); }
130
+ function crow() {
131
+ s.push('<path d="M' + n(x + dir * 11) + " " + n(y) + "L" + n(x) + " " + n(y - 6) + "M" + n(x + dir * 11) + " " + n(y) + "L" + n(x) + " " + n(y + 6) + '"' + st + "/>");
132
+ }
133
+ function circle(o) {
134
+ s.push('<circle cx="' + n(x + dir * o) + '" cy="' + n(y) + '" r="3.5" fill="' + C.bg + '" stroke="' + C.edge + '" stroke-width="1.2"/>');
135
+ }
136
+ if (card === "one") { bar(7); }
137
+ else if (card === "many") { crow(); }
138
+ else if (card === "zeroOne") { bar(6); circle(14); }
139
+ else if (card === "zeroMany") { crow(); circle(16); }
140
+ return s.join("");
141
+ }
142
+
143
+ function renderEdge(model, geo, pos, r) {
144
+ var e = edgeGeom(model, geo, pos, r);
145
+ if (!e) return "";
146
+ return '<g class="e" data-a="' + esc(r.a.t) + '" data-ac="' + esc(r.a.c) + '" data-b="' + esc(r.b.t) + '" data-bc="' + esc(r.b.c) + '">' +
147
+ '<path class="ep" d="' + e.d + '" stroke="' + C.edge + '" stroke-width="1.2" fill="none"/>' +
148
+ marker(r.a.card, e.xa, e.ya, e.da) + marker(r.b.card, e.xb, e.yb, e.db) + "</g>";
149
+ }
150
+
151
+ function subset(model, only) {
152
+ if (!only) return model;
153
+ var keep = {};
154
+ only.forEach(function (id) { keep[id] = true; });
155
+ return {
156
+ style: model.style,
157
+ tables: model.tables.filter(function (t) { return keep[t.id]; }),
158
+ rels: model.rels.filter(function (r) { return keep[r.a.t] && keep[r.b.t]; }),
159
+ };
160
+ }
161
+
162
+ function renderEdges(model, pos, mode, geo) {
163
+ geo = geo || geometry(model, mode);
164
+ return model.rels.map(function (r) { return renderEdge(model, geo, pos, r); }).join("");
165
+ }
166
+
167
+ function renderInner(model, pos, mode) {
168
+ var geo = geometry(model, mode);
169
+ var tables = model.tables.map(function (t) { return pos[t.id] ? renderTable(model, t, geo[t.id], pos[t.id]) : ""; }).join("");
170
+ return '<g class="edges">' + renderEdges(model, pos, mode, geo) + '</g><g class="tables">' + tables + "</g>";
171
+ }
172
+
173
+ function bounds(model, pos, mode) {
174
+ var geo = geometry(model, mode), b = null;
175
+ model.tables.forEach(function (t) {
176
+ var p = pos[t.id];
177
+ if (!p) return;
178
+ var g = geo[t.id];
179
+ if (!b) b = [p[0], p[1], p[0] + g.w, p[1] + g.h];
180
+ else b = [Math.min(b[0], p[0]), Math.min(b[1], p[1]), Math.max(b[2], p[0] + g.w), Math.max(b[3], p[1] + g.h)];
181
+ });
182
+ return b || [0, 0, 100, 100];
183
+ }
184
+
185
+ /* Standalone SVG document. opts: {mode, only: [ids], fontCss, pad} */
186
+ function renderSvg(model, pos, opts) {
187
+ opts = opts || {};
188
+ var mode = opts.mode || "full", m = subset(model, opts.only), pad = opts.pad == null ? 40 : opts.pad;
189
+ var edgePad = 60;
190
+ var b = bounds(m, pos, mode);
191
+ var x0 = b[0] - pad - edgePad, y0 = b[1] - pad, w = b[2] - b[0] + 2 * (pad + edgePad), h = b[3] - b[1] + 2 * pad;
192
+ var style = opts.fontCss ? "<style>" + opts.fontCss + "</style>" : "";
193
+ return '<svg xmlns="http://www.w3.org/2000/svg" width="' + n(w) + '" height="' + n(h) + '" viewBox="' + n(x0) + " " + n(y0) + " " + n(w) + " " + n(h) + '">' +
194
+ style + '<rect x="' + n(x0) + '" y="' + n(y0) + '" width="' + n(w) + '" height="' + n(h) + '" fill="' + C.bg + '"/>' +
195
+ renderInner(m, pos, mode) + "</svg>";
196
+ }
197
+
198
+ /* Tables within `depth` relationship hops of `focus`. */
199
+ function neighbourhood(model, focus, depth) {
200
+ var adj = {};
201
+ model.rels.forEach(function (r) {
202
+ (adj[r.a.t] = adj[r.a.t] || []).push(r.b.t);
203
+ (adj[r.b.t] = adj[r.b.t] || []).push(r.a.t);
204
+ });
205
+ var seen = {}, frontier = [focus], out = [focus];
206
+ seen[focus] = true;
207
+ for (var d = 0; d < depth; d++) {
208
+ var next = [];
209
+ frontier.forEach(function (id) {
210
+ (adj[id] || []).forEach(function (o) { if (!seen[o]) { seen[o] = true; next.push(o); out.push(o); } });
211
+ });
212
+ frontier = next;
213
+ }
214
+ return out;
215
+ }
216
+
217
+ root.qdbd = {
218
+ colors: C,
219
+ geometry: geometry,
220
+ renderTable: renderTable,
221
+ renderEdges: renderEdges,
222
+ renderInner: renderInner,
223
+ renderSvg: renderSvg,
224
+ bounds: bounds,
225
+ neighbourhood: neighbourhood,
226
+ esc: esc,
227
+ };
228
+ root.qdbdRenderSvg = renderSvg;
229
+ root.qdbdNeighbourhood = neighbourhood;
230
+ })(typeof window !== "undefined" ? window : globalThis);
@@ -0,0 +1,83 @@
1
+ :root {
2
+ --bg: #f4f5f4;
3
+ --blue: #2b5797;
4
+ --ink: #333;
5
+ --muted: #8a8f96;
6
+ --panel: #ffffff;
7
+ --line: #dfe3e8;
8
+ }
9
+ * { box-sizing: border-box; }
10
+ html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink);
11
+ font-family: Inter, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; overflow: hidden; }
12
+ #app { position: fixed; inset: 0; display: flex; }
13
+ #stage { position: relative; flex: 1; overflow: hidden; }
14
+ #canvas { width: 100%; height: 100%; display: block; cursor: grab; touch-action: none; user-select: none; }
15
+ #canvas.panning { cursor: grabbing; }
16
+
17
+ /* states */
18
+ .t, .e { transition: opacity .15s; }
19
+ .focus .t.dim, .focus .e.dim { opacity: .12; }
20
+ .e.hl .ep { stroke: var(--blue); stroke-width: 2.2; }
21
+ .e.hl path, .e.hl circle { stroke: var(--blue); }
22
+ .r.hl .rb { fill: #dbe6f6; fill-opacity: 1; }
23
+ .r:hover .rb { fill: #eef3fa; fill-opacity: 1; }
24
+ .t.flash .tb { stroke: #f0a020; stroke-width: 3; }
25
+ .t { cursor: pointer; }
26
+ .serve .t { cursor: move; }
27
+
28
+ /* toolbar (top right, like QuickDBD's zoom controls) */
29
+ .bar { position: absolute; top: 14px; right: 16px; display: flex; gap: 6px; align-items: center; }
30
+ .bar button, .seg button { border: 0; background: transparent; color: #555; font: inherit; cursor: pointer;
31
+ padding: 6px 9px; border-radius: 4px; }
32
+ .bar button:hover, .seg button:hover { background: #e4e7ea; }
33
+ .zoomval { min-width: 48px; text-align: center; color: #666; font-variant-numeric: tabular-nums; }
34
+ .seg { display: flex; background: #e9ecee; border-radius: 6px; padding: 2px; }
35
+ .seg button.on { background: #fff; color: var(--blue); box-shadow: 0 1px 2px rgba(0,0,0,.12); }
36
+ .sep { width: 1px; height: 20px; background: #d5d9dd; margin: 0 4px; }
37
+
38
+ /* search (top left) */
39
+ .search { position: absolute; top: 14px; left: 16px; width: 260px; }
40
+ .search input { width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px; font: inherit;
41
+ background: #fff; outline: none; }
42
+ .search input:focus { border-color: var(--blue); }
43
+ .results { margin-top: 4px; background: #fff; border: 1px solid var(--line); border-radius: 6px; max-height: 300px;
44
+ overflow: auto; display: none; box-shadow: 0 4px 14px rgba(0,0,0,.08); }
45
+ .results.open { display: block; }
46
+ .results div { padding: 6px 10px; cursor: pointer; }
47
+ .results div.sel, .results div:hover { background: #eef3fa; }
48
+ .results small { color: var(--muted); margin-left: 6px; }
49
+
50
+ /* minimap (bottom right) */
51
+ .minimap { position: absolute; right: 16px; bottom: 16px; width: 200px; height: 140px; background: rgba(255,255,255,.9);
52
+ border: 1px solid var(--line); border-radius: 6px; overflow: hidden; cursor: pointer; }
53
+ .minimap svg { width: 100%; height: 100%; display: block; }
54
+ .minimap .vpr { fill: rgba(43,87,151,.12); stroke: var(--blue); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
55
+
56
+ .hint { position: absolute; left: 16px; bottom: 14px; color: var(--muted); font-size: 12px; }
57
+
58
+ /* serve: editor pane */
59
+ #side { width: 420px; display: flex; flex-direction: column; background: #343a40; color: #ddd; border-right: 1px solid #222; }
60
+ #side.hidden { display: none; }
61
+ .tabs { display: flex; overflow-x: auto; background: #2b3035; flex: none; }
62
+ .tabs button { background: transparent; color: #aab; border: 0; padding: 8px 12px; font: inherit; cursor: pointer; white-space: nowrap; }
63
+ .tabs button.on { color: #fff; background: #343a40; }
64
+ .tabs button .dirty { color: #f0a020; }
65
+ #editor { flex: 1; min-height: 0; position: relative; }
66
+ #editor .CodeMirror, #editor textarea { position: absolute; inset: 0; height: 100%; width: 100%; font-size: 13px;
67
+ font-family: Menlo, Consolas, monospace; background: #343a40; color: #ddd; border: 0; padding: 6px; resize: none; }
68
+ #problems { height: 140px; flex: none; overflow: auto; border-top: 2px solid #4caf50; padding: 8px 10px;
69
+ font-family: Menlo, Consolas, monospace; font-size: 12px; color: #ccc; }
70
+ #problems.bad { border-top-color: #e57373; }
71
+ #problems .err { color: #ff9b9b; cursor: pointer; }
72
+ #problems .warn { color: #f0c674; cursor: pointer; }
73
+ .banner { background: #f0a020; color: #222; padding: 6px 10px; font-size: 12px; display: none; }
74
+ .banner.open { display: block; }
75
+ .banner button { margin-left: 8px; }
76
+ .cm-qdbd-op { color: #f0a020; }
77
+ .cm-qdbd-kw { color: #8fbcff; }
78
+ .CodeMirror-gutters { background: #2f353a !important; border-right: 0 !important; }
79
+ .cm-s-default .cm-comment { color: #7f8c8d; }
80
+ .cm-s-default .cm-header { color: #6fc3df; }
81
+ .CodeMirror-cursor { border-left-color: #fff !important; }
82
+ .CodeMirror-selected { background: #4a525a !important; }
83
+ .lineerr { background: rgba(229,115,115,.18); }