@sqg/sqg 0.18.0 → 0.20.0
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/README.md +1 -0
- package/dist/index.mjs +2790 -2594
- package/dist/sqg.mjs +233 -31
- package/dist/templates/java-duckdb-arrow.hbs +3 -1
- package/dist/ui-public/assets/index-C22caD-U.js +45 -0
- package/dist/ui-public/assets/index-DQWvi9s-.css +1 -0
- package/dist/ui-public/index.html +2 -2
- package/dist/ui-server.mjs +29 -78
- package/package.json +2 -2
- package/dist/ui-public/assets/index-BIikjK2O.js +0 -45
- package/dist/ui-public/assets/index-DHD4h34g.css +0 -2
package/dist/sqg.mjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { exit } from "node:process";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import consola, { LogLevels } from "consola";
|
|
5
|
-
import updateNotifier from "update-notifier";
|
|
6
5
|
import pc from "picocolors";
|
|
6
|
+
import updateNotifier from "update-notifier";
|
|
7
7
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
8
8
|
import * as clack from "@clack/prompts";
|
|
9
9
|
import { randomUUID } from "node:crypto";
|
|
@@ -229,11 +229,18 @@ SQL Annotation Syntax:
|
|
|
229
229
|
\${varName} Reference a variable in SQL
|
|
230
230
|
|
|
231
231
|
Modifiers:
|
|
232
|
-
:one
|
|
233
|
-
:pluck
|
|
234
|
-
:all
|
|
235
|
-
:batch
|
|
236
|
-
:appender
|
|
232
|
+
:one Return single row (or null) instead of array
|
|
233
|
+
:pluck Return single column value (requires exactly 1 column)
|
|
234
|
+
:all Return all rows (default)
|
|
235
|
+
:batch Generate a JDBC batch method for an EXEC (Java only)
|
|
236
|
+
:appender Generate bulk insert appender for TABLE annotation
|
|
237
|
+
:result=Name Name (and share) the row type (Java only). Annotate ONE query
|
|
238
|
+
with :result=Name — every other query in the same file with the
|
|
239
|
+
same column shape automatically gets the same name; you do NOT
|
|
240
|
+
need to repeat the modifier on each query.
|
|
241
|
+
Without :result=, each query keeps its own per-query row type.
|
|
242
|
+
Exception: SELECT * matching a -- TABLE schema (same columns,
|
|
243
|
+
same order) auto-uses the table's row type with no annotation.
|
|
237
244
|
|
|
238
245
|
Example:
|
|
239
246
|
-- MIGRATE 1
|
|
@@ -724,7 +731,7 @@ const parser = LRParser.deserialize({
|
|
|
724
731
|
maxTerm: 34,
|
|
725
732
|
skippedNodes: [0],
|
|
726
733
|
repeatNodeCount: 6,
|
|
727
|
-
tokenData: "$KR~RqOX#YXY'wYZ(iZ]#Y]^$W^p#Ypq'wqr#Yrs(}st#Ytu6^uw#Ywx9[xz#Yz{%_{}#Y}!OKi!O!P#Y!P!Q#2P!Q![$A]![!]$Bu!]!_#Y!_!`$Eu!`!b#Y!b!c$Fu!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#YU#_]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YS$ZTOz$Wz{$j{;'S$W;'S;=`%X<%lO$WS$mVOz$Wz{$j{!P$W!P!Q%S!Q;'S$W;'S;=`%X<%lO$WS%XOnSS%[P;=`<%l$WU%d__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!P#Y!P!Q&c!Q;'S#Y;'S;=`'q<%lO#YU&jVnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'UV_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'nP;=`<%l'PU'tP;=`<%l#Y~'|Xj~OX$WXY'wYp$Wpq'wqz$Wz{$j{;'S$W;'S;=`%X<%lO$W~(nTk~Oz$Wz{$j{;'S$W;'S;=`%X<%lO$WU)Sb_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U*_ZOY*[YZ$WZr*[rs+Qsz*[z{+f{#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U+VT]QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU+i]OY*[YZ$WZr*[rs+Qsz*[z{+f{!P*[!P!Q,b!Q#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U,gWnSOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-SWOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-qO]QQ-tTOY-PYZ-PZ;'S-P;'S;=`.T<%lO-PQ.WP;=`<%l-PU.^VOY*[YZ*[Zz*[z{+f{;'S*[;'S;=`.s<%lO*[U.vP;=`<%l*[U/Q]]Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU0Od_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{!P(}!P!Q1^!Q#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U1e_nS_QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ2i__QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ3oV]Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ4Z[_QOX2dXY-PYZ-PZ]2d]^-P^p2dpq-Pqt2dtu-Pu;'S2d;'S;=`5P<%lO2dQ5SP;=`<%l2dU5[^_QOX(}XY*[YZ*[Z](}]^*[^p(}pq*[qt(}tu*[uz(}z{/y{;'S(};'S;=`6W<%lO(}U6ZP;=`<%l(}U6cV_QOz$Wz{$j{#o$W#o#p6x#p;'S$W;'S;=`%X<%lO$WU6{]Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o;'S$W;'S;=`%X<%lO$WU7w_Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o#q$W#q#r8v#r;'S$W;'S;=`%X<%lO$WU8{TaQOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU9ab_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[U:lZOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU;dT^QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU;v]OY:iYZ$WZw:iwx;_xz:iz{;s{!P:i!P!Q<o!Q#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU<tWnSOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q=aWOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>OO^QQ>RXOY=^YZ=^Zw=^wx>nx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>sW^QOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q?`P;=`<%l=^U?fZOY:iYZ:iZw:iwx@Xxz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU@^Z^QOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iUASP;=`<%l:iUA^]^Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YUB[d_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{!P9[!P!QCj!Q#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UCq_nS_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQDu__QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQE{V^Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQFg`_QOXDpXY=^YZ=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxGix#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQGp_^Q_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQHrP;=`<%lDpUHzb_QOX9[XY:iYZ:iZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxJSxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UJZb^Q_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UKfP;=`<%l9[VKn__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{}#Y}!OLm!O;'S#Y;'S;=`'q<%lO#YVLthQR_QOXN`XY!&|YZ$WZ]N`]^! c^pN`pq!&|qtN`tu! cuzN`z{!#q{!dN`!d!e!=`!e!gN`!g!h!Ft!h!oN`!o!p!Ja!p!sN`!s!t#!`!t!vN`!v!w#'U!w;'SN`;'S;=`!&v<%lON`VNg^QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V! hVQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!!SXQROY! cYZ$WZz! cz{! }{!P! c!P!Q!!o!Q;'S! c;'S;=`!#k<%lO! cV!!vSnSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#XSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#hP;=`<%l!#SV!#nP;=`<%l! cV!#x`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!PN`!P!Q!$z!Q;'SN`;'S;=`!&v<%lON`V!%TZnSQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!%}ZQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!&sP;=`<%l!%vV!&yP;=`<%lN`V!'RdQROX! cXY!&|YZ$WZp! cpq!&|qz! cz{! }{!d! c!d!e!(a!e!g! c!g!h!.l!h!o! c!o!p!0p!p!s! c!s!t!4W!t!v! c!v!w!6|!w;'S! c;'S;=`!#k<%lO! cV!(fXQROY! cYZ$WZz! cz{! }{!c! c!c!d!)R!d;'S! c;'S;=`!#k<%lO! cV!)WXQROY! cYZ$WZz! cz{! }{!u! c!u!v!)s!v;'S! c;'S;=`!#k<%lO! cV!)xXQROY! cYZ$WZz! cz{! }{!g! c!g!h!*e!h;'S! c;'S;=`!#k<%lO! cV!*jXQROY! cYZ$WZz! cz{! }{!n! c!n!o!+V!o;'S! c;'S;=`!#k<%lO! cV!+[XQROY! cYZ$WZz! cz{! }{!k! c!k!l!+w!l;'S! c;'S;=`!#k<%lO! cV!+|XQROY! cYZ$WZz! cz{! }{!p! c!p!q!,i!q;'S! c;'S;=`!#k<%lO! cV!,nXQROY! cYZ$WZz! cz{! }{!g! c!g!h!-Z!h;'S! c;'S;=`!#k<%lO! cV!-`YQROX! cXY!.OYZ$WZp! cpq!.Oqz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.VVYRQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.qXQROY! cYZ$WZz! cz{! }{!z! c!z!{!/^!{;'S! c;'S;=`!#k<%lO! cV!/cXQROY! cYZ$WZz! cz{! }{!g! c!g!h!0O!h;'S! c;'S;=`!#k<%lO! cV!0TXQROY! cYZ$WZz! cz{! }{!e! c!e!f!-Z!f;'S! c;'S;=`!#k<%lO! cV!0uXQROY! cYZ$WZz! cz{! }{!k! c!k!l!1b!l;'S! c;'S;=`!#k<%lO! cV!1gXQROY! cYZ$WZz! cz{! }{!i! c!i!j!2S!j;'S! c;'S;=`!#k<%lO! cV!2XXQROY! cYZ$WZz! cz{! }{!t! c!t!u!2t!u;'S! c;'S;=`!#k<%lO! cV!2yXQROY! cYZ$WZz! cz{! }{!c! c!c!d!3f!d;'S! c;'S;=`!#k<%lO! cV!3kXQROY! cYZ$WZz! cz{! }{!v! c!v!w!,i!w;'S! c;'S;=`!#k<%lO! cV!4]XQROY! cYZ$WZz! cz{! }{!w! c!w!x!4x!x;'S! c;'S;=`!#k<%lO! cV!4}XQROY! cYZ$WZz! cz{! }{!g! c!g!h!5j!h;'S! c;'S;=`!#k<%lO! cV!5oXQROY! cYZ$WZz! cz{! }{!t! c!t!u!6[!u;'S! c;'S;=`!#k<%lO! cV!6aXQROY! cYZ$WZz! cz{! }{!{! c!{!|!-Z!|;'S! c;'S;=`!#k<%lO! cV!7RZQROY! cYZ$WZz! cz{! }{!c! c!c!d!7t!d!g! c!g!h!9W!h;'S! c;'S;=`!#k<%lO! cV!7yXQROY! cYZ$WZz! cz{! }{!d! c!d!e!8f!e;'S! c;'S;=`!#k<%lO! cV!8kXQROY! cYZ$WZz! cz{! }{!n! c!n!o!,i!o;'S! c;'S;=`!#k<%lO! cV!9]XQROY! cYZ$WZz! cz{! }{!u! c!u!v!9x!v;'S! c;'S;=`!#k<%lO! cV!9}XQROY! cYZ$WZz! cz{! }{!v! c!v!w!:j!w;'S! c;'S;=`!#k<%lO! cV!:oXQROY! cYZ$WZz! cz{! }{!f! c!f!g!;[!g;'S! c;'S;=`!#k<%lO! cV!;aXQROY! cYZ$WZz! cz{! }{!c! c!c!d!;|!d;'S! c;'S;=`!#k<%lO! cV!<RXQROY! cYZ$WZz! cz{! }{!v! c!v!w!<n!w;'S! c;'S;=`!#k<%lO! cV!<sXQROY! cYZ$WZz! cz{! }{!c! c!c!d!-Z!d;'S! c;'S;=`!#k<%lO! cV!=g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!>i!d;'SN`;'S;=`!&v<%lON`V!>p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v!?r!v;'SN`;'S;=`!&v<%lON`V!?y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!@{!h;'SN`;'S;=`!&v<%lON`V!AS`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!BU!o;'SN`;'S;=`!&v<%lON`V!B]`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!C_!l;'SN`;'S;=`!&v<%lON`V!Cf`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!pN`!p!q!Dh!q;'SN`;'S;=`!&v<%lON`V!Do`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!Eq!h;'SN`;'S;=`!&v<%lON`V!Ex^QR_QOXN`XY!.OYZ$WZ]N`]^! c^pN`pq!.OqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V!F{`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!zN`!z!{!G}!{;'SN`;'S;=`!&v<%lON`V!HU`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!IW!h;'SN`;'S;=`!&v<%lON`V!I_`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!eN`!e!f!Eq!f;'SN`;'S;=`!&v<%lON`V!Jh`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!Kj!l;'SN`;'S;=`!&v<%lON`V!Kq`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!iN`!i!j!Ls!j;'SN`;'S;=`!&v<%lON`V!Lz`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u!M|!u;'SN`;'S;=`!&v<%lON`V!NT`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d# V!d;'SN`;'S;=`!&v<%lON`V# ^`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w!Dh!w;'SN`;'S;=`!&v<%lON`V#!g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!wN`!w!x##i!x;'SN`;'S;=`!&v<%lON`V##p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h#$r!h;'SN`;'S;=`!&v<%lON`V#$y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u#%{!u;'SN`;'S;=`!&v<%lON`V#&S`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!{N`!{!|!Eq!|;'SN`;'S;=`!&v<%lON`V#']bQR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#(e!d!gN`!g!h#*w!h;'SN`;'S;=`!&v<%lON`V#(l`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!dN`!d!e#)n!e;'SN`;'S;=`!&v<%lON`V#)u`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!Dh!o;'SN`;'S;=`!&v<%lON`V#+O`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v#,Q!v;'SN`;'S;=`!&v<%lON`V#,X`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#-Z!w;'SN`;'S;=`!&v<%lON`V#-b`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!fN`!f!g#.d!g;'SN`;'S;=`!&v<%lON`V#.k`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#/m!d;'SN`;'S;=`!&v<%lON`V#/t`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#0v!w;'SN`;'S;=`!&v<%lON`V#0}`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!Eq!d;'SN`;'S;=`!&v<%lON`V#2U]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{#2}{;'S#Y;'S;=`'q<%lO#YV#3Sj_QOX#4tXY#8uYZ#8uZ]#4t]^#5r^p#4tpq#8uqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#Js!Q!d#4t!d!e$ p!e!g#4t!g!h$*_!h!o#4t!o!p$-k!p!s#4t!s!t$3P!t!v#4t!v!w$7a!w;'S#4t;'S;=`#8o<%lO#4tV#4y]_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV#5uTOz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#6XVOz#5rz{#6U{!P#5r!P!Q#6n!Q;'S#5r;'S;=`#6u<%lO#5rV#6uORRnSV#6xP;=`<%l#5rV#7Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#8P!Q;'S#4t;'S;=`#8o<%lO#4tV#8YVRRnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PV#8rP;=`<%l#4tV#8xdOX#5rXY#8uYZ#8uZp#5rpq#8uqz#5rz{#6U{!d#5r!d!e#:W!e!g#5r!g!h#?o!h!o#5r!o!p#AZ!p!s#5r!s!t#Cw!t!v#5r!v!w#E{!w;'S#5r;'S;=`#6u<%lO#5rV#:ZVOz#5rz{#6U{!c#5r!c!d#:p!d;'S#5r;'S;=`#6u<%lO#5rV#:sVOz#5rz{#6U{!u#5r!u!v#;Y!v;'S#5r;'S;=`#6u<%lO#5rV#;]VOz#5rz{#6U{!g#5r!g!h#;r!h;'S#5r;'S;=`#6u<%lO#5rV#;uVOz#5rz{#6U{!n#5r!n!o#<[!o;'S#5r;'S;=`#6u<%lO#5rV#<_VOz#5rz{#6U{!k#5r!k!l#<t!l;'S#5r;'S;=`#6u<%lO#5rV#<wVOz#5rz{#6U{!p#5r!p!q#=^!q;'S#5r;'S;=`#6u<%lO#5rV#=aVOz#5rz{#6U{!g#5r!g!h#=v!h;'S#5r;'S;=`#6u<%lO#5rV#=yYOX#5rXY#>iYZ#?ZZp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#>nXUROX#5rXY#>iYp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?`TUROz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?rVOz#5rz{#6U{!z#5r!z!{#@X!{;'S#5r;'S;=`#6u<%lO#5rV#@[VOz#5rz{#6U{!g#5r!g!h#@q!h;'S#5r;'S;=`#6u<%lO#5rV#@tVOz#5rz{#6U{!e#5r!e!f#=v!f;'S#5r;'S;=`#6u<%lO#5rV#A^VOz#5rz{#6U{!k#5r!k!l#As!l;'S#5r;'S;=`#6u<%lO#5rV#AvVOz#5rz{#6U{!i#5r!i!j#B]!j;'S#5r;'S;=`#6u<%lO#5rV#B`VOz#5rz{#6U{!t#5r!t!u#Bu!u;'S#5r;'S;=`#6u<%lO#5rV#BxVOz#5rz{#6U{!c#5r!c!d#C_!d;'S#5r;'S;=`#6u<%lO#5rV#CbVOz#5rz{#6U{!v#5r!v!w#=^!w;'S#5r;'S;=`#6u<%lO#5rV#CzVOz#5rz{#6U{!w#5r!w!x#Da!x;'S#5r;'S;=`#6u<%lO#5rV#DdVOz#5rz{#6U{!g#5r!g!h#Dy!h;'S#5r;'S;=`#6u<%lO#5rV#D|VOz#5rz{#6U{!t#5r!t!u#Ec!u;'S#5r;'S;=`#6u<%lO#5rV#EfVOz#5rz{#6U{!{#5r!{!|#=v!|;'S#5r;'S;=`#6u<%lO#5rV#FOXOz#5rz{#6U{!c#5r!c!d#Fk!d!g#5r!g!h#Gm!h;'S#5r;'S;=`#6u<%lO#5rV#FnVOz#5rz{#6U{!d#5r!d!e#GT!e;'S#5r;'S;=`#6u<%lO#5rV#GWVOz#5rz{#6U{!n#5r!n!o#=^!o;'S#5r;'S;=`#6u<%lO#5rV#GpVOz#5rz{#6U{!u#5r!u!v#HV!v;'S#5r;'S;=`#6u<%lO#5rV#HYVOz#5rz{#6U{!v#5r!v!w#Ho!w;'S#5r;'S;=`#6u<%lO#5rV#HrVOz#5rz{#6U{!f#5r!f!g#IX!g;'S#5r;'S;=`#6u<%lO#5rV#I[VOz#5rz{#6U{!c#5r!c!d#Iq!d;'S#5r;'S;=`#6u<%lO#5rV#ItVOz#5rz{#6U{!v#5r!v!w#JZ!w;'S#5r;'S;=`#6u<%lO#5rV#J^VOz#5rz{#6U{!c#5r!c!d#=v!d;'S#5r;'S;=`#6u<%lO#5rV#Jz]nS_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#Kx]_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#LtTOz#Lqz{#MT{;'S#Lq;'S;=`#Mr<%lO#LqR#MWVOz#Lqz{#MT{!P#Lq!P!Q#Mm!Q;'S#Lq;'S;=`#Mr<%lO#LqR#MrORRR#MuP;=`<%l#LqR#M}__QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{!P#Ks!P!Q#N|!Q;'S#Ks;'S;=`$ j<%lO#KsR$ TVRR_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PR$ mP;=`<%l#KsV$ u__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$!t!d;'S#4t;'S;=`#8o<%lO#4tV$!y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$#x!v;'S#4t;'S;=`#8o<%lO#4tV$#}__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$$|!h;'S#4t;'S;=`#8o<%lO#4tV$%R__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$&Q!o;'S#4t;'S;=`#8o<%lO#4tV$&V__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$'U!l;'S#4t;'S;=`#8o<%lO#4tV$'Z__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!p#4t!p!q$(Y!q;'S#4t;'S;=`#8o<%lO#4tV$(___QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$)^!h;'S#4t;'S;=`#8o<%lO#4tV$)c^_QOX#4tXY#>iYZ#?ZZ]#4t]^#5r^p#4tpq#>iqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV$*d__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!z#4t!z!{$+c!{;'S#4t;'S;=`#8o<%lO#4tV$+h__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$,g!h;'S#4t;'S;=`#8o<%lO#4tV$,l__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!e#4t!e!f$)^!f;'S#4t;'S;=`#8o<%lO#4tV$-p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$.o!l;'S#4t;'S;=`#8o<%lO#4tV$.t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!i#4t!i!j$/s!j;'S#4t;'S;=`#8o<%lO#4tV$/x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$0w!u;'S#4t;'S;=`#8o<%lO#4tV$0|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$1{!d;'S#4t;'S;=`#8o<%lO#4tV$2Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$(Y!w;'S#4t;'S;=`#8o<%lO#4tV$3U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!w#4t!w!x$4T!x;'S#4t;'S;=`#8o<%lO#4tV$4Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$5X!h;'S#4t;'S;=`#8o<%lO#4tV$5^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$6]!u;'S#4t;'S;=`#8o<%lO#4tV$6b__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!{#4t!{!|$)^!|;'S#4t;'S;=`#8o<%lO#4tV$7fa_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$8k!d!g#4t!g!h$:s!h;'S#4t;'S;=`#8o<%lO#4tV$8p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!d#4t!d!e$9o!e;'S#4t;'S;=`#8o<%lO#4tV$9t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$(Y!o;'S#4t;'S;=`#8o<%lO#4tV$:x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$;w!v;'S#4t;'S;=`#8o<%lO#4tV$;|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$<{!w;'S#4t;'S;=`#8o<%lO#4tV$=Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!f#4t!f!g$>P!g;'S#4t;'S;=`#8o<%lO#4tV$>U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$?T!d;'S#4t;'S;=`#8o<%lO#4tV$?Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$@X!w;'S#4t;'S;=`#8o<%lO#4tV$@^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$)^!d;'S#4t;'S;=`#8o<%lO#4tV$AdeVP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$A]![!c#Y!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#Y~$Bze_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#Y~$DdeW~_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#YV$E|]qP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU$Fz__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#g#Y#g#h$Gy#h;'S#Y;'S;=`'q<%lO#YU$HO__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#X#Y#X#Y$H}#Y;'S#Y;'S;=`'q<%lO#YU$IS__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#h#Y#h#i$JR#i;'S#Y;'S;=`'q<%lO#YU$JY]pQ_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#Y",
|
|
734
|
+
tokenData: "$NX~RqOX#YXY'wYZ(iZ]#Y]^$W^p#Ypq'wqr#Yrs(}st#Ytu6^uw#Ywx9[xz#Yz{%_{}#Y}!OKi!O!P#Y!P!Q#2P!Q![$A]![!]$Bu!]!_#Y!_!`$H{!`!b#Y!b!c$I{!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#YU#_]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YS$ZTOz$Wz{$j{;'S$W;'S;=`%X<%lO$WS$mVOz$Wz{$j{!P$W!P!Q%S!Q;'S$W;'S;=`%X<%lO$WS%XOnSS%[P;=`<%l$WU%d__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!P#Y!P!Q&c!Q;'S#Y;'S;=`'q<%lO#YU&jVnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'UV_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'nP;=`<%l'PU'tP;=`<%l#Y~'|Xj~OX$WXY'wYp$Wpq'wqz$Wz{$j{;'S$W;'S;=`%X<%lO$W~(nTk~Oz$Wz{$j{;'S$W;'S;=`%X<%lO$WU)Sb_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U*_ZOY*[YZ$WZr*[rs+Qsz*[z{+f{#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U+VT]QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU+i]OY*[YZ$WZr*[rs+Qsz*[z{+f{!P*[!P!Q,b!Q#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U,gWnSOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-SWOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-qO]QQ-tTOY-PYZ-PZ;'S-P;'S;=`.T<%lO-PQ.WP;=`<%l-PU.^VOY*[YZ*[Zz*[z{+f{;'S*[;'S;=`.s<%lO*[U.vP;=`<%l*[U/Q]]Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU0Od_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{!P(}!P!Q1^!Q#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U1e_nS_QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ2i__QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ3oV]Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ4Z[_QOX2dXY-PYZ-PZ]2d]^-P^p2dpq-Pqt2dtu-Pu;'S2d;'S;=`5P<%lO2dQ5SP;=`<%l2dU5[^_QOX(}XY*[YZ*[Z](}]^*[^p(}pq*[qt(}tu*[uz(}z{/y{;'S(};'S;=`6W<%lO(}U6ZP;=`<%l(}U6cV_QOz$Wz{$j{#o$W#o#p6x#p;'S$W;'S;=`%X<%lO$WU6{]Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o;'S$W;'S;=`%X<%lO$WU7w_Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o#q$W#q#r8v#r;'S$W;'S;=`%X<%lO$WU8{TaQOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU9ab_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[U:lZOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU;dT^QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU;v]OY:iYZ$WZw:iwx;_xz:iz{;s{!P:i!P!Q<o!Q#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU<tWnSOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q=aWOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>OO^QQ>RXOY=^YZ=^Zw=^wx>nx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>sW^QOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q?`P;=`<%l=^U?fZOY:iYZ:iZw:iwx@Xxz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU@^Z^QOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iUASP;=`<%l:iUA^]^Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YUB[d_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{!P9[!P!QCj!Q#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UCq_nS_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQDu__QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQE{V^Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQFg`_QOXDpXY=^YZ=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxGix#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQGp_^Q_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQHrP;=`<%lDpUHzb_QOX9[XY:iYZ:iZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxJSxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UJZb^Q_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UKfP;=`<%l9[VKn__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{}#Y}!OLm!O;'S#Y;'S;=`'q<%lO#YVLthQR_QOXN`XY!&|YZ$WZ]N`]^! c^pN`pq!&|qtN`tu! cuzN`z{!#q{!dN`!d!e!=`!e!gN`!g!h!Ft!h!oN`!o!p!Ja!p!sN`!s!t#!`!t!vN`!v!w#'U!w;'SN`;'S;=`!&v<%lON`VNg^QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V! hVQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!!SXQROY! cYZ$WZz! cz{! }{!P! c!P!Q!!o!Q;'S! c;'S;=`!#k<%lO! cV!!vSnSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#XSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#hP;=`<%l!#SV!#nP;=`<%l! cV!#x`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!PN`!P!Q!$z!Q;'SN`;'S;=`!&v<%lON`V!%TZnSQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!%}ZQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!&sP;=`<%l!%vV!&yP;=`<%lN`V!'RdQROX! cXY!&|YZ$WZp! cpq!&|qz! cz{! }{!d! c!d!e!(a!e!g! c!g!h!.l!h!o! c!o!p!0p!p!s! c!s!t!4W!t!v! c!v!w!6|!w;'S! c;'S;=`!#k<%lO! cV!(fXQROY! cYZ$WZz! cz{! }{!c! c!c!d!)R!d;'S! c;'S;=`!#k<%lO! cV!)WXQROY! cYZ$WZz! cz{! }{!u! c!u!v!)s!v;'S! c;'S;=`!#k<%lO! cV!)xXQROY! cYZ$WZz! cz{! }{!g! c!g!h!*e!h;'S! c;'S;=`!#k<%lO! cV!*jXQROY! cYZ$WZz! cz{! }{!n! c!n!o!+V!o;'S! c;'S;=`!#k<%lO! cV!+[XQROY! cYZ$WZz! cz{! }{!k! c!k!l!+w!l;'S! c;'S;=`!#k<%lO! cV!+|XQROY! cYZ$WZz! cz{! }{!p! c!p!q!,i!q;'S! c;'S;=`!#k<%lO! cV!,nXQROY! cYZ$WZz! cz{! }{!g! c!g!h!-Z!h;'S! c;'S;=`!#k<%lO! cV!-`YQROX! cXY!.OYZ$WZp! cpq!.Oqz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.VVYRQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.qXQROY! cYZ$WZz! cz{! }{!z! c!z!{!/^!{;'S! c;'S;=`!#k<%lO! cV!/cXQROY! cYZ$WZz! cz{! }{!g! c!g!h!0O!h;'S! c;'S;=`!#k<%lO! cV!0TXQROY! cYZ$WZz! cz{! }{!e! c!e!f!-Z!f;'S! c;'S;=`!#k<%lO! cV!0uXQROY! cYZ$WZz! cz{! }{!k! c!k!l!1b!l;'S! c;'S;=`!#k<%lO! cV!1gXQROY! cYZ$WZz! cz{! }{!i! c!i!j!2S!j;'S! c;'S;=`!#k<%lO! cV!2XXQROY! cYZ$WZz! cz{! }{!t! c!t!u!2t!u;'S! c;'S;=`!#k<%lO! cV!2yXQROY! cYZ$WZz! cz{! }{!c! c!c!d!3f!d;'S! c;'S;=`!#k<%lO! cV!3kXQROY! cYZ$WZz! cz{! }{!v! c!v!w!,i!w;'S! c;'S;=`!#k<%lO! cV!4]XQROY! cYZ$WZz! cz{! }{!w! c!w!x!4x!x;'S! c;'S;=`!#k<%lO! cV!4}XQROY! cYZ$WZz! cz{! }{!g! c!g!h!5j!h;'S! c;'S;=`!#k<%lO! cV!5oXQROY! cYZ$WZz! cz{! }{!t! c!t!u!6[!u;'S! c;'S;=`!#k<%lO! cV!6aXQROY! cYZ$WZz! cz{! }{!{! c!{!|!-Z!|;'S! c;'S;=`!#k<%lO! cV!7RZQROY! cYZ$WZz! cz{! }{!c! c!c!d!7t!d!g! c!g!h!9W!h;'S! c;'S;=`!#k<%lO! cV!7yXQROY! cYZ$WZz! cz{! }{!d! c!d!e!8f!e;'S! c;'S;=`!#k<%lO! cV!8kXQROY! cYZ$WZz! cz{! }{!n! c!n!o!,i!o;'S! c;'S;=`!#k<%lO! cV!9]XQROY! cYZ$WZz! cz{! }{!u! c!u!v!9x!v;'S! c;'S;=`!#k<%lO! cV!9}XQROY! cYZ$WZz! cz{! }{!v! c!v!w!:j!w;'S! c;'S;=`!#k<%lO! cV!:oXQROY! cYZ$WZz! cz{! }{!f! c!f!g!;[!g;'S! c;'S;=`!#k<%lO! cV!;aXQROY! cYZ$WZz! cz{! }{!c! c!c!d!;|!d;'S! c;'S;=`!#k<%lO! cV!<RXQROY! cYZ$WZz! cz{! }{!v! c!v!w!<n!w;'S! c;'S;=`!#k<%lO! cV!<sXQROY! cYZ$WZz! cz{! }{!c! c!c!d!-Z!d;'S! c;'S;=`!#k<%lO! cV!=g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!>i!d;'SN`;'S;=`!&v<%lON`V!>p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v!?r!v;'SN`;'S;=`!&v<%lON`V!?y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!@{!h;'SN`;'S;=`!&v<%lON`V!AS`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!BU!o;'SN`;'S;=`!&v<%lON`V!B]`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!C_!l;'SN`;'S;=`!&v<%lON`V!Cf`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!pN`!p!q!Dh!q;'SN`;'S;=`!&v<%lON`V!Do`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!Eq!h;'SN`;'S;=`!&v<%lON`V!Ex^QR_QOXN`XY!.OYZ$WZ]N`]^! c^pN`pq!.OqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V!F{`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!zN`!z!{!G}!{;'SN`;'S;=`!&v<%lON`V!HU`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!IW!h;'SN`;'S;=`!&v<%lON`V!I_`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!eN`!e!f!Eq!f;'SN`;'S;=`!&v<%lON`V!Jh`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!Kj!l;'SN`;'S;=`!&v<%lON`V!Kq`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!iN`!i!j!Ls!j;'SN`;'S;=`!&v<%lON`V!Lz`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u!M|!u;'SN`;'S;=`!&v<%lON`V!NT`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d# V!d;'SN`;'S;=`!&v<%lON`V# ^`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w!Dh!w;'SN`;'S;=`!&v<%lON`V#!g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!wN`!w!x##i!x;'SN`;'S;=`!&v<%lON`V##p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h#$r!h;'SN`;'S;=`!&v<%lON`V#$y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u#%{!u;'SN`;'S;=`!&v<%lON`V#&S`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!{N`!{!|!Eq!|;'SN`;'S;=`!&v<%lON`V#']bQR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#(e!d!gN`!g!h#*w!h;'SN`;'S;=`!&v<%lON`V#(l`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!dN`!d!e#)n!e;'SN`;'S;=`!&v<%lON`V#)u`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!Dh!o;'SN`;'S;=`!&v<%lON`V#+O`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v#,Q!v;'SN`;'S;=`!&v<%lON`V#,X`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#-Z!w;'SN`;'S;=`!&v<%lON`V#-b`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!fN`!f!g#.d!g;'SN`;'S;=`!&v<%lON`V#.k`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#/m!d;'SN`;'S;=`!&v<%lON`V#/t`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#0v!w;'SN`;'S;=`!&v<%lON`V#0}`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!Eq!d;'SN`;'S;=`!&v<%lON`V#2U]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{#2}{;'S#Y;'S;=`'q<%lO#YV#3Sj_QOX#4tXY#8uYZ#8uZ]#4t]^#5r^p#4tpq#8uqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#Js!Q!d#4t!d!e$ p!e!g#4t!g!h$*_!h!o#4t!o!p$-k!p!s#4t!s!t$3P!t!v#4t!v!w$7a!w;'S#4t;'S;=`#8o<%lO#4tV#4y]_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV#5uTOz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#6XVOz#5rz{#6U{!P#5r!P!Q#6n!Q;'S#5r;'S;=`#6u<%lO#5rV#6uORRnSV#6xP;=`<%l#5rV#7Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#8P!Q;'S#4t;'S;=`#8o<%lO#4tV#8YVRRnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PV#8rP;=`<%l#4tV#8xdOX#5rXY#8uYZ#8uZp#5rpq#8uqz#5rz{#6U{!d#5r!d!e#:W!e!g#5r!g!h#?o!h!o#5r!o!p#AZ!p!s#5r!s!t#Cw!t!v#5r!v!w#E{!w;'S#5r;'S;=`#6u<%lO#5rV#:ZVOz#5rz{#6U{!c#5r!c!d#:p!d;'S#5r;'S;=`#6u<%lO#5rV#:sVOz#5rz{#6U{!u#5r!u!v#;Y!v;'S#5r;'S;=`#6u<%lO#5rV#;]VOz#5rz{#6U{!g#5r!g!h#;r!h;'S#5r;'S;=`#6u<%lO#5rV#;uVOz#5rz{#6U{!n#5r!n!o#<[!o;'S#5r;'S;=`#6u<%lO#5rV#<_VOz#5rz{#6U{!k#5r!k!l#<t!l;'S#5r;'S;=`#6u<%lO#5rV#<wVOz#5rz{#6U{!p#5r!p!q#=^!q;'S#5r;'S;=`#6u<%lO#5rV#=aVOz#5rz{#6U{!g#5r!g!h#=v!h;'S#5r;'S;=`#6u<%lO#5rV#=yYOX#5rXY#>iYZ#?ZZp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#>nXUROX#5rXY#>iYp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?`TUROz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?rVOz#5rz{#6U{!z#5r!z!{#@X!{;'S#5r;'S;=`#6u<%lO#5rV#@[VOz#5rz{#6U{!g#5r!g!h#@q!h;'S#5r;'S;=`#6u<%lO#5rV#@tVOz#5rz{#6U{!e#5r!e!f#=v!f;'S#5r;'S;=`#6u<%lO#5rV#A^VOz#5rz{#6U{!k#5r!k!l#As!l;'S#5r;'S;=`#6u<%lO#5rV#AvVOz#5rz{#6U{!i#5r!i!j#B]!j;'S#5r;'S;=`#6u<%lO#5rV#B`VOz#5rz{#6U{!t#5r!t!u#Bu!u;'S#5r;'S;=`#6u<%lO#5rV#BxVOz#5rz{#6U{!c#5r!c!d#C_!d;'S#5r;'S;=`#6u<%lO#5rV#CbVOz#5rz{#6U{!v#5r!v!w#=^!w;'S#5r;'S;=`#6u<%lO#5rV#CzVOz#5rz{#6U{!w#5r!w!x#Da!x;'S#5r;'S;=`#6u<%lO#5rV#DdVOz#5rz{#6U{!g#5r!g!h#Dy!h;'S#5r;'S;=`#6u<%lO#5rV#D|VOz#5rz{#6U{!t#5r!t!u#Ec!u;'S#5r;'S;=`#6u<%lO#5rV#EfVOz#5rz{#6U{!{#5r!{!|#=v!|;'S#5r;'S;=`#6u<%lO#5rV#FOXOz#5rz{#6U{!c#5r!c!d#Fk!d!g#5r!g!h#Gm!h;'S#5r;'S;=`#6u<%lO#5rV#FnVOz#5rz{#6U{!d#5r!d!e#GT!e;'S#5r;'S;=`#6u<%lO#5rV#GWVOz#5rz{#6U{!n#5r!n!o#=^!o;'S#5r;'S;=`#6u<%lO#5rV#GpVOz#5rz{#6U{!u#5r!u!v#HV!v;'S#5r;'S;=`#6u<%lO#5rV#HYVOz#5rz{#6U{!v#5r!v!w#Ho!w;'S#5r;'S;=`#6u<%lO#5rV#HrVOz#5rz{#6U{!f#5r!f!g#IX!g;'S#5r;'S;=`#6u<%lO#5rV#I[VOz#5rz{#6U{!c#5r!c!d#Iq!d;'S#5r;'S;=`#6u<%lO#5rV#ItVOz#5rz{#6U{!v#5r!v!w#JZ!w;'S#5r;'S;=`#6u<%lO#5rV#J^VOz#5rz{#6U{!c#5r!c!d#=v!d;'S#5r;'S;=`#6u<%lO#5rV#Jz]nS_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#Kx]_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#LtTOz#Lqz{#MT{;'S#Lq;'S;=`#Mr<%lO#LqR#MWVOz#Lqz{#MT{!P#Lq!P!Q#Mm!Q;'S#Lq;'S;=`#Mr<%lO#LqR#MrORRR#MuP;=`<%l#LqR#M}__QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{!P#Ks!P!Q#N|!Q;'S#Ks;'S;=`$ j<%lO#KsR$ TVRR_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PR$ mP;=`<%l#KsV$ u__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$!t!d;'S#4t;'S;=`#8o<%lO#4tV$!y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$#x!v;'S#4t;'S;=`#8o<%lO#4tV$#}__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$$|!h;'S#4t;'S;=`#8o<%lO#4tV$%R__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$&Q!o;'S#4t;'S;=`#8o<%lO#4tV$&V__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$'U!l;'S#4t;'S;=`#8o<%lO#4tV$'Z__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!p#4t!p!q$(Y!q;'S#4t;'S;=`#8o<%lO#4tV$(___QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$)^!h;'S#4t;'S;=`#8o<%lO#4tV$)c^_QOX#4tXY#>iYZ#?ZZ]#4t]^#5r^p#4tpq#>iqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV$*d__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!z#4t!z!{$+c!{;'S#4t;'S;=`#8o<%lO#4tV$+h__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$,g!h;'S#4t;'S;=`#8o<%lO#4tV$,l__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!e#4t!e!f$)^!f;'S#4t;'S;=`#8o<%lO#4tV$-p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$.o!l;'S#4t;'S;=`#8o<%lO#4tV$.t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!i#4t!i!j$/s!j;'S#4t;'S;=`#8o<%lO#4tV$/x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$0w!u;'S#4t;'S;=`#8o<%lO#4tV$0|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$1{!d;'S#4t;'S;=`#8o<%lO#4tV$2Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$(Y!w;'S#4t;'S;=`#8o<%lO#4tV$3U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!w#4t!w!x$4T!x;'S#4t;'S;=`#8o<%lO#4tV$4Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$5X!h;'S#4t;'S;=`#8o<%lO#4tV$5^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$6]!u;'S#4t;'S;=`#8o<%lO#4tV$6b__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!{#4t!{!|$)^!|;'S#4t;'S;=`#8o<%lO#4tV$7fa_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$8k!d!g#4t!g!h$:s!h;'S#4t;'S;=`#8o<%lO#4tV$8p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!d#4t!d!e$9o!e;'S#4t;'S;=`#8o<%lO#4tV$9t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$(Y!o;'S#4t;'S;=`#8o<%lO#4tV$:x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$;w!v;'S#4t;'S;=`#8o<%lO#4tV$;|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$<{!w;'S#4t;'S;=`#8o<%lO#4tV$=Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!f#4t!f!g$>P!g;'S#4t;'S;=`#8o<%lO#4tV$>U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$?T!d;'S#4t;'S;=`#8o<%lO#4tV$?Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$@X!w;'S#4t;'S;=`#8o<%lO#4tV$@^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$)^!d;'S#4t;'S;=`#8o<%lO#4tV$AdeVP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$A]![!c#Y!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#Y~$Bze_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#Y~$DdgW~_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!_#Y!_!`$E{!`!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#Y~$FQe_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$Gc![!c#Y!c!}$Gc!}#R#Y#R#S$Gc#S#T#Y#T#o$Gc#o;'S#Y;'S;=`'q<%lO#Y~$GjeW~_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$Gc![!c#Y!c!}$Gc!}#R#Y#R#S$Gc#S#T#Y#T#o$Gc#o;'S#Y;'S;=`'q<%lO#YV$IS]qP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU$JQ__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#g#Y#g#h$KP#h;'S#Y;'S;=`'q<%lO#YU$KU__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#X#Y#X#Y$LT#Y;'S#Y;'S;=`'q<%lO#YU$LY__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#h#Y#h#i$MX#i;'S#Y;'S;=`'q<%lO#YU$M`]pQ_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#Y",
|
|
728
735
|
tokenizers: [
|
|
729
736
|
0,
|
|
730
737
|
1,
|
|
@@ -774,6 +781,10 @@ var SQLQuery = class {
|
|
|
774
781
|
allColumns;
|
|
775
782
|
/** Database-reported parameter types (variable name → SQL type), set by database adapters */
|
|
776
783
|
parameterTypes;
|
|
784
|
+
/** Explicit row-type name from `:result=Name` modifier, when present. */
|
|
785
|
+
resultTypeOverride;
|
|
786
|
+
/** Final row-type identifier assigned by assignResultTypeNames (after introspection). */
|
|
787
|
+
resultTypeName;
|
|
777
788
|
constructor(filename, id, rawQuery, queryAnonymous, queryNamed, queryPositional, type, isOne, isPluck, isBatch, variables, config, line) {
|
|
778
789
|
this.filename = filename;
|
|
779
790
|
this.id = id;
|
|
@@ -887,6 +898,7 @@ function parseSQLQueries(filePath, extraVariables) {
|
|
|
887
898
|
const isOne = modifiers.includes(":one");
|
|
888
899
|
const isPluck = modifiers.includes(":pluck");
|
|
889
900
|
const isBatch = modifiers.includes(":batch");
|
|
901
|
+
const resultTypeOverride = modifiers.find((m) => m.startsWith(":result="))?.slice(8);
|
|
890
902
|
let configStr = getStr("Config", true);
|
|
891
903
|
if (configStr?.endsWith("*/")) configStr = configStr.slice(0, -2);
|
|
892
904
|
let config = null;
|
|
@@ -1041,6 +1053,7 @@ function parseSQLQueries(filePath, extraVariables) {
|
|
|
1041
1053
|
config
|
|
1042
1054
|
});
|
|
1043
1055
|
const query = new SQLQuery(filePath, name, sqlContentStr, sql.toSqlWithAnonymousPlaceholders(), sql.toSqlWithNamedPlaceholders(), sql.toSqlWithPositionalPlaceholders(), queryType, isOne, isPluck, isBatch, variables, config, annotationLine);
|
|
1056
|
+
query.resultTypeOverride = resultTypeOverride;
|
|
1044
1057
|
checkDuplicate(queryType, name);
|
|
1045
1058
|
queries.push(query);
|
|
1046
1059
|
consola.debug(`Added query: ${name} (${queryType})`);
|
|
@@ -1325,6 +1338,7 @@ const postgres = new class {
|
|
|
1325
1338
|
mode;
|
|
1326
1339
|
dynamicTypeCache = /* @__PURE__ */ new Map();
|
|
1327
1340
|
enumTypeCache = /* @__PURE__ */ new Map();
|
|
1341
|
+
tableOidCache = /* @__PURE__ */ new Map();
|
|
1328
1342
|
async startContainer(reporter) {
|
|
1329
1343
|
reporter?.onContainerStarting?.();
|
|
1330
1344
|
const container = await new PostgreSqlContainer("postgres:16-alpine").withDatabase("sqg-db").withUsername("sqg").withPassword("secret").start();
|
|
@@ -1375,10 +1389,17 @@ const postgres = new class {
|
|
|
1375
1389
|
if (enumType) return enumType;
|
|
1376
1390
|
return this.getTypeName(dataTypeID);
|
|
1377
1391
|
}
|
|
1392
|
+
async resolveTableOids(db, oids) {
|
|
1393
|
+
const missing = oids.filter((oid) => !this.tableOidCache.has(oid));
|
|
1394
|
+
if (missing.length === 0) return;
|
|
1395
|
+
const res = await db.query("SELECT oid::int AS oid, relname FROM pg_class WHERE oid = ANY($1)", [missing]);
|
|
1396
|
+
for (const row of res.rows) this.tableOidCache.set(Number(row.oid), row.relname);
|
|
1397
|
+
}
|
|
1378
1398
|
async initializeDatabase(queries, reporter) {
|
|
1379
1399
|
const externalUrl = process.env.SQG_POSTGRES_URL;
|
|
1380
1400
|
this.dynamicTypeCache = /* @__PURE__ */ new Map();
|
|
1381
1401
|
this.enumTypeCache = /* @__PURE__ */ new Map();
|
|
1402
|
+
this.tableOidCache = /* @__PURE__ */ new Map();
|
|
1382
1403
|
if (externalUrl) this.mode = new ExternalDbMode(externalUrl);
|
|
1383
1404
|
else {
|
|
1384
1405
|
const { connectionUri, container } = await this.startContainer(reporter);
|
|
@@ -1444,11 +1465,18 @@ const postgres = new class {
|
|
|
1444
1465
|
});
|
|
1445
1466
|
consola.debug("Columns:", columnNames);
|
|
1446
1467
|
consola.debug("Types:", columnTypes.map((t) => t.toString()));
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1468
|
+
const tableOids = Array.from(new Set(result.fields.map((f) => f.tableID).filter((oid) => oid && oid > 0)));
|
|
1469
|
+
await this.resolveTableOids(db, tableOids);
|
|
1470
|
+
query.columns = columnNames.map((name, index) => {
|
|
1471
|
+
const field = result.fields[index];
|
|
1472
|
+
const sourceTable = field.tableID && field.tableID > 0 ? this.tableOidCache.get(field.tableID) : void 0;
|
|
1473
|
+
return {
|
|
1474
|
+
name,
|
|
1475
|
+
type: columnTypes[index],
|
|
1476
|
+
nullable: true,
|
|
1477
|
+
sourceTable
|
|
1478
|
+
};
|
|
1479
|
+
});
|
|
1452
1480
|
}
|
|
1453
1481
|
if (query.isQuery) {
|
|
1454
1482
|
if (query.isOne) return result.rows[0] || null;
|
|
@@ -1486,6 +1514,7 @@ const postgres = new class {
|
|
|
1486
1514
|
await this.mode.close(this.db);
|
|
1487
1515
|
this.dynamicTypeCache = /* @__PURE__ */ new Map();
|
|
1488
1516
|
this.enumTypeCache = /* @__PURE__ */ new Map();
|
|
1517
|
+
this.tableOidCache = /* @__PURE__ */ new Map();
|
|
1489
1518
|
}
|
|
1490
1519
|
}();
|
|
1491
1520
|
//#endregion
|
|
@@ -1596,7 +1625,8 @@ const sqlite = new class {
|
|
|
1596
1625
|
return {
|
|
1597
1626
|
name: col.name,
|
|
1598
1627
|
type: col.type || probed.type || "unknown",
|
|
1599
|
-
nullable: col.table ? colInfo?.pk === 0 && colInfo?.notnull === 0 : probed.nullable
|
|
1628
|
+
nullable: col.table ? colInfo?.pk === 0 && colInfo?.notnull === 0 : probed.nullable,
|
|
1629
|
+
sourceTable: col.table ?? void 0
|
|
1600
1630
|
};
|
|
1601
1631
|
});
|
|
1602
1632
|
}
|
|
@@ -1666,13 +1696,13 @@ var TypeMapper = class {
|
|
|
1666
1696
|
* @param path - Optional prefix path for nested type references
|
|
1667
1697
|
* @returns Generated type declaration code, or empty string for primitive types
|
|
1668
1698
|
*/
|
|
1669
|
-
getDeclarations(column, path = "") {
|
|
1670
|
-
if (column.type instanceof StructType) return this.generateStructDeclaration(column, path);
|
|
1699
|
+
getDeclarations(column, path = "", nameOverride) {
|
|
1700
|
+
if (column.type instanceof StructType) return this.generateStructDeclaration(column, path, nameOverride);
|
|
1671
1701
|
if (column.type instanceof ListType) return this.getDeclarations({
|
|
1672
1702
|
name: column.name,
|
|
1673
1703
|
type: column.type.baseType,
|
|
1674
1704
|
nullable: true
|
|
1675
|
-
}, path);
|
|
1705
|
+
}, path, nameOverride);
|
|
1676
1706
|
return "";
|
|
1677
1707
|
}
|
|
1678
1708
|
};
|
|
@@ -1789,6 +1819,26 @@ var JavaTypeMapper = class JavaTypeMapper extends TypeMapper {
|
|
|
1789
1819
|
if (column.type instanceof EnumType && column.type.name) return path + pascalCase(column.type.name);
|
|
1790
1820
|
return super.getTypeName(column, path);
|
|
1791
1821
|
}
|
|
1822
|
+
/**
|
|
1823
|
+
* Returns the primitive Java type for a column when it's non-nullable and
|
|
1824
|
+
* its mapped type has a primitive equivalent (Integer→int, Long→long, etc.).
|
|
1825
|
+
* Falls back to {@link getTypeName} otherwise. Used for appender row types
|
|
1826
|
+
* to avoid auto-boxing on hot bulk-insert paths.
|
|
1827
|
+
*/
|
|
1828
|
+
getUnboxedTypeName(column, path = "") {
|
|
1829
|
+
const typeName = this.getTypeName(column, path);
|
|
1830
|
+
if (column.nullable) return typeName;
|
|
1831
|
+
return JavaTypeMapper.boxedToPrimitive[typeName] ?? typeName;
|
|
1832
|
+
}
|
|
1833
|
+
static boxedToPrimitive = {
|
|
1834
|
+
Integer: "int",
|
|
1835
|
+
Long: "long",
|
|
1836
|
+
Short: "short",
|
|
1837
|
+
Byte: "byte",
|
|
1838
|
+
Boolean: "boolean",
|
|
1839
|
+
Double: "double",
|
|
1840
|
+
Float: "float"
|
|
1841
|
+
};
|
|
1792
1842
|
mapPrimitiveType(type, _nullable) {
|
|
1793
1843
|
const upperType = type.toString().toUpperCase();
|
|
1794
1844
|
const mappedType = this.typeMap[upperType];
|
|
@@ -1809,9 +1859,9 @@ var JavaTypeMapper = class JavaTypeMapper extends TypeMapper {
|
|
|
1809
1859
|
formatStructTypeName(fieldName) {
|
|
1810
1860
|
return `${pascalCase(fieldName)}Result`;
|
|
1811
1861
|
}
|
|
1812
|
-
generateStructDeclaration(column, path = "") {
|
|
1862
|
+
generateStructDeclaration(column, path = "", nameOverride) {
|
|
1813
1863
|
if (!(column.type instanceof StructType)) throw new Error(`Expected StructType ${column}`);
|
|
1814
|
-
const structName = this.formatStructTypeName(column.name);
|
|
1864
|
+
const structName = nameOverride ?? this.formatStructTypeName(column.name);
|
|
1815
1865
|
const newPath = `${path}${structName}.`;
|
|
1816
1866
|
const children = column.type.fields.map((field) => {
|
|
1817
1867
|
return this.getDeclarations({
|
|
@@ -2005,7 +2055,7 @@ var TypeScriptTypeMapper = class extends TypeMapper {
|
|
|
2005
2055
|
formatMapTypeName(fieldName) {
|
|
2006
2056
|
return "Map";
|
|
2007
2057
|
}
|
|
2008
|
-
generateStructDeclaration(column) {
|
|
2058
|
+
generateStructDeclaration(column, _path, _nameOverride) {
|
|
2009
2059
|
if (!(column.type instanceof StructType)) throw new Error("Expected StructType");
|
|
2010
2060
|
return `interface ${this.formatStructTypeName(column.name)} {\n entries: {\n${column.type.fields.map((field) => {
|
|
2011
2061
|
const fieldType = this.getTypeName({
|
|
@@ -2140,7 +2190,7 @@ var PythonTypeMapper = class PythonTypeMapper extends TypeMapper {
|
|
|
2140
2190
|
formatMapTypeName(_fieldName) {
|
|
2141
2191
|
return "dict";
|
|
2142
2192
|
}
|
|
2143
|
-
generateStructDeclaration(column, path = "") {
|
|
2193
|
+
generateStructDeclaration(column, path = "", _nameOverride) {
|
|
2144
2194
|
if (!(column.type instanceof StructType)) throw new Error(`Expected StructType ${column}`);
|
|
2145
2195
|
const structName = this.formatStructTypeName(column.name);
|
|
2146
2196
|
const newPath = `${path}${structName}.`;
|
|
@@ -2211,7 +2261,7 @@ var BaseGenerator = class {
|
|
|
2211
2261
|
...query.columns[0],
|
|
2212
2262
|
name: query.id
|
|
2213
2263
|
});
|
|
2214
|
-
return this.getClassName(`${query.id}_Result`);
|
|
2264
|
+
return this.getClassName(query.resultTypeName ?? `${query.id}_Result`);
|
|
2215
2265
|
}
|
|
2216
2266
|
getStatement(q) {
|
|
2217
2267
|
return q.queryAnonymous;
|
|
@@ -2221,6 +2271,8 @@ var BaseGenerator = class {
|
|
|
2221
2271
|
//#region src/generators/java-generator.ts
|
|
2222
2272
|
var JavaGenerator = class extends BaseGenerator {
|
|
2223
2273
|
engine;
|
|
2274
|
+
/** Query ids that should emit their row-type record declaration (set per render). */
|
|
2275
|
+
declareTypeOwners = /* @__PURE__ */ new Set();
|
|
2224
2276
|
constructor(template, engine = "duckdb") {
|
|
2225
2277
|
super(template, new JavaTypeMapper());
|
|
2226
2278
|
this.template = template;
|
|
@@ -2271,14 +2323,28 @@ var JavaGenerator = class extends BaseGenerator {
|
|
|
2271
2323
|
if (readExpr !== null) return readExpr;
|
|
2272
2324
|
return this.typeMapper.parseValue(column, `rs.getObject(${idx})`, path);
|
|
2273
2325
|
}
|
|
2274
|
-
async beforeGenerate(_projectDir, _gen,
|
|
2326
|
+
async beforeGenerate(_projectDir, _gen, queries, tables) {
|
|
2327
|
+
this.declareTypeOwners = /* @__PURE__ */ new Set();
|
|
2328
|
+
const seenRowTypes = /* @__PURE__ */ new Set();
|
|
2329
|
+
const tableRowTypes = new Set(this.supportsAppenders(this.engine) ? tables.filter((t) => t.hasAppender).map((t) => this.getClassName(`${t.id}_row`)) : []);
|
|
2330
|
+
for (const q of queries) {
|
|
2331
|
+
if (q.skipGenerateFunction) continue;
|
|
2332
|
+
if (!q.isQuery || q.isPluck) continue;
|
|
2333
|
+
if (q.columns.length === 0) continue;
|
|
2334
|
+
const rowTypeName = this.rowType(q);
|
|
2335
|
+
if (tableRowTypes.has(rowTypeName)) continue;
|
|
2336
|
+
if (seenRowTypes.has(rowTypeName)) continue;
|
|
2337
|
+
seenRowTypes.add(rowTypeName);
|
|
2338
|
+
this.declareTypeOwners.add(q.id);
|
|
2339
|
+
}
|
|
2340
|
+
Handlebars.registerHelper("shouldDeclareType", (queryHelper) => this.declareTypeOwners.has(queryHelper.id));
|
|
2275
2341
|
Handlebars.registerHelper("isDuckDB", () => this.engine === "duckdb");
|
|
2276
2342
|
Handlebars.registerHelper("isPostgres", () => this.engine === "postgres");
|
|
2277
2343
|
Handlebars.registerHelper("pgBulkType", (column) => {
|
|
2278
2344
|
return pgBulkInsertType(column.type.toString().toUpperCase());
|
|
2279
2345
|
});
|
|
2280
2346
|
Handlebars.registerHelper("pgBulkAccessor", (column) => {
|
|
2281
|
-
return pgBulkInsertAccessor(column
|
|
2347
|
+
return pgBulkInsertAccessor(column);
|
|
2282
2348
|
});
|
|
2283
2349
|
Handlebars.registerHelper("javaVarName", (name) => {
|
|
2284
2350
|
const n = camelCase(name);
|
|
@@ -2294,10 +2360,12 @@ var JavaGenerator = class extends BaseGenerator {
|
|
|
2294
2360
|
...query.columns[0],
|
|
2295
2361
|
name: query.id
|
|
2296
2362
|
}, " ");
|
|
2297
|
-
|
|
2363
|
+
if (!this.declareTypeOwners.has(query.id)) return "";
|
|
2364
|
+
const structName = this.rowType(query);
|
|
2365
|
+
return queryHelper.typeMapper.getDeclarations(query.allColumns, "", structName);
|
|
2298
2366
|
});
|
|
2299
2367
|
Handlebars.registerHelper("appenderType", (column) => {
|
|
2300
|
-
return this.
|
|
2368
|
+
return this.typeMapper.getUnboxedTypeName(column);
|
|
2301
2369
|
});
|
|
2302
2370
|
Handlebars.registerHelper("declareEnums", (queryHelpers) => {
|
|
2303
2371
|
const enumTypes = /* @__PURE__ */ new Map();
|
|
@@ -2486,8 +2554,21 @@ function pgBulkInsertType(sqlType) {
|
|
|
2486
2554
|
if (sqlType.startsWith("_")) return `array(PgBulkInsert.PostgresTypes.${PG_BULK_TYPE_MAP[sqlType.substring(1)] || "TEXT"})`;
|
|
2487
2555
|
return PG_BULK_TYPE_MAP[sqlType] || "TEXT";
|
|
2488
2556
|
}
|
|
2489
|
-
|
|
2557
|
+
const PG_BULK_PRIMITIVE_TYPES = new Set([
|
|
2558
|
+
"INT2",
|
|
2559
|
+
"INT4",
|
|
2560
|
+
"INT8",
|
|
2561
|
+
"FLOAT4",
|
|
2562
|
+
"FLOAT8",
|
|
2563
|
+
"BOOLEAN"
|
|
2564
|
+
]);
|
|
2565
|
+
function pgBulkInsertAccessor(column) {
|
|
2566
|
+
const sqlType = column.type.toString().toUpperCase();
|
|
2490
2567
|
if (sqlType === "TIMESTAMPTZ") return "offsetDateTime";
|
|
2568
|
+
if (!column.nullable) {
|
|
2569
|
+
const pgType = PG_BULK_TYPE_MAP[sqlType];
|
|
2570
|
+
if (pgType && PG_BULK_PRIMITIVE_TYPES.has(pgType)) return "primitive";
|
|
2571
|
+
}
|
|
2491
2572
|
return "from";
|
|
2492
2573
|
}
|
|
2493
2574
|
//#endregion
|
|
@@ -2505,13 +2586,25 @@ var JavaDuckDBArrowGenerator = class extends BaseGenerator {
|
|
|
2505
2586
|
async beforeGenerate(projectDir, gen, queries, tables) {
|
|
2506
2587
|
const q = queries.filter((q) => q.isQuery && q.isOne || q.isMigrate);
|
|
2507
2588
|
const name = `${gen.name}-jdbc`;
|
|
2508
|
-
writeGeneratedFile(projectDir, {
|
|
2589
|
+
await writeGeneratedFile(projectDir, {
|
|
2509
2590
|
name,
|
|
2510
2591
|
generator: "java/duckdb/jdbc",
|
|
2511
2592
|
output: gen.output,
|
|
2512
2593
|
config: gen.config,
|
|
2513
2594
|
projectName: gen.projectName
|
|
2514
2595
|
}, this.javaGenerator, name, q, tables, "duckdb");
|
|
2596
|
+
const owners = /* @__PURE__ */ new Set();
|
|
2597
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2598
|
+
for (const q of queries) {
|
|
2599
|
+
if (q.skipGenerateFunction) continue;
|
|
2600
|
+
if (!q.isQuery || q.isOne) continue;
|
|
2601
|
+
if (q.columns.length === 0) continue;
|
|
2602
|
+
const rowTypeName = this.rowType(q);
|
|
2603
|
+
if (seen.has(rowTypeName)) continue;
|
|
2604
|
+
seen.add(rowTypeName);
|
|
2605
|
+
owners.add(q.id);
|
|
2606
|
+
}
|
|
2607
|
+
Handlebars.registerHelper("shouldDeclareType", (queryHelper) => owners.has(queryHelper.id));
|
|
2515
2608
|
}
|
|
2516
2609
|
isCompatibleWith(engine) {
|
|
2517
2610
|
return engine === "duckdb";
|
|
@@ -2573,7 +2666,7 @@ var JavaDuckDBArrowGenerator = class extends BaseGenerator {
|
|
|
2573
2666
|
}
|
|
2574
2667
|
rowType(query) {
|
|
2575
2668
|
if (query.isOne) return this.javaGenerator.rowType(query);
|
|
2576
|
-
return this.getClassName(`${query.id}_Result`);
|
|
2669
|
+
return this.getClassName(query.resultTypeName ?? `${query.id}_Result`);
|
|
2577
2670
|
}
|
|
2578
2671
|
};
|
|
2579
2672
|
//#endregion
|
|
@@ -3325,6 +3418,106 @@ function getOutputPath(projectDir, sqlFileName, gen, generator) {
|
|
|
3325
3418
|
mkdirSync(dirname(outputPath), { recursive: true });
|
|
3326
3419
|
return outputPath;
|
|
3327
3420
|
}
|
|
3421
|
+
function assignResultTypeNames(queries, tables, projectDir = process.cwd()) {
|
|
3422
|
+
const hints = [];
|
|
3423
|
+
const tablesByName = /* @__PURE__ */ new Map();
|
|
3424
|
+
for (const t of tables) tablesByName.set(t.tableName, t);
|
|
3425
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3426
|
+
const eligible = queries.filter((q) => q.isQuery && !q.isPluck && !q.skipGenerateFunction && q.columns.length > 0);
|
|
3427
|
+
for (const q of eligible) {
|
|
3428
|
+
const cols = effectiveColumns(q);
|
|
3429
|
+
const key = JSON.stringify(cols.map((c) => ({
|
|
3430
|
+
n: c.name,
|
|
3431
|
+
t: c.type.toString(),
|
|
3432
|
+
nu: c.nullable,
|
|
3433
|
+
s: c.sourceTable ?? null
|
|
3434
|
+
})));
|
|
3435
|
+
let g = groups.get(key);
|
|
3436
|
+
if (!g) {
|
|
3437
|
+
g = { queries: [] };
|
|
3438
|
+
groups.set(key, g);
|
|
3439
|
+
}
|
|
3440
|
+
g.queries.push(q);
|
|
3441
|
+
}
|
|
3442
|
+
const recordShape = (cols) => JSON.stringify(cols.map((c) => ({
|
|
3443
|
+
n: c.name,
|
|
3444
|
+
t: c.type.toString(),
|
|
3445
|
+
nu: c.nullable
|
|
3446
|
+
})));
|
|
3447
|
+
const claims = /* @__PURE__ */ new Map();
|
|
3448
|
+
for (const t of tables) {
|
|
3449
|
+
if (!t.hasAppender) continue;
|
|
3450
|
+
const cols = t.columns.filter((c) => !c.generated);
|
|
3451
|
+
claims.set(pascalCase(`${t.id}_row`), {
|
|
3452
|
+
shape: recordShape(cols),
|
|
3453
|
+
offenderId: t.id,
|
|
3454
|
+
source: `TABLE ${t.tableName}`
|
|
3455
|
+
});
|
|
3456
|
+
}
|
|
3457
|
+
const claim = (name, shape, representative, source) => {
|
|
3458
|
+
const canonical = pascalCase(name);
|
|
3459
|
+
const existing = claims.get(canonical);
|
|
3460
|
+
if (existing && existing.shape !== shape) throw SqgError.inQuery(`Result type '${name}' would be emitted with two incompatible shapes: ${source} ('${representative.id}') vs ${existing.source} ('${existing.offenderId}')`, "VALIDATION_ERROR", representative.id, representative.filename, { suggestion: "Use a different `:result=` name for one of the queries, or change the queries so their result columns match" });
|
|
3461
|
+
if (!existing) claims.set(canonical, {
|
|
3462
|
+
shape,
|
|
3463
|
+
offenderId: representative.id,
|
|
3464
|
+
source
|
|
3465
|
+
});
|
|
3466
|
+
};
|
|
3467
|
+
for (const group of groups.values()) {
|
|
3468
|
+
const overrides = group.queries.map((q) => q.resultTypeOverride).filter((v) => !!v);
|
|
3469
|
+
const uniqueOverrides = new Set(overrides);
|
|
3470
|
+
if (uniqueOverrides.size > 1) {
|
|
3471
|
+
const offenders = group.queries.filter((q) => q.resultTypeOverride);
|
|
3472
|
+
throw SqgError.inQuery(`Conflicting ':result=' names for queries with identical result shapes: ${offenders.map((q) => `'${q.id}' uses '${q.resultTypeOverride}'`).join(", ")}`, "VALIDATION_ERROR", offenders[0].id, offenders[0].filename, { suggestion: "Pick a single name for this row type or change the queries so their shapes differ" });
|
|
3473
|
+
}
|
|
3474
|
+
const shape = recordShape(effectiveColumns(group.queries[0]));
|
|
3475
|
+
if (uniqueOverrides.size === 1) {
|
|
3476
|
+
const resolved = [...uniqueOverrides][0];
|
|
3477
|
+
claim(resolved, shape, group.queries.find((q) => q.resultTypeOverride === resolved), `:result=${resolved}`);
|
|
3478
|
+
for (const q of group.queries) q.resultTypeName = resolved;
|
|
3479
|
+
continue;
|
|
3480
|
+
}
|
|
3481
|
+
const fullMatch = tryFullTableMatch(group.queries[0], tablesByName);
|
|
3482
|
+
if (fullMatch) {
|
|
3483
|
+
claim(fullMatch, shape, group.queries[0], `full-table match`);
|
|
3484
|
+
for (const q of group.queries) q.resultTypeName = fullMatch;
|
|
3485
|
+
continue;
|
|
3486
|
+
}
|
|
3487
|
+
if (group.queries.length >= 2) {
|
|
3488
|
+
const list = group.queries.map((q) => `'${q.id}' (${displayPath(q.filename, projectDir)}:${q.line})`).join(", ");
|
|
3489
|
+
hints.push({
|
|
3490
|
+
queryIds: group.queries.map((q) => q.id),
|
|
3491
|
+
message: `${group.queries.length} queries return the same row shape: ${list}. Add \`:result=Name\` to any one of them to share a single row type.`
|
|
3492
|
+
});
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
return hints;
|
|
3496
|
+
}
|
|
3497
|
+
/** Show paths relative to the project root when it's inside the tree; otherwise fall back to absolute. */
|
|
3498
|
+
function displayPath(fullPath, projectDir) {
|
|
3499
|
+
const rel = relative(projectDir, fullPath);
|
|
3500
|
+
return rel && !rel.startsWith("..") ? rel : fullPath;
|
|
3501
|
+
}
|
|
3502
|
+
/** Resolve config-overridden column info, mirroring what validateQueries does for allColumns. */
|
|
3503
|
+
function effectiveColumns(query) {
|
|
3504
|
+
return query.columns.map((col) => query.config?.getColumnInfo(col.name) ?? col);
|
|
3505
|
+
}
|
|
3506
|
+
function tryFullTableMatch(query, tablesByName) {
|
|
3507
|
+
const cols = effectiveColumns(query);
|
|
3508
|
+
const firstSource = cols[0]?.sourceTable;
|
|
3509
|
+
if (!firstSource) return void 0;
|
|
3510
|
+
if (!cols.every((c) => c.sourceTable === firstSource)) return void 0;
|
|
3511
|
+
const table = tablesByName.get(firstSource);
|
|
3512
|
+
if (!table) return void 0;
|
|
3513
|
+
if (table.columns.some((c) => c.generated)) return void 0;
|
|
3514
|
+
if (table.columns.length !== cols.length) return void 0;
|
|
3515
|
+
for (let i = 0; i < cols.length; i++) {
|
|
3516
|
+
if (cols[i].name !== table.columns[i].name) return void 0;
|
|
3517
|
+
if (cols[i].type.toString() !== table.columns[i].type.toString()) return void 0;
|
|
3518
|
+
}
|
|
3519
|
+
return `${table.id}_row`;
|
|
3520
|
+
}
|
|
3328
3521
|
function validateQueries(queries) {
|
|
3329
3522
|
for (const query of queries) {
|
|
3330
3523
|
if (query.isQuery && query.isPluck && query.columns.length !== 1) throw SqgError.inQuery(`':pluck' modifier requires exactly 1 column, but query has ${query.columns.length} columns`, "VALIDATION_ERROR", query.id, query.filename, { suggestion: query.columns.length === 0 ? "Ensure the query returns at least one column" : `Remove ':pluck' or select only one column. Current columns: ${query.columns.map((c) => c.name).join(", ")}` });
|
|
@@ -3482,6 +3675,9 @@ async function processProjectFromConfig(project, projectDir, writeToStdout = fal
|
|
|
3482
3675
|
if (tables.length > 0) await dbEngine.introspectTables(tables, reporter);
|
|
3483
3676
|
ui?.succeedPhase(`Introspected ${executableQueries.length} queries`);
|
|
3484
3677
|
validateQueries(queries);
|
|
3678
|
+
const hints = assignResultTypeNames(queries, tables, projectDir);
|
|
3679
|
+
for (const hint of hints) if (ui) ui.hint(hint.message);
|
|
3680
|
+
else consola.info(hint.message);
|
|
3485
3681
|
await dbEngine.close();
|
|
3486
3682
|
} catch (e) {
|
|
3487
3683
|
ui?.failPhase(`Failed to process ${sqlFile}`);
|
|
@@ -3532,7 +3728,7 @@ async function processProject(projectPath, ui) {
|
|
|
3532
3728
|
//#region src/mcp-server.ts
|
|
3533
3729
|
const server = new Server({
|
|
3534
3730
|
name: "sqg-mcp",
|
|
3535
|
-
version: process.env.npm_package_version ?? "0.
|
|
3731
|
+
version: process.env.npm_package_version ?? "0.20.0"
|
|
3536
3732
|
}, { capabilities: {
|
|
3537
3733
|
tools: {},
|
|
3538
3734
|
resources: {}
|
|
@@ -3954,6 +4150,12 @@ var UI = class {
|
|
|
3954
4150
|
this.log("");
|
|
3955
4151
|
this.log(` ${pc.green("done")} ${pc.dim(`in ${formatMs(totalMs)}`)}`);
|
|
3956
4152
|
}
|
|
4153
|
+
/** Display an info-level hint (e.g. "these queries could share a row type") */
|
|
4154
|
+
hint(message) {
|
|
4155
|
+
if (this.silent) return;
|
|
4156
|
+
this.stopSpinner();
|
|
4157
|
+
this.log(` ${pc.cyan(pc.bold("hint"))} ${message}`);
|
|
4158
|
+
}
|
|
3957
4159
|
/** Display a formatted error */
|
|
3958
4160
|
error(err) {
|
|
3959
4161
|
if (this.silent) return;
|
|
@@ -3997,7 +4199,7 @@ function formatMs(ms) {
|
|
|
3997
4199
|
}
|
|
3998
4200
|
//#endregion
|
|
3999
4201
|
//#region src/sqg.ts
|
|
4000
|
-
const version = process.env.npm_package_version ?? "0.
|
|
4202
|
+
const version = process.env.npm_package_version ?? "0.20.0";
|
|
4001
4203
|
updateNotifier({ pkg: {
|
|
4002
4204
|
name: "@sqg/sqg",
|
|
4003
4205
|
version
|
|
@@ -4121,7 +4323,7 @@ program.command("ui").description("Start the SQG UI — interactive SQL developm
|
|
|
4121
4323
|
const { startUi } = await import("./start-ui-DuHxwbjr.mjs");
|
|
4122
4324
|
await startUi({
|
|
4123
4325
|
project,
|
|
4124
|
-
port: parseInt(options.port, 10)
|
|
4326
|
+
port: Number.parseInt(options.port, 10)
|
|
4125
4327
|
});
|
|
4126
4328
|
});
|
|
4127
4329
|
program.command("mcp").description("Start MCP (Model Context Protocol) server for AI assistants").action(async () => {
|
|
@@ -75,6 +75,7 @@ public class {{className}} {
|
|
|
75
75
|
|
|
76
76
|
{{#*inline "columnTypesRecord"}}
|
|
77
77
|
{{#if isQuery}}
|
|
78
|
+
{{#if (shouldDeclareType this)}}
|
|
78
79
|
{{#if isOne}}
|
|
79
80
|
public record {{rowType}}({{#each columns}}{{type}} {{name}}{{#unless @last}}, {{/unless}}{{/each}}) {}
|
|
80
81
|
{{else}}
|
|
@@ -83,7 +84,7 @@ public record {{rowType}}(PreparedStatement statement, RootAllocator allocator,
|
|
|
83
84
|
public boolean loadNextBatch() throws IOException {
|
|
84
85
|
return reader.loadNextBatch();
|
|
85
86
|
}
|
|
86
|
-
|
|
87
|
+
|
|
87
88
|
public int getRowCount() throws IOException {
|
|
88
89
|
return reader.getVectorSchemaRoot().getRowCount();
|
|
89
90
|
}
|
|
@@ -96,6 +97,7 @@ public record {{rowType}}(PreparedStatement statement, RootAllocator allocator,
|
|
|
96
97
|
}
|
|
97
98
|
{{/if}}
|
|
98
99
|
{{/if}}
|
|
100
|
+
{{/if}}
|
|
99
101
|
{{/inline}}
|
|
100
102
|
|
|
101
103
|
{{#*inline "returnType"}}
|