diff --git a/docs/kcl/offsetPlane.md b/docs/kcl/offsetPlane.md index 4e45792b71..c5e87f6559 100644 --- a/docs/kcl/offsetPlane.md +++ b/docs/kcl/offsetPlane.md @@ -99,4 +99,20 @@ loft([squareSketch, circleSketch]) ![Rendered example of offsetPlane 3](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAECy0lEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV131/8zrvM7rvPeLvdiLvRZXXXXVVVf9v/MP//APv/Nbv/Vb381VV1111VVX/f9B5aqrrrrqqqv+H3md13md9/7wD//w7+Kqq6666qr/l17sxV7stQF+67d+67u56qqrrrrqqv8fqFx11VVXXXXV/yMv9mIv9lo80w/90A/xH0US/50k8e8hif8JJPHvJYn/iSTxv4Ek/jNJ4v8DSfxvJYn/q17rtV6La6655sEv9mIv9lq/9Vu/9d1cddVVV1111f8PVK666qqrrrrq/5H77rvvVp7pwoULPOUpTwFAEv9Wkvi3ksS/lyT+PSTx7yGJfy9J/HtJ4j+KJP6jSOI/kiT+o0niP5Mk/itI4r+LJP43kcT/Ny/90i/N8ePHAbjvvvtu5aqrrrrqqqv+/yC46qqrrrrqqv9Hzp49+wye6Y3e6I2QhCT+LSQhiX8LSUji30MSkvi3koQk/q0kIYl/D0lI4t9DEpL4jyAJSfxHkIQk/qNIQhL/kSQhif8MkpCEJP4zSUISkvivJAlJSEIS/1NJQhKSkIQkJPH/0Uu91Etxv7Nnzz6Dq6666qqrrvr/g+Cqq6666qqr/h+57777buWZHv7wh/Owhz2Mfy1JSOLfShL/HpKQxL+VJCTxbyUJSfx7SEIS/x6SkMS/lyQkIYl/L0lIQhL/ESQhCUn8R5GEJCTxH00SkpDEfyZJSEIS/5UkIQlJ/E8kCUlIQhKSuOqKBz/4wTz4wQ/mqquuuuqqq/6fIrjqqquuuuqq/4f+6I/+CIA3eqM34l9DEv9WkpDEv5UkJPFvJQlJ/FtJQhL/HpKQxL+HJCTx7yUJSfxHkIQk/qNIQhL/kSQhif8MkpDEfyZJSEIS/1UkIQlJSOJ/EklIQhKSkMRVL9hLvdRLAfB3f/d3ANx33323ctVVV1111VX/fxBcddVVV1111f8jZ8+evRXgyU9+MgAnT57k5MmT/EskIYl/C0lI4t9DEv9WkpDEv4ck/j0kIYl/D0lI4t9LEpL4jyAJSfxHkYQk/iNJQhL/0SQhCUn8Z5GEJCTxX0USkpDE/xSSkIQkJCGJq/51XvqlXxqAX//1Xwfg7Nmzt3LVVVddddVV/38QXHXVVVddddX/Q+fPn+dJT3oSJ0+e5I3e6I14YSTxbyWJfw9JSOLfShL/HpKQxL+VJCTx7yEJSfx7SUIS/xEkIYn/CJKQhCT+o0hCEpL4jyQJSUjiP4skJCGJ/wqSkIQkJPHfTRKSkIQkJHHVCyYJSUhCEpKQhCQkIYm3fuu3BuDXf/3Xud999913K1ddddVVV131/wfBVVddddVVV/0/ct99990KcOrUKX7hF34BgIc97GE8P5KQxL+FJCTxbyUJSfxbSUIS/1aSkMS/lSQk8e8hCUn8e0lCEv8RJCGJ/wiSkMR/JElI4j+aJCTxn0USkpDEfwVJSEIS/90kIQlJSOL/A0lIQhKSkIQkJCEJSUhCEpKQhCQkIQlJSEISL4qXeqmXAuDXf/3Xueqqq6666qr/pwiuuuqqq6666v+Z++6779aTJ0/ypCc9iSc96UmcPHmSV3iFV+CBJPFvJYl/D0n8W0lCEv9WkpDEv4ck/j0kIYl/L0lI4j+CJCTxH0ESkviPIglJSOI/kiQkIYn/DJKQhCT+K0hCEpL47yQJSUhCEv9XSEISkpCEJCQhCUlIQhKS+K/0Ui/1UgD87d/+LX/3d3/Htddey3333XcrV1111VVXXfX/C8FVV1111VVX/T9z9uzZW0+dOgXAL/zCLwDwRm/0RgBIQhL/FpKQxL+VJCTxbyEJSfxbSUIS/x6SkMS/hyT+vSQhiX8vSUhCEv8RJCGJ/yiSkMR/NElI4j+LJCTxX0ESkpDEfxdJSEISkvjfShKSkIQkJCEJSUjif6rXeq3XAuA3fuM3ALjmmms4e/bsrVx11VVXXXXV/y8EV1111VVXXfX/0KlTpwA4f/48T3rSkzh58iQPf/jD+beQhCT+rSQhiX8rSfx7SOLfQxKS+PeQhCT+PSQhiX8vSUjiP4okJPEfRRKS+I8kCUlI4j+DJCQhif9skpCEJP47SEISkpDE/yaSkIQkJCEJSUjif6OXeqmX4vjx4wD8+q//OpIAuO+++27lqquuuuqqq/5/Ibjqqquuuuqq/2fuu+++W3mmCxcu8Md//McAvNEbvRH/WpL495DEv5UkJPFvJQlJ/FtJQhL/HpKQxL+HJCTx7yUJSfxHkIQkJPEfRRKS+I8kCUn8Z5CEJCTxn00SkpDEfzVJSEISkvjfQBKSkIQkJCGJ/2te6qVeCoCv/Mqv5H7XXnstV1111VVXXfX/EMFVV1111VVX/T9z33333Xrq1Cnu9+QnPxmAhz3sYTzsYQ/jRSEJSfxbSUIS/xaSkMS/lSQk8W8lCUn8e0hCEv8ekpDEv5ckJPEfQRKS+I8iCUlI4j+SJCTxn0ESkvjPJglJSOK/miQkIYn/ySQhCUlIQhKS+P/gQQ96EA9+8IMB+PVf/3Xud+2113LffffdylVXXXXVVVf9/0Jw1VVXXXXVVf/PnD179hk8wPnz5/njP/5jAF7hFV6Bf4kk/q0kIYl/K0n8W0lCEv9WkpDEv4ckJPHvIQlJ/HtJQhL/ESQhif8okpDEfyRJSEIS/9EkIQlJ/GeShCQk8V9JEpKQhCT+J5KEJCQhCUn8f/bSL/3SAPzar/0az+3s2bPP4Kqrrrrqqqv+fyG46qqrrrrqqv9n7rvvvltPnTqFJO73C7/wCwA87GEP4wWRhCT+rSTxbyUJSfxbSeLfQxL/HpKQxL+HJCTx7yUJSfxHkIQk/qNIQhL/kSQhif8MkpDEfyZJSEIS/5UkIQlJ/E8jCUlIQhKSuOo5vdRLvRQAP/iDP4gk7nfNNddw1VVXXXXVVf8PEVx11VVXXXXV/1OnTp3ifufPn+dJT3oSJ0+e5A3f8A15bpL4t5KEJP4tJCGJfytJSOLfShKS+LeShCT+PSQhiX8vSUjiP4IkJPEfRRKS+I8kCUn8R5OEJCTxn0USkpDEfyVJSEIS/5NIQhKSkMRVL9xLvdRLAfBrv/Zr3HvvvdzvmmuuAeC+++67lauuuuqqq676/4Xgqquuuuqqq/6fOXv27K0AJ0+e5IF+4Rd+AYBXeIVX4H6SkMS/lST+rSTxbyUJSfxbSUIS/1aSkMS/hyQk8e8lCUn8R5CEJP6jSEIS/1EkIQlJ/EeThCT+M0lCEv9VJCEJSUjifwJJSEISkpDEVf86r/VarwXAr//6r3M/SVx77bUAnD179lauuuqqq6666v8Xgquuuuqqq6666rInP/nJPPnJT+bkyZO8wiu8ApL4t5KEJP4tJCGJfwtJSOLfShKS+PeQxL+XJP69JCGJ/wiSkMR/BElIQhL/USQhif9okpCEJP6zSEISkvivIAlJSOJ/AklIQhKSuOrZJCEJSUhCEpKQhCQkIQlJSEISL/3SL83x48f527/9W/72b/+WB7rmmmsAuO+++27lqquuuuqqq/5/Ibjqqquuuuqq/2fuu+++WwFOnTrFA0nij//4jwF4wzd8Q/6tJPFvJYl/K0n8e0ji30MSkvj3kIQk/j0kIYn/CJKQxH8ESUjiP5IkJPEfTRKS+M8iCUlI4r+CJCQhif9ukpCEJCTx/4EkJCEJSUhCEpKQhCQkIQlJSEIS/xYv9VIvBcCv/dqv8dwkcdVVV1111VX/TxFcddVVV1111f9D9913362nTp3iuT35yU/m/PnznDx5koc97GH8a0hCEv8WkpDEv4UkJPFvJQlJ/FtJQhL/HpKQxL+HJCTxH0ESkviPIAlJ/EeShCT+o0lCEv9ZJCGJ/wqSkIQk/jtJQhKSkMT/JZKQhCQkIQlJSEISkpDEf5UHPehBPOhBDwLg13/915HEA11zzTXcd999t3LVVVddddVV//8QXHXVVVddddX/Q2fPnr2V5+P8+fP88R//MQBv+IZvyItKEv8WkpDEv5Uk/q0kIYl/K0lI4t9DEpL495CEJP4jSEIS/xEkIYn/KJKQhCT+I0lCEpL4zyAJSUjiP5skJCGJ/06SkIQk/reThCQkIQlJSEIS/9O81Eu9FADf//3fz/0kcb9rr72Ws2fP3spVV1111VVX/f9DcNVVV1111VX/Tz3iEY/gfpK435/8yZ8AcOLECR72sIfxwkhCEv8Wkvi3koQk/i0kIYl/K0lI4t9DEpL495LEfwRJSOI/giQk8R9FEpL4jyYJSfxnkYQk/itIQhL/XSQhCUlI4n8bSUhCEpKQhCQk8b/JS73USwHwa7/2a7wg9913361cddVVV1111f8/BFddddVVV131/9B99913Ky/A+fPn+eM//mNOnjzJy7/8y/OCSOLfQhKS+LeQhCT+rSTx7yGJfw9JSOLfSxKS+PeShCT+I0hCEv9RJCGJ/2iSkMR/BklIQhL/2SQhCUn8d5CEJCTxv4UkJCEJSUhCEv8XvOVbviUAv/Zrv8a9997LA0kC4JprruGqq6666qqr/p8iuOqqq6666qr/h+67775bT506xQvyi7/4iwA87GEP47lJQhL/FpL4t5LEv5UkJPFvJQlJ/FtJQhL/XpKQxL+XJCTxH0ESkviPIglJ/EeShCQk8Z9BEpL4zyYJSUjiv5okJCEJSfxPJwlJSEISkvi/7KVe6qUA+NVf/VVekGuvvZb77rvvVq666qqrrrrq/x+Cq6666qqrrvp/6OzZs8/ghTh//jxPfvKTOXnyJC//8i/P/STxbyEJSfxbSEIS/xaSkMS/lSQk8e8hiX8vSUji30sSkviPIAlJ/EeRhCT+I0lCEv8ZJCEJSfxnkoQkJPFfTRKSkMT/ZJKQhCQkIYn/T17qpV4KgL/5m7/hb//2b3l+JAFw9uzZZ3DVVVddddVV//8QXHXVVVddddX/Q/fdd9+tp06dAkASz00Sv/iLvwjAG77hGyIJSfxbSOLfQhKS+LeSxL+VJCTx7yEJSfx7SEIS/16SkMR/BElI4j+KJCTxH0kSkvjPIAlJ/GeThCT+q0lCEpL4n0oSkpCEJP6/e83XfE0Avu/7vg9JSEISz+2aa67hqquuuuqqq/6fIrjqqquuuuqq/8dOnTrFC3L+/Hme/OQnc/LkSR72sIfxryUJSfxbSOLfShKS+LeSxL+HJCTx7yEJSfx7SUIS/xEkIYn/KJKQxH8kSUjiP4MkJPGfSRKSkMR/JUlIQhL/00hCEpKQhCSueraXeqmX4vjx49x777383d/9HQ8kiftdc801APzDP/zDb3PVVVddddVV//8QXHXVVVddddX/Q2fPnr0V4OTJk7wgFy5c4E/+5E8AeIM3eAP+NSTxbyEJSfxbSEIS/1aSkMS/lSQk8e8hCUn8e0lCEv8RJCGJ/yiSkMR/JElI4j+aJCQhif9MkpDEfyVJSEIS/5NIQhKSkMRVL9xLvdRLAfB93/d9PD+SALj22mu56qqrrrrqqv/HCK666qqrrrrq/zFJPDdJ3O9JT3oSAA972MN42MMexr9EEpL4t5DEv5Uk/q0kIYl/D0n8e0hCEv9ekpDEfwRJSOI/iiQk8R9JEpL4jyYJSfxnkoQkJPFfRRKSkMT/FJKQhCQkcdWL7kEPehAPetCDAPjVX/1VXphrrrkGgPvuu+9Wrrrqqquuuur/H4Krrrrqqquu+n/ovvvuuxXg1KlTvDAXLlzgj//4jwF4+Zd/eV4YSfxbSEIS/xaSkMS/lST+PSQhiX8PSfx7SUIS/xEkIYn/CJKQhCT+o0hCEpL4jyYJSfxnkoQk/qtIQhKS+J9CEpKQxFXPnyQkIQlJSEISkpCEJF7qpV4KgF/91V/lqquuuuqqq656oQiuuuqqq6666v+p++6779aTJ0/yL/nFX/xFAB72sIdx4sQJnpskJPFvIYl/K0n8W0lCEv9WkpDEv4ckJPHvIQlJ/EeQhCT+I0hCEv+RJCGJ/wySkMR/FklIQhL/FSQhCUn8TyAJSUhCEv+fSEISkpCEJCQhCUlIQhKSkIQkJPGieKmXeikAvvd7v5cXRhLXXHMN9913361cddVVV1111f9PBFddddVVV131/9TZs2dv5blI4rlduHCBJz/5yZw4cYI3fMM35IEk8W8hCUn8W0hCEv8WkpDEv5UkJPHvIQlJ/HtJ4j+CJCTxH0ESkviPJAlJ/EeThCQk8Z9FEpL4ryIJSfxPIAlJSOL/KklIQhKSkIQkJCEJSfxnec3XfE0AfvVXf5V7770XAElIQhLP7dprr+Xs2bO3ctVVV1111VX/PxFcddVVV1111f9jj3zkI/mXSOKXfumXAHjYwx4GgCQk8W8hiX8rSfxbSeLfQxL/HpKQxL+XJCTx7yUJSfxHkIQk/iNJQhL/0SQhif8skpCEJP4rSEISkvjvJAlJSEIS/1dIQhKSkIQkJCGJ/04v+ZIvCcCv/uqvAiCJB5LEc7vvvvtu5aqrrrrqqqv+fyK46qqrrrrqqv+n/v7v//63eRE9+clP5slPfjInTpzgFV7hFfi3kIQk/i0kIYl/C0lI4t9KEpL4t5KEJP69JCGJfy9JSOI/giQk8R9JEpL4jyYJSfxnkYQk/itIQhKS+O8kCUlI4n87SUhCEpKQhCT+J3rJl3xJjh8/zt/8zd/wN3/zN0ji+ZHE/a655hquuuqqq6666v8xgquuuuqqq676f+zkyZPcTxIvzJ/8yZ8A8AZv8Ab8a0ni30ISkvi3ksS/lSQk8e8hiX8vSUji30sSkviPIAlJ/EeShCT+o0lCEv9ZJCGJ/wqSkMR/J0lIQhL/G0lCEpKQhCQk8b/JS73USwHwq7/6q7yorr32Wu67775bueqqq6666qr/nwiuuuqqq6666v+ps2fPPoN/gSTu9+QnP5kLFy5w4sQJHvrQh/KikIQk/i0k8W8lCUn8W0ni30MSkvj3kIQk/r0kIYn/KJL4jyQJSfxHk4Qk/jNIQhKS+M8mCUlI4r+LJCQhif9NJCEJSUhCEv/bveRLviQPetCDAPjVX/1V/jXOnj37DK666qqrrrrq/yeCq6666qqrrvp/6r777rv11KlTvKguXLjAL/7iLwLwBm/wBvxLJPFvIQlJ/FtIQhL/VpKQxL+VJCTx7yEJSfx7SUIS/1EkIYn/KJKQxH80SUjiP4MkJPFfQRKS+O8iCUlI4n8DSUhCEpKQxP9FL/VSLwXA937v9/KikATANddcw1VXXXXVVVf9P0Zw1VVXXXXVVf/PnTp1ihfVk5/8ZAAe9rCH8dCHPpQXRBL/FpL4t5LEv5UkJPHvIYl/L0n8R5DEfxRJSOI/iiQk8R9NEpL4zyAJSfxnk4QkJPHfQRKSkMT/dJKQhCQk8f/B8ePHedCDHgTAr/7qr/JAkpCEJJ7bNddcA8A//MM//DZXXXXVVVdd9f8TwVVXXXXVVVf9P3X27NlbAU6ePIkknpskntuFCxf4kz/5EwBe/uVfnucmCUn8a0lCEv8WkpDEv5Uk/j0kIYl/D0lI4t9LEpL4jyAJSfxHkYQk/iNJQhKS+M8gCUn8Z5OEJP47SEISkvifTBKSkIQk/j96jdd4DQB+9Vd/lXvvvZf7SeKBJPFA1157LVddddVVV131/xzBVVddddVVV131IpPEL/3SLwHwsIc9jAeSxL+FJP6tJPFvJQlJ/FtJQhL/HpKQxL+XJCTxH0ESkviPIglJ/EeShCT+s0hCEv+ZJCEJSfxXk4QkJPE/lSQkIQlJXAUv9VIvBcD3fu/3cj9JPD+SuN+1114LwH333XcrV1111VVXXfX/E8FVV1111VVX/T9133333Qpw6tQp/jUuXLjAk5/8ZE6cOMEbvMEbIAlJ/FtI4t9CEpL4t5CEJP6tJCGJfw9JSOLfSxKS+I8gCUn8R5GEJP4jSUIS/xkkIQlJ/GeShCT+q0lCEpL4n0gSkpCEJK56Ti/5ki8JwK/+6q9y7733ctVVV1111VVX/asQXHXVVVddddX/Y/fdd9+tp06d4rlJ4oX5pV/6JQBe/uVfnn8LSUji30IS/1aS+PeQxL+HJCTx7yUJSfxHkIQk/qNIQhL/kSQhif8MkpDEfzZJSOK/miQk8T+RJCQhiateuNd8zdcE4Fd/9Vf517rmmmu47777buWqq6666qqr/v8iuOqqq6666qr/x86ePXsrLyJJ3O8pT3kKT37ykzlx4gQPfehD+deQxL+FJCTxbyEJSfxbSUIS/x6S+PeShCT+I0hCEv9RJCGJ/0iSkMR/BklI4j+TJCQhif9KkpCEJP4nkYQkJCGJq140L/mSL8nx48e59957+Zu/+RteVJIAuOaaazh79uytXHXVVVddddX/XwRXXXXVVVdd9f/cyZMn+bf40z/9UwDe4A3egBeFJCTxbyGJfytJ/FtJQhL/HpKQxL+XJP4jSEIS/1EkIYn/SJKQxH8GSUjiP5MkJPFfTRKS+J9EEpKQxFX/Ni/1Ui8FwPd+7/fy/EhCEpJ4Qe67775bueqqq6666qr/vwiuuuqqq6666v+xv//7v//tU6dO8UCSeG6SeG5PfvKTAXjoQx/KQx/6UF4YSfxbSEIS/xaSkMS/lST+PSQhiX8vSUji30sSkviPIglJ/EeShCT+M0hCEv+ZJCGJ/0qSkIQk/qeQhCQkcdW/nSQe/OAH86AHPQiAX/3VX+W5SeKBJPHcrrnmGq666qqrrrrq/zmCq6666qqrrvp/7uTJk/xbXLhwgV/6pV8C4A3e4A14fiQhiX8LSfxbSeLfShKS+PeQxL+XJCTx7yUJSfxHkYQk/iNJQhL/GSQhif9MkpDEfyVJSOJ/CklIQhJXPZskJCEJSUhCEpKQhCQkIQlJSEISkgB4yZd8SQB+9Vd/lecmiedHEveTxLXXXst99913K1ddddVVV131/xfBVVddddVVV/0/dvbs2WfwbySJP/3TPwXgxIkTPPShD+WBJPFvIQlJ/FtIQhL/VpL495CEJP49JCGJ/wiS+I8iCUn8R5KEJP4zSEIS/5kkIYn/KpKQhCT+J5CEJCTx/5UkJCEJSUhCEpKQxL/XS77kSwLwvd/7vfx7nD179hlcddVVV1111f9fBFddddVVV131/9h9991366lTp7ifJJ6bJF6QCxcu8JSnPIUTJ07w8i//8txPEv8Wkvi3ksS/lSQk8W8lCUn8e0hCEv8RJCGJ/wiSkMR/JElI4j+DJCTxn0USkpDEfxVJSOJ/AklIQhL/X0hCEpKQhCQkIYn/TG/xFm8BwK/+6q9y77338m91zTXXcNVVV1111VX/zxFcddVVV1111VWcPHmSfw1J3O+XfumXAHjoQx+KJCTxryUJSfxbSEIS/xaSkMS/hyT+vSTxH0ESkviPIAlJ/EeShCT+M0hCEv9ZJCGJ/yqSkIQk/rtJQhKS+L9MEpKQhCQkIYn/Li/5ki8JwK/+6q/ywkjiuUnigf7hH/7ht7nqqquuuuqq/78Irrrqqquuuur/sbNnz94KcOrUKf6tnvKUp/CUpzyFEydO8HIv93L8a0ni30oS/1aS+PeQhCT+PSQhiX8vSUjiP4IkJPEfSRKS+M8gCUn8Z5GEJP6rSEIS/90kIQlJ/F8kCUlIQhKS+J/kJV/yJQH4m7/5G/7mb/6GF0QSAJKQxHO75ppruOqqq6666qqrILjqqquuuuqq/8fuu+++W3kmSTw3SbwofumXfgmA13/91+dfQxL/FpKQxL+FJCTxbyUJSfx7SEIS/16SkMR/FEn8R5KEJP4zSEIS/1kkIYn/KpKQxH8nSUhCEv+XSEISkpCEJP6ne83XfE0AfvVXf5UXRBL/kmuuuQaA++6771auuuqqq6666v8vgquuuuqqq676f+6+++679dSpU7yoJPHcLly4wFOe8hROnDjBQx/6UP4lkpDEv4Uk/q0k8e8hiX8PSUji30sSkviPIglJ/EeRhCT+M0hCEv9ZJCGJ/wqSkIQk/jtJQhL/V0hCEpKQxP82L/mSL8mxY8cA+NVf/VWeH0k8P5K4nySuvfZarrrqqquuuuoqCK666qqrrrrq/7mzZ8/eevLkSf49Lly4wJ/+6Z8C8Pqv//q8MJL4t5CEJP4tJCGJfytJSOLfQxL/ESTxH0USkviPIglJ/GeQhCT+s0hCEv8VJCGJ/06SkIQk/reThCQkIYn/7V7yJV8SgC/7si/jP8J99913K1ddddVVV131/xvBVVddddVVV131fEniRSWJpzzlKQA89KEP5aEPfSjPjyT+LSTxbyWJfytJSOLfQxKS+PeShCT+I0hCEv+RJPGfQRKS+M8iCUn8V5CEJP47SUIS/5tJQhKSkMT/JQ960IN40IMeBMCv/uqv8u91zTXXcPbs2Vu56qqrrrrqqv/fCK666qqrrrrq/7n77rvv1lOnTvGikMQLcuHCBf70T/8UgJd7uZfjgSQhiX8tSUji30ISkvi3ksS/hyQk8e8lCUn8R5CEJP4jSUIS/9EkIYn/LJKQxH8FSUjiv4skJCGJ/40kIQlJSOL/spd8yZcE4Fd/9Vd5UUjiuUniftdccw333XffrVx11VVXXXXV/28EV1111VVXXfX/3H333XfryZMn+beSxP1++Zd/GYCHPvSh3E8S/xaS+LeSxL+VJCTx7yGJfy9JSOI/giQk8R9JEpL4jyYJSfxnkYQk/itIQhL/XSQhif+NJCEJSfx/8pIv+ZIAfO/3fi//EkkASEISz88111zDVVddddVVV10FwVVXXXXVVVddxalTp3ggSTw3SfxLLly4wFOe8hROnDjB67/+6yOJfwtJ/FtIQhL/VpL495CEJP69JPEfQRKS+I8kCUn8R5OEJP6zSEIS/9kkIQlJ/HeQhCQk8b+NJCQhif+PXuM1XgOAX/3VX+Xee+/lhZHEi+Laa6/lvvvuu5Wrrrrqqquu+v+N4Kqrrrrqqqv+nzt79uwz+DeSxHP75V/+ZQBe7uVejn8tSUji30IS/1aSkMS/lSQk8e8lCUn8R5DEfyRJSOI/miQk8Z9FEpL4zyYJSfx3kYQk/jeRhCQkIYn/717qpV4KgF/91V/lhZHE8yOJ+0nifmfPnn0GV1111VVXXfX/G8FVV1111VVX/T9333333Xry5En+ozzlKU/hKU95CidOnODlXu7leFFJ4t9CEpL4t5LEv4ck/r0kIYn/CJKQxH8USUjiP5okJPGfRRKS+M8mCUn8d5CEJCTxv4UkJCGJq57tJV/yJTl27Bh/8zd/w9/8zd/wH+Waa67hqquuuuqqq66C4KqrrrrqqquuuuzkyZO8IJJ4UUniz/7szwB4vdd7Pf4lkpDEv4Uk/q0kIYl/K0lI4t9DEpL4jyAJSfxHkYQk/qNJQhL/WSQhif9skpDEfwdJSOJ/C0lIQhJXPX8v+ZIvCcCv/uqv8h/tH/7hH36bq6666qqrrvr/jeCqq6666qqr/p87e/bsrQCnTp0CQBIvCkm8IE95ylO4cOECJ06c4KEPfSgviCT+LSQhiX8LSUji30MS/16S+I8gCUn8R5GEJP6jSUIS/1kkIYn/bJKQxH8HSUjifwNJSEISV71wD3rQg3jQgx4EwK/+6q/yopLEc5PE/a655hquuuqqq6666qrLCK666qqrrrrq/7n77rvvVv6DXbhwgT/90z8F4PVe7/V4fiTxbyGJfytJ/HtIQhL/HpKQxL+XJCTxH0USkviPJglJ/GeRhCT+s0lCEv8dJCGJ/w0kIYmrXnSv8RqvAcD3fu/38qKSBIAkJPH8XHPNNQDcd999t3LVVVddddVV/78RXHXVVVddddVV3HfffbeePHmS50cSLypJ3O/P/uzPADhx4gQPfehDuZ8kJPFvIYl/K0n8W0lCEv8ekpDEfwRJ/EeRhCT+o0lCEv9ZJCGJ/2ySkMR/NUlIQhL/00lCEpK46l/vQQ96EAC/+qu/yotCEi+Ka6+9lquuuuqqq6666jKCq6666qqrrrqKs2fP3nry5Ekk8aKQxL/kwoUL/Omf/iknTpzgZV/2ZQGQxL+FJCTxbyEJSfxbSeLfSxL/ESQhif8okviPJglJ/GeRhCT+s0lCEv/VJCGJ/+kkIQlJXPVv9xZv8RYA/Oqv/ir33nsv/xJJPD+SeH7uu+++W7nqqquuuuqqqwiuuuqqq6666qr/EJJ4br/yK78CwEMf+lAk8W8hiX8rSfxbSUIS/x6SkMS/lyQk8R9FEpL4jyQJSfxnkYQk/rNJQhL/1SQhif/pJCGJq140kpCEJCQhCUlIQhIv+ZIvCcCv/uqv8h9FEgDXXHMNZ8+evZWrrrrqqquuuorgqquuuuqqq67ivvvuu/XUqVM8N0k8N0m8qC5cuMBTnvIUTpw4wcu+7MvyryWJfwtJSOLfShL/HpKQxL+XJCTxH0USkviPJAlJ/GeRhCT+s0lCEv/VJCGJ/8kkIQlJXPW8JCEJSUhCEpKQxAvzki/5kgD8zd/8DX/zN3/Df7Rrr72W++6771auuuqqq6666iqCq6666qqrrrqK++6779aTJ0/ybyWJ50cSv/IrvwLA673e6/GikoQk/i0k8W8lCUn8e0jiP4Ik/qNIQhL/0STxn0USkvjPJglJ/FeThCT+J5OEJK66QhKSkIQkJCGJf6vXeI3XAOD7vu/7+NeSxHOTxFVXXXXVVVdd9XwRXHXVVVddddVV/6kuXrzIU57yFE6cOMFDHvIQ/iWS+LeQhCT+rSTx7yEJSfx7SUIS/xEkIYn/aJKQxH8GSUjiP5skJPFfTRKS+J9KEpKQxP9XkpCEJCQhCUn8R3rJl3xJjh07xr333svf/M3f8K8hCQBJSOIFefEXf3Huu+++W7nqqquuuuqqqwiuuuqqq6666irOnj37jFOnTvFAknhuknhRSQLgwoUL/Nmf/RkAr/d6r8cLI4l/C0n8W0lCEv9WkpDEv5ckJPEfQRKS+I8mCUn8Z5CEJP6zSUIS/5UkIQlJ/E8lCUn8fyQJSUhCEv8VXuIlXgKA7/3e7+VfQxL/GmfPnn0GV1111VVXXXUVwVVXXXXVVVddxX333XfryZMn+beQxL/kqU99KgAPfehDechDHsJzk4Qk/rUkIYl/K0n8e0ji30sSkviPIon/aJKQxH8GSUjiP5skJPFfSRKS+J9KEpKQxP8nkpCEJCTxX+2WW27hQQ96EAC/+qu/yotKEs+PJJ6fa665hquuuuqqq6666jKCq6666qqrrrrqWU6ePMl/BEk80IULF/izP/szAF7u5V6OB5LEv4Uk/q0kIYl/K0lI4t9LEv9RJCGJ/0iSkMR/BklI4j+bJCTxX0kSkvifShKS+P9CEpKQhCT+u73kS74kAL/6q7/KfzRJAEgC4B/+4R9+m6uuuuqqq666iuCqq6666qqrruLs2bO3Apw8eZIXRBLPTRIvql/5lV8B4CEPeQgnTpwAQBL/FpL4t5LEv4ck/r0kIYn/CJKQxH8kSUjiP4MkJPGfTRKS+K8kCUn8TyUJSfx/IAlJSOJ/mpd8yZcE4Hu/93v5z3LNNddw1VVXXXXVVVc9C8FVV1111VVXXcV99913Kw8gif9oFy5c4KlPfSonTpzg9V7v9ZDEv5YkJPFvIQlJ/FtJQhL/HpKQxH8ESUjiP5IkJPGfQRKS+M8mCUn8V5KEJP4nkoQkJPF/mSQkIQlJ/E/1Gq/xGgD86q/+Kvfeey//FpJ4bpJ4oGuuuQaA++6771auuuqqq6666iqCq6666qqrrrrqsvvuu+/WU6dO8e8liedHEr/yK78CwEMe8hD+tSTxbyWJfw9J/HtJ4j+CJCTxH0kSkvjPIAlJ/GeThCT+K0lCEv8TSUIS/5dJQhKS+N/iJV/yJQH41V/9Vf4tJAEgCUm8INdccw1XXXXVVVddddWzEFx11VVXXXXVVZedPXv21pMnT/L8SOK5SeJf66lPfSpPfepTOXHiBC/7si/Li0oS/xaSkMS/lSQk8e8hCUn8R5DEfyRJSOI/iyT+s0lCEv+VJCGJ/4kkIYn/qyQhCUn8b/OSL/mSHDt2jL/5m7/hb/7mb/jXksS/xn333XcrV1111VVXXXUVAMFVV1111VVXXfUcJPFvJYnnRxL3+7M/+zMAXvd1X5d/iSQk8W8hiX8PSfx7SEIS/xEkIYn/SJL4zyIJSfxnkoQk/itJQhL/E0lCEv8XSUISkvjf7CVe4iUA+NVf/VX+tSTx/Eji+bnmmms4e/bsrVx11VVXXXXVVQAEV1111VVXXXXVZffdd9+tJ0+e5D/bU5/6VC5cuMCJEyd4yEMewgsiiX8rSfxbSUIS/x6S+I8gCUn8R5KEJP4zSEIS/5kkIYn/SpKQxP9EkpDE/zWSkIQk/i94yZd8SR70oAcB8Ku/+qv8Z5DE/a699lruu+++W7nqqquuuuqqqwAIrrrqqquuuuqqy+67775bT548yXOTxHOTxItKEg904cIFfvVXfxWA13u91+P5kcS/hSQk8W8liX8PSUji30sSkviPJAlJ/GeQhCT+M0lCEv+VJCGJ/2kkIQlJ/F8jCUn8X/MSL/ESAHzv934v/9kkcdVVV1111VVXPQeCq6666qqrrrrqP4QkXlRPfepTAXjIQx7CQx7yEB5IEv8Wkvi3koQk/j0k8R9BEv+RJCGJ/wySkMR/JklI4r+SJCTxP40kJPF/jSQkIYn/i44dO8aDHvQgAH71V3+Vfw9JSOKBJPHcXvzFX5z77rvvVq666qqrrrrqKgCCq6666qqrrrrqsrNnzz7j1KlT/EeSxPNz8eJF/uzP/gyAl33ZlwVAEpL4t5DEv5Uk/j0kIYl/L0lI4j+KJCTxn0ESkvjPJAlJ/FeShCT+p5GEJP6vkYQk/q97jdd4DQB+9Vd/lXvvvZd/K0ncTxL/krNnzz6Dq6666qqrrroKgOCqq6666qqrrrrsvvvuu5UXgSSemyT+tX71V38VgIc85CFI4t9CEpL4t5CEJP6tJCGJfy9JSOI/iiQk8Z9BEpL4zyaJ/0qSkMT/NJKQxP8lkpCEJP6/eMmXfEkAvvd7v5d/K0n8a1xzzTXcd999t3LVVVddddVVVwEQXHXVVVddddVVl509e/bWkydPcvLkSe4niX8rSTw/kgC4ePEiT33qUzlx4gSv+7qvy7+WJP6tJPHvIYn/CJL4jyIJSfxnkIQk/rNJQhL/VSQhif9pJCGJ/0skIYn/b17yJV8SgF/91V/l3nvv5d9CEs+PJF6Ys2fP3spVV1111VVXXQVAcNVVV1111VVXPYeTJ0/yX+VXf/VXAXiZl3kZ/jUk8W8hCUn8W0lCEv9ekpDEfxRJ/GeQhCT+s0lCEv9VJCGJ/2kkIYn/SyQhif+vXuM1XgOAX/3VX+U/kyTud80113DVVVddddVVVz0Hgquuuuqqq6666rL77rvvVv4FknhuknhRSeKBnvrUp/LUpz6VEydO8JCHPIR/iSQk8W8hiX8PSfx7SUIS/1EkIYn/aJKQxH82SUjiv4okJPE/jSQk8X+FJCQhif/PXvIlX5Jjx45x77338jd/8zf8V5DENddcA8B99913K1ddddVVV111FQDBVVddddVVV131LPfdd9+tPJMk/q0k8aL6sz/7MwBe93VflxdGEv9Wkvi3koQk/r0k8R9FEpL4jyYJSfxnk4Qk/itJ4n8aSUji/wpJSOKqK17iJV4CgO/93u/lP4IkJPFAknhu11xzDVddddVVV1111XMguOqqq6666qqrnuXs2bO3PvzhD+e/0lOf+lQAHvKQh/CQhzyE50cS/xaSkMS/lST+vSQhif8IkpDEfzRJSOI/myQk8V9JEpL4n0QSkvi/QhKSuOrZbrnlFh70oAcB8Ku/+qv8e0nifpL4l9x33323ctVVV1111VVX3Y/gqquuuuqqq656kUjiuUniuUni+ZHE83Px4kV+9Vd/FYDXfd3X5blJ4t9CEv9WkpDEv4ckJPEfRRL/0SQhif9skpDEfyVJSOJ/EklI4v8KSUjiquf1ki/5kgD86q/+Kv9ekvjXuOaaazh79uytXHXVVVddddVV9yO46qqrrrrqqque5b777rv11KlTSOK/iiT+/M//HIDjx4/zkIc8BABJSOLfQhL/VpL495LEfxRJSOI/kiQk8Z9NEpL4ryQJSfxPIglJ/F8hCUlc9YK95Eu+JADf+73fy7+HJJ4fSbwg1157Lffdd9+tXHXVVVddddVV9yO46qqrrrrqqque5b777rv15MmT/EeTxAtz8eJFnvrUp3LixAle5mVeBkn8W0hCEv9Wkvj3kIQk/iNIQhL/0STxn00SkvivJAlJ/E8iCUn8XyAJSUjiqhfuzd/8zQH41V/9Ve69916uuuqqq6666qr/dgRXXXXVVVddddW/SBLPTRLPTRL/GpK434/8yI8A8NCHPpR/C0n8W0lCEv8ekviPIAlJ/EeThCT+M0lCEv+VJCGJ/0kkIYn/CyQhiatedC/5ki8JwK/+6q/yX0ESD/TiL/7i3Hfffbdy1VVXXXXVVVfdj+Cqq6666qqrrnqWs2fPPuPkyZP8R5LEi+LixYs89alP5fjx47zMy7wM/xqS+LeSxL+HJCTxH0ES/9EkIYn/TJKQxH8lSUjifxJJSOL/AklI4qp/nZd8yZcE4G/+5m/4m7/5G/6jSEISDySJB5LE/c6ePfsMrrrqqquuuuqq+xFcddVVV1111VXPct99993KfxFJPLdf+7VfA+B1X/d1eVFJ4t9CEpL495DEfwRJSOI/kiQk8Z9JEpL4ryQJSfxPIQlJSOL/AklI4qp/m9d4jdcA4Fd/9Vf5jyKJ+0niX3LNNddw33333cpVV1111VVXXXU/gquuuuqqq6666lnOnj1768mTJ3kgSTw3STw3Sfx7Xbhwgac+9akcP36chzzkIbwwkpDEv4Uk/j0kIYl/L0lI4j+SJCTxn0kSkvivJAlJ/E8hCUn8XyEJSVz1b/eSL/mSHDt2DIBf/dVf5T+CJP4tzp49eytXXXXVVVddddX9CK666qqrrrrqqudx8uRJ/iNI4vmRxPOzu7vLX/zFXwDwOq/zOrwgkvi3ksS/hyT+I0jiP5IkJPGfRRKSkMR/JUlI4n8KSUji/wpJSOKqf7+XeImXAODLvuzL+I8giedHEi/INddcw1VXXXXVVVdd9TwIrrrqqquuuuqqZ7nvvvtuBTh58iT/GpL4j/LUpz4VgIc85CE85CEP4blJ4t9CEpL4t5KEJP69JCGJ/yiSkMR/FklI4r+SJCQhif8pJCGJ/yskIYmr/mPccsstPOhBDwLgV3/1V/nvcs011wBw33333cpVV1111VVXXXU/gquuuuqqq6666jncd999t/JCSOJFIYnnRxLPjyQALl68yJ//+Z8D8DIv8zI8kCT+LSTx7yGJfy9JSOI/kiT+s0hCEv+VJCGJ/0kkIYn/KyQhiav+Y73kS74kAL/6q7/KfyVJPNA111zDVVddddVVV131PAiuuuqqq6666qrncPbs2Vsf/vCHAyCJ/w6/9mu/BsBDHvIQ7ieJfwtJ/FtJQhL/XpL4jyQJSfxnkIQk/itJQhL/k0hCEv9XSEISV/3neMmXfEkAvvd7v5f/aJKQxANJ4oEkcb9/+Id/+G2uuuqqq6666qoHIrjqqquuuuqqq/5dJPGiksTzI4kHunjxIk996lM5fvw4r/u6r4sk/i0k8W8liX8vSUjiP4okJPGfQRKS+K8kCUn8TyIJSfxfIQlJXPWf5zVe4zUA+NVf/VXuvfde/iNJ4n6S+Jdcc8013Hfffbdy1VVXXXXVVVc9EMFVV1111VVXXfUc7rvvvltPnjzJ8yOJF4Uk/r1+7dd+DYCXeZmX4V9LEpL4t5LEv5ck/qNIQhL/WSTxX0kSkvifRBKS+L9EElf953vJl3xJAH71V3+V/0iS+Ne69tprueqqq6666qqrngfBVVddddVVV131HO67775bT548iST+K0ji+Xna057G0572NI4fP87LvMzL8KKSxL+VJCTx7yEJSfxHkcR/FklI4r+KJCTxP4kkJPF/iSQkcdV/vpd8yZfk2LFj/M3f/A1/8zd/w38USTw/kviX3Hfffbdy1VVXXXXVVVc9EMFVV1111VVXXfVvJonnJonnRxL/GpL48z//cwBe53VehxeFJP6tJPHvJYn/KJKQxH8GSUjiv4okJPE/iSQk8X+JJCRx1X+dl3iJlwDgV3/1V/mf4JprruHs2bPP4KqrrrrqqquueiCCq6666qqrrrrqOZw9e/YZJ0+e5LlJ4j+aJF6Ypz3taVy8eJHjx4/z4Ac/mBdGEv9Wkvj3kIQk/iNIQhL/GSQhif8qkpDE/ySSkMT/JZKQxFX/tW655RYe9KAHAfCrv/qr/FeTxHO75ppruOqqq6666qqrngfBVVddddVVV131HO67775b+Q8miX8NSQBcvHiRP//zPwfgdV7ndXh+JCGJfwtJSOLfQxL/ESQhif8MkpDEfwVJSEIS/5NIQhL/l0hCElf993iN13gNAL73e7+X/wySkIQkHkgSL8g111zDfffddytXXXXVVVddddUDEVx11VVXXXXVVc/h7Nmzt548eZJ/iSSemyT+o/3FX/wFACdOnODBD34wDySJfytJ/HtIQhL/ESTxn0ESkvivIAlJ/E8jCUn8XyEJSUjiqv9eD3rQgwD41V/9Vf6jSeKBJPGCSOKBzp49eytXXXXVVVddddUDEVx11VVXXXXVVc/XyZMnuZ8k/qNJ4vmRxANdvHiRv/iLv+D48eO8zMu8DPeTxL+VJP49JPEfQRKS+I8mCUn8V5CEJP6nkYQk/q+QhCSu+p/hzd/8zQH41V/9Ve69917+J7jmmmu46qqrrrrqqqueL4Krrrrqqquuuuo53HfffbcCnDx5kv8Ikvj3+rVf+zUAHvKQhwAgiX8LSUji30oSkvj3koQk/qNJQhL/FSQhif9pJCGJ/yskIYmr/md5yZd8SQB+9Vd/lf9oknh+JPHCXHPNNQDcd999t3LVVVddddVVVz0QwVVXXXXVVVdd9Tzuu+++W3khJPHcJPGiksTzI4nn5+LFizztaU/j+PHjvMzLvAz/FpL495DEfwRJ/EeThCT+K0hCEv/TSEIS/1dIQhJX/c/zki/5kgD8zd/8DX/zN3/D/xTXXHMNV1111VVXXXXV80Vw1VVXXXXVVVc9j7Nnz9568uRJACTxbyWJ/wiS+PVf/3UAXud1Xod/LUn8e0ji30sSkviPJAlJ/FeQhCT+J5GEJCTxf4UkJHHV/1yv8RqvAcD3fd/38d9FEs/PP/zDP/w2V1111VVXXXXVcyO46qqrrrrqqquerxMnTvCfQRLPjySeH0kAPO1pT+NpT3sax48f58EPfjAvKkn8W0lCEv9ekviPJAlJ/FeQhCT+J5GEJP4vkYQkrvqf7SVf8iU5duwY9957L3/zN3/DfxZJSEISDySJF+Saa67hvvvuu5Wrrrrqqquuuuq5EVx11VVXXXXVVc/jvvvuu/XkyZM8P5J4bpL4r/AXf/EXALzO67wOLwpJ/FtJ4t9LEpL4jySJ/2ySkIQk/ieRhCT+L5GEJK763+ElXuIlAPje7/1e/rNI4oEk8YJI4n7XXnstV1111VVXXXXV80Vw1VVXXXXVVVc9j/vuu+/WkydP8u8hiReVJJ4fSTzQ0572NAAe/OAH8+AHP5gXRBKS+LeSxL+XJP4jSUIS/5kkIYn/SSQhCUn8XyEJSUjiqv89brnlFh70oAcB8Ku/+qv8V5LEi+K+++67lauuuuqqq6666rkRXHXVVVddddVVL5Ak/iNJ4t/j4sWL/MVf/AUAL/MyL8PzI4l/K0lI4t9DEpL4jyIJSfxnkoQk/ieRhCT+L5GEJK763+klX/IlAfjVX/1V/rNI4t/qmmuu4ezZs8/gqquuuuqqq656bgRXXXXVVVddddXzOHv27DNOnjzJc5PEc5PEv4cknh9JPD+//uu/DsCDH/xgjh8/zgNJ4t9KEv9ekviPIglJ/GeShCT+J5GEJP4vkYQkrvrf7SVf8iUB+N7v/V7+J7rmmmu46qqrrrrqqqueL4Krrrrqqquuuup53Hfffbfy7yCJ/yy7u7s87WlP4/jx47zO67wO95PEv5Uk/j0kIYn/KJL4zyQJSfxPIQlJSOL/CklIQhJX/e/3Gq/xGgD86q/+Kvfeey//HSQBIInn55prruG+++67lauuuuqqq6666rkRXHXVVVddddVVz+Ps2bO3njx5kv9IknhRSeKF+Y3f+A0AHvzgBwMgiX8rSfx7SOI/iiQk8Z9FEpL4n0ISkvi/RBKSuOr/lpd8yZcE4Fd/9Vf5zyYJSUhCEv8aZ8+evZWrrrrqqquuuuq5EVx11VVXXXXVVS/QyZMneWEk8e8hiX8NSQA87WlP42lPexrHjx/nZV7mZfi3kIQk/q0kIYn/CJKQxH8WSUjifwJJSEIS/1dIQhKSuOr/npd8yZfk2LFj/M3f/A1/8zd/w38mSbyoJHG/a665hquuuuqqq6666gUiuOqqq6666qqrnsd99913K8CJEye4nyReFJJ4bpL4j/aXf/mXALz2a782/1qS+PeQxH8USfxnkYQk/ieQhCT+L5GEJK76v+01XuM1APjVX/1V/jNJ4vmRxL/kmmuuAeC+++67lauuuuqqq6666rkRXHXVVVddddVVz9d99913K/+JJPH8SOL5kcQDPe1pT+PixYscP36cBz/4wbyoJPHvIYn/CJKQxH8GSUjiv5skJCGJ/yskIQlJXPV/30u+5Ety7NgxAH71V3+V/6muueYarrrqqquuuuqqF4jgqquuuuqqq656vs6ePXvryZMneUEk8d/p4sWL/MZv/AYAr/3ar82LQhL/VpKQxH8ESfxnkIQk/rtJQhL/V0hCEpK46v+Xl3iJlwDgy7/8y/mfQBIvyD/8wz/8NlddddVVV1111fNDcNVVV1111VVXvUAnT54EQBIvCkk8N0m8qCTx/Eji+Xna054GwIMf/GAe/OAH88JI4t9KEv8RJCGJ/2iSkMR/J0lIQhL/V0hCElf9/3Ts2DEe9KAHAfC3f/u3/FeRhCQeSBIvzDXXXMN99913K1ddddVVV1111fNDcNVVV1111VVXPV/33XffrSdPnuQ/gyT+I+zu7vKXf/mXALz0S780L4gk/q0k8R9BEv/RJCGJ/06SkMT/FZKQhCSu+v/tNV7jNQD4tV/7Ne69917+K0jifpJ4UV177bVcddVVV1111VUvEMFVV1111VVXXfV83XfffbeeOHGC50cS/9Ek8fxI4oX5jd/4DQAe/OAH89wkIYl/K0n8e0lCEv/RJPHfRRKSkMT/BZKQhCSuuup+L/mSLwnAD/zAD/BfQRIvKkk8t/vuu+9Wrrrqqquuuuqq54fgqquuuuqqq656oSTxopDEc5PEc5PEfwRJAFy8eJGnPe1pHD9+nNd+7dfmfpL4t5KEJP69JPEfTRKS+O8gCUn8XyAJSUjiqque20u+5EsC8Ou//uvce++9/GeTxPMjiRfFNddcw9mzZ5/BVVddddVVV131/BBcddVVV1111VXP1z/8wz/8zsmTJ/nvJIkXxW/8xm8A8NIv/dIASOLfShL/XpKQxH8kSUjiv5okJCGJ/wskIYmrrnphXuM1XgOAX//1X+d/g2uuuYarrrrqqquuuuoFIrjqqquuuuqqq/5VJPEfTRL/GpJ4oKc//ek87WlP4/jx4zzkIQ/h30oS/16S+I8kCUn8V5OEJP4vkIQkJHHVVf+Sl3zJl+TYsWPce++9/N3f/R3/U0jiBbnmmmu47777buWqq6666qqrrnp+CK666qqrrrrqqufr7Nmzt548eZIXhSSemySemyReVJL41/jLv/xLAF7rtV6LfwtJ/HtIQhL/kSTxX00SkvjfThKSkMRVV/1rvMRLvAQAP/iDP8j9bPOfTRKSkMQDSeJFcfbs2Vu56qqrrrrqqqueH4KrrrrqqquuuuqFOnnyJP+ZJPGvIYnn5+lPfzoAD37wg3nwgx/Mv4Yk/j0k8R9JEpL4ryIJSUjifytJSEISkrjqqn+LW265hQc96EEA/MZv/Aa2sc1/Nkk8kCReVNdccw1XXXXVVVddddULRXDVVVddddVVVz1f9913360AJ06c4H6S+J9qd3eX3/iN3wDgtV7rtXhRSeLfQxL/USQhif8qkpDE/1aSkIQkrrrqP8JLvuRLAvAbv/Eb/HeTxPMjiQe65pprALjvvvtu5aqrrrrqqquuen4IrrrqqquuuuqqF+i+++67lX+BJJ6bJJ6bJF5Uknh+JPHC/NVf/RUAx48f58EPfjD/Ekn8e0jiP4ok/qtIQhL/G0lCEpK46qr/aC/5ki8JwA/90A/xX0US/x7XXHMN9913361cddVVV1111VUvCMFVV1111VVXXfUCnT179taTJ0/yn0US/xEkAXDx4kWe/vSnc/z4cV7qpV6KF0QSkvi3koQk/iNIQhL/FSQhif9NJCEJSUjiqqteFLaxjW1sYxvb2MY2trGNbWxjmzd/8zcH4Dd/8ze57777+N/k7Nmzt3LVVVddddVVV70gBFddddVVV1111Qt14sQJACTx3CTxH00Sz48kXhQ/8RM/AcCDH/xgnh9J/HtI4j+KJP4rSEIS/xtIQhKSkMRVVz0329jGNraxjW1sYxvb/Fu85Eu+JAC/8Ru/wX8HSUjigSQBIIkX5JprruG+++67lauuuuqqq6666gUhuOqqq6666qqrXqD77rvv1pMnT/KvIYnnJon/LJJ4oIsXL/L0pz+d48eP89Iv/dI8kCT+PSTxH0ESkvjPJglJ/E8nCUlI4qqrbGMb29jGNraxjW3+M7zkS74kAH//93/P3//93/PcbPOfSRL3k8S/xrXXXstVV1111VVXXfVCEVx11VVXXXXVVS/Qfffdd+vJkyf5zyCJF5Uk/jV+4zd+A4DXeq3X4n6S+PeQxH8ESfxnk4Qk/qeShCQkIYmr/n+yjW1sYxvb2Oa/w2u+5msC8Ju/+ZsA2Oa/iiT+ve67775bueqqq6666qqrXhCCq6666qqrrrrqXySJ5yaJ/2iS+NeQxPOzu7vL05/+dI4fP86DH/xgJPFvJQlJ/HtJQhL/mSQhif+JJCEJSVz1/49tbGMb29jmf4qXfMmX5NixYwD85m/+Jv+VJPH8SOL5kcRzu+aaazh79uwzuOqqq6666qqrXhCCq6666qqrrrrqBfqHf/iH3zlx4gQvKkk8N0k8N0m8qCTx/EjiBdnd3eUv//IvAXit13ot/q0k8R9BEv+ZJCGJ/0kkIQlJSOKq/z9sYxvb2MY2/5O95Eu+JABf93Vfx/Njm//JrrnmGq666qqrrrrqqheK4Kqrrrrqqquu+h9BEv+Rnv70pwPw4Ac/mAc96EH8a0ni30sSkvjPIglJ/E8hCUlI4qr/P2xjG9vY5n+TBz3oQTzoQQ8C4Ld+67d4INv8d5IEgCRemGuuuYb77rvvVq666qqrrrrqqheE4KqrrrrqqquueoHOnj1768mTJ3luknhukvifQBIAu7u7/OVf/iUAL/3SL82/hiT+vSTxn0USkvifQBKSkMRV/3/Yxja2+d/sJV/yJQH4rd/6LZ4f2/xnk4QkJCGJf4uzZ8/eylVXXXXVVVdd9YIQXHXVVVddddVV/6ITJ07wbyGJ5yaJF5Uknh9JvCh+8zd/E4AHPehBvKgk8e8lif8MkpDEfzdJSEISV/3/YRvb2Ob/ipd8yZcE4Ed/9Ef57yCJf49rrrmGq6666qqrrrrqX0Rw1VVXXXXVVVe9QPfdd9+tACdPnuQ/kyT+I0jigXZ3d3n605/O8ePHea3Xei3+JZL495CEJP4zSOK/kyQkIYmr/v+wjW1s83/Na7zGawDwW7/1W9x33338TyGJF9U111wDwH333XcrV1111VVXXXXVC0Jw1VVXXXXVVVe9UPfdd9+tPIAknpsk/qNJ4vmRxPMjiefnN3/zNwF4qZd6KV4YSfx7SOI/gyQk8d9BEpKQxFX/f9jGNrb5v+ylXuqlAPjt3/5t/jtI4l9DEs/tmmuu4b777ruVq6666qqrrrrqhSG46qqrrrrqqqteqLNnz9564sQJ/rUk8dwk8V/t6U9/Ok9/+tM5fvw4L/VSL8XzI4l/D0n8R5OEJP6rSUISkrjq/xfb2Ob/g5d8yZfk2LFj/MM//AP/8A//AIBtAGzzQLb57yKJf8nZs2dv5aqrrrrqqquuemEIrrrqqquuuuqqf9HJkyf5zyKJF5Uknh9JvCCS+Ku/+isAXuu1XovnJol/D0n8R5PEfzVJSOKq/19sYxvb/H/yki/5kgD89m//Nv/dJCGJB5LEi+Kaa67hvvvuu5WrrrrqqquuuuqFIbjqqquuuuqqq16o++6779YTJ04AIInnJon/aJL4j/T0pz+d3d1djh8/zoMe9CDuJ4l/D0n8R5KEJP6rSEISkrjq/xfb2Ob/owc96EE86EEPAuC3f/u3eWFs859JEveTxL/Wtddey1VXXXXVVVdd9S8iuOqqq6666qqrXqj77rvv1pMnT/KvIYnnJol/D0k8P5J4QSQBsLu7y2/+5m8C8Fqv9VoASOLfQxL/kSTxX0USkrjq/x/b2Ob/s9d4jdcA4Md+7Md4QWzzn00Sz00S/1r33XffrVx11VVXXXXVVS8MwVVXXXXVVVdd9d9GEv9Vnv70pwNw/PhxHvzgB/PvIYn/KJKQxH8FSUjiqv9/bGOb/++OHTvGgx70IAB++7d/mxfGNgC2+Y8miX8NSTw/11xzDWfPnn0GV1111VVXXXXVC0Nw1VVXXXXVVVe9UP/wD//wOydOnEASz00S/9Ek8R9BEg+0u7vLX/3VX3H8+HFe6qVein8LSUjiP4ok/rNJQhKSuOr/J9tcdcVrvMZrAPA7v/M7nD17lv/JJPEvueaaa7jqqquuuuqqq/5FBFddddVVV1111X8oSTw3Sfx7SOL5kcS/xm/+5m8C8KAHPYh/LUn8R5GEJP4zSUISV/3/ZRvb/H9iG9vYxja2sY1tbPNSL/VSAPz2b/82/xNIQhIPJIkX1TXXXMN99913K1ddddVVV1111QtDcNVVV1111VVXvVBnz5699eTJk/xHk8Rzk8R/BEk8P7u7uzz96U/n+PHjvNRLvRQvKkn8R5HEfyZJSOKq/79sY5v/y2xjG9vYxja2eWFe8iVfEoDHPe5xPO5xj+O/myTuJ4l/q7Nnz97KVVddddVVV131whBcddVVV1111VUvkhMnTvBAknhukvivIonnRxIvzG/91m8B8Jqv+Zq8KCTxH0US/1kkIYmr/n+zzf8ltrGNbWxjG9v8W7zma74mAD/+4z/Oc7MNgG0eyDb/GSTx3CTxr3HNNddw1VVXXXXVVVe9SAiuuuqqq6666qoX6r777rsV4OTJk/xbSOLfQxL/USRx66238vSnP53jx4/zoAc9iBdGEv9RJPGfRRJX/f9mG9v8b2cb29jGNv9RXvIlX5Ljx49z9uxZHve4x/G/iSSen2uuuQaA++6771auuuqqq6666qoXhuCqq6666qqrrvoX3XfffbfyAJL495DEc5PEi0oS/1qSuN9f//VfA/Bar/Va/GeThCT+M0hCElf9/2ab/41sYxvb2MY2/1le6qVeCoCf+Imf4F9iGwDb/GeQxL9EEv+Sa665hvvuu+9WrrrqqquuuuqqfwnBVVddddVVV131Lzp79uytJ06c4IWRxH80SfxrSOJF8fSnPx2ABz3oQTzoQQ/i+ZHEv5ck/jNIQhL/V0niqheNbf43sY1tbPNf5UEPehAPetCDAPjd3/1dXhS2+c8mCUk8kCT+Nc6ePXsrV1111VVXXXXVv4Tgqquuuuqqq656kZw4cYJ/LUn8TyCJB9rd3eWv/uqvAHipl3opnpsk/r0k8R9NEpL430QSkpCEJCQhCUlIQhKSkIQkJAEgCUlIQhKSkIQkJCEJSUhCEv/f2MY2/9PZxja2sc1/h5d8yZcE4Hd/93f517LNfwZJ3E8S/xbXXHMN9913361cddVVV1111VX/EoKrrrrqqquuuupfdN9999168uRJACTx7yGJ5yaJF5Uknh9J/Gv81m/9FgAPetCDOH78OPeTxL+XJP6jSeJ/MklIQhKSkIQk/qtIQhKSkIQk/q+yzf9ktrGNbf4neKmXeikAfvInf5L/CSTx3CTxr3Xttddy1VVXXXXVVVe9SAiuuuqqq6666qp/0X333XfriRMneEEk8R9NEv8RJPH87O7u8vSnP53jx4/zmq/5mgBI4t9LEv+RJCGJ/0kkIQlJSEIS/xNJQhKS+L/CNv8T2cY2tvmf5DVf8zUB+N3f/V3Onj2LbZ6bbQBs8z+NJF6Y++6771auuuqqq6666qp/CcFVV1111VVXXfWfQhL/0STx/Eji3+K3f/u3AXjQgx6EJP69JPEfSRL/E0hCEpKQxP9GkpDE/2a2+Z/ENraxzf9UL/mSLwnA7/3e7/GvZZv/aJL4l0jiRXHNNddw9uzZZ3DVVVddddVVV/1LCK666qqrrrrqqn/RP/zDP/zOyZMnkcRzk8SLShL/lSTxgkji1ltv5dZbb+X48eO85Eu+JP8ekviPIglJ/HeShCQk8X+JJCTxv41t/qewjW3+p3vJl3xJjh8/zuMf/3ge//jH829hm/8MkpDEA0niX+Oaa67hqquuuuqqq656kRBcddVVV1111VX/rSTx3CTxopLEv8df/dVfAfCar/ma/FtJ4j+KJP67SEISkvi/ThL/W9jmv5ttbGOb/y1e8zVfE4Df/d3f5UVlGwDb/GeRxP0k8W91zTXXcN99993KVVddddVVV131LyG46qqrrrrqqqv+RWfPnr31xIkTvKgk8R9NEv8aknhBJHG/W2+9ld3dXY4fP86DHvQg/rUk8R9FEv/VJCEJSfx/I4n/6Wzz38k2tvnfwja2ecmXfEmOHz8OwO/93u/xr2Gb/yySeG6S+Lc6e/bsrVx11VVXXXXVVf8Sgquuuuqqq6666kV24sQJHkgSLypJ/E+0u7vLb/3WbwHwmq/5mvxrSOI/giQk8V9JEpL4/04S/1PZ5r+LbWzzP5VtbGMb29jGNvd7qZd6KQC+9Vu/FUkA2OZfwzb/nSTxglxzzTVcddVVV1111VUvMoKrrrrqqquuuupfdN99990KcOLECf4lknhRSeK5SeJFJYnnRxIviCSe26233grAgx70IB70oAfxopDEfwRJ/FeRhCQkcdWzSeJ/Gtv8V7ONbWzzP4ltbGMb29jmhTl+/DgPetCDAHj84x/PC2Ob/yqSeEEkASCJF8U111wDwH333XcrV1111VVXXXXVv4Tgqquuuuqqq656kdx333238gCS+K8iif8Iknh+dnd3+eu//msAXvIlX5J/iST+I0jiv4IkJHHVCyaJ/yls81/JNrb5n8I2trGNbf61XvM1XxOA3/u93+PcuXO8KGzzX0USkvj3uOaaa7jvvvtu5aqrrrrqqquuelEQXHXVVVddddVVL5KzZ8/eevLkSf4tJPEfTRLPjyT+LX7rt34LgAc96EG8MJL4jyCJ/2ySkMRV/3vY5r+Sbf672cY2trHNv9dLvdRLAfBTP/VT3M82/xq2+c8giftJ4t/j7Nmzt3LVVVddddVVV70oCK666qqrrrrqqhfZiRMneGEk8aKSxH8lSbwwly5d4tZbb+X48eO85mu+Jv+ZJPGfSRKSuOpfRxL/nWzzX8U2tvnvYBvb2MY2/5Fe6qVeCoDf//3f59y5cwDY5kVhGwDbANjmP5Iknpsknh9JvDDXXHMN9913361cddVVV1111VUvCoKrrrrqqquuuupFct9999164sQJACTxn0ESz00SLypJ/FtIAuC3f/u3AXjJl3xJnh9J/HtJ4j+LJCRx1f8+tvmvYBvb/FezjW1s85/pNV/zNQH4vd/7Pf4tbPPfRRIvqmuvvZarrrrqqquuuupFRnDVVVddddVVV71I7rvvvltPnDjBCyKJ50cS/9Ek8a8hiRfFrbfeyq233srx48d50IMexANJ4t9LEv9ZJHHV/062+c9mG9v8V7KNbWzzX+GlXuqlOH78OOfOneMJT3gC/xLb/FeRxAsiiX+L++6771auuuqqq6666qoXBcFVV1111VVXXfWvIol/L0n8TyGJB/rrv/5rAF7zNV+T+0ni30sS/xkkIYmr/mNI4v8a2/xXsY1tbPNf7aVe6qUA+Omf/mn+NWzz3Gxjm/9okpCEJP49zpw5w9mzZ5/BVVddddVVV131oiC46qqrrrrqqqteJP/wD//wOydPnuQ/iyT+PSTx/EjiBZHEc7v11lsBeNCDHsSDHvQg/iNI4j+aJCRx1f9utvnPYhvb/GezjW1s89/lQQ96EA960IMA+P3f/33+J5LEA0ni+ZHEv+Saa67hqquuuuqqq656kRFcddVVV1111VX/bpJ4fiTx7yGJ5yaJ/0y7u7v89m//NgCv+ZqviST+PSTxH00SV/3vZ5v/LLb5z2Yb2/x3sI1tbGObl3qplwLg93//9/n3ss1/NEn8R7r22mu57777buWqq6666qqrrnpREFx11VVXXXXVVS+Ss2fP3nrixAn+r5DEC/LXf/3XABw/fpwHPehB/FtJ4j+aJK763882/xlsY5v/LLaxjW3+q9jGNraxjW2e20u91EsB8DM/8zP8W9gGwDYAtvmvIAkASfxrnT179lauuuqqq6666qoXBcFVV1111VVXXfWvcuLECR5IEs+PJJ4fSfxHk8TzI4l/i93dXW699VaOHTvGS77kS/JvIYn/SJKQxFVXvSC2+c9iG9v8V7CNbWxjm3/JW73VWwHwB3/wB5w7d44XhW2em23+M0jiP9I111wDwH333XcrV1111VVXXXXVi4Lgqquuuuqqq656kdx33323Apw4cYL/aJJ4bpL4zyKJF0YSP/MzPwPAgx70IP61JPEfSRJX/d9hm/9otvnPYBvb/GeyjW1sY5t/rZd6qZcC4Pd///f5n0wSkpDECyKJf8k111zDVVddddVVV131r0Jw1VVXXXXVVVe9yO67775beQBJ/FeSxItKEv8WkgDY3d3l1ltv5dixY7zkS74k/10kcdX/Hbb5j2Qb2/xHs41t/rPYxja2+fd4qZd6KQCe+MQn8sQnPpF/Lds8N9vY5j+SJB5IEv9W11xzDWfPnn0GV1111VVXXXXVi4rgqquuuuqqq656kZ09e/bWhz70ofxLJPH8SOI/miT+NSTxovqd3/kdAF7zNV+TF5Uk/qNI4n8iSUhCEpKQhCQkIQlJSEISkpCEJCRx1X8c2/xHs41t/jPYxja2+Y/yWq/1WgD8wR/8Af9TSeKFkcS/1n333XcrV1111VVXXXXVi4rgqquuuuqqq676N5HEfwRJ/EeTxL+FJB5od3eXW2+9lWPHjvGgBz2If4kk/qNI4n8CSUhCEpKQxL+HJCQhCUlI4v8L2/xHsc1/JNvY5j+abWxjm/9oL/VSL8Xx48cB+IM/+AP+I9jmv4ok/i2uueYa7rvvvlu56qqrrrrqqqteVARXXXXVVVddddWL7L777rv15MmTvDCSeH4k8aKSxHOTxL+XJF4QSTy33d1d/uZv/gaA13iN1+CFkcR/FEn8d5GEJCQhif8KkpDE/2W2+Y9im/8otrHNfyTb2MY2/5le6qVeCoDv/M7v5F/DNg9kG9vYBsA2tvmPIIn7SUISL4gkXhTXXnstV1111VVXXXXVvwrBVVddddVVV131IrvvvvtuPXHiBP9TSOI/26233grAgx70IB70oAfxn00S/9UkIQlJ/HeShCQkcdXzso1t/iPYxjb/UWxjG9v8Z7KNbR70oAfx4Ac/GIA//MM/5N/CNv9VJHE/Sfx73XfffU/nqquuuuqqq656URFcddVVV1111VUvsrNnzz4DQBLPjyT+u0ni+ZHECyKJF2R3d5e//uu/BuAlX/IleX4k8R9BEv+VJCGJ/4kk8X+Fbf69bPMfxTb/UWxjm/8MtrGNbWxjm/u91Eu9FAB/8Ad/wP90knhBJPGv9eIv/uKcPXv2GVx11VVXXXXVVS8qgquuuuqqq6666kV233333XrixAn+tSTx/EjiuUnif5rf/d3fBeBBD3oQz00S/xEk8V9FEpL4n04SkvjfzDb/Xrb5j2Ab2/x72cY2tvmPZhvb2OaFeemXfmkAfvZnf5b/SLaxzX8USTw/krjqqquuuuqqq/7LEFx11VVXXXXVVf8hJPGfRRLPTRL/ESTxwkhid3eXW2+9lWPHjvEar/Ea/EeTxH8FSUjifxtJ/H9lm38v29jm38s2tvmPZBvb2MY2L4rXeq3XAuAP//APOX/+PP8atvmfSBIvqmuuuYazZ8/eylVXXXXVVVdd9aIiuOqqq6666qqrXmRnz5699cSJE/xrSOK/iiSeH0n8e/3O7/wOAC/1Ui/F/STx7yWJ/2ySkMT/ZpL438Y2/x62+feyzb+XbWzzH8U2trHNv8VLv/RLA/CHf/iHSOLfwzb3s81/JEkASEISkviPct99993KVVddddVVV131oiK46qqrrrrqqqv+1U6cOMEDSeJfSxL/3STxwkjifs94xjO49dZbOXbsGC/5ki/JfwRJ/GeShCT+r5CEJP4/sM2/h21s8+9hG9v8R7CNbWzz7/HSL/3SHD9+nCc+8Yk88YlP5N/KNvezjW0AbGOb/yiSeCBJ3E8S/1rXXHMNAPfdd9+tXHXVVVddddVVLyqCq6666qqrrrrqRXbffffdCnDixAn+M0jiP5ok/i0k8dz+5m/+BoDXfM3XRBL/HpL4zySJ/6sk8T+dbf6tbPPvYZt/D9vY5t/LNraxzX+Ul3qplwLgj/7oj/jfShL/Vtdccw1XXXXVVVddddW/GsFVV1111VVXXfWvct99993KA0jiBZHEv5cknpsknpsk/jUk8a/1jGc8g93dXY4dO8Ytt9zC/0SSkMRV/31s829lm38P2/xb2cY2/x62sY1t/iPZ5kEPehAPfvCDAfjDP/xD/qPZBsA2/xEk8aKQxIvqmmuu4b777ruVq6666qqrrrrqX4Pgqquuuuqqq676Vzl79uytD33oQ/n3kMT/ZJJ4fnZ3d/md3/kdAF7jNV6DfytJ/GeQxP8Xkvi/xjb/Vraxzb+FbWzz72Eb2/xHsY1tbGMbgNd+7dcG4Od//uf5t7DNv8Q2/xEkcT9JSOI/ytmzZ2/lqquuuuqqq6761yC46qqrrrrqqqv+zSTxgkjiv5sknh9JvCCSeGGe8YxnAHD8+HFuueUW/rUk8Z9BEv/fSOJ/Gtv8W9jm38o2/xa2sc2/lW1sY5t/L9vYxja2eW7Hjx/nwQ9+MAB/+Id/yH8E29zPNv8ZJHE/SdxPEv8W11xzDffdd9+tXHXVVVddddVV/xoEV1111VVXXXXVv8p9991364kTJ/iPJon/DXZ3d/mbv/kbjh07xku+5EvyP4Ekrvr/yTb/Frb5t7KNbf69bGMb2/xLXvu1XxuAP/qjP+L8+fP8e9jmfraxzX8GSTw3Sfx7XHvttVx11VVXXXXVVf9qBFddddVVV1111b/Kfffdd+uJEyeQxAsiiRdEEi8qSTw3STw3SfxHkMS/RBK/+7u/C8CDHvQg/jUk8R9JEpL4/0wS/5Fs829lm38L2/xb2OZfyza2+bewjW3+PWxjG9v8a7z0S780AH/0R3/Ev4Vt/iW2sc1/BEm8KCTxr3XffffdylVXXXXVVVdd9a9BcNVVV1111VVX/aucPXv2GbwQkvifQBLPjyT+rSQBsLu7yzOe8QyOHTvGS77kS/LfQRJXXSGJ/61s869lG9v8a9jGNv9atrGNbf6tbGMb2/xbvPRLvzQAf/RHf8STnvQk/j978Rd/cc6ePfsMrrrqqquuuuqqfw2Cq6666qqrrrrqX+W+++679cSJE/xbSOJ/Kkm8MJJ4oN/5nd8B4DVe4zV4UUjiP4okrvqfxTb/Wrb517LNv5Zt/i1s829lG9vY5t/rtV/7tQH4oz/6I/6j2OaBbANgm38vSQBIQhKSkMT9JHHVVVddddVVV/2XIrjqqquuuuqqq/7DSOLfQhL/FSTxH+UZz3gGz3jGMzh27Bi33HILL4wkrvrPJYn/TWzzr2Wbfw3b2OZfyza2+deyjW1s8+9lG9u81Eu9FMePH+f8+fM86UlP4t/LNs/NNgC2+Y8iiecmiQeSxL/WNddcw3333XcrV1111VVXXXXVvwbBVVddddVVV131r3L27NlbT5w4wb+WJP41JPHcJPHcJPHvJYkXRhLPz9/8zd8A8Bqv8Rr8V5HEVf+z2OY/m23+NWzzr2Ub2/xr2cY2/x62sY1tbHO/l3mZlwHgF37hF5DEv4Vtnh/b2OaBbPM/3dmzZ2/lqquuuuqqq6761yC46qqrrrrqqqv+TU6cOMEDSeJ/Ckn8R5HEC/KMZzwDgAc96EHccsst/GeTxFX/+9nmX8M2/xq2+dewjW3+NWxjG9v8W9nGNrZ5fh784Afz4Ac/GIA/+qM/4j+TbWzzH0ES/xmuueYaAO67775bueqqq6666qqr/jUIrrrqqquuuuqqf5X77rvvVoATJ05wP0m8MJJ4QSTxX0ES/9F2d3f5nd/5HQBe8iVfkudHEv8RJHHVCyeJ/+ls869hmxeVbWzzorKNbf41bGObfwvb2MY2tvmXvMzLvAwAf/zHf8x/JNv8Z5HE/SQhCUncTxL/Vtdccw1XXXXVVVddddW/CcFVV1111VVXXfWvdt99993K/xGSeEEk8S/527/9WwAe9KAHcezYMa76/8U2Lyrb/GvY5kVlm38N2/xr2MY2/xa2sc2/1ku/9EsD8Au/8Av8W9nmfrZ5fmwDYJv/KJJ4IEk8kCT+ta655hruu+++W7nqqquuuuqqq/61CK666qqrrrrqqn+1s2fP3vqQhzwEAEm8MJL4zyKJ5yaJ/0qXLl3iGc94BseOHeM1XuM1eCBJ/EeQxP8kkpCEJCQhCUlI4n8z2/xPYZsXlW1eVLaxzYvKNrb517KNbWzzb/Har/3aAPzxH/8x58+f5z+abQBsA2Cb/yiS+LeQhCRemLNnz97KVVddddVVV131r0Vw1VVXXXXVVVf9t5HE8yOJ5yaJfytJPD+SeEEk8S+RBMDv/u7vAvCgBz2I/2iS+O8kCUlIQhKSeGEkIQlJSOK/miT+q9jmRWWbF5VtXlS2eVHYxjYvKtvY5l/DNraxzb+FbWxjm5d5mZcB4I//+I/5z2Kb/2iS+LeQxL/kmmuu4b777ruVq6666qqrrrrqX4vgqquuuuqqq676V7vvvvtuPXHiBJJ4YSTxf5Uk7veMZzyDZzzjGRw7doyXfMmX5H87SUhCEv9ekpCEJP6/ss2LyjYvCtvY5kVhmxeVbWzzr2Eb2/xb2MY2trnfy7zMy3D8+HGe/OQn8+QnP5l/K9u8KGxjG9v8R5GEJCRxP0kASOLf4pprruGqq6666qqrrvo3oXLVVVddddVVV/2r3Xfffbc+6EEP4oWRxP9WkvjX+t3f/V3e4z3eg9d4jdfgb//2b5HEv5ck/itJ4j+TJABs8x/l2LFjABw7doxjx44BsLOzw/2OHz/Oi2p3dxeAS5cuAbC7uwvApUuXuHTpEg9km/9otnlR2OZFYZsXlW3+NWzzb2WbF+Z1Xud1APjjP/5j/qPYBsA2L4ht/j0kASCJB5LECyOJF9V99913K1ddddVVV1111b8Wlauuuuqqq6666l/t7Nmzz+DfSRL/0STxopLEv5UkntulS5fY3d3l+PHj3HLLLdx+++38byGJ/0qSALDNv+TYsWMcO3aMW265BYBbbrkFgFtuuQWAS5cucezYMf4rXLp0CYBnPOMZADzjGc/g0qVLADzjGc/g+bHNi8I2LwrbvChs86KyzYvKNv8WtnlRvMzLvAzHjx8H4I//+I/5z2Cb+9nmP5Ik/rO8xEu8BD/6oz/6DK666qqrrrrqqn8tKlddddVVV1111b/afffdd+uJEyd4QSTxbyWJF4UkXhSS+NeQxAsjiednd3eX3/3d3+Ut3/IteY3XeA1+8Ad/kH8PSfxXkMR/F0nYBuDYsWMcO3aMW265hWPHjnHs2DFuueUW/iXjOHLu3DnOnTvHuXPnADh37hySADh37hwvqtOnT3P69Gnud+rUKQBOnz7N6dOnOXbsGAAv+ZIvCcBLvuRLcr9nPOMZHD9+nGc84xkAPOMZz2B3d5dnPOMZ/EexzYvCNi8K27yobPOvZZt/rZd+6ZcG4Pu///uRhG3+LWzzwtjGNgC2sc2/lyReEEkASOKBJPGisM1VV1111VVXXfVvRuWqq6666qqrrvo3OXHiBM+PJP4lkvjXkMT/BrfddhsAD3rQg7jlllu47bbb+J9KEv9djh07xrFjx7j55pu55ZZbuOWWW3hBzp07x7lz53jCE54AwPnz5zl37hxPeMITeH4k8Z/l9OnTnDp1itOnTwPw6Ec/mlOnTnH69Gke9KAHAfCSL/mSALzkS74kALu7u1y6dInd3V2e8Yxn8Ld/+7c8N9v8S2zzL7HNi8I2Lyrb/GvY5t/q2LFjPOQhDwHgSU96Ev9bSUISkviPdM0113DffffdylVXXXXVVVdd9a9F5aqrrrrqqquu+lc7e/bsrQAnTpzg4sWL3E8S/xtI4t9CEi/M7u4uf/M3f8NLvdRL8ZIv+ZLcdttt/FtI4j+TJP4rHTt2jFtuuYWdnR1e4iVegmPHjvHczp07x7lz53jCE57A+fPnOXfuHE94whN4UUniP9u5c+c4d+4cT3ziEwH4gz/4A+53+vRpAB71qEfx6Ec/mlOnTvHoRz+a48ePc/z4cR70oAfxoAc9iLd8y7dkd3eXv/3bv2V3d5e/+Zu/4V9im3+JbV4UtnlR2OZfwzb/Fra53+u+7usC8Cd/8idcuHCBfyvbPJBtAGzz3GwDYJt/D0kASOKBJPEf6ezZs7dy1VVXXXXVVVf9a1G56qqrrrrqqqv+zY4fP87Fixf515DE/1SS+Pf6vd/7PV7qpV6KW265hf+JJPFf4dixY7z4i784t9xyC7fccgvP7dy5c/z+7/8+T3ziE3nCE57Av5Uk/ic4d+4cAOfOneMP/uAPuN/p06d59KMfzalTp3j0ox/N8ePHOX78OK/5mq8JwFu+5Vuyu7vLM57xDP7mb/6GZzzjGTyQbf4ltvmX2OZFYZsXlW3+tWzzgrzMy7wMAL/4i7/IfwXbANjmP4Ik/jUk8aK65pprALjvvvtu5aqrrrrqqquu+teictVVV1111VVX/avdd999t/JcJPHvJYl/K0k8N0n8R5HEi+LSpUs84xnP4EEPehCv/uqvzu///u/zP4Uk/rMcO3aMF3/xF+fYsWO8xEu8BA907tw5zp07xxOe8ASe+MQn8oQnPIF/L0n8TyYJgPPnz/MHf/AHAPzsz/4sp0+fBuBRj3oUr/Zqr8ajHvUojh8/zvHjx3mpl3opdnd3ecYznsEznvEM/vqv/5p/iW3+Jbb5l9jmRWWbfw3b/Ete5mVeBoA/+ZM/4cKFCzw3SdjmX2KbF8Y2ALZ5INv8Z5EEgCT+ra655hquuuqqq6666qp/MypXXXXVVVddddW/yX333XfriRMnHvz0pz+dF5Uk/rtJ4vmRxAsiiX+N3/u93+NBD3oQL/mSL8nv//7v868hif8MkviPduzYMV78xV+cW265hVtuuYUHOnfuHL//+7/PE5/4RJ7whCfwH0ES/9NJ4oU5d+4cAOfOneMP/uAPOH36NKdOneJRj3oUj370o3nUox7F8ePHeamXeile8zVfk93dXf7mb/6Gv/mbv+GBbPMvsc2LwjYvCtv8a9jmRfW6r/u6APzJn/wJ/xq2eWFs89xscz/b2MY2/x6SAJCEJCTxwkjiX+Paa6/lvvvuu5WrrrrqqquuuurfgspVV1111VVXXfVvcvbs2VtPnDjxYABJ/Esk8R9FEv8TSQLgGc94Bs94xjN40IMexC233MJtt93GfydJ/Ee65ZZbePEXf3Fe4iVeggc6d+4cv//7v8/P/MzP8B9JEv/TSeLf4ty5c5w7d44nPvGJ/OzP/iynT5/mUY96FK/2aq/Gox71KI4fP86DH/xgXuu1XotnPOMZ3Hrrrfz1X/81/xLb/Ets86KwzYvKNv9aL/3SL83x48e5cOECT3nKU/i3ss0LYpv/LJIAkMQDSeI/gm0Azp49eytXXXXVVVddddW/BZWrrrrqqquuuuo/nST+rSTx30kSLwpJPNDf/u3f8qAHPYjXeI3X4Ad+4Af43+7YsWO8+Iu/OK/+6q/OA507d47f//3f52d+5mf4jyaJ/8kk8R/t3LlznDt3jj/4gz/g9OnTPOpRj+LVXu3VeNSjHsXx48d5qZd6KV7rtV6LW2+9lb/5m7/h1ltv5bnZ5oWxzYvCNi8q2/xr2OZ+L/uyLwvAL/3SL/FvZZt/LdvYxjb/XpJ4fiQBIIn7SeIFsc3zc80113DffffdylVXXXXVVVdd9W9B5aqrrrrqqquu+je57777bj1x4gSSeGEk8aKQxH8XSfx7SOK5PeMZzwDglltu4ZZbbuG2227jXyKJ/2iS+Pd4tVd7NV7iJV6CY8eOcb9z587x+7//+/zMz/wM/xkk8T+ZJP4rnDt3jnPnzvEHf/AHnD59mkc96lG82qu9Go961KN46Zd+aV76pV+a3d1dfud3foe//uu/xjb/Etv8S2zzorDNv4ZtnttDHvIQHvKQhwDwJ3/yJ/xb2Ob5sc0D2eZ+tvnf5JprruGqq6666qqrrvo3o3LVVVddddVVV/2b3Hfffbc+6EEP4n8qSTw3SfxXuXTpEr/7u7/La77ma/Iar/Ea/MAP/AD/1STxb3Hs2DFe/MVfnFd/9VcH4Ny5c5w7d47f//3f5w/+4A84d+4c/xkk8T+ZJP67nDt3jnPnzvEHf/AHnD59mld91Vflrd7qrTh+/Dhv9VZvxWu91mvx13/91/z1X/81u7u7PDfb/Ets86KwzYvKNi/My7zMywDwp3/6p/xnsc39bGObB7LNv4ckACQhCUlI4j/afffddytXXXXVVVddddW/BZWrrrrqqquuuurf5OzZs8+QxAsjif8KkvjPIIl/iSRekL/927/lNV/zNTl27Bi33HILt912G/+THTt2jBd/8Rfn1V/91bnfuXPn+P3f/31+5md+hv8skvifShL/05w7d46f/dmf5Q//8A951KMexau92qvxqEc9itd+7dfmpV/6pbn11lv567/+a2699VYAbPPC2OZFYZsXlW1eFC/7si8LwC/90i/xX802trHNv5ckXhBJ3E8S/xYv8RIvwY/+6I8+g6uuuuqqq6666t+CylVXXXXVVVdd9W9y33333Xr8+HFeEEm8qCTx30US/1aSeGEuXbrEM57xDB70oAfxki/5ktx22238V5HEi+rYsWO86Zu+Kbfccgv3++mf/mn+4A/+gHPnzvGfRRL/U0nif7rz58/zh3/4h/zhH/4hp06d4i3f8i15tVd7NV76pV+al37pl+bWW2/lt37rt7j11lt5QWzzL7HNi8I2/xpv+7ZvC8Cf/umfcuHCBf4r2eY/giQk8fxI4t/LNlddddVVV1111b8blauuuuqqq6666t/sxIkTPD+S+I8gif8ukviP8HM/93N8+Id/OLfccgv/0xw7dow3fdM35ZZbbgHg3Llz/P7v/z4/8zM/w38mSfxPJYn/ySTx/Jw/f57v+q7v4md/9md5tVd7Nd7yLd+SBz/4wbzP+7wPu7u7/NRP/RS33nor97PNv8Q2LwrbvKhsc7+XfdmXBeBP//RP+Y9mmweyzf1sA2Ab29jmP4okXhBJ/Ftdc8013Hfffbdy1VVXXXXVVVf9W1C56qqrrrrqqqv+Tc6ePXsrwIkTJ7h48SL3k8S/hiT+NSTxP4EkXhSXLl3iGc94Bg960IN4iZd4Cf7u7/6O/27Hjh3jTd/0TbnlllsAOHfuHL//+7/Pz/zMz/CfSRL/E0nifzpJvCjOnz/Pz/7sz/IHf/AHvNqrvRpv+ZZvyfHjx3mf93kfdnd3+amf+ime/vSn88LY5l9imxeVbZ7by77sywLwlKc8hac85Sk8N0nY5t/LNvezjW3+I0kCQBKSAJDE/STxH+Xs2bO3ctVVV1111VVX/VtQueqqq6666qqr/l2OHz/OxYsXAZDE/1SS+O8gid/7vd/jQQ96EK/xGq/B3/3d3/GfTRLPz7Fjx3jTN31TbrnlFgDOnTvH7//+7/MzP/Mz/GeSxP9EkvifTBL/VufPn+dnf/Zn+YM/+ANe7dVejbd8y7fk+PHjvM/7vA9/9Vd/xW/91m+xu7vLA9nmX2KbF4VtXpjXfd3XBeBP//RP+Y9mm3+JbWxjm38vSTw3SfxHueaaawC47777buWqq6666qqrrvq3oHLVVVddddVVV/2b3Hfffbfy7ySJ/wySeFFI4vmRxAsjiReFJAAuXbrEM57xDB70oAdxyy23cNttt/Ff6dixY7z4i784r/7qrw7AuXPn+P3f/31+5md+hv9MkvifSBL/k0niP8r58+f52Z/9Wf7gD/6AV3u1V+Mt3/IteZmXeRke8pCH8Fd/9Vf81V/9FRcvXuRfYpsXhW3+JS/7si/LiRMnAPjTP/1T7icJ2/xHs80LYpt/K0lI4kUhiX+ra665hquuuuqqq6666t+FylVXXXXVVVdd9W9233333XrixIkHP/3pT0cS/xqS+L9MEve7dOkSf/d3f8eDHvQgXuM1XoMf+IEf4LlJ4j/Dq73aq/Hqr/7q3O+nf/qn+Zmf+Rn+M0nifyJJ/E8lif9M58+f52d/9mf5gz/4A17t1V6Nt3zLt+R1Xud1eJmXeRn+8i//kt/6rd/i+bHNv8Q2LyrbvMzLvAwAP/RDP8R/Jts8P7b5jyYJSUjifpL4j3DNNddw33333cpVV1111VVXXfVvReWqq6666qqrrvo3O3v27K3Hjx9/MP9KkvjfShL/Fs94xjMAuOWWW7jlllu47bbb+M8gCYBbbrmFN33TN+XYsWMAPOEJT+A7vuM7OHfuHP9ZJPE/jST+J5PEf6Xz58/zsz/7s/zBH/wBr/Zqr8ZbvuVb8rqv+7q87Mu+LD/5kz/J05/+dABs8y+xzYvCNvd7yEMewkMf+lAA/vRP/5T/aLZ5fmxjG9sA2MY2tvm3kgSAJB5IEv8RbHO/s2fP3spVV1111VVXXfVvReWqq6666qqrrvp3k8SLShIvCkm8KCTxH0kS/16SeG6XLl3ib//2b3nJl3xJXvIlX5LbbruN/wzHjh3jxV/8xXn1V391AM6dO8d3fMd38IQnPIH/LJL4n0YS/1NJ4r/b+fPn+dmf/Vme+MQn8j7v8z6cPn2a933f9+Uv//Iv+c3f/E12d3d5QWzzL7HN8/NyL/dyAPzZn/0Z/91sY5t/D0n8SyTxorDN83Pttddy33333cpVV1111VVXXfVvReWqq6666qqrrvo3+/u///vffsQjHvHavAgk8d9FEs9NEv9akviXSOIF+b3f+z1e8iVfkltuuYVjx45x6dIl/iO9xEu8BG/2Zm/G/X76p3+an/mZn+E/iyT+p5HE/1SS+J/miU98Il/2ZV/Gq73aq/GWb/mWvOzLviwPfehD+cu//Et+8zd/k/vZ5kVhmxfmZV/2ZQH4lV/5Ff4r2Oa52cY2/x6SkMQLIon/KNdccw1XXXXVVVddddW/C5Wrrrrqqquuuurf5cSJE/xLJPH/gSRemEuXLvGMZzyDBz3oQbzES7wEv//7v8/9bCOJf4tjx47xZm/2Ztxyyy0APOEJT+A7vuM7OHfuHP8ZJPE/jST+J5LE/3Tnz5/nZ3/2Z/mDP/gD3uqt3opXfdVX5XVf93V5yEMewk/8xE9w8eJFXhjbvChe93VfF4A/+7M/48KFC/xr2OZfYpv72eZ+trmfbe5nm/8IkpCEJJ6bJP69rrnmGh73uMfdylVXXXXVVVdd9W9FcNVVV1111VVX/ZudPXv2GcePH+eFkcR/FEn8Z5LECyKJ/wi/93u/B8BLvuRL8h/hlltu4UM+5EO45ZZbOHfuHD/90z/Nl3zJl3Du3Dn+o0lCEv+TSEIS/9NIQhL/G0hCEhcuXOC7vuu7+Nmf/VkAHvKQh/B+7/d+vO7rvi7Pj21s88LYxja2ebmXezkA/vRP/5T7SeK/gm1sA2Ab2/x7SAJAEg8kif9o11xzDWfPnn0GV1111VVXXXXVvxWVq6666qqrrrrq3+y+++67lRdCEv8WkvjfRhIvittuu41nPOMZPOhBD+IlXuIl+Lu/+zv+LY4dO8abvdmbccsttwDwhCc8gS/5ki/hP4Mk/ieRxP9UkvjfQBIvyM/93M/xh3/4h7zqq74qb/mWb8nrvd7rIYnf+I3fAMA2L4xtntvLvdzLceLECZ761Kfy1Kc+lf9otnlutnlhbPPvIYnnRxJXXXXVVVddddX/KARXXXXVVVddddW/y4kTJ3h+JPHfQRL/0/3d3/0dAK/xGq/Bv8WxY8d413d9V2655RYAfvqnf5ov+ZIv4T+aJCTxP4UkJPE/jSQkIYn/6SQhiX/J+fPn+bmf+zl+9md/FoDXfd3X5eM//uM5fvw4L4htbPP8vOzLviwAf/Znf8Z/Ntu8ILaxjW1s828hCUncTxKSeG6S+Leyzf2uvfZa/uEf/uG3ueqqq6666qqr/q0Irrrqqquuuuqqf7OzZ8/eCnD8+HEeSBL/k0niX0MSL4wk/jVuu+02Ll26xLFjx7jlllv413j1V391PuRDPoRjx45x7tw5PuETPoGf+Zmf4T+SJCTxP4UkJPE/jSQk8T+dJCQhiX+tn/u5n+OTP/mTOX/+PCdOnOD93//9eb3Xez0eyDa2eUEe+tCH8tCHPhSAP/uzP+M/mm1eENvczzYPZJt/D0lI4n6SuOqqq6666qqr/kciuOqqq6666qqr/t1OnDjB/STx7yGJ/w6S+K8giUuXLvF7v/d7ALzGa7wGL6p3fdd35dVf/dUB+Omf/mk+4RM+gXPnzvEfRRKS+J9CEpL4n0YSkvifTBKSkMS/1/nz5/myL/syfvZnf5YTJ07weq/3erz/+78/trHNC2Ib27ze670eAL/yK7/Cv4dt/i1sYxsA2wDY5t9KEi+IJAAk8R/hxV/8xQG47777buWqq6666qqrrvq3Irjqqquuuuqqq/7N7rvvvlt5AEn8fyOJF5Uk7nfbbbcBcOzYMW655RZemGPHjvEhH/Ih3HLLLZw7d44v+ZIv4Wd+5mf4jyIJSfxPIQlJ/E8iCUlI4n8ySUjiP9r58+f5uZ/7Ob78y78cgIc+9KF84id+IidOnOCBbGMb2wCcOHGChz70oQD8+Z//Of+RbGObB7INgG1eENvY5t9DEv9akvjXuvbaa7nqqquuuuqqq/7dCK666qqrrrrqqn+X++6779bjx4/zH0ES/9Ek8e8hif8IknigS5cu8Xd/93ccO3aMl3zJl+QFueWWW/iQD/kQjh07xrlz5/iSL/kSnvCEJ/AfQRKS+J9CEpL4n0QSkvifTBKSkMR/tic+8Yl88id/MufPn+fEiRN8wAd8AK/3eq+HbWzz3F7/9V8fgD/7sz/jwoUL/HvZBsA2/1q2AbDNv5UkJAEgCUlIQhIvjCQAJPH82OYFOXv27DO46qqrrrrqqqv+PQiuuuqqq6666qp/l7Nnz9564sQJJPHvIYn/bSTxopDE8/N7v/d7ANxyyy0A2OaBXv3VX513fdd3BeAJT3gCn/AJn8C5c+f495KEJP6nkIQk/ieRhCT+J5OEJP6rnT9/ni/7si/jZ3/2Zzlx4gQv93Ivx+u//uvz/Lzcy70cAH/+53+OJP4j2Ob5sc0D2cY2trENgG0AbPPvIYnnJgkASTyQJP6trrnmGu67775bueqqq6666qqr/j2oXHXVVVddddVV/+0k8f/RpUuXuO2227jlllt4iZd4Cf7u7/6O+73Zm70ZL/ESLwHAT//0T/MzP/Mz/HtJ4n8SSfxPIon/6STxP8H58+f5uZ/7OQDe8i3fkpd7uZcD4Nd//dexDcDLvdzLAfDnf/7nPPWpT+W/im1eGNvY5t9CEpL4r3LNNddw33333cpVV1111VVXXfXvQXDVVVddddVVV/27/P3f//1vnzhxgn8LSUjiv5sknh9JvCCSeFFI4oX5vd/7PQBe4zVeg/u967u+Ky/xEi8BwJd8yZfwMz/zM/x7SeJ/CklI4n8KSUjifypJSEIS/9P83M/9HN/1Xd/FiRMneP3Xf30+8AM/kPu9wRu8AQB//ud/zgNJ4r+DbWwDYJt/L0lIQhIviCT+tWxz1VVXXXXVVVf9h6Jy1VVXXXXVVVf9ux0/fpwXlST+LSTxH0ES/1Uk8S+57bbbuO2227jlllt4iZd4CV7yJV+SW265hXPnzvEd3/EdPOEJT+DfQxL/U0jifxJJ/E8mif/JJAHwR3/0RzzpSU/i4z/+43noQx/KJ3/yJ/Pnf/7nnDhxgosXL/LUpz6V/2y2eSDbPJBt7mebfwtJSAJAEg8kCQBJ3E8S/17XXHMNj3vc457OVVddddVVV13170Fw1VVXXXXVVVf9u5w9e/YZJ06c4IWRhCQk8R9JEv8dJPEvkcSL6m//9m8BePM3f3NuueUWzp07x3d8x3fwhCc8gX8rSUjifwJJSOJ/CklI4n8iSUhCEv8TSUISknig8+fP8+Vf/uWcP3+eEydO8AZv8AYA/Oqv/ir/lWxzP9vYxjYAtrGNbf4tJAEgiX8PSbyorr32Ws6ePfsMrrrqqquuuuqqfw+Cq6666qqrrrrq3+W+++67lRdAEpK46oW7dOkS9zt37hyf8AmfwBOe8AT+LSQhif8JJCGJ/wkkIQlJ/E8kCUn8TyQJSUjihTl//jxf/uVfzvnz57nfU5/6VP4vkQSAJCQhiftJ4n6SuOqqq6666qqr/scguOqqq6666qqr/t2OHz/Oc5PE/2aS+LeSxIvq2LFjvNu7vRsAT3jCE/iET/gE/i0kIYn/CSQhif8JJCGJ/4kkIQlJ/E8jCUlI4l/j/PnzfPmXfzlPfOITAfiQD/kQTpw4wX8m2zyQbZ6bbWxjG9v8a0lCEgCSeCBJ/GewzTXXXMM//MM//DZXXXXVVVddddW/B8FVV1111VVXXfXvcvbs2VsBjh8/zv0k8X+VJP6jHDt2jA/90A8F4AlPeAJf8iVfwr+WJCTxP4EkJPE/gSQk8T+RJCTxP5EkJPHvcf78eb77u7+bJz7xiZw4cYIP+ZAP4cSJE/xr2OZfyzb3sw2AbWxzP9vY5t9KEv8SSfxr2Ob5ueaaa7jqqquuuuqqq/5DEFx11VVXXXXVVf8hTpw4AYAk/j+TxIvi2LFjfOiHfigAT3jCE/iSL/kS/rUk8T+BJCTxP4EkJPE/kSQk8T+NJCQhif8o58+f57u/+7t54hOfyIkTJ/iQD/kQTpw4wX8027wgtrmfbWwDYJt/LUlI4n6SeCBJ/Eewzf2uvfZaAO67775bueqqq6666qqr/j0Irrrqqquuuuqqf5f77rvvVv4Xk8R/tWPHjvHmb/7mADzhCU/gS77kS/jXkIQk/rtJQhL/E0hCEv/TSEISkvifRBKSkMR/lvPnz/Pd3/3dPPGJT+TkyZN8yId8CCdPnuS/mm3uZ5t/L0kASEISDySJ/yjXXHMNV1111VVXXXXVfwiCq6666qqrrrrq3+2+++679fjx40jiP4Mk/ieQxAsjiRfFm7/5m3PLLbfwhCc8gS/5ki/hRSUJSfx3k4Qk/ieQhCT+p5GEJP6nkYQk/qucP3+e7/7u7+aJT3wiJ0+e5EM+5EP4j2Kb+9kGwDYPZBsA29jGNv9akpAEgCT+vWzzorrvvvtu5aqrrrrqqquu+vciuOqqq6666qqr/t3Onj1764kTJ/i/QhL/Wd7t3d6NW265hXPnzvElX/IlvCgkIYn/bpKQxH83SUhCEv+TSEISkvifRBKSkMR/h/Pnz/Pd3/3dnD9/npMnT/Jpn/Zp/HvZ5gWxjW1s80C2sc2/lSSeH0kASOI/0jXXXMPZs2dv5aqrrrrqqquu+vciuOqqq6666qqrrvoPIIl/ybu927txyy23cO7cOT7hEz6BF4Uk/rtJQhL/3SQhif9pJCGJ/0kkIQlJ/E9w/vx5vvzLv5zz589z8uRJ3uVd3oX/KraxDYBt/rUkIQkASUhCEpL4z2Kba6+9lvvuu+9Wrrrqqquuuuqqfy+Cq6666qqrrrrq3+3v//7vf/vBD34wV71gb/7mb84tt9wCwHd8x3fwL5GEJP47SUIS/90kIYn/aSQhif9JJCGJ/4kuXLjAV3zFVwDwCq/wCrzxG78xL4xtnh/bPJBtAGzz3GxzP9vY5t9KEs9NEgCSuOqqq6666qqr/sciuOqqq6666qqr/keTxP8EknhBJPHC3HLLLbzES7wEAF/yJV/CE57wBF4QSUjiv5MkJPHfTRKS+J9EEpKQxP8UkpCEJP6nkYQkJAFw/vx5PvVTPxWAN3qjN+KN3uiN+NewzQtjm/vZBsA2trHNv5YkJCGJ/2y2eaBrrrmG++6771auuuqqq6666qp/L4Krrrrqqquuuurf7ezZs884ceIE/xJJSOL/k1tuuYV3e7d3A+BLvuRLeMITnsDzIwlJ/HeShCT+u0lCEv+TSEIS/5NIQhL/00hCEpJ4fs6fP893f/d3A/CKr/iKPPzhD+cFsc39bPPcbPPcbGObB7LNv4Uk7icJSUhCEv8RbPOCXHvttZw9e/YZXHXVVVddddVV/14EV1111VVXXXXVv9t99913Ky+AJCQhiftJQhKSkIQknh9J/G927Ngx3u3d3g2An/7pn+YJT3gCz48k/jtJQhL/3SQhif9JJCGJ/ykkIQlJ/E8iCUlI4kXxR3/0R/zcz/0cJ0+e5I3f+I05efIkL4htbPPC2Ob5sY1tAGzzbyEJSTw3SQBI4oEkIQlJXHXVVVddddVV/yMQXHXVVVddddVV/yGOHz/Oc5PEi0oSkpCEJCTxv4EkXpA3f/M3B+AJT3gCP/MzP8Nzk4Qk/jtJ4r+bJCTxP4kkJPE/hSQk8T+JJCQhiX+LP/qjP+JJT3oSD3/4w/mIj/gI/r1s80C2uZ9tbPOvJYl/DUn8e9kG4JprruEf/uEffpurrrrqqquuuurfi+Cqq6666qqrrvp3O3v27K0Ax48f536S+N9IEv8R3vzN35xbbrmFc+fO8SVf8iU8kCQk8d9JEpL47yQJSfxPIQlJSOJ/AklIQhL/k0hCEv9e58+f57u/+7s5f/48J0+e5N3e7d3417ANgG3uZxvb2AbANraxjW3+NSQBIAkASUhCEveTxAsjiX+La665hquuuuqqq6666j8MwVVXXXXVVVdd9e9233333Qpw/PhxACTxf4kk/jVuueUWXuIlXgKA7/iO7+CBJPHfSRKS+O8kCUn8TyEJSfxPIQlJ/E8iCUlI4j/S+fPn+Yqv+AoAXvEVX5FXeqVX4j+KbR7INv8akpAEgCQeSBLPTRL/Ua699loA7rvvvlu56qqrrrrqqqv+vQiuuuqqq6666qr/EPfdd9+tAJL4/0ISz+3YsWO827u9GwDf8R3fwROe8AQAJCGJ/y6SkMR/J0lI4n8KSUjifwJJSEIS/1NIQhKS+M90/vx5vvu7vxuAN3mTN+HkyZP8S2zzQLZ5INsA2MY2tvm3ksTzI4n7SeLfwzYPdM0113DVVVddddVVV/2HIbjqqquuuuqqq/5DnD179tYTJ07wX8k2/9O8xmu8BgBPeMIT+P3f/30kIYn/LpKQxH8nSUjifwpJSOJ/AklI4n8KSUhCEv+V/uiP/ognPvGJnDx5ko/6qI/iRWWb+9kGwDYPZBvb/GtIQhKSAJCEJCQhif8K9913361cddVVV1111VX/EQiuuuqqq6666qr/MMePH+f/s1d/9VfnJV7iJTh37hxf8iVfgiT+u0hCEv+dJCGJ/wkkIQlJ/HeThCQk8T+FJCTx3+l7vud7OH/+PCdPnuRN3/RNeUFs84LY5n62sY1tbPOvJQkASbwwkvi3sM0Lcs0113D27Nlbueqqq6666qqr/iMQXHXVVVddddVV/yHuu+++W0+cOMH/V8eOHeM1XuM1APiO7/gOJPHfRRL/nSQhif8JJCGJ/wkkIYn/KSQhCUn8T3D+/Hm++7u/G4BXeqVX4hGPeAQvCts8N9sA2AbANv8akgCQxPMjif8MtgG49tprue+++27lqquuuuqqq676j0Bw1VVXXXXVVVf9h7jvvvtuPX78OP9fSOKB3vzN3xyAP/iDP+CJT3wi/x0kIYn/LpKQxP8EkpDEfzdJSEIS/xNIQhKS+J9EEpJ48pOfzM///M9z6tQp3uzN3oznZpv72eZ+trmfbQBsA2Ab2/xrSEISAJKQhCQk8UCS+NewzVVXXXXVVVdd9V+O4Kqrrrrqqquuuurf6SVe4iW45ZZbOHfuHN/xHd/BfzVJSOK/iyQk8T+BJCTx300SkvifQhKS+J9EEpKQxAP90R/9EefPn+cRj3gEb/Zmb8b9bPPC2MY2ALYBsI1t/jUkcT9JPDdJAEjiP8s111zDfffddytXXXXVVVddddV/BIKrrrrqqquuuuo/xNmzZ59x/Phx/q+RxAtz7Ngx3vzN3xyA7/iO7+C/kiQk8d9FEpL4n0ASkvjvJglJ/E8gCUlI4n8KSUhCEi/I+fPn+Z7v+R4AXuVVXoVTp07x3GwDYJsXxDa2sc2/hiQkIYn7SeI/i22e2zXXXMPZs2efwVVXXXXVVVdd9R+B4Kqrrrrqqquu+g9x33333crzIQlJSEISkpDEfxbb/Fd68zd/cwCe8IQn8MQnPpH/KpL47yIJSfxPIAlJ/HeShCQk8d9NEpKQxP8UkpCEJF5UT3rSk/ijP/ojTp48yXu+53timxeVbWxjGwDb/FtJQhIAkrifJP4zXXvttVx11VVXXXXVVf9hCK666qqrrrrqqv8wx48f54Ek8YJIQhL/m91yyy3ccsstAHznd34n/xUkIYn/DpKQxP8EkpDEfydJSOJ/AklI4n8KSUhCEv9WP//zPw/AIx/5SB75yEfygtjGNraxzQPZxjYvKklIQhKSeG6S+M9imwf6h3/4h9/mqquuuuqqq676j0Bw1VVXXXXVVVf9hzh79uytAMePHwdAEi8KSfxvIwmAl3zJlwTgZ37mZzh37hz/mSQhif8OkpDE/wSSkMR/J0lI4r+bJCQhif8pJCGJ/wjnz5/ne77newB47/d+b+5nGwDbPD+2sY1tbGObF5UkJCGJ+0lCEveTxANJQhKSeFHZ5gW55ppruOqqq6666qqr/kMRXHXVVVddddVV/yHuu+++WwGOHz+OJP41JPGfxTb/GV7iJV6Cl3iJl+DcuXP8zM/8DP9ZJCGJ/y6S+O8mCUlI4r+LJCQhif9ukpDE/xSSkIQk/qM96UlP4klPehKnTp3iVV/1VXlutnkg29zPNrb5t5KEJO4niecmiQeSxL/XNddcA8B99913K1ddddVVV1111X8Egquuuuqqq6666j/Mfffdd6sk/i0k8b/Jm7/5mwPwHd/xHfxnkcR/F0lI4r+TJCTx30kSkvjvJglJSOJ/AklIQhL/mc6fP8/P//zPA/AWb/EW2Oa52cY2tgGwjW0AbPOvIQlJSOJfIon/DNdccw1XXXXVVVddddV/KIKrrrrqqquuuuo/zNmzZ289fvw4/1aS+N/g1V/91QF4whOewBOf+ET+o0lCEv8dJCGJ/06SkMR/J0lI4r+bJCTxP4EkJCGJ/0pPetKTeNKTnsSpU6d4n/d5HwBs8/zY5n62sc2LShKSkASAJCQhCUkASOLfyjbPzTbPz3333XcrV1111VVXXXXVfxSCq6666qqrrrrqP9Tx48f595DE/3Sv8RqvAcDP/MzP8B9JEpL47yAJSfx3koQk/jtJQhL/nSQhCUn8d5OEJCTx3+l7vud7AHjUox7F6dOnAbDNA9kGwDa2sY1tXlSSuJ8kXhhJ/Ge59tprOXv27K1cddVVV1111VX/UQiuuuqqq6666qr/MPfdd9+tx48f599LEi8q2/xXevM3f3MA/uAP/oAnPvGJ/EeRxH8HSUjiv5MkJPHfRRKSkMR/J0lI4n8CSUjif4rz58/zpCc9idOnT/OWb/mW3M82trENgG0AbGMb27yoJCEJSTw/kgCQxH8029zvmmuu4b777ruVq6666qqrrrrqPwrBVVddddVVV131H+a+++679fjx4/xHkMS/lW1eENv8e7zkS74kAL//+7/PfwRJSOK/miQk8d9JEpL47yIJSfx3koQkJPHfTRKSkMT/FJKQhCS+93u/F4BHP/rRnD59mhfENraxzYtKEg8kCUlIQhL/Vra56qqrrrrqqqv+2xFcddVVV1111VVXvYje/M3fHIA/+IM/4IlPfCL/HpKQxH81SUjiv5MkJPHfRRKS+O8kCUn8d5OEJCTxP4UkJCGJBzp//jxPetKTOHXqFG/1Vm/Fc7MNgG0AbPOikoQkJCGJ5yYJAEn8e9nmBbHNtddey3333XcrV1111VVXXXXVfxSCq6666qqrrrrqP8zZs2efcfz4cf6jSOJ/kpd8yZcE4Pd///f595DEfwdJ/HeShCT+u0hCEv+dJCGJ/26SkMT/FJKQhCRemO/93u8F4NGPfjS2AbCNbQBsA2Ab2/xrSEISAJKQhCT+q11zzTWcPXv2GVx11VVXXXXVVf9RCK666qqrrrrqqv8w99133608F0lIQhKSkIQk/ivZ5t/rJV/yJQF4whOewBOf+ET+LSQhif9qkpDEfxdJSOK/iyQk8d9FEpKQxH8nSUhCEv8TSEISknhRnT9/nic96UmcPn2a13iN18A297ONbWxjG9u8KCQhiftJ4oEkASCJ/0i2eX6uvfZarrrqqquuuuqq/1AEV1111VVXXXXVf5izZ8/eevz4ce4niRdEEpL4l0jif4LXeI3XAOBnfuZn+NeShCT+q0lCEv9dJCGJ/y6SkMR/F0lI4r+TJCQhif8JJCEJSfxb/fzP/zwAb/M2b8P9bHM/29jGNi8qSUhCEi8KSUhCEv9etnlu//AP//DbXHXVVVddddVV/1EIrrrqqquuuuqq/3DHjx9HEi8KSfxLJPGvZZv/KC/5ki/JsWPHOHfuHE984hP515DEfzVJSOK/iyQk8d9BEpKQxH8HSUhCEv+dJCGJ/wkkIQlJ/Ed48pOfzJOe9CROnz7NYx7zGGwDYBvb2MY2LypJSEISAJKQhCQkASCJ+0niX8s2L4prrrmGq6666qqrrrrqPxzBVVddddVVV131H+a+++67FeDEiRP8a0ji38M2/5le4iVeAoCf+Zmf4UUlCUn8V5PEfxdJSOK/gyQk8d9FEpL47yQJSUjiv5skJCGJ/wx//Md/DMDbvu3bAmAbANsA2OZFJYn7SeK5SeJ+knhukviPYJtrr70WgPvuu+9Wrrrqqquuuuqq/ygEV1111VVXXXXVf6j77rvvVv4NJPHCSOI/g21emGPHjvGgBz0IgD/4gz/gXyIJSfxXk4Qk/rtI4r+DJCTx30USkvjvJAlJ/HeThCQk8Z/tSU96EgCPecxjeMxjHgOAbQBsY5sXhSQkIQlJAEhCEs9NEv9etnlhrrnmGq666qqrrrrqqv9wBFddddVVV1111X+os2fP3vqgBz2I/2lscz/bvKhe4zVeA4A/+IM/4F8iif9qkpDEfxdJSOK/miQk8d9FEpL47yIJSUjiv5skJPFf6fz58/zRH/0RAK/1Wq+FbWxjG9tkJi8KSUhCEgCSuJ8k/rPY5gW57777buWqq6666qqrrvqPRHDVVVddddVVV/2PIYkXRhL/1R70oAcB8Pu///u8IJKQxH8lSUjiv4skJPFfTRKS+O8gCUlI4r+LJCTx300SkpDEf5c//uM/BuCxj30s97ONbV5UkrifJJ6bJAAk8V/h2muv5ezZs7dy1VVXXXXVVVf9RyK46qqrrrrqqqv+Q9133323Hj9+nH8rSfxb2Oa52ebf4yVf8iU5duwY586d44lPfCLPjyT+q0niv4skJPFfTRKS+O8gCUn8d5GEJCTx30kSkpDE/wRPfvKTedKTnsSZM2d47GMfi21sY5sXhSQkIQlJAEhCEpK4nyT+LWzzL7HNA11zzTXcd999t3LVVVddddVVV/1HIrjqqquuuuqqq/5D3XfffbceP36c/wse9KAHAfAzP/MzPDdJSOK/kiQk8d9BEpL4ryYJSfx3kIQk/rtIQhL/nSQhCUn8TyAJSUgC4MlPfjIA7/iO74htbJOZvCgkASAJAEk8kCT+q9jmqquuuuqqq676T0Nw1VVXXXXVVVf9jyOJF0QS/5lsc7+XfMmXBOCJT3wi95OEJP4rSUIS/x0kIYn/apKQxH8HSUjiv4MkJCGJ/06SkMT/BJKQhCSe2x//8R8DcM011wBgG9u8KCQhCQBJAEhCEveTxL+XbV5UL/ESL8F99913K1ddddVVV1111X8kgquuuuqqq6666j/U2bNnn3H8+HGemyQkIYn/LLZ5YWzzonrJl3xJAJ7whCdw7tw5ACTxX0kSkvjvIAlJ/FeThCT+q0lCEpL47yAJSfx3koQkJPHfTRKSkMQLc/78eZ70pCdx5swZXuzFXgzb2OZfIglJSEISkpDE/STx3CQhCUn8W9jmRXH27NlncNVVV1111VVX/UciuOqqq6666qqr/kPdd999tx4/fpz7SUISDyQJSbwwkviPYJvnxzb3s81ze9CDHgTAH/zBHyAJSfxXksR/B0lI4r+aJCTxX00SkvjvIAlJSOK/iyQkIYn/bpKQhCT+NZ785CcD8Lqv+7rY5kUhCQBJSOJ+krifJO4nif8otnlBrr32Wu67775bueqqq6666qqr/iMRXHXVVVddddVV/6HOnj17K8Dx48eRxAsjiX8LSfxne9CDHgTAk570JP4rSUIS/x0k8V9NEpL4ryYJSfx3kIQk/jtJQhL/3SQhCUn8W/3xH/8xAC/xEi+BbV4UkpDE/SQhCQBJPJAkXlS2eVHZ5vk5e/bsrVx11VVXXXXVVf+RCK666qqrrrrqqv8Ux48f50UhiRdEEv9atvn3esmXfEmOHTsGwLlz5/ivIAlJ/HeQhCT+K0lCEv/VJCGJ/w6SkMR/F0lIQhL/nSQhCUn8Rzh//jxPetKTuOaaa3iJl3gJXhSSkIQkJPHcJAEgiedHEv9RbANwzTXXcNVVV1111VVX/acguOqqq6666qqr/kPdd999t/KvJIn/SY4dOwbAH/zBH/BfQRL/HSQhif9KkpDEfzVJSOK/miQkIYn/DpKQhCT+O0lCEpL4z/DkJz8ZgJd4iZfgXxIRAEhCEgCSkIQk/iPY5l/rmmuuAeC+++67lauuuuqqq6666j8SwVVXXXXVVVdd9R/uvvvuu/X48eP8a0ji+ZHEv5dt7mebf8lLvdRLAfDEJz6R/0ySkMR/NUlI4r+SJCTxX0kSkpDEfzVJSOK/iyQk8d9JEpKQxH+2Jz3pSQC81Eu9FP8SSUjifpJ4IEkASOLfyzYvqmuvvZarrrrqqquuuuo/BcFVV1111VVXXfUf7uzZs7ceP36cfy1JvKgk8YLY5kVhm+fn2LFjAPzBH/wB/1kk8V9NEpL4ryQJSfxXkoQk/jtIQhL/HSQhCUn8d5GEJCTxX+n8+fMAXHfddbwoJCEJSQBIQhKSAJDEfyTbANjmhTl79uwzuOqqq6666qqr/qMRXHXVVVddddVV/+NJ4j+bbQBe8iVfEoA/+IM/4D+DJCTxX00S/5UkIYn/SpKQxH81SUhCEv8dJCGJ/y6SkIQk/rtcuHCBJz3pSVx77bW81Eu9FC+IJCQhCUlIQhL/1Wzz3K655hruu+++W7nqqquuuuqqq/6jEVx11VVXXXXVVf/h7rvvvluPHz/Ov4Uk/iPY5oFs86I4fvw4/xkkIYn/apKQxH8VSUjiv5IkJPFfTRKS+O8gCUlI4r+LJCTx300Sknjyk58MwEu+5EvygkhCEpJ4IEncTxL3k4QkJPGfwTb3u/baa7nvvvtu5aqrrrrqqquu+o9GcNVVV1111VVX/Ye77777bj127Bj/VpL4z2SbF+TYsWMAPPGJT+Q/iiT+q0lCEv9VJCGJ/0qSkMR/NUlI4r+DJCTx30USkpDEfydJSEIS93vyk58MwEu91EvxgkhCEgCSkIQkACQhiftJ4oEk8fzY5t/LNtdeey1XXXXVVVddddV/CoKrrrrqqquuuuo/xfHjx/mPJInnJokXxjb/Ets80IMe9CAAnvjEJ/LvJQlJ/FeShCT+q0hCEv+VJCGJ/2qSkMR/NUlIQhL/HSQhCUn8d5KEJCTx/Fy4cAGA6667judHEpKQhCQk8YJI4l/LNv8e11xzDffdd9/Tueqqq6666qqr/qMRXHXVVVddddVV/+HOnj37DJ6LJCQhCUlI4oWRxH802/xLjh8/DsC5c+f4t5KEJP6rSeK/iiQk8V9JEpL4ryQJSUjiv5okJPHfQRKSkMR/J0lIQhL/kvPnz3P+/HmuvfZaXuqlXornJglJSEISAJKQhCQkASCJfw/bANgGwDYAtvmXnD179hlcddVVV1111VX/0Qiuuuqqq6666qr/cPfdd9+tx48f536SeH4k8d/FNs/tJV/yJQH4gz/4A/6tJPFfTRKS+K8iif9KkpDEfyVJSOK/miQkIYn/DpKQxH8nSUhCEv9aFy5c4AWRhCTuJ4n/DrZ5fq699lrOnj17K1ddddVVV1111X80gquuuuqqq6666j/c2bNnbwU4fvw4knhhJPGCSOKBJPGvZZsX1bFjxwA4d+4c/1qSkMR/JUlI4r+KJCTxX0USkvivJAlJ/FeThCT+O0hCEpL47yIJSUji3+NJT3oSAC/5ki/JA0lCEpKQhCQkIQlJSAJAEv9VbPPc7rvvvlu56qqrrrrqqqv+oxFcddVVV1111VX/aY4fP86LQhL/VWzz3GwDcPz4cQDOnz/Pv4Yk/itJQhL/VSQhif8qkpDEfyVJSOK/kiQkIYn/apKQhCT+u0hCEpL4j/LkJz8ZgJd6qZfigSQhCUlIQhLPTRL3k4Qk/ivY5iVe4iW46qqrrrrqqqv+01C56qqrrrrqqqv+w91333238q8kCdv8a0nCNi+MbSTxL3nQgx4EwBOf+EReFJL4ryaJ/yqS+K8kif9KkvjvIIn/LpL47ySJ/0wXLlzg+ZGEJCQhCQBJSEISDySJ+0nCNs/NNv+Rrr32WgDuu+++W7nqqquuuuqqq/6jEVx11VVXXXXVVf8p7rvvvluPHz/Ov4YknpskHkgS/1Fs80DHjx8H4Ny5c/xLJPFfSRKS+K8gCUn8V5GEJP6rSEIS/9UkIYn/apKQhCT+O0hCEpL4r3LddddxP0lIQhL3k8QDSQJAEv+RbHPVVVddddVVV/23I7jqqquuuuqqq/5TnD179tZjx47xryWJ/wy2uZ9t/q0kIYn/KpKQxH8FSUjiv4okJPFfRRKS+K8kCUlI4r+aJCTx30ESkpDEf6Xz589z/vx5rr32Wq677joAJCEJSUhCEpKQhCQkASCJfy3bANgGwDYAtnkg2wDY5vm55ppr+Id/+Iff5qqrrrrqqquu+s9AcNVVV1111VVX/Y8nif9st9xyCwBPfOITeUEk8V9JEv9VJPFfRRKS+K8iCUn8V5KEJP6rSUISkvjvIAlJ/He6cOECANdeey0AkpCEJCQhiecmif9KtgGwDcC1117LfffddytXXXXVVVddddV/BoKrrrrqqquuuuo/xX333Xfrgx/8YP4tJPHCSOLfwjbPzTYAx48fB+DcuXM8N0lI4r+KJCTxX0ESkvivIAlJ/FeRhCT+K0lCEv/VJCGJ/w6SkIQk/rtIQhKSOH/+PADXXnstkogIJCEJSQBIQhKSuOqqq6666qqr/s8juOqqq6666qqr/lPcd999t/IfSBIviCT+tWzzQMePH+f5kcR/JUn8V5CEJP4rSEIS/1UkIYn/KpKQhCT+K0lCEpL4ryYJSUjiv4skJCGJB7pw4QL3k4QkJCEJAEk8kCTuJ4n/Dtdccw333XffrVx11VVXXXXVVf8ZCK666qqrrrrqqv80x44d4/mRxL9EEv8ZbPP8HD9+HIAnPvGJAEhCEv9VJCGJ/2ySkMR/BUlI4r+KJCTxX0USkvivJglJ/FeThCQk8d9FEpKQxL/k2muvRRKSkASAJCQhCUk8kCQAJPEfwTYAtvmXXHvttZw9e/YZXHXVVVddddVV/xmoXHXVVVddddVV/ynOnj37DB5AEg8kCQDb/FtIwjb/EWzzQJL4ryKJ/yqS+K8gif9KkvivJIn/apL47yKJ/06S+Ne4cOECANdffz0RgSQkIQlJPJAkACTxQJKwzb+GbQBs8/zYBsA2V1111VVXXXXVfykqV1111VVXXXXVf4r77rvv1uPHjwMgiRdEEgC2eW6SsM39JGGbF5VtACTx/NhGEgDHjh3jv5ok/itI4r+CJP4rSeK/kiT+q0niv4Mk/jtJ4t/q/PnzAFx77bVIQhKSkASAJCQhCQBJ/GvYBsA2ALb5t7DN/a699lruu+++W7nqqquuuuqqq/4zEFx11VVXXXXVVf8pzp49eyvA8ePHeVFI4t9DEi+IbR7INi/I+fPn+c8mCUn8Z5OEJP4rSOK/iiQk8V9BEpKQxH8VSUhCEv+VJCEJSfx3kIQkJPEfQRKSkIQkJCGJB5LEi8o2/xmuueYaAM6ePXsrV1111VVXXXXVfwaCq6666qqrrrrqP9Xx48d5UUniuUniBZHEi8o2z49tHujcuXP8Z5GEJP6zSUIS/xUkIYn/CpKQxH8FSUjiv5IkJPFfTRKS+O8gCUlI4j/K+fPnAbj22muRBIAkACQhCUn8T3HNNddw1VVXXXXVVVf9p6Jy1VVXXXXVVVf9p7jvvvtu5T+BJGzzb2EbSQDYRhL3O378OP+ZJPFfQRL/FSTxX0US/1Uk8V9JEv8dJPHfRRL/VSQhCQBJPJAkACRxP9v8R7ANgG0AbPOCXHvttQDcd999t3LVVVddddVVV/1nILjqqquuuuqqq/7T3HfffbceO3aMfw1JPDdJvCgk8T+NJCTxn00SkvjPJglJ/FeQhCT+K0hCEv9VJCGJ/0qSkIQk/qtJQhKS+K8kCUlIQhKSkIQkACTxH8E2ALZ5YWxz1VVXXXXVVVf9lyO46qqrrrrqqqv+05w9e/bW48eP868liRdGEveTxAsiiedmm/vZBsA2/xkk8Z9NEpL4zyYJSfxXkIQk/itIQhL/VSQhif9KkpDEfzVJSEIS/10kIQlJPDdJ/HvZ5t/CNve79tpr+Yd/+Iff5qqrrrrqqquu+s9C5aqrrrrqqquu+k917Ngx/iNIwjb/EknY5oWxjST+s0jiv4Ik/rNJ4r+KJP6rSOK/iiT+q0niv4Mk/jtJQhL3k4QkACQhCUlI4vmRhG1eENsA2OY/gm2uvfZa7rvvvlu56qqrrrrqqqv+sxBcddVVV1111VX/ae67775bjx8/zr+FJP4r2OY/kiT+s0lCEv/ZJPFfQRKS+M8mCUlI4r+CJCTxX0kSkvivJglJ/HeQhCQk8dwkIQlJSEISV1111VVXXXXV/zsEV1111VVXXXXVf5r77rvvVv6TSOJ+knhBJPH82OY/kiQk8Z9JEpL4zyYJSfxnk4Qk/rNJQhL/VSQhif8qkpCEJP4rSUISkvivJglJSOJFIYn7SeJ+knhR2OZfYhsA2wDYBsA2ALZ5fq655hruu+++W7nqqquuuuqqq/6zEFx11VVXXXXVVf+pjh07xr+VJB5IEi8KSfxr2ObfQxL/2STxn00SkvjPJglJ/GeThCT+K0hCEpL4ryIJSfxXkoQkJPFfTRKSkMSLShKSkIQkJAEgCUkASOIFsc2/xDb/GrZ5oGuvvZazZ88+g6uuuuqqq6666j8LwVVXXXXVVVdd9Z/m7Nmzz+C5SEISkpCEJF4YSbwoJPGvZZv77e7uAnD69GleVJKQxH8mSUjiP5MkJPGfTRKS+M8mCUn8V5CEJP6rSEISkvivIglJSOK/miQkIYl/LUlIQhIPJIl/iW3+Jbb597ANwLXXXstVV1111VVXXfWfispVV1111VVXXfWf5r777rv1+PHj3E8Sz48kbPOikIRtACRhm3+JJGzz/NhGEv9akvjPJIn/bJL4ryCJ/wqS+K8iif9KkvivJon/DpL49zh16hQA9913H5KQhCQkIYkXxjb/Etv8R7vvvvtu5aqrrrrqqquu+s9CcNVVV1111VVX/ac5e/bsrQDHjx9HEi+MJCTx/EjiX0sSL4xtHsg2LwpJSOI/kyT+s0niP5skJPGfTRKS+K8gCUn8V5CEJCTxX0USkpDEfyVJSEIS/5Ek8R/FNv8S2wDYBsA2L8y1114LwNmzZ2/lqquuuuqqq676z0Jw1VVXXXXVVVf9pzt+/Dj/FSTxb2GbS5cuAXDq1CleEEn8Z5KEJP4zSUIS/5kkIYn/bJKQxH82SUhCEv8VJCGJ/yqSkIQk/itJQhKS+I908uRJAM6ePYskJCEJSQBIQhIvKtv8S2zzwtgGwDYPdM0113DVVVddddVVV/2no3LVVVddddVVV/2nue+++27lX0kStnlukrANgCRsAyAJ2/xLJGGbB7KNJAAuXrwIwOnTp3lukvjPJon/TJL4zyaJ/wqS+K8gif8qkvivJon/apL4ryIJAElIAkAS95OEbf4tbANgm38L2wBce+21ANx33323ctVVV1111VVX/WchuOqqq6666qqr/lPdd999t95yyy38a0ji30oS95PECyIJANu8MJL4zyQJSfxnksR/JklI4j+bJCTxn00SkvivIAlJ/FeRhCQk8V9FEpKQxH+FkydPAnDfffchiftJ4l/DNlddddVVV1111f8JBFddddVVV1111X+qs2fP3sq/gSReGEncTxL/XhcvXgTg1KlTAEhCEv9ZJCGJ/0ySkMR/Jkn8Z5OEJP6zSUIS/xUkIYn/KpKQxH8lSUjiv9qpU6cAOHv2LJKQhCReVLZ5brYBsM2/xDYvqmuuuYZ/+Id/+G2uuuqqq6666qr/TFSuuuqqq6666qr/dMePH+c/giRs8x/NNru7uwCcPn0aSfxnksR/Jkn8Z5PEfzZJ/FeQxH8FSfxXksR/NUn8d5DE/U6ePAnA4x//eP4r2AbANg9kGwDbANjmuV177bXcd999t3LVVVddddVVV/1nIrjqqquuuuqqq/5T3XfffbceO3aMfwtJvKgkcT9J3E8S95PEC3Lx4kUATp8+zX8WSUjiP4skJPGfSRKS+M8kCUn8Z5OEJP6zSUIS/xUkIQlJ/FeRhCQk8V9JEpKQxAOdOnUKAElIQhIAkpDEC2Kb52abF8Q2/xa2ueqqq6666qqr/ksRXHXVVVddddVV/6nuu+++W48fP86/lSQeSBL3k8R/tFOnTvGfQRL/mSTxn0kSkvjPJAlJ/GeShCQk8Z9NEpL4ryAJSfxXkYQkJPFfSRKSkMQLcvLkSQDOnTuHJAAkcT9J/HvY5j/KS77kS3LffffdylVXXXXVVVdd9Z+J4Kqrrrrqqquu+j9JEv8SSdxvd3eX3d1dAB71qEfxH0USkvjPIglJ/GeRhCT+M0lCEv+ZJCGJ/2ySkIQk/rNJQhKS+K8iCUn8V5KEJCTxLzl58iQAZ8+e5X6SeGFs89xs89xs8x/JNgBnz559BlddddVVV1111X8mgquuuuqqq6666j/VP/zDP/zOsWPHeCBJSEISkpCEJF4QSTyQJJ4fSTw/krifJF6Qixcv8h9JEv9ZJCGJ/0yS+M8kCUn8Z5KEJP6zSUIS/xUkIYn/KpKQhCT+q0hCEpL413jEIx4BwOMf/3gkIYl/Dds8N9u8ILYBsA2AbQBsA2CbF+baa6/lqquuuuqqq676T0dw1VVXXXXVVVf9lzh27BgAknhBJPGvJYn/KE9/+tMBeOQjH8m/hyQk8Z9FEv+ZJCGJ/yySkMR/JklI4j+bJCTxn00SkpDEfwVJSEIS/1UkIQlJ/FudPHmS+0kCQBKS+NeyzQtim38N27wg9913361cddVVV1111VX/mQiuuuqqq6666qr/VGfPnr0V4Pjx40jiXyKJ50cSLwpJ3E8S/xq33norAI961KP4t5LEfxZJSOI/iyQk8Z9FEpL4zyQJSfxnk4Qk/rNJQhL/FSQhCUn8V5GEJCTxH+HkyZMAPP7xjwdAEveTxAPZ5n62eVHY5t/DNvd7iZd4CQDOnj17K1ddddVVV1111X8mKlddddVVV1111f84krDNCyMJ2wBIwjYvjCRs88JcvHgRgNOnT/OvJYn/TJL4zyKJ/0yS+M8mif9skvivIon/KpL4rySJ/yyPeMQjAHj84x+PJP4tbPPcbPMfyTbXXnstV1111VVXXXXVfwmCq6666qqrrrrqP9V99913K8Dx48f515DEc5PEfwRJ3E8Sz+3UqVP8a0jiP4skJPGfRRL/mSTxn0kSkvjPJAlJ/GeThCQk8Z9NEpKQxH8VSUjiP9PJkycBOH/+PC+Ibe5nmxfGNi+IbQBsA2AbANsA2OZFcd99993KVVddddVVV131n4ngqquuuuqqq676T3fffffdeuzYMf61JPHCSOJ+krifJO4niRfV7u4uT3/60wF41KMexb9EEpL4zyAJSfxnkYQk/rNIQhL/WSQhif9MkpDEfzZJSOK/giQk8V9FEpKQxH+2V3qlVwLgd3/3dwGQhCReVLa5n21eENv8a9jm+bn22mu57777buWqq6666qqrrvrPRnDVVVddddVVV/2nO3v27K38B5HEv5Uk/iVPf/rTAXjkIx/JCyOJ/yyS+M8iCUn8Z5GEJP6zSEIS/5kkIYn/TJKQhCT+s0lCEpL4ryAJSUjiv4okTp48CYAkJPHcbPPvYZt/D9s80LXXXsvZs2dv5aqrrrrqqquu+s9GcNVVV1111VVX/Zd40IMexL+FJF4YSdxPEveTxAsjiefn1ltvBeBRj3oUz48kJPGfQRKS+M8gCUn8Z5GEJP6zSEIS/5kkIYn/TJKQxH8FSUjiv4IkJCGJ/yqSkIQkAB7xiEcA8PjHP54HksRzs839bHM/2zw32/xLbPOiss397rvvvlu56qqrrrrqqqv+sxFcddVVV1111VX/6e67775b+XeQxANJ4l9DEi+qixcvAnD69GmemyT+s0jiP4sk/rNIQhL/WSQhif9MkpDEfyZJSOI/myQkIYn/bJKQhCT+q0hCEpJ4bg9/+MMBeMITnsB/BNu8ILYBsM0D2QbANv+Sa6+9lquuuuqqq6666r8EwVVXXXXVVVdd9Z/uvvvuu/XYsWP8TyCJ5yaJ++3u7vL0pz+dU6dO8ahHPQoASUjiP4MkJPGfQRKS+M8gCUn8Z5GEJP6zSEISkvjPIglJSOI/kyQkIYn/CpKQxH8VSUhCEi/IK77iKwLw+Mc/nvPnzyOJ+9nmfra5n23uZ5v72ea52QbANv8atnlBrr32Wu67775bueqqq6666qqr/rMRXHXVVVddddVV/2WOHTvGv5UkHkgS95PE/SRxP0ncTxIvqqc//ekAPPKRj0QS/1kk8Z9BEpL4zyKJ/yySkMR/FklI4j+TJCTxn00SkvivIAlJSOK/giQkIYkXxSMe8QgAzp8/z7+GbV4Y2/xHsM0DXXvttQCcPXv2GVx11VVXXXXVVf/ZCK666qqrrrrqqv90v/3bv/09d9xxx2+/+7u/O6/xGq/B/SQhCUlIQhL/lSTx/Dz96U8H4NVe7dX4zyAJSfxnkMR/FklI4j+DJCTxn0USkvjPJAlJ/GeThCT+s0lCEpL4ryAJSUjiX+vhD384AL/3e7/Hv8Q2z49t7mebf4ltAGwDYJt/iW1e8iVfku/+7u9G0q2/9Vu/9d1cddVVV1111VX/2Qiuuuqqq6666qr/dPfdd9+tX/d1X/fe6/X61td4jdfgzd/8zTl+/DjPjyReEEk8kCTuJ4n7SeJ+knhuknhhdnd3ATh16hSPfOQj+Y8iCUn8Z5CEJP4zSEIS/xkkIYn/LJKQxH8mSUjiP5MkJCGJ/0ySkIQk/itIQhKS+Pc4efIkAE94whN4fmzzQLa5n21eFLYBsM0LYxsA2zzQtddey5d8yZfwJV/yJdx33323fv3Xf/37cNVVV1111VVX/VegHD9+nKuuuuqqq6666j/f0dHRpT/7sz/7mcPDw93Xe73Xe+1HPvKRzOdzbrvtNp6bJCTxH00SL4gk7rdcLnnIQx7CiRMnOH/+PE960pP495LEfxZJ/GeQhCT+M0hCEv9ZJCGJ/yySkIQk/jNJQhL/2SQhif8KkpCEJP4jvOIrviIv+ZIvye///u/zV3/1V7wgtvmX2Oa52ebfwzYv8RIvwdd//ddz7bXX8iM/8iOf/aVf+qVvc/bs2Vu56qqrrrrqqqv+K1COHz/OVVddddVVV131X+Pw8HD3H/7hH37nt3/7t7/n0Y9+9Eu//Mu//IOPHz/Ovffey3q95kUhiReFJF4Uknhukrh48SIv+7IvC8Af/dEf8W8lCUn8Z5CEJP4zSOI/iyT+s0hCEv9ZJCGJ/0ySkIQk/jNJQhKS+M8mCUlI4j/a277t23Ly5El+9Vd/ldtuu40Hss0D2eZ+trmfbZ6bbf69rr32Wj790z+dd3/3d+e+++679eM//uNf5k//9E9/hquuuuqqq6666r8S5fjx41x11VVXXXXVVf+1Dg8Pd//hH/7hdw4PD3df93Vf97Uf+chHMpvNuO2223ggSfxLJHE/STw/knhuknhhbPOqr/qqnD59mic+8YmcP3+efy1J/GeQhCT+M0hCEv8ZJCGJ/wySkMR/FklI4j+TJCTxn00SkvivIAlJ/Gd6t3d7NwC+9mu/lv8ItnlBbANgGwDbANgGwDb3e4mXeAm+7uu+jmuvvZYf+ZEf+ewv/dIvfZvDw8Ndrrrqqquuuuqq/2qU48ePc9VVV1111VVX/dc7PDzc/Yd/+Iff+e3f/u3vefSjH/3SL//yL//g48ePc++997Jer7mfJJ6bJP6tJPGiWK1WPOQhD+HEiROcP3+eJz3pSbyoJCGJ/wyS+M8gCUn8Z5CEJP4zSEIS/1kkIYn/LJKQhCT+M0lCEpL4zyYJSUjiP9srvuIr8pIv+ZL8wR/8AX/5l3/J82ObB7LN/WxzP9s8N9sA2OZFdc011/Dpn/7pvNu7vRv33XffrR//8R//Mn/6p3/6M1x11VVXXXXVVf9dKMePH+eqq6666qqrrvrvc3h4uPsP//APv3N4eLj7uq/7uq/9yEc+ktlsxm233cb9JPHcJHE/SdxPEveTxP0k8S+RxAPt7u7ysi/7spw+fZrf+I3f4EUhif8MkpDEfzRJSOI/gyQk8Z9BEpL4zyIJSfxnkYQk/jNJQhKS+M8mCUlI4r+CJCTxtm/7tpw8eZJf+7Vf47bbbuN+tnkg2zyQbe5nm+dmm3+Ll3iJl+Drvu7ruPbaa/mRH/mRz/7SL/3Stzk8PNzlqquuuuqqq67670Tlqquuuuqqq676b3fffffd+qM/+qOf89u//dvf8+Ef/uHf9Rqv8Rqvffz4cX7v936PS5cuASAJ2/xHkoRtJGGb53bx4kUATp06xSMf+Uie9KQn8YJI4j+LJP4zSOI/gyT+s0jiP5Mk/jNJ4j+bJP4rSOK/kiQe6OTJkzz84Q8H4Pd///d5brZ5INv8S2zzL7ENgG0AbHPNNdfw0R/90bzES7wE//AP//DbX//1X/8+9913361cddVVV1111VX/E1COHz/OVVddddVVV131P8Ph4eHub/3Wb30PwOu+7uu+9iMf+Uhmsxm33XYbz48k7ieJ+0nifpJ4bpJ4UaxWK44fP871118PwF//9V/z/EjiP4MkJPEfTRKS+I8mCUn8Z5CEJP4zSEISkvjPIAlJSOI/iyQkIYn/TJKQhCT+K0hCEpJ4bm/zNm/DjTfeyO///u/zV3/1Vzw/tnkg29zPNvezzQtiGwDbPD8v8RIvwdd+7ddy7bXX8iM/8iOf/fVf//Xvc3h4uMtVV1111VVXXfU/BZWrrrrqqquuuup/nB/90R/9nN/+7d/+ng//8A//rtd4jdd47ePHj/N7v/d7XLp0Cdv8W0nCNi8KSdjmN3/zN3nZl31ZHvWoR/H8SOI/miT+M0jiP4sk/jNI4j+LJP4zSeI/myT+K0jiv4okXhQPf/jDAfiDP/gD7mcb2zyQbR7INvezzXOzDYBtXphrrrmGj/qoj+IlXuIl+Id/+Iff/vqv//r3ue+++27lqquuuuqqq676n4Zy/Phxrrrqqquuuuqq/3kODw93f+u3fut7AF73dV/3tR/5yEcym8247bbbeFFI4n6SeG6SAJAEgCQAJPFAq9WKhzzkIdxwww2cP3+e22+/HQBJSOI/miT+M0jiP4MkJPEfTRKS+M8gCUn8Z5GEJP6zSEISkvjPJAlJSOI/myQkIYkXxSu+4ivyiq/4ijzhCU/gZ37mZ3hutnkg2/xLbPOievEXf3G+5mu+hmuvvZYf+ZEf+eyv//qvf5/Dw8Ndrrrqqquuuuqq/4kox48f56qrrrrqqquu+p/rH/7hH37nt37rt767tbb7pm/6pq99/Phx7r33XtbrNQCSuJ8k/iWS+Ld47GMfy80338xv/MZvIIn/aJKQxH80SUjiP5okJPEfTRKS+M8gCUn8Z5GEJP6zSEIS/5kkIQlJ/GeThCQk8a/1Nm/zNpw8eZKf+Zmf4bbbbuP5sc0D2eZ+trmfbV4Q2wDYBuDMmTN86qd+Ku/yLu/CP/zDP/z2h3zIhzzkH/7hH36Hq6666qqrrrrqfzLK8ePHueqqq6666qqr/mc7Ojq69A//8A+/A/C6r/u6r/2oRz2K+XzObbfdxgsjif8Iq9WKV33VV2VjY4MnP/nJnD9/nv9IkviPJglJ/EeThCT+o0lCEv8ZJCGJ/wySkIQk/rNIQhL/mSQhif9skpCEJP6tHv7wh/PGb/zGAHz91389ALaxjW0eyDYPZJv72eYFsc1ze/EXf3G++qu/GuDWn//5n//qr//6r38frrrqqquuuuqq/w0ox48f56qrrrrqqquu+t/hH/7hH37nt3/7t79nmqbdN33TN33tY8eOce+997Jer7mfJJ4fSTw3SQBIAkASAJIAkATAarXCNg996EM5deoUf/RHf8R/BElI4j+aJP6jSUIS/xkk8Z9BEpL4zyAJSfxnkYQkJPGfRRKSkMR/JklIQhL/Ed71Xd+VkydP8gd/8Af81V/9Fc/NNg9km3+JbQBs89yuueYaPuVTPoV3fud35h/+4R9+++M//uNf5h/+4R9+h6uuuuqqq6666n8LyvHjx7nqqquuuuqqq/73ODw83P2Hf/iH3wF4vdd7vdd+1KMexXw+5xnPeAYvKkn8a+3u7vKqr/qqANx+++2cP3+efw9J/EeThCT+o0niP4MkJPEfTRKS+M8gCUn8Z5GEJP4zSUIS/5kkIQlJ/Ec6efIkb/M2bwPA13/913N4eMjzYxvb3M8297PN/WzzgtjmxV/8xfnKr/xKgFt//ud//qu//uu//n246qqrrrrqqqv+t6EcP36cq6666qqrrrrqf59/+Id/+J3f/u3f/p5pmnbf9E3f9LWPHz/Ovffey3q9RhL3k8T9JPFvtVwuOXHiBA972MOQxF//9V/zbyEJSfxHk8R/NElI4j+aJCTxH00SkvjPIAlJ/GeQhCQk8Z9FEpKQxH8mSUjiP8vbvM3bcOONN/IHf/AH/MEf/AEAtrGNbZ6bbe5nm/vZ5rnZBsA211xzDZ/8yZ/MO7/zO/MP//APv/3xH//xL/MP//APv8NVV1111VVXXfW/EeX48eNcddVVV1111VX/Ox0eHu7+wz/8w++cPXv2Ga/0Sq/00i/7si97fDabcdttt/EvkQSAJAAkASAJAEk8t3vuuYdXfdVXZWNjg9tvv53z58/zryGJ/2iSkMR/JElI4j+aJCTxH00SkvjPIAlJ/GeQhCT+s0hCEpL4zyQJSUjiP9OpU6d413d9VwC+4Ru+gaOjI56bbWzzQLa5n22em20e6MVe7MX4yq/8SoBbv+RLvuRtfvRHf/RzuOqqq6666qqr/jejHD9+nKuuuuqqq6666n+3W2+99a//7M/+7Gemadp9szd7s9c+fvw49957L6vVCgBJ/FtJAkASy+WSEydO8LCHPQxJ/PVf/zUvCklI4j+SJCTxH00S/9EkIYn/aJKQxH8GSUjiP4MkJPGfRRKS+M8kCUlI4j+TJCQhibd+67fmxhtv5A/+4A/4/d//fWxjG9s8N9v8S2zzQNdccw2f9EmfxDu90zvxD//wD7/98R//8S9z9uzZW7nqqquuuuqqq/63oxw/fpyrrrrqqquuuup/v8PDw91/+Id/+J2zZ88+45Ve6ZVe+mVf9mWPz+dznvGMZ/BAknhukgCQxL/k7rvv5tVe7dXY2Njg9ttv5/z587wwkviPJon/aJKQxH8kSUjiP5okJPEfTRKSkMR/NElIQhL/GSQhCUn8Z5GEJCTxn0kSkpDE/U6ePMm7vuu7AvAN3/ANHB0d8UC2sc0D2eZ+trmfbZ7bYx/7WL7iK74C4NYv+ZIveZsf/dEf/Ryuuuqqq6666qr/KyjHjx/nqquuuuqqq676v+PWW2/96z/7sz/7mWmadt/szd7stY8fP84Tn/hEJPHcJPH8SAJAEs9ttVpx4sQJHvawh3H69Gn+6I/+iOdHEpL4jyQJSfxHkoQk/iNJQhL/0SQhif9okpDEfwZJSOI/iyQk8Z9JEpL4zyQJSUji+Xnf931fTp48yR/8wR/wB3/wB7wgtnkg29zPNs/t9OnTfNInfRLv9E7vxG/91m9992d91me9ztmzZ2/lqquuuuqqq676v4Ry/Phxrrrqqquuuuqq/1sODw93/+Ef/uF3/uEf/uF3Xvd1X/e1X+VVXuX4fD7nGc94BgCS+NeQxAPdfffdvNqrvRqnTp3iSU96EufPn+eBJPEfTRL/0STxH00S/9EkIYn/aJKQxH8GSUjiP4MkJCGJ/yySkIQk/jNJQhIvzMMf/nDe+I3fmHPnzvFd3/VdHB4eYhvb2MY2D2Qb29zPNvezDYBtXuzFXowv//IvB7j1S77kS97mF37hF76Gq6666qqrrrrq/yLK8ePHueqqq6666qqr/m86e/bsrX/6p3/606213Td7szd77ePHj3PvvfeyWq24nyQAJAEgCQBJPDdJACyXSy5evMhjH/tYHvWoR/Ebv/EbAEhCEv+RJCGJ/0iSkMR/JElI4j+SJCTxH00SkvjPIAlJ/GeQhCT+s0hCEpL4zyQJSUjiRfEu7/IunDx5kl//9V/nr/7qr3h+bGObB7LN83PmzBk+4RM+gXd8x3fkt37rt777sz7rs17n7Nmzt3LVVVddddVVV/1fRTl+/DhXXXXVVVddddX/XUdHR5f+4R/+4Xf+4R/+4Xde7/Ve77Vf9mVf9vhiseAZz3gGLwpJPDdJrFYrHvvYx3Ly5EkuXLjAHXfcwX80SfxHkoQk/iNJQhL/kSQhif9okpDEfzRJSEIS/xkkIYn/LJKQxH8mSUhCEv8ar/AKr8BrvdZrAfClX/ql2MY2trGNbR7INs+PbQAe+9jH8mVf9mUAt37Jl3zJ2/zCL/zC13DVVVddddVVV/1fRzl+/DhXXXXVVVddddX/fWfPnr31z/7sz36mtbb7Zm/2Zq99/Phx7r33XlarFS8KSTzQcrlktVrx2Mc+lptvvpnf/M3f5D+KJCTxH0kS/5EkIYn/aJL4jyYJSfxHk4Qk/jNIQhKS+M8gCUlI4j+LJCQhiX+r93u/92OxWPBlX/ZlnDt3jufHNra5n23uZxuAM2fO8PEf//G84zu+Iz/yIz/y2V/6pV/6NmfPnr2Vq6666qqrrrrq/wPK8ePHueqqq6666qqr/n84PDzc/Yd/+Iff+a3f+q3vfsu3fMu3ftmXfdnj8/mcZzzjGQBIAkASAJJ4bpK43913381DHvIQbrzxRk6dOsXf/M3f8O8hCUn8R5KEJP4jSeI/miQk8R9JEpL4jyYJSfxnkIQk/jNIQhKS+M8iCUlI4t/rXd7lXXj4wx/OE5/4RH7mZ34G29jGNraxzQPZ5n62ud9jHvMYvvRLvxTg1i/5ki95m9/+7d/+Hq666qqrrrrqqv9PKMePH+eqq6666qqrrvr/5ejo6NKf/dmf/UxrbffN3uzNXhvg1ltv5QWRxHOTBMDTnvY0Xu3VXo2NjQ3uuOMOzp8/z7+FJP4jSUIS/5EkIYn/SJKQxH8kSUjiP5okJPEfTRKSkMR/BklI4j+LJCQhif8oD3/4w3mbt3kbAL7ru76Lc+fO8fzY5oFsc7/Tp0/zXu/1XrzXe70XP/IjP/LZX/qlX/o2Z8+evZWrrrrqqquuuur/G8rx48e56qqrrrrqqqv+/zk8PNz9h3/4h9/57d/+7e95h3d4h7d+tVd7tePz+ZxnPOMZAEjiuUniuS2XSwBe/MVfnEc+8pH85m/+Jv8akpDEfyRJ/EeShCT+I0lCEv+RJCGJ/2iSkMR/NElI4j+DJCQhif8skpDEf4Z3eZd34eTJk/zcz/0cv//7v49tbGMb2zyQbWxzP9s89rGP5Yu/+IvZ2Ni49Uu+5Eve5rd/+7e/h6uuuuqqq6666v8ryvHjx7nqqquuuuqqq/7/Ojw83P2zP/uzn2mt7b75m7/5awPceuut3E8Sz00S95PExYsXuf7667nxxhsBeNKTnsSLQhL/kSQhif8okpDEfyRJSOI/kiQk8R9NEpL4jyYJSfxnkIQk/rNIQhKS+M/yxm/8xrziK74iT3ziE/nO7/xOnh/b2OaBbHPmzBne+I3fmA/5kA/hR37kRz77S7/0S9/m7Nmzt3LVVVddddVVV/1/Rjl+/DhXXXXVVVddddX/b4eHh7v/8A//8Du//du//T3v+I7v+Nav9mqvdnw+n3PrrbdyP0k8N0kALJdLdnd3ebmXezlOnTrFHXfcwfnz53lBJCGJ/0iS+I8kif9IkpDEfyRJSOI/kiQkIYn/aJKQxH80SUhCEv8ZJCEJSfxnkYQkHv7wh/Mu7/IuAHzXd30X586dwza2sY1tbHM/29gG4LGPfSxf9EVfxOnTp2/9ki/5krf57d/+7e/hqquuuuqqq666CijHjx/nqquuuuqqq666CuDw8HD3z/7sz36mtbb75m/+5q8tiVtvvRVJ3E8Sz8/FixcBePEXf3Ee+chH8pu/+Zs8P5L4jyQJSfxHkYQk/qNIQhL/kSQhif9IkpDEfzRJSEIS/9EkIYn/LJKQxH8WSUhCEvd7l3d5F06ePMnP/uzP8od/+Ie8ILa535kzZ3jjN35jPviDP5gf+ZEf+ewv/dIvfZuzZ8/eylVXXXXVVVddddUVlOPHj3PVVVddddVVV111v8PDw91/+Id/+J3f/u3f/p53fMd3fOtXf/VXPz6fz7n11luRxP0kcT9JAFy8eJEbbriBG2+8kVOnTvE3f/M3PJAk/qNIQhL/USQhif9IkviPJAlJ/EeShCT+o0lCEv/RJCEJSfxnkIQkJPGfQRKSkMRz+9AP/VAe/vCHc/78eb7hG74B29jGNraxjW3uZ5tHP/rRfOEXfiGnT5++9Uu+5Eve5rd/+7e/h6uuuuqqq6666qrnRDl+/DhXXXXVVVddddVVz+3w8HD3T//0T3+6tbb75m/+5q8NcOuttwIgiftJ4n7L5ZKnPe1pvPqrvzo333wz58+f54477kASkviPIon/SJL4jyQJSfxHkYQk/iNJQhL/0SQhif9okpDEfwZJSEIS/xkkIQlJvCAPe9jDeOM3fmMAvvEbv5Fz585hG9s8N9ucPn2aN37jN+aDPuiD+JEf+ZHP/tIv/dK3OXv27K1cddVVV1111VVXPS/K8ePHueqqq6666qqrrnp+jo6OLv3DP/zD7/z2b//297zjO77jW7/6q7/68cViwdOf/nQAJPFAklgul1y4cIEXe7EX4+abb+Zv//ZvWS6X/EeQhCT+o0hCEv9RJCGJ/yiSkMR/JElI4j+aJCTxH00SkvjPIAlJ/GeRhCT+JSdPnuTjP/7jAfjZn/1Z/uAP/gDb3M82trENwGMe8xi+4Au+gFOnTt36JV/yJW/z27/929/DVVddddVVV1111QtGOX78OFddddVVV1111VUvzOHh4e6f/dmf/UxrbffN3/zNXxvg6U9/Og8kifvdfffdHD9+nIc//OG81Eu9FL/5m7/Jv5ck/qNIQhL/USQhif9IkviPJAlJ/EeShCQk8R9JEpKQxH80SUhCEv8ZJCEJSbyo3ud93oeTJ0/yxCc+ke/6ru/CNraxjW3ud/r0ad7wDd+QD/zAD+RHfuRHPvtLv/RL3+bs2bO3ctVVV1111VVXXfXCUY4fP85VV1111VVXXXXVv+Tw8HD3H/7hH37nt37rt777nd7pnd76NV7jNY7P53Oe/vSnI4n7SQLgrrvu4vrrr+fGG2/k1KlT/M3f/A3/FpKQxH8USfxHksR/JElI4j+KJCTxH0kSkviPJglJ/EeThCQk8Z9BEpKQxL/Wh37oh/Lwhz+c8+fP87mf+7k8P7Z51KMexed//udz6tSpW7/kS77kbX77t3/7e7jqqquuuuqqq6560VCOHz/OVVddddVVV1111Yvq6Ojo0p/92Z/9TGtt9y3e4i1eWxJPf/rTAZDE/ZbLJU972tN49Vd/dW6++WYAnvzkJ/OvIYn/KJKQxH8USUjiP4okJPEfRRKS+I8kCUn8R5OEJP6jSUIS/xkkIQlJ/Fu90Ru9Ea/4iq8IwDd+4zdy7tw5bGMb29jm1KlTvOEbviEf+IEfyI/8yI989pd+6Ze+zdmzZ2/lqquuuuqqq6666kVHOX78OFddddVVV1111VX/GoeHh7v/8A//8Du//du//T2v+7qv+9Jv/MZv/OD5fM7Tn/507ieJ5XLJxYsXebEXezFOnTrFHXfcwfnz5/mXSEIS/1Ek8R9FEpL4jyIJSfxHkYQk/iNJQhL/kSQhCUn8R5KEJCTxn0ESkvj3etjDHsa7vMu7APDlX/7lPOEJT8A2trENwKMf/Wg+7/M+j1OnTt368R//8S/zp3/6pz/DVVddddVVV1111b8e5fjx41x11VVXXXXVVVf9WxweHu7+wz/8w++01nbf4i3e4rUBnva0pyGJ+911110AvPiLvziPfOQj+Zu/+RuWyyUviCT+o0hCEv9RJPEfRRKS+I8iCUn8R5KEJP4jSUIS/9EkIYn/DJKQhCT+I5w8eZKP//iPB+Dnfu7n+MM//EMe6PTp07zBG7wB7//+78+P/MiPfPaXfumXvs3h4eEuV1111VVXXXXVVf82lOPHj3PVVVddddVVV131b3V4eLj7D//wD7/z27/929/zuq/7ui/9xm/8xg+ez+c87WlPA0AST33qU7HNS7zES/BSL/VS/M3f/A3L5ZIHkoQk/iNIQhL/USQhif8IkpDEfxRJSOI/kiQk8R9JEpL4jyQJSUjiP5okJCGJ/0gnT57kQz/0Qzk6OuL222/nu77ru7CNbWzzqEc9is/5nM/h5MmTt378x3/8y/zpn/7pz3DVVVddddVVV13170M5fvw4V1111VVXXXXVVf9eh4eHu//wD//wO6213bd8y7d8bYCnP/3p3O/ChQvccMMN3HjjjbzUS70Uv/mbv8n9JPEfRRL/USQhif8okviPIglJ/EeShCT+o0hCEpL4jyQJSfxnkIQk/jNI4n3f93258cYbueOOO/jyL/9ybGObU6dO8fqv//q8//u/Pz/yIz/y2V/6pV/6NoeHh7tcddVVV1111VVX/fuhBz3oQVx11VVXXXXVVVf9R7rmmmse/OEf/uHfdcMNN7z2n//5n/Nrv/ZrABw/fpwP/uAP5uTJk5w/f57P+IzP4D+KJP6jSOI/kiT+o0jiP5ok/iNJ4j+DJP4zSOI/iyTu96Ef+qE87GEP4/z583zKp3wKmYltHvWoR/GJn/iJ3Hfffbd+1md91uvcd999t3LVVVddddVVV131H4dy/Phxrrrqqquuuuqqq/4jHR4e7v7Wb/3W98znc97yLd/ytQGe9rSnsVwu+fu//3te/MVfnFOnTnHq1Cn+5m/+hn8vSfxHkcR/FElI4j+KJP6jSEISkviPIglJ/EeShCQk8R9JEpKQxH80SUhCEvf70A/9UB72sIdx/vx5vuu7votz585x6tQpXv/1X5/3e7/340d+5Ec++0u/9Evf5vDwcJerrrrqqquuuuqq/1iU48ePc9VVV1111VVXXfWf4R/+4R9+57d/+7e/5/Ve7/Ve+k3f9E0fvFgs+Id/+Af+/u//nhd/8RfnEY94BKdOneJv/uZv+LeQhCT+I0hCEv8RJCGJ/yiSkMR/BElI4j+SJCTxH0kSkviPJglJ/GeQhCSe24d+6IfysIc9DIBv/MZv5IlPfCKPfOQj+azP+ixaa7/9WZ/1Wa/zp3/6pz/DVVddddVVV1111X8OyvHjx7nqqquuuuqqq676z3J4eLj7W7/1W98zn895y7d8y9cG+Id/+Af+/u//ntd8zdfkpptu4tSpU/zN3/wN/xqS+I8iif8okviPIglJ/EeQhCT+I0lCEv9RJCEJSfxHkoQkJPEfTRKSkMTz86Ef+qE87GEPA+DLv/zLOXfuHK//+q/P+77v+/IjP/Ijn/31X//173N4eLjLVVddddVVV1111X8eyvHjx7nqqquuuuqqq676z/YP//APv/Nbv/Vb3/36r//6L/1mb/ZmDwb44R/+YV7zNV+Tm266iVOnTvE3f/M3/EskIYn/CJKQxH8ESUjiP4IkJPEfQRKS+I8iCUlI4j+KJCTxH00SkviPJglJSOKF+dAP/VAe9rCHAfDlX/7lAHzmZ34m0zT99md+5me+9p/92Z/9DFddddVVV1111VX/+SjHjx/nqquuuuqqq6666r/C0dHRpd/6rd/6nvl8zlu91Vu99nK55Id+6Id4rdd6LW666SZOnTrF3/zN3/CCSOI/giQk8R9BEpL4jyAJSfxHkIQk/qNIQhL/kSQhif9IkpCEJP4jSUISknhRfOiHfigPe9jDAPju7/5ubrrpJt7szd7s1p//+Z//6q//+q9/n6Ojo0tcddVVV1111VVX/ddAD3rQg7jqqquuuuqqq676r3bNNdc8+LVf+7Xf6w3f8A0/+ylPeQqv8AqvAMCTnvQkvvqrv5oHksR/FEn8R5DEfxRJ/EeSxH8USfxHk8R/NEn8Z5DEv9aHfuiH8rCHPQyAn/u5n+Mt3uIt+Id/+Iff/szP/MzX4aqrrrrqqquuuuq/HuX48eNcddVVV1111VVX/Vc7PDzc/Yd/+Iffmc/nvOEbvuFr/+mf/imLxYKbbrqJV3mVV+Fv/uZvWC6XSOI/giQk8R9BEv8RJCGJ/yiSkMR/BElI4j+KJCQhif8okpCEJP4jSUISkvjXOHnyJO/zPu/Dwx72MACe9KQn8fCHP/zWn//5n//qr//6r38frrrqqquuuuqqq/57UI4fP85VV1111VVXXXXVf5d/+Id/+J3f/u3f/p7jx4/vvsIrvMJrAywWC17qpV6Kv/u7v2O5XPLvJYn/CJKQxH8ESfxHkYQk/iNIQhL/USQhif9IkpDEfyRJSEIS/xYnT57knd/5nXnYwx7G/e65557f/viP//iX+Yd/+Iff4aqrrrrqqquuuuq/D+X48eNcddVVV1111VVX/Xc6PDzc/Yd/+IffOXv27DMe/OAHv/Tm5ubxjY0NXvIlX5K//du/Zblc8m8hCUn8e0lCEv8RJCGJ/wiSkMR/BElI4j+KJCTxH0USkpDEfyRJSOLf4+TJk3zap30aJ0+eBOC+++679Uu+5Eve5kd/9Ec/h6uuuuqqq6666qr/fpTjx49z1VVXXXXVVVdd9T/Brbfe+td/9md/9jOHh4e7L/7iL/7aGxsbvORLviSLxYInP/nJvKgkIYn/CJL4jyAJSfxHkIQk/iNIQhL/USQhif8okpDEfyRJSEIS/14Pe9jD+LiP+zju9w//8A+//fEf//Evc/bs2Vu56qqrrrrqqquu+p+Bcvz4ca666qqrrrrqqqv+pzg8PNz9h3/4h985e/bsMx784Ae/9JkzZ44/8pGPRBJPfvKT+ZdI4j+CJCTx7yUJSfxHkIQk/iNIQhL/ESQhCUn8R5GEJP4jSUIS/1He8A3fkHd5l3cB4L777rv1S77kS97mR3/0Rz+Hq6666qqrrrrqqv9ZKMePH+eqq6666qqrrrrqf5pbb731r//sz/7sZw4PD3df/MVf/LUf8YhH8MhHPpI//uM/5vmRhCT+vSQhif8IkviPIAlJ/EeQhCT+I0hCEv9RJCEJSfxHkYQkJPEf5eTJk7zP+7wPr/AKrwDAP/zDP/z2x3/8x7/M2bNnb+Wqq6666qqrrrrqfx70oAc9iKuuuuqqq6666qr/yV7ndV7nvT/8wz/8uwDOnz/P13zN13D+/HnuJ4n/CJL4jyCJ/wiS+I8iif8okviPJIn/SJL4zyCJEydO8CEf8iGcPHmS++6779av//qvf59/+Id/+G2uuuqqq6666qqr/udCD3rQg7jqqquuuuqqq676n+7MmTMP+tzP/dzfvuaaax58/vx5/viP/5hf+qVf4j+CJP4jSOI/giT+o0jiP4ok/iNJ4j+SJP6jSeJ+L//yL887v/M7A3Dffffd+pmf+Zmvffbs2Wdw1VVXXXXVVVdd9T8b5fjx41x11VVXXXXVVVf9T3d0dHTpz/7sz37m8PBw9xVe4RVe+5GPfCQAT37yk/n3kMS/lyQk8R9BEv8RJCGJ/wiSkMR/BElIQhL/USQhif9IkpAEwIkTJ3if93kfXvM1XxOA3/qt3/ruz/qsz3qdo6OjS1x11VVXXXXVVVf9z0c5fvw4V1111VVXXXXVVf8bHB4e7v7DP/zD7wC8+Iu/+Gs/4hGP4JVe6ZW48847uXDhAv8akpDEv5ck/iNIQhL/XpKQxH8ESUjiP4IkJPEfRRKSkMR/FElIQhL3e9jDHsZ7v/d7c+ONNwLwmZ/5ma/zC7/wC1/DVVddddVVV1111f8elOPHj3PVVVddddVVV131v8k//MM//M5v//Zvf89DHvKQl37Qgx704Ec84hFsbGzw5Cc/mX+JJCTx7yUJSfx7SUIS/16SkMR/BElI4j+CJCTxH0USkviPIglJSOK5veEbviHv/M7vzGKx4L777rv14z/+41/m1ltv/Wuuuuqqq6666qqr/nehHD9+nKuuuuqqq6666qr/bQ4PD3f//u///rcPDw93X+EVXuG1H/GIR/BKr/RK3HnnnVy4cIHnRxL/XpKQxL+XJCTx7yUJSfxHkIQk/iNIQhL/ESQhCUn8R5GEJJ6fEydO8LEf+7G8+Iu/OAA/8iM/8tlf+qVf+jaHh4e7XHXVVVddddVVV/3vgx70oAdx1VVXXXXVVVdd9b/ZNddc8+DP+ZzP+a1rrrnmwRcuXOCP//iP+cVf/EXuJ4n/CJL495LEfwRJ/EeRxH8ESfxHksR/JEn8S97wDd+QN3zDNwTgvvvuu/Xrv/7r3+cf/uEffpurrrrqqquuuuqq/73Qgx70IK666qqrrrrqqqv+t7vmmmse/Nqv/drv9U7v9E6fDXD+/Hn+5E/+hF/6pV/i30sS/xEk8e8lif8okviPIIn/SJL4jySJf8nDHvYwPuRDPoT7/ciP/Mhn/+iP/ujncNVVV1111VVXXfW/H3rQgx7EVVddddVVV1111f8VZ86cedBHfMRHfPeLvdiLvTbAk5/8ZL7/+7+fCxcu8G8hiX8vSfxHkMR/BEn8R5DEfxRJ/EeSxIvixIkTvPM7vzMPe9jDALjvvvtu/czP/MzXPnv27DO46qqrrrrqqquu+r+Bcvz4ca666qqrrrrqqqv+rzg6Orr0W7/1W98D8OIv/uKvferUKV7qpV6KxWLBU57yFF5UkpDEv4ckJPHvJQlJ/HtJQhL/XpKQxH8ESUjiP4okJPEvOXHiBK/5mq/J+7zP+3Dy5Enuu+++W3/+53/+q7/0S7/0bY6Oji5x1VVXXXXVVVdd9X8HetCDHsRVV1111VVXXXXV/0XXXHPNg1/7tV/7vd7pnd7pswEuXLjAH//xH/NLv/RLvCCS+I8giX8vSfxHkMR/BEn8R5HEfxRJ/Gu84Ru+IW/4hm/I/X7kR37ks3/0R3/0c7jqqquuuuqqq676vwk96EEP4qqrrrrqqquuuur/sjNnzjzoIz7iI777xV7sxV4b4MKFC/zJn/wJv/iLv8gDSeLfSxL/XpL4jyCJ/wiS+I8gif9IkvjXeNjDHsY7vdM7cfLkSQDuu+++Wz/zMz/ztc+ePfsMrrrqqquuuuqqq/7vQg960IO46qqrrrrqqquu+v/gdV7ndd77Hd/xHT/rmmuueTDAhQsX+MVf/EX+9E//lH8vSfx7SeI/giT+I0jiP4Ik/qNI4l/rYQ97GO/0Tu/EyZMnAbjvvvtu/dEf/dHP+a3f+q3v5qqrrrrqqquuuur/PvSgBz2Iq6666qqrrrrqqv8vrrnmmge/2Iu92Gu/4zu+42ddc801Dwa4cOECv/RLv8Sf/Mmf8K8lif8Ikvj3ksR/BEn8R5DEfxRJ/Gu9/Mu/PG/4hm/IyZMnAbjvvvtu/a3f+q3v/tEf/dHP4aqrrrrqqquuuur/D/SgBz2Iq6666qqrrrrqqv9vzpw586DXeZ3Xee/XeZ3Xee9rrrnmwQAXLlzgT/7kT/ilX/olXhSS+PeSxL+XJP4jSOI/giT+o0jiX+sN3/ANeYVXeAVOnDgBwH333Xfrb/3Wb333j/7oj34OV1111VVXXXXVVf//oAc96EFcddVVV1111VVX/X91zTXXPPjFXuzFXvsd3/EdP+uaa655MMCFCxf4kz/5E/7kT/6ECxcu8Nwk8e8liX8vSfxHkMR/BEn8R5DEv9aJEyd4hVd4Bd7wDd+Q+9133323/tZv/dZ3/+iP/ujncNVVV1111VVXXfX/F3rQgx7EVVddddVVV1111f9311xzzYNf7MVe7LVe53Ve571f7MVe7LUBLly4wJOf/GT+5E/+hKc85SkASOLfQxL/XpL4jyCJfy9J/EeRxL/WiRMneIVXeAXe8A3fkPvdd999t/7Wb/3Wd//oj/7o53DVVVddddVVV111FXrQgx7EVVddddVVV1111VXPds011zz4Hd/xHT/rdV7ndd6bZ7pw4QJ/8id/wi//8i/zbyWJfw9J/EeQxL+XJP6jSOJf48SJE7zCK7wCL//yL8/Jkye53z/8wz/89o/8yI98zj/8wz/8NlddddVVV1111VVX3Q896EEP4qqrrrrqqquuuuqq53XNNdc8+LVf+7Xf63Ve53Xe+5prrnkwwIULF3jKU57Ck5/8ZP70T/+UF4Uk/r0k8e8liX8vSfxHkMS/1okTJ3iFV3gF3vAN35D73Xfffbf+1m/91nf/9m//9vfcd999t3LVVVddddVVV1111XNDD3rQg7jqqquuuuqqq6666gW75pprHvxiL/Zir/06r/M67/ViL/Zir80zXbhwgac85Sn8yZ/8CU95ylN4bpL495LEv5ck/r0k8R9BEv8aJ06c4BVe4RV4wzd8Qy5cuMDJkycBuO+++2790R/90c/5rd/6re/mqquuuuqqq6666qoXBj3oQQ/iqquuuuqqq6666qoXzTXXXPPg137t136vF3/xF3/tF3uxF3ttnunChQs85SlP4U/+5E94ylOegiT+PSTx7yWJfy9J/EeQxIvqxIkTvMIrvAJv+IZvyAPdd999t/7Wb/3Wd//oj/7o53DVVVddddVVV1111YsKPehBD+Kqq6666qqrrrrqqn+9a6655sGv/dqv/V4v/uIv/tov9mIv9to804ULF3jKU57CU57yFJ7ylKdw4cIFXlSS+PeSxL+XJP4jSOJfcuLECV7hFV6BEydO8Aqv8Ao80H333Xfrb/3Wb333b//2b3/PfffddytXXXXVVVddddVVV/1roQc96EFcddVVV1111VVXXfXvc+bMmQe9zuu8znu/+Iu/+Gu/2Iu92GvzABcuXOApT3kKT3nKU/jTP/1TXhBJ/HtI4t9LEv9eknhhTpw4wcmTJ3nYwx7Gy7/8y3Py5Eke6L777rv1t37rt777t37rt7777Nmzz+Cqq6666qqrrrrqqn8P9KAHPYirrrrqqquuuuqqq/7jXHPNNQ9+sRd7sdd+sRd7sdd6ndd5nffmuVy4cIGnPOUpPOUpT+HChQs89alP5d9DEv9ekvj3ksTzc+LECV7hFV4BgIc97GE87GEP44Huu+++W8+ePXvrb/3Wb33Pb/3Wb303V1111VVXXXXVVVf9R0IPetCDuOqqq6666qqrrrrqP8c111zz4DNnzjz4xV7sxV7rxV/8xV/7xV7sxV6b53LhwgUuXLjAhQsXeOpTn8qFCxd4ylOewr9EEv9ekvj3kgTAiRMnAHjYwx7GyZMnedjDHsbDHvYwnp/77rvv1t/6rd/67n/4h3/4nX/4h3/4ba666qqrrrrqqquu+s+CHvSgB3HVVVddddVVV1111X+NM2fOPEiSzpw58+DXeZ3Xea9rrrnmwS/2Yi/22jwfFy5c4MKFC1y4cIGnPvWpAFy4cIGnPOUpSOLfQxL/FidPngTgxIkTPPzhDwfgYQ97GA972MN4Qe67775b/+Ef/uG377vvvlv/4R/+4Xf+4R/+4be56qqrrrrqqquuuuq/CnrQgx7EVVddddVVV1111VX/fc6cOfOga6655iHXXHPNg1/sxV7sta655poHv9iLvdhr80JcuHABgIsXL3LhwgUALly4wIULF7jfhQsXeG6SeEFOnjwJwIkTJ7jfyZMnOXnyJCdOnODkyZP8S+67775b/+Ef/uG377vvvlv/4R/+4Xf+4R/+4be56qqrrrrqqquuuuq/E3rQgx7EVVddddVVV1111VX/s5w5c+ZBknTmzJkHX3PNNQ9+sRd7sde65pprHgzwYi/2Yq/Nf7H77rvv1muuuebB9913360AZ8+evfW3fuu3vufMmTMP+od/+IffOXv27K333XffrVx11VVXXXXVVVdd9T8NetCDHsRVV1111VVXXXXVVf+7XHPNNQ8GOHPmzIOuueaahwCcOXPmQddcc82DeaZrrrnmwfwr3HfffbcC3HfffbfyTGfPnn3Gfffd9/SzZ88+47777ruVq6666qqrrrrqqqv+t0EPetCDuOqqq6666qqrrrrqqquuuuqqq6666qqr/k+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/Vfwj2y9Vb9P7xIsAAAAASUVORK5CYII=) +```js +// A circle on the XY plane +startSketchOn("XY") + |> startProfileAt([0, 0], %) + |> circle({ radius: 10, center: [0, 0] }, %) + +// Triangle on the plane 4 units above +startSketchOn(offsetPlane("XY", 4)) + |> startProfileAt([0, 0], %) + |> line([10, 0], %) + |> line([0, 10], %) + |> close(%) +``` + +![Rendered example of offsetPlane 4](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAACDrUlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rCK666qqrrrrqqquuuuqqq/4Puuaaax7MVVddddVVV11F5aqrrrrqqquuuuqqq6666v+Ia6655sGv/dqv/V6v8zqv897XXHPNg3/rt37ru++7775bf/RHf/RzuOqqq6666qr/n9CDHvQgrrrqqquuuuqqq6666qqr/je75pprHvyO7/iOn/U6r/M67w3wu7/7u98FMJ/Ptx784Ae/wmd91me9zn333XcrV1111VVXXfX/D3rQgx7EVVddddVVV1111VVXXXXV/zbXXHPNg1/7tV/7vd7pnd7pswF+93d/97t4Pq699tqHT9PUPvMzP/N1uOqqq6666qr/f6hcddVVV1111VVXXXXVVVf9L3HNNdc8+LVf+7Xf63Ve53Xe+5prrnkwwO/+7u9+Fy/EpUuX7nnFV3zFd3id13md9/6t3/qt7+aqq6666qqr/n9BD3rQg7jqqquuuuqqq6666qqrrvqf7JprrnnwO77jO37W67zO67w3wO/+7u9+F/8K8/l868EPfvArfNZnfdbr3Hfffbdy1VVXXXXVVf9/oAc96EFcddVVV1111VVXXXXVVVf9T3PNNdc8+LVf+7Xf653e6Z0+G+B3f/d3v4t/h9d8zdd8n9/6rd/67q//+q9/H6666qqrrrrq/w8qV1111VVXXXXVVVddddVV/0Ncc801D37t137t93qd13md977mmmseDPC7v/u738V/gD/90z/9sdd5ndd573/4h3/4nd/6rd/6bq666qqrrrrq/wf0oAc9iKuuuuqqq6666qqrrrrqqv9O11xzzYNf+7Vf+73e6Z3e6bMBfvd3f/e7+E8wn8+3HvzgB7/Ch3zIhzyEq6666qqrrvr/AT3oQQ/iqquuuuqqq6666qqrrrrqv9o111zz4Nd+7dd+r3d6p3f6bIDf/d3f/S7+C7zma77m+/zWb/3Wd3/913/9+3DVVVddddVV//ehBz3oQVx11VVXXXXVVVddddVVV/1XuOaaax782q/92u/14i/+4q/9Yi/2Yq8N8Lu/+7vfxX+h+Xy+9Yqv+Irv8Jmf+Zmv8w//8A+/zVVXXXXVVVf934Ye9KAHcdVVV1111VVXXXXVVVdd9Z/pmmuuefBrv/Zrv9c7vdM7fTbA7/7u734X/42OHTt23fXXX/+YD/mQD3kIV1111VVXXfV/G3rQgx7EVVddddVVV1111VVXXXXVf7Rrrrnmwa/92q/9Xu/0Tu/02QC/+7u/+138D/Kar/ma7/Nbv/Vb3/31X//178NVV1111VVX/d9F5aqrrrrqqquuuuqqq6666j/INddc8+DXfu3Xfq8Xf/EXf+0Xe7EXe22A3/3d3/0u/gf60z/90x97sRd7sdd+8Rd/8df++7//+9/mqquuuuqqq/5vQg960IO46qqrrrrqqquuuuqqq67697jmmmse/Nqv/drv9U7v9E6fDfC7v/u738X/Atdee+3DT548ecsHf/AHP5irrrrqqquu+r+Jcvz4ca666qqrrrrqqquuuuqqq/61rrnmmge/2Zu92Ud9+Id/+He/0zu902dfuHDh6c94xjP++hnPeMZf87/E4eHhhcc+9rGvDfAP//APv8NVV1111VVX/d+DHvSgB3HVVVddddVVV1111VVXXfWiuOaaax782q/92u/14i/+4q/9Yi/2Yq8N8Lu/+7vfxf9i8/l868EPfvArfP3Xf/37/MM//MNvc9VVV1111VX/t6AHPehBXHXVVVddddVVV1111VVXvTDXXHPNg1/7tV/7vd7pnd7pswF+93d/97v4P+Taa699+IkTJ27+kA/5kIdw1VVXXXXVVf+3UI4fP85VV1111VVXXXXVVVddddVzu+aaax78Zm/2Zh/14R/+4d/9Tu/0Tp994cKFpz/jGc/462c84xl/zf8xh4eHFx772Me+DsA//MM//A5XXXXVVVdd9X8HetCDHsRVV1111VVXXXXVVVddddX93vEd3/GzXvzFX/y1X+zFXuy1AX73d3/3u/h/YD6fbz34wQ9+ha//+q9/n3/4h3/4ba666qqrrrrq/wb0oAc9iKuuuuqqq6666qqrrrrq/7drrrnmwa/92q/9Xu/0Tu/02QC/+7u/+138P3Tttdc+fJqm9pmf+Zmvw1VXXXXVVVf930A5fvw4V1111VVXXXXVVVddddX/P9dcc82D3+zN3uyjPvzDP/y73+md3umzL1y48PRnPOMZf/2MZzzjr/l/qrU2vMzLvMybSdI//MM//DZXXXXVVVdd9b8fetCDHsRVV1111VVXXXXVVVdd9f/HO77jO37WNddc8+DXeZ3XeW+A3/3d3/0urnqW+Xy+9ZCHPOQVP/MzP/O177vvvlu56qqrrrrqqv/d0IMe9CCuuuqqq6666qqrrrrqqv/brrnmmge/9mu/9nu90zu902cD/O7v/u53cdULdO211z58mqb2mZ/5ma/DVVddddVVV/3vRjl+/DhXXXXVVVddddVVV1111f8911xzzYPf7M3e7KM+/MM//Lvf6Z3e6bMvXLjw9Gc84xl//YxnPOOvueqFaq0NL/MyL/NmZ8+efcatt97611x11VVXXXXV/17oQQ96EFddddVVV1111VVXXXXV/x2v8zqv894v9mIv9lqv8zqv894Av/u7v/tdXPWvNp/Ptx784Ae/wmd91me9zn333XcrV1111VVXXfW/E+X48eNcddVVV1111VVXXXXVVf+7XXPNNQ9+szd7s4/63M/93N9+xVd8xbe+/fbb/+oZz3jGXz/jGc/4a676N5mmaXjsYx/7Opubm8f/9E//9Ge46qqrrrrqqv+d0IMe9CCuuuqqq6666qqrrrrqqv99rrnmmge/9mu/9nu9zuu8zntfc801D/7d3/3d7+Kq/1Dz+XzrFV/xFd/hMz/zM1/nH/7hH36bq6666qqrrvrfBz3oQQ/iqquuuuqqq6666qqrrvrf43Ve53Xe+8Ve7MVe63Ve53XeG+B3f/d3v4ur/tMcO3bsuuuvv/4xH/IhH/IQrrrqqquuuup/H/SgBz2Iq6666qqrrrrqqquuuup/tmuuuebBr/3ar/1e7/RO7/TZAL/7u7/7XVz1X+Y1X/M13+e3fuu3vvvrv/7r34errrrqqquu+t8FPehBD+Kqq6666qqrrrrqqquu+p/nmmuuefBrv/Zrv9frvM7rvPc111zzYIDf/d3f/S6u+i83n8+3XvEVX/EdPvMzP/N1/uEf/uG3ueqqq6666qr/PdCDHvQgrrrqqquuuuqqq6666qr/OV7sxV7stV/ndV7nvV7ndV7nvQF+93d/97u46r/dsWPHrrv++usf8yEf8iEP4aqrrrrqqqv+90APetCDuOqqq6666qqrrrrqqqv+e11zzTUPfu3Xfu33eqd3eqfPBvjd3/3d7+Kq/3Fe8zVf831+67d+67u//uu//n246qqrrrrqqv8dqFx11VVXXXXVVVddddVV/y2uueaaB7/2a7/2e73O67zOe19zzTUPBvjd3/3d7+Kq/7H+9E//9Mde7MVe7LVf7MVe7LX/4R/+4be56qqrrrrqqv/50IMe9CCuuuqqq6666qqrrrrqqv8611xzzYPf8R3f8bNe53Ve570Bfvd3f/e7uOp/jWuvvfbhJ06cuPlDPuRDHsJVV1111VVX/c9HOX78OFddddVVV1111VVXXXXVf65rrrnmwW/2Zm/2UZ/7uZ/722/+5m/+0bfffvtfPeMZz/jrZzzjGX/NVf+rHB4eXnjsYx/7OgD/8A//8DtcddVVV1111f9s6EEPehBXXXXVVVddddVVV1111X+8a6655sGv/dqv/V6v8zqv897XXHPNgwF+93d/97u46n+9+Xy+9eAHP/gVvuEbvuF9/v7v//63ueqqq6666qr/udCDHvQgrrrqqquuuuqqq6666qr/ONdcc82DX/u1X/u93umd3umzAX73d3/3u7jq/5xrr7324SdPnrzlgz/4gx/MVVddddVVV/3PRTl+/DhXXXXVVVddddVVV1111b/PNddc8+A3e7M3+6jP/dzP/e03f/M3/+gLFy48/RnPeMZfP+MZz/hrrvo/6fDw8MJjH/vY1wb4h3/4h9/hqquuuuqqq/5nQg960IO46qqrrrrqqquuuuqqq/71rrnmmge/9mu/9nu9zuu8zntfc801Dwb43d/93e/iqv835vP51oMf/OBX+KzP+qzXue++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fcatt97611x11VVXXXXVfx70oAc9iKuuuuqqq6666qqrrvr3uuaaax782q/92u/1Oq/zOu99zTXXPBjgd3/3d7+Lq6666vmaz+dbD37wg1/hsz7rs17nvvvuu5Wrrrrqqquu+s+BHvSgB3HVVVddddVVV1111VX/Vtdcc82D3/Ed3/GzXud1Xue9AX73d3/3u7jqqqteJA960INe+uDg4NJnfuZnvg5XXXXVVVdd9Z8DPehBD+Kqq6666qqrrrrqqqv+Na655poHv/Zrv/Z7vdM7vdNnA/zu7/7ud3HVVVf9q83n861XfMVXfIev//qvf5/f+q3f+m6uuuqqq6666j8eetCDHsRVV1111VVXXXXVVVf9S6655poHv/Zrv/Z7vc7rvM57X3PNNQ8G+N3f/d3v4qqrrvp3mc/nWw9+8INf4bM+67Ne57777ruVq6666qqrrvqPReWqq6666qqrrrrqqqteiGuuuebB7/iO7/hZr/M6r/PeAL/7u7/7XU94whO46qqr/mOsVquDa6655sHv+I7v+Flf//Vf/z5cddVVV1111X8s9KAHPYirrrrqqquuuuqqq656oGuuuebBr/3ar/1e7/RO7/TZAL/7u7/7XVx11VX/aebz+dYrvuIrvsNnfdZnvc7f//3f/zZXXXXVVVdd9R8HPehBD+Kqq6666qqrrrrqqquuueaaB7/2a7/2e73O67zOe19zzTUPBvjd3/3d7+Kqq676L3Hs2LHrbrjhhsd+8Ad/8IO56qqrrrrqqv846EEPehBXXXXVVVddddVVV/3/dc011zz4tV/7td/rnd7pnT4b4Hd/93e/i6uuuuq/xWu+5mu+z2/91m9999d//de/D1ddddVVV131HwM96EEP4qqrrrrqqquuuuqq/5muueaaB/MAZ86ceTAPcM011zyY5+PMmTMP4kXwTu/0Tp8N8Lu/+7vfxVVXXfXfbj6fb73iK77iO3zmZ37m6/zDP/zDb3PVVVddddVV/37oQQ96EFddddVVV1111VVX/ee45pprHgxw5syZB19zzTUPBjhz5syDAK655poHA1xzzTUP5pnOnDnzYIBrrrnmwfwX+N3f/d3v4qqrrvof5dixY9ddf/31j/mQD/mQh3DVVVddddVV/37oQQ96EFddddVVV1111VVXveiuueaaB585c+bB11xzzYPPnDnzIIBrrrnmwddcc82DAc6cOfPga6655sG8EL/7u7/7Xfw3mM/nW6/4iq/4Dlx11VX/o/3Wb/3Wd3/913/9+3DVVVddddVV/37oQQ96EFddddVVV1111VVXXXHNNdc8+MyZMw++5pprHnzmzJkHAbz4i7/4awO82Iu92GvzfPzu7/7ud/G/yIMe9KCX5n+RBz3oQS/DC3Dffffdes011zwY4L777rv17Nmzt95333233nfffbdy1VX/i/3DP/zD7/zDP/zDb3PVVVddddVV/37oQQ96EFddddVVV1111VX/X1xzzTUPPnPmzIOvueaaB585c+ZB11xzzYOvueaaB7/Yi73Ya/N8/O7v/u53cdX/eK/5mq/5PjyX++6779azZ8/eet99990K8A//8A+/c99999169uzZW++7775bueqqq6666qqrrvr/AT3oQQ/iqquuuuqqq6666v+Sa6655sEAL/ZiL/baZ86cedCLv/iLvzbAi73Yi702D/C7v/u738VV/2+85mu+5vvwTPfdd9+tAP/wD//w2wD/8A//8Dv33Xffrf/wD//w21x11VVXXXXVVVf934Ie9KAHcdVVV1111VVXXfW/0TXXXPPgM2fOPPjFXuzFXgvgxV/8xV/7xV7sxV6bB/jd3/3d7+Kqq/4Fr/mar/k+PNPZs2efcd999z39vvvuu/Uf/uEffue+++679ezZs7fed999t3LVVVddddVVV131vw960IMexFVXXXXVVVddddX/ZNdcc82DAV77tV/7vQBe/MVf/LVf7MVe7LV5gN/93d/9Lq666j/Ya77ma74Pz3Tffffdevbs2Vvvu+++W//hH/7hd+67775b/+Ef/uG3ueqqq6666qqrrvqfDT3oQQ/iqquuuuqqq6666n+Ka6655sFnzpx58Iu92Iu91jXXXPPg13md13lvHuB3f/d3v4urrvpv9pqv+ZrvwzPdd999t/7DP/zDb9933323/sM//MPv/MM//MNvc9VVV1111VVXXfU/B3rQgx7EVVddddVVV1111X+Ha6655sFnzpx58Iu92Iu91ou/+Iu/9ou92Iu9Ng/wu7/7u9/FVVf9L/Gar/ma78Mz3Xfffbf+wz/8w2/fd999t/7DP/zD7/zDP/zDb3PVVVddddVVV1313wM96EEP4qqrrrrqqquuuuq/wjXXXPPg137t134vgNd5ndd572uuuebBPNPv/u7vfhdXXfV/zGu+5mu+D89033333foP//APv/0P//APv3Pffffd+g//8A+/zVVXXXXVVVddddV/PvSgBz2Iq6666qqrrrrqqv9o11xzzYPPnDnz4Bd7sRd7rRd/8Rd/7Rd7sRd7bZ7pd3/3d7+Lq676f+o1X/M13wfgvvvuu/Xs2bO33nfffbf+1m/91vf8wz/8w29z1VVXXXXVVVdd9R8PPehBD+Kqq6666qqrrrrq3+uaa6558Iu92Iu99pkzZx704i/+4q/9Yi/2Yq/NM/3u7/7ud3HVVVe9QK/5mq/5PgD33Xffrf/wD//w2//wD//wO7/1W7/13Vx11VVXXXXVVVf9+6EHPehBXHXVVVddddVVV/1rXXPNNQ9+sRd7sdc+c+bMg17ndV7nva+55poHA/zu7/7ud3HVVVf9u7zma77m+wCcPXv2GX//93//W//wD//wO7/1W7/13Vx11VVXXXXVVVf966EHPehBXHXVVVddddVVV/1LrrnmmgefOXPmwS/2Yi/2Wi/+4i/+2i/2Yi/22gC/+7u/+11cddVV/6le8zVf830A7rvvvlv/4R/+4Xd+67d+67v/4R/+4be56qqrrrrqqquu+pehBz3oQVx11VVXXXXVVVc9P9dcc82DX/u1X/u9XvzFX/y1X+zFXuy1AX73d3/3u7jqqqv+W73ma77m+9x33323nj179ta///u//+1/+Id/+J1/+Id/+G2uuuqqq6666qqrnhd60IMexFVXXXXVVVdddRXANddc8+AzZ848+MVe7MVe653e6Z0+m2f63d/93e/iqquu+h/pNV/zNd8H4L777rv1H/7hH377H/7hH37nt37rt76bq6666qqrrrrqqivQgx70IK666qqrrrrqqv+/rrnmmge/9mu/9nu9+Iu/+Gu/2Iu92GsD/O7v/u53cdVVV/2v9Jqv+Zrvc99999169uzZZ/zWb/3Wd9933323/sM//MNvc9VVV1111VVX/X+FHvSgB3HVVVddddVVV/3/cs011zz4tV/7td/rdV7ndd77mmuueTDA7/7u734XV1111f8pr/mar/k+APfdd9+tv/Vbv/Xd//AP//A7//AP//DbXHXVVVddddVV/5+gBz3oQVx11VVXXXXVVf/3XXPNNQ9+7dd+7fd6p3d6p8/mmX73d3/3u7jqqqv+X3jN13zN9wG47777bv2Hf/iH3/6t3/qt7/mHf/iH3+aqq6666qqrrvq/Dj3oQQ/iqquuuuqqq676v+maa6558Gu/9mu/1zu90zt9NsDv/u7vfhdXXXXVVcBrvuZrvs9999136z/8wz/8zm/91m999z/8wz/8NlddddVVV1111f9F6EEPehBXXXXVVVddddX/Hddcc82DX/u1X/u93umd3umzAX73d3/3u7jqqquueiFe8zVf833uu+++W//hH/7ht3/rt37re/7hH/7ht7nqqquuuuqqq/6vQA960IO46qqrrrrqqqv+d7vmmmse/Nqv/drv9Tqv8zrvfc011zwY4Hd/93e/i6uuuuqqf6XXfM3XfJ+zZ88+4zd/8ze/6x/+4R9+5x/+4R9+m6uuuuqqq6666n8z9KAHPYirrrrqqquuuup/n2uuuebBr/3ar/1er/M6r/Pe11xzzYMBfvd3f/e7uOqqq676D/Car/ma7wNw33333fpbv/Vb3/2jP/qjn8NVV1111VVXXfW/EXrQgx7EVVddddVVV131v8c111zz4Hd8x3f8rNd5ndd5b4Df/d3f/S6uuuqqq/4TveZrvub7nD179hl///d//1v/8A//8Du/9Vu/9d1cddVVV1111VX/W6AHPehBXHXVVVddddVV/7Ndc801D37t137t93qnd3qnzwb43d/93e/iqquuuuq/wWu+5mu+z3333Xfrb/3Wb333b//2b3/PfffddytXXXXVVVddddX/ZOhBD3oQV1111VVXXXXV/0yv8zqv894v9mIv9lqv8zqv894Av/u7v/tdXHXVVVf9D/Car/ma7wPwD//wD7/9W7/1W9/zW7/1W9/NVVddddVVV131PxF60IMexFVXXXXVVVdd9T/HNddc8+DXfu3Xfq93eqd3+myA3/3d3/0urrrqqqv+B3vN13zN97nvvvtu/a3f+q3v/u3f/u3vue+++27lqquuuuqqq676nwI96EEP4qqrrrrqqquu+u93zTXXPPgd3/EdP+t1Xud13hvgd3/3d7+Lq6666qr/RV7zNV/zfc6ePfuMv//7v/+t3/qt3/qef/iHf/htrrrqqquuuuqq/27oQQ96EFddddVVV1111X+fd3zHd/ys13md13nva6655sG/+7u/+11cddVVV/0f8Jqv+Zrvc9999936W7/1W9/9oz/6o5/DVVddddVVV1313wU96EEP4qqrrrrqqquu+q91zTXXPPi1X/u13+ud3umdPhvgd3/3d7+Lq6666qr/g17zNV/zfc6ePfuM3/zN3/yuH/3RH/0crrrqqquuuuqq/2roQQ96EFddddVVV1111X+Na6655sGv/dqv/V7v9E7v9NkAv/u7v/tdXHXVVVf9P/Car/ma73Pffffd+lu/9Vvf/du//dvfc999993KVVddddVVV131XwE96EEP4qqrrrrqqquu+s91zTXXPPgd3/EdP+t1Xud13hvgd3/3d7+Lq6666qr/h17zNV/zfe67775b/+Ef/uF3fuu3fuu7/+Ef/uG3ueqqq6666qqr/jOhBz3oQVx11VVXXXXVVf85rrnmmge/4zu+42e9zuu8znv/7u/+7ndx1VVXXXXVs7zma77m+/zDP/zDb//Ij/zI5/zDP/zDb3PVVVddddVVV/1nQA960IO46qqrrrrqqqv+Y11zzTUPfsd3fMfPep3XeZ33/t3f/d3v4qqrrrrqqhfoNV/zNd/nvvvuu/Xrv/7r3+cf/uEffpurrrrqqquuuuo/EuX48eNcddVVV1111VX/Ma655poHf9InfdJPvc/7vM9X33777X/1jGc846+56qqrrrrqhXrGM57x1+fOnbv1vd/7vb/6mmuuefDh4eGls2fP3spVV1111VVXXfUfgXL8+HGuuuqqq6666qp/n2uuuebB7/M+7/NVH/7hH/7dT3jCE37rGc94xl9z1VVXXXXVv8oznvGMv44I3vu93/urr7nmmgcfHh5eOnv27K1cddVVV1111VX/HpTjx49z1VVXXXXVVVf921xzzTUPfrM3e7OP+qRP+qSfvv322//qGc94xl9z1VVXXXXVv8sznvGMv44I3vu93/urr7nmmofceuutf314eLjLVVddddVVV131b4Ee9KAHcdVVV1111VVX/etcc801D37t137t93qnd3qnzwb43d/93e/iqquuuuqq/xSPfvSjX+e3fuu3vvtHf/RHP4errrrqqquuuupfCz3oQQ/iqquuuuqqq6560b3jO77jZ73TO73TZwP87u/+7ndx1VVXXXXVf7rXfM3XfJ/77rvv1t/6rd/67h/90R/9HK666qqrrrrqqhcVetCDHsRVV1111VVXXfUve7EXe7HX/vAP//Dvuuaaax78u7/7u9/FVVddddVV/+Ve8zVf833Onj37jB/5kR/57N/6rd/6bq666qqrrrrqqn8JetCDHsRVV1111VVXXfWCXXPNNQ/+8A//8O96sRd7sdf+3d/93e/iqquuuuqq/3av+Zqv+T7/8A//8Ntf//Vf/z733XffrVx11VVXXXXVVS8I5fjx41x11VVXXXXVVc/fO77jO37WJ33SJ/30E57whN96xjOe8ddcddVVV131P8IznvGMv14ul7vv8A7v8Nmbm5vH/+Ef/uF3uOqqq6666qqrnh/0oAc9iKuuuuqqq6666jm92Iu92Gt/+Id/+Hddc801D/7d3/3d7+Kqq6666qr/sV7zNV/zfc6ePfuM3/zN3/yuH/3RH/0crrrqqquuuuqqB6IcP36cq6666qqrrrrqimuuuebB7/M+7/NV7/u+7/vVf/EXf/FTz3jGM/6aq6666qqr/kd7xjOe8dfnzp17+pu92Zt9zDXXXPPgW2+99W8ODw93ueqqq6666qqrANCDHvQgrrrqqquuuuoqeMd3fMfPeqd3eqfPBvjd3/3d7+Kqq6666qr/dV7zNV/zfe67775bf+u3fuu7f/RHf/RzuOqqq6666qqr0IMe9CCuuuqqq6666v+za6655sEf/uEf/l0v9mIv9tq/+7u/+11cddVVV131v95rvuZrvs8//MM//PbXf/3Xv8999913K1ddddVVV131/xfl+PHjXHXVVVddddX/V6/zOq/z3p/7uZ/7W094whN+6xnPeMZfc9VVV1111f8Jz3jGM/56uVzuvsM7vMNnb25uHv+Hf/iH3+Gqq6666qqr/n+iHD9+nKuuuuqqq676/+aaa6558Cd90if91Ju/+Zt/9O/+7u9+F1ddddVVV/2fdO7cuVvf7M3e7GOuueaaB996661/c3h4uMtVV1111VVX/f9COX78OFddddVVV131/8mLvdiLvfZXfMVX/NU111zz4N/93d/9Lq666qqrrvo/7RnPeMZfv/Zrv/b7vOIrvuJbb21tnfiHf/iH3+aqq6666qqr/v+gHD9+nKuuuuqqq676/+Id3/EdP+ud3umdPvsv/uIvfuoZz3jGX3PVVVddddX/C894xjP++ty5c7e+6Zu+6UcD/MM//MPvcNVVV1111VX/P6AHPehBXHXVVVddddX/dddcc82DP/zDP/y7XuzFXuy1f/d3f/e7uOqqq6666v+t13zN13yf++6779bP+qzPep377rvvVq666qqrrrrq/zbK8ePHueqqq6666qr/y17sxV7stb/iK77ir57whCf81jOe8Yy/5qqrrrrqqv/XnvGMZ/z1uXPnbn2Hd3iHz97c3Dz+D//wD7/DVVddddVVV/3fRTl+/DhXXXXVVVdd9X/VO77jO37WR3zER3z37/7u734XV1111VVXXfUA586du/XN3uzNPkaS/uEf/uG3ueqqq6666qr/m9CDHvQgrrrqqquuuur/mmuuuebBH/7hH/5dL/ZiL/bav/u7v/tdXHXVVVddddUL8Jqv+Zrvc9999936WZ/1Wa9z33333cpVV1111VVX/d9COX78OFddddVVV131f8k111zz4M/5nM/5rYc85CEv/bu/+7vfxVVXXXXVVVe9EM94xjP++rGPfezrvOIrvuJb/9mf/dnPHB4e7nLVVVddddVV/3dQjh8/zlVXXXXVVVf9X/FiL/Zir/0VX/EVf/UXf/EXP/WMZzzjr7nqqquuuuqqF8EznvGMvz537tyt7/AO7/DZm5ubx//hH/7hd7jqqquuuuqq/xsox48f56qrrrrqqqv+L3id13md9/6kT/qkn/rd3/3d7+Kqq6666qqr/g3OnTt365u92Zt9jCT9wz/8w29z1VVXXXXVVf/7UY4fP85VV1111VVX/W/34R/+4d/1Tu/0Tp/9u7/7u9/FVVddddVVV/07POMZz/jrN33TN/1ogH/4h3/4Ha666qqrrrrqfzfK8ePHueqqq6666qr/zT73cz/3t17xFV/xrX/3d3/3u7jqqquuuuqq/wDPeMYz/vrN3uzNPuaaa6558J/+6Z/+DFddddVVV131vxd60IMexFVXXXXVVVf9b/W5n/u5v/ViL/Zir/27v/u738VVV1111VVX/Qd7zdd8zfe57777bv2QD/mQh3DVVVddddVV/zsRXHXVVVddddX/Up/7uZ/7Wy/2Yi/22r/7u7/7XVx11VVXXXXVf4Lf/d3f/a5rrrnmwd/0Td/0dK666qqrrrrqfyeCq6666qqrrvpf5pprrnnw537u5/7Wi73Yi7327/7u734XV1111VVXXfWf6Hd/93e/65prrnnwN3/zN9/KVVddddVVV/3vQ3DVVVddddVV/4tcc801D37t137t93qxF3ux1/7d3/3d7+Kqq6666qqr/gv87u/+7nedOXPmQd/0Td/09GuuuebBXHXVVVddddX/HpTjx49z1VVXXXXVVf9bfNInfdJPvc7rvM57/+7v/u53cdVVV1111VX/hZ7xjGf89WMf+9jXecVXfMW3/rM/+7OfOTw83OWqq6666qqr/udDD3rQg7jqqquuuuqq/w0+93M/97de7MVe7LV/93d/97u46qqrrrrqqv8mr/mar/k+9913360f8iEf8hCuuuqqq6666n8+gquuuuqqq676X+BzP/dzf+vFXuzFXvt3f/d3v4urrrrqqquu+m/0u7/7u991zTXXPPibvumbns5VV1111VVX/c9HOX78OFddddVVV131P9nnfu7n/taLvdiLvfbv/u7vfhdXXXXVVVdd9T/AM57xjL9+7GMf+zrXXHPNg//0T//0Z7jqqquuuuqq/7kox48f56qrrrrqqqv+p/rwD//w73rFV3zFt/7d3/3d7+Kqq6666qqr/gd5xjOe8dev/dqv/T4A//AP//A7XHXVVVddddX/TJTjx49z1VVXXXXVVf8Tvc7rvM57v9M7vdNn/+7v/u53cdVVV1111VX/Az3jGc/46zd7szf7GIB/+Id/+B2uuuqqq6666n8eyvHjx7nqqquuuuqq/2le7MVe7LU/6ZM+6ad+93d/97u46qqrrrrqqv/BnvGMZ/z1K7zCK7zN0dHRpVtvvfWvueqqq6666qr/WSjHjx/nqquuuuqqq/4nueaaax78FV/xFX/1u7/7u9/FVVddddVVV/0vcO7cuVtf67Ve673/7M/+7GcODw93ueqqq6666qr/OdCDHvQgrrrqqquuuup/ks/93M/9rfPnzz+dq6666qqrrvpf5tGPfvTrfMiHfMhDuOqqq6666qr/OQiuuuqqq6666n+Qz/3cz/2tF3uxF3ttrrrqqquuuup/oWuuuebBH/7hH/5dXHXVVVddddX/HJTjx49z1VVXXXXVVf8TvNiLvdhrv9M7vdNn/+7v/u53cdVVV1111VX/Cz3jGc/469d+7dd+H4B/+Id/+B2uuuqqq6666r8f5fjx41x11VVXXXXVf7drrrnmwV/xFV/xV7/7u7/7XVx11VVXXXXV/2LPeMYz/voVXuEV3ubWW2/9m7Nnz97KVVddddVVV/33Qg960IO46qqrrrrqqv9un/u5n/tb58+ffzpXXXXVVVdd9X/Eox/96Nf5kA/5kIdw1VVXXXXVVf+9CK666qqrrrrqv9k7vuM7ftaLvdiLvTZXXXXVVVdd9X/INddc8+B3fMd3/Cyuuuqqq6666r8X5fjx41x11VVXXXXVf5cXe7EXe+2P+IiP+O7f/d3f/S6uuuqqq6666v+QZzzjGX/9Cq/wCm9z6623/s3Zs2dv5aqrrrrqqqv+e6AHPehBXHXVVVddddV/l8/93M/9rfPnzz+dq6666qqrrvo/aD6fbz34wQ9+hQ/5kA95CFddddVVV13134Pgqquuuuqqq/6bvM7rvM57v9iLvdhrc9VVV1111VX/R61Wq4Nrrrnmwa/zOq/z3lx11VVXXXXVfw/0oAc9iKuuuuqqq6767/ATP/ET/t3f/d3v4qqrrrrqqqv+D5vP51sPechDXvGDP/iDH8xVV1111VVX/dcjuOqqq6666qr/Bu/4ju/4WVx11VVXXXXV/wOr1ergzJkzD/rwD//w7+Kqq6666qqr/usRXHXVVVddddV/sWuuuebB7/RO7/TZv/u7v/tdXHXVVVddddX/A3/6p3/6Yy/2Yi/22tdcc82Dueqqq6666qr/WpTjx49z1VVXXXXVVf+V3ud93uerhmHYPzw8vMBVV1111VVX/T8wTdNQSqm33HLLS/7pn/7pz3DVVVddddVV/3UIrrrqqquuuuq/0DXXXPPg13md13nve++99ylcddVVV1111f8jly5duud1Xud13vvFXuzFXpurrrrqqquu+q9DOX78OFddddVVV131X+V93ud9vmoYhv3Dw8MLXHXVVVddddX/I9M0DavV6uD06dO3/Omf/unPcNVVV1111VX/NQiuuuqqq6666r/INddc8+DXeZ3Xee977733KVx11VVXXXXV/0OXLl2658Ve7MVe+5prrnkwV1111VVXXfVfg+Cqq6666qqr/ou84zu+42dx1VVXXXXVVf+PrVarg2uuuebB7/iO7/hZXHXVVVddddV/DSpXXXXVVVdd9V/kdV7ndd77d3/3d7+Lq6666qqrrvp/7E//9E9/7MVe7MVem6uuuuqqq676r0Fw1VVXXXXVVf8FXud1Xue9ueqqq6666qqrWK1WB9dcc82DX+d1Xue9ueqqq6666qr/fARXXXXVVVdd9V/gdV7ndd7rd3/3d7+Lq6666qqrrrqKP/3TP/2x13md13lvrrrqqquuuuo/H8FVV1111VVX/Sd7sRd7sdd+sRd7sdfmqquuuuqqq666bLVaHbzYi73Ya73Yi73Ya3PVVVddddVV/7kIrrrqqquuuuo/2eu8zuu8F1ddddVVV1111fN4sRd7sdfiqquuuuqqq/5zEVx11VVXXXXVf7IXe7EXe+3f/d3f/S6uuuqqq6666qpn+d3f/d3vep3XeZ335qqrrrrqqqv+cxFcddVVV1111X+ya6655sFcddVVV1111VXP45prrnnwi73Yi702V1111VVXXfWfh+Cqq6666qqr/hO9zuu8zntz1VVXXXXVVVe9QC/2Yi/2Wlx11VVXXXXVfx6Cq6666qqrrvpP9GIv9mKv9bu/+7vfxVVXXXXVVVdd9Tx+93d/97te/MVf/LW56qqrrrrqqv88BFddddVVV131n+h1Xud13purrrrqqquuuuoFOnPmzIO56qqrrrrqqv88BFddddVVV131n+TFXuzFXpurrrrqqquuuuqFuuaaax78Yi/2Yq/NVVddddVVV/3nILjqqquuuuqq/yTXXHPNg7nqqquuuuqqq/5FL/ZiL/ZaXHXVVVddddV/DoKrrrrqqquu+k/yYi/2Yq/1u7/7u9/FVVddddVVV131Av3u7/7ud734i7/4a3PVVVddddVV/zkIrrrqqquuuuo/yYu92Iu9NlddddVVV1111VVXXXXVVVf9dyK46qqrrrrqqv8k11xzzYO56qqrrrrqqqv+RWfOnHkwV1111VVXXfWfg8pVV1111VVXXXXVVVddddVV/62uueaaB3PVVVddddVV/zkIrrrqqquuuuo/wYu92Iu9NlddddVVV1111YvsxV7sxV6bq6666qqrrvqPR+Wqq6666qqrrrrqqquuuuqqq6666qqrrvq/iuCqq6666qqr/hNcc801D+aqq6666qqrrnqRXXPNNQ/mqquuuuqqq/7jUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVV/wnOnDnzIK666qqrrrrqqhfZmTNnHsRVV1111VVX/cejctVVV1111VVXXXXVVVddddV/q9/93d/9Lq666qqrrrrqPweVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yqCq6666qqrrrrqqquuuuqqq/5bveZrvub7nD179hlcddVVV1111X88KlddddVVV131n+R3f/d3v4urrrrqqquuuupFcubMmQdx1VVXXXXVVf/xCK666qqrrrrqP8HZs2ef8Zqv+Zrvw1VXXXXVVVdd9SI5e/bsM7jqqquuuuqq/3hUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddV/gvvuu+9WrrrqqquuuuqqF9l99913K1ddddVVV131H4/KVVddddVVV/0nOHv27K1cddVVV1111VUvsrNnz97KVVddddVVV/3Ho3LVVVddddVVV1111VVXXXXVf7v77rvvVq666qqrrrrqPx6Vq6666qqrrvpPcN99991633333cpVV1111VVXXXXVVVddddVV/52oXHXVVVddddV/krNnz97KVVddddVVV131L/qt3/qt7+aqq6666qqr/nMQXHXVVVddddV/kr//+7//ba666qqrrrrqqn/RfffddytXXXXVVVdd9Z+D4Kqrrrrqqqv+k/zDP/zD77zma77m+3DVVVddddVVV71Ar/mar/k+Z8+efQZXXXXVVVdd9Z+DylVXXXXVVVf9Jzl79uytXHXVVVddddVV/6J/+Id/+G2uuuqqq6666j8Hlauuuuqqq676T3Lffffd+g//8A+/zVVXXXXVVVdd9ULdd999t3LVVVddddVV/zmoXHXVVVddddVVV1111VVXXfXf5rd+67e+m6uuuuqqq676z0Nw1VVXXXXVVf+JfuRHfuRzXvM1X/N9uOqqq6666qqrnsdrvuZrvs8//MM//A5XXXXVVVdd9Z+HylVXXXXVVVf9J/qHf/iH3+aqq6666qqrrnqBfuu3fuu7ueqqq6666qr/PFSuuuqqq6666j/ZP/zDP/w2V1111VVXXXXV8/it3/qt7+aqq6666qqr/nMRXHXVVVddddV/st/6rd/6ntd8zdd8H6666qqrrrrqqmd5zdd8zff5h3/4h9/hqquuuuqqq/5zUbnqqquuuuqq/2T/8A//8NtcddVVV1111VXP4x/+4R9+m6uuuuqqq676z0Xlqquuuuqqq/6T3Xfffbf+wz/8w29z1VVXXXXVVVc9y2/91m99z3333XcrV1111VVXXfWfi+Cqq6666qqr/gv8yI/8yOecOnXqIVx11VVXXXXVVbzma77m+/zWb/3Wd3PVVVddddVV//moXHXVVVddddV/gbNnz97KVVddddVVV1112X333XfrP/zDP/w2V1111VVXXfWfj+Cqq6666qqr/gvcd999t/7Wb/3W97zma77m+3DVVVddddVV/4+95mu+5vv86I/+6Odw1VVXXXXVVf81qFx11VVXXXXVf5F/+Id/+O377rvvVq666qqrrrrq/7nf+q3f+m6uuuqqq6666r8GwVVXXXXVVVf9F7nvvvtu/dEf/dHPec3XfM334aqrrrrqqqv+H3rN13zN9/mRH/mRz+aqq6666qqr/utQueqqq6666qr/Qv/wD//w21x11VVXXXXV/2M/+qM/+jlcddVVV1111X8dgquuuuqqq676L3Tffffd+lu/9Vvf/Zqv+Zrvw1VXXXXVVVf9P/Kar/ma7/MjP/Ijn81VV1111VVX/dciuOqqq6666qr/Yj/6oz/6Offdd9+tXHXVVVddddX/Mz/6oz/6OVx11VVXXXXVfy2Cq6666qqrrvovdt999936oz/6o5/zmq/5mu/DVVddddVVV/0/8Jqv+Zrv8/Vf//Xvw1VXXXXVVVf91yO46qqrrrrqqv8Gv/Vbv/Xd//AP//DbXHXVVVddddX/A/fdd9+tv/Vbv/XdXHXVVVddddV/PYKrrrrqqquu+m/y9V//9e/zmq/5mu/DVVddddVVV/0f9pqv+Zrv8/Vf//Xvw1VXXXXVVVf99yC46qqrrrrqqv8m9913362/9Vu/9d2v+Zqv+T5cddVVV1111f9Br/mar/k+v/Vbv/Xd//AP//DbXHXVVVddddV/D4Krrrrqqquu+m/0oz/6o59z33333cpVV1111VVX/R9033333fr1X//178NVV1111VVX/fchuOqqq6666qr/Rvfdd9+tP/qjP/o5r/mar/k+XHXVVVddddX/Ia/5mq/5Pl//9V//Plx11VVXXXXVfy/K8ePHueqqq6666qr/TrfeeutfA7zZm73ZxzzjGc/4a6666qqrrrrqf7nXfM3XfJ/f+q3f+u5f+IVf+Bquuuqqq6666r8X5fjx41x11VVXXXXVf7ezZ88+4yEPechLL5fLXa666qqrrrrqf7nFYnHisz7rs16Hq6666qqrrvrvR3DVVVddddVV/wPcd999t37913/9+7zma77m+3DVVVddddVV/4u95mu+5vt8/dd//ftw1VVXXXXVVf8zUI4fP85VV1111VVX/U9weHi4e/bs2We8wzu8w2c/4xnP+Guuuuqq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/fVf//Xvw1VXXXXVVVf9/4Me9KAHcdVVV1111VX/X11zzTUP/vAP//DverEXe7HX/t3f/d3v4qqrrrrqqv8zXvM1X/N97rvvvlu//uu//n3+4R/+4be56qqrrrrqqv+fKMePH+eqq6666qqr/r86PDzc/Yd/+IffOTw83H2zN3uzj3nGM57x11x11VVXXfW/3mu+5mu+z4/8yI989pd+6Ze+zdmzZ2/lqquuuuqqq/7/Qg960IO46qqrrrrqqqvgmmuuefA7vuM7ftbrvM7rvPfv/u7vfhdXXXXVVVf9r/Oar/ma7/MP//APv/31X//173PffffdylVXXXXVVVddRTl+/DhXXXXVVVdddRUcHh7u3nrrrX9zeHi4+2Zv9mYf86AHPehlnvGMZ/w1V1111VVX/Y/3mq/5mu+zWCxO/PzP//xXf/3Xf/37HB4e7nLVVVddddVVVwGgBz3oQVx11VVXXXXVVc/pmmuuefBrv/Zrv9c7vdM7ffbv/u7vfhdXXXXVVVf9j/War/ma7/MP//APv/2Zn/mZr8NVV1111VVXXfXc0IMe9CCuuuqqq6666qrn75prrnnw53zO5/zWNddc8+Df/d3f/S6uuuqqq676H+M1X/M13+e+++679eu//uvf5x/+4R9+m6uuuuqqq6666vmhHD9+nKuuuuqqq6666vk7PDzc/bM/+7OfOTw83H2zN3uzj3nQgx70Ms94xjP+mquuuuqqq/7bvOZrvub7LBaLEz//8z//1V/6pV/6NmfPnr2Vq6666qqrrrrqBUEPetCDuOqqq6666qqr/mXXXHPNg1/7tV/7vd7pnd7ps3/3d3/3u7jqqquuuuq/3Gu+5mu+z4/8yI989o/+6I9+DlddddVVV1111YsCPehBD+Kqq6666qqrrnrRXXPNNQ/+8A//8O96sRd7sdf+3d/93e/iqquuuuqq/3Sv+Zqv+T7/8A//8Ntf//Vf/z733XffrVx11VVXXXXVVS8q9KAHPYirrrrqqquuuupf75prrnnwh3/4h3/Xi73Yi7327/7u734XV1111VVX/Yd7zdd8zfe57777bv36r//69/mHf/iH3+aqq6666qqrrvrXQg960IO46qqrrrrqqqv+7V7ndV7nvd7xHd/xs6+55poH/+7v/u53cdVVV1111b/ba77ma77Pfffdd+tv/dZvffeP/uiPfg5XXXXVVVddddW/FXrQgx7EVVddddVVV13173PNNdc8+LVf+7Xf63Ve53Xe+5prrnnw7/7u734XV1111VVX/au95mu+5vvcd999t/7Wb/3Wd//oj/7o53DVVVddddVVV/17oQc96EFcddVVV1111VX/Ma655poHv9iLvdhrf/iHf/h3Afzu7/7ud3HVVVddddW/6DVf8zXf57777rv1t37rt777R3/0Rz+Hq6666qqrrrrqPwp60IMexFVXXXXVVVdd9R/rzJkzD3qd13md936d13md977mmmse/Lu/+7vfxVVXXXXVVc/jNV/zNd/nvvvuu/W3fuu3vvtHf/RHP4errrrqqquuuuo/GnrQgx7EVVddddVVV131n+Oaa6558Iu92Iu99ju+4zt+1jXXXPPg3/3d3/0urrrqqquu4jVf8zXf57777rv1t37rt777R3/0Rz+Hq6666qqrrrrqPwt60IMexFVXXXXVVVdd9Z/rmmuuefCLvdiLvdbrvM7rvPeLvdiLvfbv/u7vfhdXXXXVVf8PveZrvub73Hfffbf+1m/91nf/6I/+6Odw1VVXXXXVVVf9Z0MPetCDuOqqq6666qqr/uu8zuu8znu/zuu8znudOXPmwU94whN+i6uuuuqq/wde8zVf833uu+++W3/0R3/0c37rt37ru7nqqquuuuqqq/6roAc96EFcddVVV1111VX/9a655poHv+M7vuNnvc7rvM57A/zu7/7ud3HVVVdd9X/Ia77ma74PwI/8yI989m//9m9/z3333XcrV1111VVXXXXVfzX0oAc9iKuuuuqqq6666r/PNddc8+DXfu3Xfq93eqd3+myA3/3d3/0urrrqqqv+F3vN13zN97nvvvtu/a3f+q3v/tEf/dHP4aqrrrrqqquu+u+EHvSgB3HVVVddddVVV/33u+aaax78Yi/2Yq/9Oq/zOu/1Yi/2Yq/9u7/7u9/FVVddddX/Iq/5mq/5Pvfdd9+tv/Vbv/XdP/qjP/o5XHXVVVddddVV/xOgBz3oQVx11VVXXXXVVf+zXHPNNQ9+x3d8x896ndd5nfcG+N3f/d3v4qqrrrrqf6DXfM3XfB+AH/mRH/nsf/iHf/idf/iHf/htrrrqqquuuuqq/0nQgx70IK666qqrrrrqqv+Zrrnmmge/9mu/9nu9zuu8zntfc801D/7d3/3d7+Kqq6666n+A13zN13yf++6779bf+q3f+u4f/dEf/Ryuuuqqq6666qr/qdCDHvQgrrrqqquuuuqq//le7MVe7LVf53Ve571e53Ve570Bfvd3f/e7uOqqq676L/Sar/ma7wPwIz/yI5/9D//wD7/zD//wD7/NVVddddVVV131Px160IMexFVXXXXVVVdd9b/HNddc8+AXe7EXe+3XeZ3Xea8Xe7EXe22A3/3d3/0urrrqqqv+E7zma77m+wDcd999t/7Wb/3Wd//oj/7o53DVVVddddVVV/1vgh70oAdx1VVXXXXVVVf973TNNdc8+LVf+7Xf63Ve53Xe+5prrnnw7/7u734XV1111VX/AV7zNV/zfe67775bf+u3fuu7f/u3f/t77rvvvlu56qqrrrrqqqv+N0IPetCDuOqqq6666qqr/ve75pprHvyO7/iOn/U6r/M67w3wu7/7u9/FVVddddW/wmu+5mu+z3333Xfrb/3Wb333P/zDP/zOP/zDP/w2V1111VVXXXXV/3boQQ96EFddddVVV1111f8d11xzzYNf7MVe7LVf7MVe7LVe53Ve570Bfvd3f/e7uOqqq656Pl7zNV/zfe67775bf+u3fuu7/+Ef/uF3/uEf/uG3ueqqq6666qqr/i9BD3rQg7jqqquuuuqqq/5vuuaaax585syZB73O67zOe7/O67zOewP87u/+7ndx1VVX/b/2mq/5mu9z33333foP//APv/0P//APv/1bv/Vb38NVV1111VVXXfV/FXrQgx7EVVddddVVV131f98111zz4DNnzjz4dV7ndd7rdV7ndd6bZ/rd3/3d7+Kqq676P+81X/M13+e+++679bd+67e++x/+4R9+5x/+4R9+m6uuuuqqq6666v8D9KAHPYirrrrqqquuuur/lzNnzjzommuuecjrvM7rvNc111zz4Bd7sRd7bYDf/d3f/S6uuuqq/xNe8zVf830A7rvvvlt/67d+67v/4R/+4Xf+4R/+4be56qqrrrrqqqv+v0EPetCDuOqqq6666qqr/n+75pprHvxiL/Zir/U6r/M67/1iL/Zirw3wu7/7u9/FVVdd9b/Ka77ma74PwH333Xfrb/3Wb333b//2b3/PfffddytXXXXVVVddddX/Z+hBD3oQV1111VVXXXXVVfe75pprHvxiL/Zir/1iL/Zir/ViL/Zir33NNdc8GOB3f/d3v4urrrrqf5TXfM3XfB+A++6779Z/+Id/+O377rvv1h/90R/9HK666qqrrrrqqqueDT3oQQ/iqquuuuqqq6666gW55pprHvzar/3a7/XiL/7ir/1iL/Zirw3wu7/7u9/FVVdd9V/uNV/zNd+HZ/qHf/iH3/77v//73/6Hf/iH3/mHf/iH3+aqq6666qqrrrrq+UMPetCDuOqqq6666qqrrnpRXHPNNQ9+sRd7sdd6sRd7sde+5pprHvxiL/Zirw3wu7/7u9/FVVdd9Z/iNV/zNd8H4L777rv1t37rt777H/7hH377H/7hH36Hq6666qqrrrrqqhcNetCDHsRVV1111VVXXXXVv8U111zz4Bd7sRd77Rd7sRd7rWuuuebBL/ZiL/baAL/7u7/7XVx11VX/Jq/5mq/5PgD33Xffrb/1W7/13QA/+qM/+jlcddVVV1111VVX/dugBz3oQVx11VVXXXXVVVf9R7jmmmse/GIv9mKv/WIv9mKvdc011zz4xV7sxV6bZ/rd3/3d7+Kqq656Dq/5mq/5PjzTfffdd+tv/dZvffc//MM//M4//MM//DZXXXXVVVddddVV/zHQgx70IK666qqrrrrqqqv+M1xzzTUPPnPmzINf7MVe7LVe/MVf/LVf7MVe7LV5pt/93d/9Lq666v+Z13zN13wfgPvuu+/Ws2fP3vr3f//3v/0P//APv/MP//APv81VV1111VVXXXXVfw70oAc9iKuuuuqqq6666qr/Ktdcc82DX+zFXuy1X+zFXuy1rrnmmge/2Iu92GvzTL/7u7/7XVx11f8Rr/mar/k+PNN9991362/91m99N8Bv//Zvf8999913K1ddddVVV1111VX/NdCDHvQgrrrqqquuuuqqq/67nDlz5kGS9GIv9mKv/WIv9mKvdc011zz4xV7sxV6bZ/rd3/3d7+Kqq/6He83XfM334Znuu+++W3/rt37ruwH+4R/+4Xf+4R/+4be56qqrrrrqqquu+u+DHvSgB3HVVVddddVVV131P8mZM2cedM011zzkmmuuefCLvdiLvdY111zz4Bd7sRd7bR7gd3/3d7+Lq676L/aar/ma78MD3Hfffbf+1m/91ncD/MM//MPv/MM//MNvc9VVV1111VVXXfU/C3rQgx7EVVddddVVV1111f8G11xzzYPPnDnz4GuuuebBL/ZiL/Za11xzzYNf7MVe7LV5gN/93d/9Lq666t/pNV/zNd+HB7jvvvtu/Yd/+Iffvu+++249e/bsM/7hH/7ht++7775bueqqq6666qqrrvqfDz3oQQ/iqquuuuqqq6666n+ra6655sEAL/ZiL/baZ86cedA111zz4GuuuebBL/ZiL/baPMDv/u7vfhdXXfVcXvM1X/N9eKb77rvvVoB/+Id/+O377rvv1n/4h3/4nbNnz95633333cpVV1111VVXXXXV/17oQQ96EFddddVVV1111VX/F11zzTUPPnPmzIOvueaaB73Yi73YawNcc801D36xF3ux1+a5/O7v/u53cdX/Oa/5mq/5PjyX++6779azZ8/e+vd///e/DfAP//APv/MP//APv81VV1111VVXXXXV/03oQQ96EFddddVVV1111VX/35w5c+ZB11xzzUOuueaaB585c+ZB11xzzYOvueaaB585c+bB11xzzYN5Lr/7u7/7XVz1P85rvuZrvg/P5b777rv17Nmzt95333233nfffbeePXv2Gffdd9+t//AP//DbXHXVVVddddVVV/3/gx70oAdx1VVXXXXVVVddddVzuuaaax4M8GIv9mKvBejFXuzFXgvgmmuuefCZM2ceDHDNNdc8mOfyu7/7u9/FVf9ur/mar/k+PJf77rvvVoCzZ8/eet99991633333Qpw9uzZW++7775nnD179tb77rvvVq666qqrrrrqqquueiD0oAc9iKuuuuqqq6666qqr/vWuueaaBwOcOXPmwddcc82DAJ05c+ZB11xzzYMBrrnmmgcDnDlz5sHXXHPNg/kX/O7v/u538X/Ia77ma74P/4L77rvvVoCzZ8/eCnDffffdet99990KcPbs2Vvvu+++Z5w9e/bW++6771auuuqqq6666qqrrvq3QA960IO46qqrrrrqqquuuuo/3zXXXPNg277mmmseAnDNNdc8mCt85syZBwNcc801D+aZrrnmmgcDnDlz5sE80zXXXPNg/pvdd999t/IAZ8+evZVnuu+++24F+Id/+IffOXPmzIMAzp49+4z77rvvVoCzZ8/eattnz559BlddddVVV1111VVX/VdAD3rQg7jqqquuuuqqq6666n+va6655sE8gG1L0pkzZx7MsxkQz8mAzp49eyvPZNuSxAPcd999t3LVVVddddVVV1111f9W6EEPehBXXXXVVVddddVVV1111VVXXXXVVVddddX/SVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KfwS1lbqCz04iTwAAAABJRU5ErkJggg==) + diff --git a/docs/kcl/polygon.md b/docs/kcl/polygon.md index de75c3538a..9e84c5e8a3 100644 --- a/docs/kcl/polygon.md +++ b/docs/kcl/polygon.md @@ -55,6 +55,6 @@ square = startSketchOn('XY') example = extrude(5, square) ``` -![Rendered example of polygon 1](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAADIcUlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666v+Na6655sEA9913361cddVVV1111VVXXfX/AZWrrrrqqquuuuqqq/7Puuaaax782q/92u8F8E7v9E6ffd99993KM/3DP/zDb//DP/zD7/zWb/3Wd3PVVVddddVVV1111f9V6EEPehBXXXXVVVddddVVV/3fcc011zz4tV/7td/rdV7ndd77mmuueTAvgvvuu+/Wf/iHf/jt3/qt3/qef/iHf/htrrrqqquuuuqqq676vwI96EEP4qqrrrrqqquuuuqq/72uueaaB7/2a7/2e734i7/4a7/Yi73Ya/MAFy5c4MKFCzz1qU/lz/7sz3ijN3ojAH7lV36Fhz3sYTz84Q/nFV7hFXig++6779Z/+Id/+O1/+Id/+J377rvv1n/4h3/4ba666qqrrrrqqquu+t8KPehBD+Kqq6666qqrrrrqqv89rrnmmgefOXPmwS/2Yi/2Wu/0Tu/02TyXCxcu8Gd/9mc85SlP4alPfSr/kpMnT3LixAke/vCH87CHPYyHP/zhPNB999136z/8wz/89j/8wz/8zm/91m99N1ddddVVV1111VVX/W+CHvSgB3HVVVddddVVV1111f9s11xzzYNf+7Vf+71e/MVf/LVf7MVe7LV5gAsXLvDUpz6VCxcu8Cu/8iv8e508eZKHPexhPPzhD+cVXuEVeKD77rvv1rNnz97693//97/9D//wD7/zD//wD7/NVVddddVVV1111VX/k6EHPehBXHXVVVddddVVV131P8s111zz4Nd+7dd+L4B3eqd3+myey4ULF/izP/sznvrUp/LUpz6V/0wnT57k5V/+5Xn4wx/Owx72MB7ovvvuu/Uf/uEffvsf/uEffue3fuu3vpurrrrqqquuuuqqq/6nQQ960IO46qqrrrrqqquuuuq/3zXXXPPg137t136vF3/xF3/tF3uxF3ttHuDChQv82Z/9GRcvXuTP/uzP+O9y8uRJHvawh/Gwhz2MkydP8rCHPYwHuu+++279rd/6re/+h3/4h9/5h3/4h9/mqquuuuqqq6666qr/buhBD3oQV1111VVXXXXVVVf917vmmmse/Nqv/drv9eIv/uKv/WIv9mKvzXN56lOfylOe8hT+/M//nAsXLvA/0cmTJ3nYwx7GK7zCK/Cwhz2MB7rvvvtu/Yd/+Iff/od/+Iffue+++279h3/4h9/mqquuuuqqq6666qr/auhBD3oQV1111VVXXXXVVVf957vmmmsefObMmQe/2Iu92Gu9zuu8zntfc801D+YBLly4wJ/92Z/x1Kc+lac+9an8b3Py5ElOnDjBwx72MB7+8IfzsIc9jAe67777bv2Hf/iH3/6Hf/iH3/mt3/qt7+aqq6666qqrrrrqqv8K6EEPehBXXXXVVVddddVVV/3nuOaaax782q/92u/14i/+4q/9Yi/2Yq/NA1y4cIGnPvWpXLhwgV/91V/l/5qTJ0/ysIc9jIc97GG8wiu8Ag9033333Xr27Nlb//7v//63/+Ef/uF3/uEf/uG3ueqqq6666qqrrrrqPwN60IMexFVXXXXVVVddddVV/zGuueaaB7/Yi73Ya585c+ZB7/RO7/TZPJcLFy7w53/+5zz1qU/lqU99Ki+Ibf4vOXnyJAAv//Ivz8Mf/nAe9rCH8UD33Xffrf/wD//w2//wD//wO7/1W7/13Vx11VVXXXXVVVdd9R8FPehBD+Kqq6666qqrrrrqqn+7a6655sGv/dqv/V4v/uIv/tov9mIv9to8wIULF/jzP/9zAH71V3+V/21s85/h5MmTPOxhD+NhD3sYD3vYwzh58iQPdN999936W7/1W9/9D//wD7/zD//wD7/NVVddddVVV1111VX/VuhBD3oQV1111VVXXXXVVVe96K655poHv/Zrv/Z7XXPNNQ9+ndd5nffmuVy4cIE///M/58/+7M+4ePEiV/3LTpw4wcMe9jBe4RVegYc97GE80H333XfrP/zDP/z2P/zDP/zOfffdd+s//MM//DZXXXXVVVddddVVV72o0IMe9CCuuuqqq6666qqrrnrhXuzFXuy1X+zFXuy1Xud1Xue9r7nmmgfzABcuXODP//zPeepTn8pTn/pUrvr3OXHiBCdPnuTlX/7lOXnyJA972MN4oPvuu+/Wf/iHf/jt3/qt3/qef/iHf/htrrrqqquuuuqqq656YdCDHvQgrrrqqquuuuqqq656Ttdcc82DX/u1X/u9XvzFX/y1X+zFXuy1eYALFy5w8eJFnvrUp/Krv/qrXPWf68SJEzzsYQ/jYQ97GK/wCq/AA9133323nj179ta///u//+1/+Id/+J1/+Id/+G2uuuqqq6666qqrrnog9KAHPYirrrrqqquuuuqq/++uueaaB7/Yi73Ya585c+ZB7/RO7/TZPJcLFy7w53/+5zz1qU/lqU99Klf99zhx4gQAr/AKr8DDHvYwHvawh/FA9913363/8A//8Nv/8A//8Du/9Vu/9d1cddVVV1111VVXXYUe9KAHcdVVV1111VVXXfX/0TXXXPPg137t136vF3/xF3/tF3uxF3ttHuDChQv8+Z//OQC/+qu/ylX/M504cYKHPexhPOxhD+MVXuEVeKD77rvvVoDf+q3f+u5/+Id/+J1/+Id/+G2uuuqqq6666qqr/v9BD3rQg7jqqquuuuqqq676/+Caa6558Gu/9mu/F8A7vdM7fTbP5eLFi/zZn/0ZT3va03jqU5/K/za2+f/uxIkTPOxhD+MVXuEVeNjDHsYD3Xfffbf+wz/8w2//wz/8w+/8wz/8w2/fd999t3LVVVddddVVV131fx960IMexFVXXXXVVVddddX/Vddcc82DX/u1X/u9Xud1Xue9r7nmmgfzABcvXuTP/uzPeNrTnsZTn/pUrvq3s83/NCdOnOBhD3sYD3vYwzh58iQPe9jDeKD77rvv1n/4h3/47d/6rd/6nn/4h3/4ba666qqrrrrqqqv+b0IPetCDuOqqq6666qqrrvq/4pprrnnwa7/2a7/Xi7/4i7/2i73Yi702D3Dx4kUuXLjAU5/6VP78z/+cixcvctX/Hrb59zhx4gQPe9jDeNjDHsYrvMIr8ED33XffrWfPnr31t37rt77nvvvuu/Uf/uEffpurrrrqqquuuuqq/xvQgx70IK666qqrrrrqqqv+t7rmmmsefObMmQe/2Iu92Gu90zu902fzXC5evMif/dmf8bSnPY2nPvWpXHUVwIkTJzh58iQPfehDedjDHsbDHvYwHui+++679R/+4R9++x/+4R9+57d+67e+m6uuuuqqq6666qr/vdCDHvQgrrrqqquuuuqqq/43ueaaax782q/92u/14i/+4q/9Yi/2Yq/NA1y8eJE/+7M/A+DXfu3XuOqqF8WJEyd42MMexsMe9jBe/uVfnge67777bj179uytf//3f//b//AP//A7//AP//DbXHXVVVddddVVV/3vgR70oAdx1VVXXXXVVVdd9T/ZNddc8+DXfu3Xfi+Ad3qnd/psnsvFixf5sz/7M572tKfx1Kc+lauu+vc6ceIEL//yL8/DHvYwHvawh/FA9913363/8A//8Nv/8A//8Du/9Vu/9d1cddVVV1111VVX/c+GHvSgB3HVVVddddVVV131P80111zz4Nd+7dd+rxd/8Rd/7Rd7sRd7bR7g4sWL/Pmf/zkXL17kz//8z/n/wDZX/fc4ceIED3vYw3jYwx7GiRMneNjDHsYD3Xfffbf+wz/8w2//1m/91vf8wz/8w29z1VVXXXXVVVdd9T8LetCDHsRVV1111VVXXXXVf7drrrnmwa/92q/9Xi/+4i/+2i/2Yi/22jyXpz71qTztaU/jz//8z7l48SJX/fewzf93J06c4GEPexgv//Ivz8Me9jAe6L777rv1H/7hH377H/7hH37nvvvuu/Uf/uEffpurrrrqqquuuuqq/17oQQ96EFddddVVV1111VX/1a655poHnzlz5sEv9mIv9lqv8zqv897XXHPNg3mAixcv8ud//uc89alP5WlPexpX/f9im/8NTpw4wcmTJ3noQx/Kwx72MB72sIfxQPfdd9+t//AP//Db//AP//A7v/Vbv/XdXHXVVVddddVVV/3XQw960IO46qqrrrrqqquu+q9wzTXXPPi1X/u13+vFX/zFX/vFXuzFXpsHuHjxIk996lO5ePEiv/Zrv8ZVV/1Hs81/thMnTvCwhz2Mhz3sYbz8y788D3Tffffdevbs2Vv//u///rf/4R/+4Xf+4R/+4be56qqrrrrqqquu+s+HHvSgB3HVVVddddVVV131n+Gaa6558Iu92Iu99pkzZx70Tu/0Tp/Nc7l48SJ//ud/zlOf+lSe9rSncdVV/5vY5l9y4sQJXv7lX56HPexhPOxhD+OB7rvvvlv/4R/+4bf/4R/+4Xd+67d+67u56qqrrrrqqquu+s+BHvSgB3HVVVddddVVV131H+Waa6558Gu/9mu/14u/+Iu/9ou92Iu9Ng9w8eJF/vzP/xyAX/u1X+Oqq/4/OXHiBA972MN46EMfysMe9jBOnDjBA9133323/tZv/dZ3/8M//MPv/MM//MNvc9VVV1111VVXXfUfAz3oQQ/iqquuuuqqq6666t/qmmuuefBrv/Zrv9c111zz4Nd5ndd5b57LxYsX+fM//3P+4i/+gosXL3LVc7LNVf8/nThxgoc97GG83Mu9HA972MN4oPvuu+/Wf/iHf/jtf/iHf/id++6779Z/+Id/+G2uuuqqq6666qqr/m3Qgx70IK666qqrrrrqqqv+NV7sxV7stV/sxV7stV7ndV7nva+55poH8wAXL17kz//8z3na057G0572NK7638k2V/3XOXHiBCdOnODlX/7lOXHiBA972MN4oPvuu+/Wf/iHf/jt3/qt3/qef/iHf/htrrrqqquuuuqqq1506EEPehBXXXXVVVddddVVL8w111zz4Nd+7dd+rxd/8Rd/7Rd7sRd7bR7g4sWLXLx4kac+9an8+q//Oldd9a9lm6ue04kTJ3jYwx7GQx/6UF7+5V+eB7rvvvtuPXv27K1///d//9v/8A//8Dv/8A//8NtcddVVV1111VVXvWDoQQ96EFddddVVV1111VUPdM011zz4xV7sxV77zJkzD3qnd3qnz+a5XLx4kT//8z/naU97Gk972tO46qr/iWzzf8GJEycAePmXf3ke+tCH8rCHPYwHuu+++279h3/4h9/+h3/4h9/5rd/6re/mqquuuuqqq6666jmhBz3oQVx11VVXXXXVVVddc801D37t137t93rxF3/x136xF3ux1+YBLl68yJ//+Z8D8Ou//utcddX/R7b5n+DEiRM87GEP46EPfSgv//IvzwPdd999twL81m/91nf/wz/8w+/8wz/8w29z1VVXXXXVVVf9f4ce9KAHcdVVV1111VVX/f9zzTXXPPi1X/u13wvgnd7pnT6b53Lx4kX+/M//nL/4i7/g4sWLXHXVVf9+tvmPduLECR72sIfxci/3cjzsYQ/jge67775b/+Ef/uG3/+Ef/uF3/uEf/uG377vvvlu56qqrrrrqqqv+v0EPetCDuOqqq6666qqr/n+45pprHvzar/3a7/U6r/M6733NNdc8mAe4ePEif/EXf8HTnvY0nva0p3HVv51trrrqP4NtXpgTJ07wsIc9jIc+9KGcOHGChz3sYTzQfffdd+s//MM//PZv/dZvfc8//MM//DZXXXXVVVddddX/B+hBD3oQV1111VVXXXXV/03XXHPNg1/7tV/7vV78xV/8tV/sxV7stXmAixcvcvHiRZ72tKfx67/+61z1/5Ntrvq/68SJEzz0oQ/lYQ97GC/3ci/HA9133323nj179tbf+q3f+p777rvv1n/4h3/4ba666qqrrrrqqv+L0IMe9CCuuuqqq6666qr/G6655poHnzlz5sEv9mIv9lrv9E7v9Nk8l4sXL/IXf/EXPO1pT+NpT3saV131X802V/33OHHiBCdOnOChD30oD3vYw3joQx/KA9133323/sM//MNv/8M//MPv/NZv/dZ3c9VVV1111VVX/V+BHvSgB3HVVVddddVVV/3vdc011zz4tV/7td/rxV/8xV/7xV7sxV6bB7h48SJ/8Rd/AcCv//qvc9VV/5fZ5qoX3YkTJ3joQx/Kwx72MF7u5V6OB7rvvvtuBfit3/qt7/6Hf/iH3/mHf/iH3+aqq6666qqrrvrfCj3o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fydJ/EeRxH8ESQBsbW0BcPbs2Wdw1VVXXXXVVVf9WxBcddVVV1111VX/Jv/wD//wOwA333wzV131f40k/qeQxL+GJP41JPGiksR/N0m8qCTxH0kS/1EkcdVVV1111VVX/ZcguOqqq6666qqrrrrqqn8nSfxrSOJfQxL/GpL4zyKJF5UkXlSSeFFJ4kUliReFJF4UkviXSOI/giS2trYAuO+++27lqquuuuqqq676tyC46qqrrrrqqqv+Tc6ePXsrwLFjx7jqqv+LJPGvIYl/DUn8a0jiP4sk/rNI4kUlif8rJPEvkcS/ZGtrC4CzZ8/eylVXXXXVVVdd9W9BcNVVV1111VVXXXXVVS+AJP41JPE/hST+NSTxopLEfzdJvKgk8aKQxItCEv9Vtre3ueqqq6666qqr/l0Irrrqqquuuuqqf5P77rvvVoBjx45x1VX/l0niP4sk/jUk8a8hif8sknhRSeJFJYkXlSReVJJ4UUjiP4ok/iWSeFHcd999t3LVVVddddVVV/1bEFx11VVXXXXVVf9m9913360Ax44d46qrrrpCEv8akvjXkMS/hiReVJL415DEi0oSLypJ/E8nif9sW1tbANx33323ctVVV1111VVX/VsRXHXVVVddddVV/2Znz569FWBnZ4er/veQxP93kvjXkMS/hiT+NSTxP4Uk/jeRxItKEi8KSbwoJPEvkcS/RBLPz9bWFgBnz569lauuuuqqq6666t+K4Kqrrrrqqquuuuqq/1SS+J9IEv8akvjXkMR/Fkn8a0jiX0MSLypJvKgk8aKSxItKEi8qSbwoJPHfbWtrC4D77rvvVq666qqrrrrqqn8rgquuuuqqq6666t/svvvuuxXglltu4aqr/jeSxP8UkvjXkMS/hiT+s0jiRSWJF5Uk/qeTxL9EEv8SSVx11VVXXXXVVf8pCK666qqrrrrqqn+z++6771b+n5PEVf9/SOJfQxL/GpL415DEfxZJ/GeRxH80SbyoJPGikMR/FEn8a21tbQFw33333cpVV1111VVXXfVvRXDVVVddddVVV/2bnT179hkAx44d46qr/reSxL+GJP41JPGvIYn/LJL415DEi0oS/xkk8aKSxItKEv9RJPEfQRIPtL29DcDZs2efwVVXXXXVVVdd9W9FcNVVV1111VVX/Zvdd999twLs7Oxw1VX/m0niX0MS/xqS+M8iiX8NSfxrSOJFJYkXlSReVJL47yKJF4Uk/iWSuOqqq6666qqr/ssRXHXVVVddddVVV131f44k/rUk8T+FJP41JPGvIYn/LJJ4UUniRSWJF4UkXlSSeFFI4r+KJO533XXXAfAP//APv81VV1111VVXXfVvRXDVVVddddVVV/2bnT179laAY8eOcdVV/99I4l9DEv8akvjXkMS/hiReVJL4zyKJ/2iSeFFJ4j+KJP4lkviXSOKqq6666qqrrvoPQ3DVVVddddVVV/2b3XfffbcCHDt2jKuu+r9AEv8akvjXkMS/hiT+NSTxn0USLypJ/GeQxH8XSfxX29raAuC+++67lauuuuqqq6666t+K4Kqrrrrqqquu+ne57777bgU4duwYV/3fIYn/ryTxryGJfw1J/E8hiX8NSbyoJPGiksSLShIvCkm8qCTxopDEv0QS/xJJ/EskcdVVV1111VVX/YcguOqqq6666qqr/l3Onj17K8DOzg7/20jiqqueH0n8TyGJfw1J/GtI4j+LJF5UkviPJon/ra677joAzp49+wyuuuqqq6666qp/D4Krrrrqqquuuuqqq676d5LEv4Yk/jUk8a8hiX8NSbyoJPHfTRL/0STxopDEv0QS/xJJvDBbW1sA/P3f//1vc9VVV1111VVX/XsQXHXVVVddddVV/y733XffrQDHjh3jqqv+L5HEv4Yk/jUk8a8hiX8NSfxnkcSLShIvKkm8qCTxopDEi0oS/1Ek8S+RxFVXXXXVVVdd9Z+O4Kqrrrrqqquu+ne57777bgU4duwYV131n00S/5Uk8a8hiX8NSfxrSOI/iyT+NSTxopLEi0oSLypJvCgk8R9JEv/Ztra2ALjvvvuezlVXXXXVVVdd9e9BcNVVV1111VVXXXXVVS+EJP41JPE/hST+NSTxn0USLypJ/EeTxItCEi8KSfxLJPEvkcTzs7W1BcDZs2efwVVXXXXVVVdd9e9BcNVVV1111VVX/bv8wz/8w+8A3HzzzVx11f8WkvifQhL/GpL415DEv4YkXlSS+O8mif9okrjqqquuuuqqq/7PILjqqquuuuqqq6666qp/gST+NSTxryGJfw1J/GtI4l9DEi8qSbyoJPGiksSLShIvCkn8R5LEv0QS/xJJPLetrS0Azp49eytXXXXVVVddddW/B8FVV1111VVXXfXvcvbs2VsBjh07xlVX/W8iiX8NSfxrSOJfQxL/GpL415DEfxZJvKgk8aKSxH80SbwoJPEfRRL/WltbWwDcd999t3LVVVddddVVV/17EFx11VVXXXXVVVf9N5PE/0aS+N9OEv8akvjXkMS/hiT+NSTxn0US/xqSeFFJ4kUliReFJP6jSeJfIon/CJJ4oK2tLa666qqrrrrqqv8QVK666qqrrrrqqn+X++6771aAY8eOcezYMXZ2drj99tu56qr/LSRhmxeVJGzzopKEbV5UkrDNfwZJ2OZFJQnb/G8hCdv8SyRhm/8okrDNCyMJ2/xLrrvuOh7ovvvuu5Wrrrrqqquuuurfg+Cqq6666qqrrvp3u++++24F+KAP+iDe9E3flKuu+teSxH8nSfxvJYl/DUn8a0jiRSWJF5UkXlSS+I8miReFJP6rSOLVX/3VeeM3fmMA7rvvvlu56qqrrrrqqqv+vQiuuuqqq6666qp/tx/90R/9HK666v8RSfxrSOJfQxL/GpL415DEv4YkXlSSeFFJ4kUliReFJP6jSeJfIol/iSRemK2tLe655x7u96M/+qOfw1VXXXXVVVdd9e9FcNVVV1111VVX/bv9wz/8w2//wz/8w28DHDt2jHd+53fm2LFjXHXV/yaS+NeQxL+GJP41JPGvIYl/DUn8Z5HEi0oSLypJvCgk8aKQxH8kSfxbbW1t8Wqv9mo8/OEPB+C+++679R/+4R9+m6uuuuqqq6666t+Lcvz4ca666qqrrrrqqn+fw8PD3X/4h3/4ncPDw90Xf/EXf+1jx47xiEc8gtlsxu23384LIokXRhIvjCReGEm8MJL4l0jihZHEv0QSL4wkXhSS+JdI4l8iiX+JJP4lknhRSOJfIokXhSReFJJ4fl72ZV8WgCc84Qk8P5L415DEv4Yk/jUk8a8hiX8NSbyoJPGfRRL/0STxopDEi0IS/xEk8dxe6qVeitd93ddla2uL++6779af//mf/+ov/dIvfZvDw8Ndrrrqqquuuuqqfy/K8ePHueqqq6666qqr/v0ODw93/+Ef/uF3fvu3f/t7Dg8Pd1/u5V7utW+55RZe/MVfnPvuu4+9vT2emyReGEm8MJJ4YSTxwkjiXyKJF0YS/xJJvDCSeFFI4l8iiX+JJP4lkviXSOJFIYl/iSReFJJ4UUji+XnZl31ZAJ7whCfwgkjiX0MS/xqS+NeQxL+GJP6zSOJFJYn/DJL47yKJf4kk/iWSALjuuut4ozd6I2655RYAfuu3fuu7P+uzPut1/uEf/uF3uOqqq6666qqr/qOgBz3oQVx11VVXXXXVVf/xrrnmmgd/zud8zm9dc801Dwb4+7//e/7wD/+QS5cucT9JvDCSeGEk8cJI4oWRxL9EEi+MJF4YSfxLJPGikMQLI4kXhST+JZL4l0jiRSGJf4kkXhSSeFFI4vl5v/d7PwB++qd/mn+JbV5UtvnXsM2/hm3+NWzzr2Gbfw3bvKhs86KyzYvKNi8K27wobPOisM2/xDYvzNbWFi/1Ui/Fwx72MADuu+++W7/+67/+ff7hH/7ht7nqqquuuuqqq/6jUY4fP85VV1111VVXXfUf7/DwcPfP/uzPfubw8HD3xV/8xV/7mmuu4eEPfziz2Yzbb78dAEm8MJJ4YSTxwkjihZHECyOJf4kkXhhJ/Esk8S+RxL9EEv8SSbwoJPEvkcSLQhL/Ekm8KCTxopDE8/OyL/uyADzhCU/gP5Ik/jUk8a8hiX8NSfxrSOJfQxIvKkm8qCTxH00SLwpJvCgk8S+RxAvyUi/1UrzO67wOJ0+eBOBHfuRHPvtLv/RL3+bs2bO3ctVVV1111VVX/WegHD9+nKuuuuqqq6666j/H4eHh7j/8wz/8zm//9m9/z+Hh4e7LvdzLvfYtt9zCi7/4i3Pfffext7fHCyOJF0YSL4wkXhhJvDCS+JdI4oWRxL9EEv8SSfxLJPEvkcSLQhL/Ekn8SyTxopDEi0ISLwpJPD8v+7IvC8ATnvAE/iWS+NeQxL+GJP41JPGvIYl/DUn8Z5HEi0oSLwpJ/E8miQfa2tritV/7tXn4wx8OwD/8wz/89od8yIc85B/+4R9+h6uuuuqqq6666j8T5fjx41x11VVXXXXVVf+5Dg8Pd//hH/7hd/7hH/7hd17sxV7stU+dOnX8xV/8xQG4dOkS6/Wa50cSL4wkXhhJvDCSeGEk8S+RxAsjiX+JJP4lkviXSOJfIokXhST+JZL4l0jiRSGJF4UkXhSSeH5e9mVfFoAnPOEJvCgk8a8hiX8NSfxrSOJfQxL/GpJ4UUniv5skXhSSeFFI4kUhiRfV1tYWj3nMY3id13kdtra2uO+++279ki/5krf50R/90c/hqquuuuqqq676r0A5fvw4V1111VVXXXXVf42zZ8/e+md/9mc/c3h4uPviL/7ir33zzTfz8Ic/nPl8zu23385zk8QLI4kXRhIvjCReGEn8SyTxwkjiXyKJf4kk/iWS+JdI4kUhiX+JJP4lknhRSOJFIYkXhSSen5d92ZcF4AlPeAIvKkn8a0jiX0MS/xqS+NeQxL+GJF5UknhRSeJFJYkXlSReFJJ4UUjiRSGJf8lLvdRL8Tqv8zpcd911APzIj/zIZ3/pl37p25w9e/ZWrrrqqquuuuqq/yqU48ePc9VVV1111VVX/dc5PDzc/Yd/+Iff+e3f/u3vechDHvLSN99884NvvvlmXuzFXoynPOUprNdr7ieJF0YSL4wkXhhJvDCS+JdI4oWRxL9EEv8SSfxLJPEvkcS/RBIvCkn8SyTxopDEi0ISLwpJPD8v+7IvC8ATn/hE/jUk8a8hiX8NSfxrSOJfQxL/WSTxopLEi0oS/9Ek8V9ha2uL137t1+ZhD3sYAP/wD//w25/1WZ/1On/6p3/6M1x11VVXXXXVVf/VKMePH+eqq6666qqrrvqvd3h4uPtbv/Vb33P27NlnPPjBD37pU6dOHX/4wx/OfD7n9ttvB0ASL4wkXhhJvDCSeGEk8S+RxAsjiX+JJP4lkviXSOJfIol/iSReFJL4l0jiRSGJF4Uk/iWSeEFe9mVfFoAnPvGJSOJfQxL/GpL415DEv4Yk/rNI4l9DEi8qSbyoJPGikMR/JEm8KCTx3F7yJV+S137t12Zra4v77rvv1u/6ru/6mO/6ru/6mMPDw12uuuqqq6666qr/DpTjx49z1VVXXXXVVVf997n11lv/+s/+7M9+5vDwcPflXu7lXvvmm2/mxV7sxZjP59xxxx28MJJ4YSTxwkjihZHEv0QSL4wk/iWS+JdI4l8iiX+JJP4lknhRSOJfIokXhSReFJL4l0jiBXnZl31ZAJ74xCcCIIn/LyTxryGJ/yyS+I8miReFJF4UknhRSALg2muv5W3f9m257rrrAPiRH/mRz/7SL/3St7n11lv/mquuuuqqq6666r8T5fjx41x11VVXXXXVVf+9Dg8Pd//hH/7hd377t3/7ex7ykIe89M033/zgm2++mZtvvpnbb7+d9XrN8yOJF0YSL4wkXhhJ/Esk8cJI4l8iiX+JJP4lkviXSOJfIokXhST+JZJ4UUjiXyKJF4UkXpCXfdmXBeCJT3wi/xaS+NeQxL+GJP41JPGvIYl/DUm8qCTxn0ESLypJvCgk8R9lc3OT137t1+alXuqlALjvvvtu/ZIv+ZK3+e3f/u3v4aqrrrrqqquu+p+Acvz4ca666qqrrrrqqv8ZDg8Pd3/rt37rewBe/MVf/LWPHTvGIx7xCObzObfffjvPTRIvjCReGEm8MJL4l0jihZHEv0QS/xJJ/Esk8S+RxL9EEi8KSfxLJPGikMS/RBIvCkm8IC/7si8LwBOf+ETuJ4l/DUn8a0jiX0MS/xqS+NeQxL+GJF5UknhRSeJFJYn/DpJ4YV7yJV+S137t12Zra4v77rvv1p//+Z//6i/90i99m7Nnz97KVVddddVVV131PwXl+PHjXHXVVVddddVV/7P8wz/8w+/89m//9vccHh7uvtzLvdxr33zzzbz4i7846/Was2fPcj9JvDCSeGEk8cJI4l8iiRdGEv8SSfxLJPEvkcS/RBL/Ekn8SyTxopDEi0IS/xJJvCgk8YK87Mu+LABPfOITeSBJ/GtI4l9DEv8akvjXkMS/hiT+NSTxopLEi0oSLypJvCgk8aKQxItCEs/t2muv5Q3e4A24+eabAfiRH/mRz/7SL/3St/mHf/iH3+Gqq6666qqrrvqfhnL8+HGuuuqqq6666qr/eQ4PD3f/4R/+4Xd++7d/+3te8RVf8a1Pnjx5/OEPfzjHjh3jvvvuY71eI4kXRhIvjCReGEm8MJL4l0jiXyKJf4kk/iWS+JdI4l8iiX+JJF4UkviXSOJFIYkXhSRekJd92ZcF4IlPfCLPTRL/GpL415DEv4Yk/jUk8a8hif8sknhRSeJFJYkXhSReFJL419jc3OTlX/7lefmXf3n6vue+++679Uu+5Eve5rd/+7e/h6uuuuqqq6666n8qyvHjx7nqqquuuuqqq/7nOjw83P3TP/3Tnz48PNx98Rd/8de+5ppreMQjHsF8PueOO+7ghZHECyOJF0YSL4wk/iWS+JdI4l8iiX+JJP4lkviXSOJfIokXhST+JZJ4UUjiRSGJF+RlX/ZlAXjiE5/I8yOJfw1J/GtI4l9DEv8akvjXkMSLShL/GpJ4UUniP5okXhSS+JdI4iVf8iV57dd+bU6ePAnAj/zIj3z2l37pl77N2bNnb+Wqq6666qqrrvqfjHL8+HGuuuqqq6666qr/2Y6Oji79wz/8w+/89m//9vccHh7uvtzLvdxr33zzzbzYi70Y9913H3t7ezw/knhhJPHCSOKFkcS/RBIvjCReFJL4l0jiXyKJf4kk/iWSeFFI4l8iiReFJF4UknhBXvZlXxaAJz7xibwgkvjXkMS/hiT+NSTxryGJfw1JvKgk8d9NEv+VNjc3ebM3ezNuvvlmAP7hH/7htz/kQz7kIf/wD//wO1x11VVXXXXVVf8bUI4fP85VV1111VVXXfW/w+Hh4e4//MM//M4//MM//M6LvdiLvfbJkyePv9iLvRgAe3t7rNdrHkgSL4wkXhhJvDCS+JdI4oWRxItCEv8SSfxLJPEvkcS/RBIvCkn8SyTxopDEi0ISL8jLvuzLAvDEJz6RF0YS/xqS+NeQxL+GJP41JPGfRRIvKkm8qCTxopLEi0ISLwpJPLfNzU0e/ehH81qv9Vr0fc99991365d8yZe8zY/+6I9+DlddddVVV1111f8mlOPHj3PVVVddddVVV/3vcvbs2Vv/9E//9KcPDw93X/zFX/y1b775Zh7+8Iczm8244447uJ8kXhhJvDCSeGEk8S+RxAsjiReFJP4lkviXSOJfIol/iSReFJL4l0jiRSGJF4UkXpCXfdmXBeCJT3wi/9tI4j+LJP41JPGiksSLShIvKkm8KCTxopDE/V7iJV6C13qt1+Laa68F4Ed+5Ec++0u/9Evf5uzZs7dy1VVXXXXVVVf9b0M5fvw4V1111VVXXXXV/z5HR0eX/uEf/uF3fvu3f/t7HvKQh7z0zTff/OCbb76ZF3uxF+MpT3kK6/UaSbwwknhhJPHCSOJfIokXRhIvCkm8MJL4l0jiRSGJf4kk/iWSeFFI4kUhiReFJF6Ql33ZlwXgiU98Iv8SSfxrSOJfQxL/mSTxryGJfw1JvKgk8aKSxH80SbwoNjc3ea3Xei0e9rCHAfAP//APv/1Zn/VZr/Onf/qnP8NVV1111VVXXfW/FeX48eNcddVVV1111VX/ex0eHu7+1m/91vecPXv2GQ9+8INf+uTJk8cf/vCHM5vNuOOOO3hhJPHCSOKFkcS/RBIvjCT+JZL4l0jiXyKJF4Uk/iWS+JdI4kUhiReFJF4UknhBXvZlXxaAJz7xibwoJPGvIYl/DUn8a0jiX0MS/xqS+NeQxItKEi8qSbwoJPEfYXNzk0c/+tG81mu9FltbW9x33323ftd3fdfHfNd3fdfHHB4e7nLVVVddddVVV/1vRjl+/DhXXXXVVVddddX/frfeeutf/+mf/ulPHx4e7r7cy73ca99888282Iu9GPP5nDvuuIPnRxIvjCReGEn8SyTxwkjiXyKJf4kk/iWS+JdI4kUhiX+JJF4UknhRSOJFIYkX5GVf9mUBeOITn8iLShL/GpL415DEv4Yk/jUk8a8hif8sknhRSeJFIYkXhSSen2uuuYY3fdM35dprrwXgR37kRz77S7/0S9/m1ltv/Wuuuuqqq6666qr/CyjHjx/nqquuuuqqq676v+Ho6OjSP/zDP/zOb//2b3/PQx7ykJe++eabH3zTTTfxYi/2Yjz1qU9lvV7zQJJ4YSTxwkjihZHEv0QS/xJJ/Esk8S+RxL9EEi8KSfxLJPGikMSLQhL/Ekm8MC/7si8LwJOe9CT+NSTxryGJfw1J/GtI4l9DEv8aknhRSeJfQxL/0STxopDE/TY3N3nN13xNXvIlXxKA++6779aP//iPf5k//dM//Rmuuuqqq6666qr/SyjHjx/nqquuuuqqq676v+Xw8HD3t37rt74H4JprrnnwyZMnjz/84Q9nNptxxx13cD9JvDCSeGEk8cJI4l8iiX+JJP4lkviXSOJfIokXhST+JZJ4UUjiXyKJF4UkXpiXfdmXBeCJT3wikvjXkMS/hiT+NSTxryGJfw1J/GtI4kUlif8MknhRSeJFIYmXeImX4DVf8zXZ2trivvvuu/Xnf/7nv/pLv/RL3+bw8HCXq6666qqrrrrq/xrK8ePHueqqq6666qqr/m/6h3/4h9/50z/9058+PDzcfbmXe7nXvvnmm3mxF3sx1us1586d418iiRdGEi+MJP4lkviXSOJfIol/iST+JZL4l0jiRSGJF4Uk/iWSeFFI4oV52Zd9WQCe+MQnAiCJfw1J/GtI4l9DEv8akvjXkMS/hiReVJJ4UUniRSWJ/yjXXHMNr/d6r8dNN90EwI/8yI989pd+6Ze+zT/8wz/8DlddddVVV1111f9VlOPHj3PVVVddddVVV/3fdXR0dOkf/uEffue3f/u3v+cVX/EV3/rkyZPHH/7wh7Ozs8PZs2dZr9e8IJJ4YSTxwkjiXyKJf4kk/iWS+JdI4l8iiX+JJF4UkviXSOJFIYkXhSRemJd92ZcF4IlPfCL3k8S/hiT+NSTxryGJfw1J/GtI4l9DEi8qSbyoJPGiksSLQhLPz+bmJq/5mq/JS7zES9D3Pffdd9+tX/IlX/I2v/3bv/09XHXVVVddddVV/9dRjh8/zlVXXXXVVVdd9X/f4eHh7p/92Z/9zOHh4e6Lv/iLv/aZM2d42MMexmw244477uD5kcQLI4kXRhL/Ekn8SyTxL5HEv0QS/xJJ/Esk8aKQxL9EEi8KSbwoJPHCvOzLviwAT3ziE3kgSfxrSOJfQxL/GpL415DEv4Yk/rNI4kUliReVJF4UknigF3/xF+c1X/M12dzcBOBHfuRHPvtLv/RL3+bs2bO3ctVVV1111VVX/X9AOX78OFddddVVV1111f8Ph4eHu//wD//wO7/1W7/13YeHh7sv93Iv99o33XQTj33sYzl79ix7e3vcTxL/Ekm8MJL4l0jiXyKJf4kk/iWS+JdI4l8iiReFJP4lknhRSOJFIYkX5mVf9mUBeOITn8hzk8S/hiT+NSTxryGJfw1J/GtI4kUliX8NSbyoJPEfTRKbm5u8yZu8CTfddBMA//AP//DbH/IhH/KQf/iHf/gdrrrqqquuuuqq/0/Qgx70IK666qqrrrrqqv+frrnmmgd/zud8zm9dc801Dwb44z/+Yx73uMext7eHJP4lknhhJPEvkcS/RBL/Ekn8SyTxL5HEv0QSLwpJ/Esk8aKQxItCEi/M+73f+wHwsz/7s7wgtvnXsM2/hm3+NWzzr2Gbfw3bvKhs869hmxeVbV4UtnlhNjc3echDHsKLv/iLA3Dffffd+vVf//Xv8w//8A+/zVVXXXXVVVdd9f8R5fjx41x11VVXXXXVVf8/HR4e7v7Zn/3ZzxweHu6++Iu/+GvfdNNNPOxhD2M2m3HnnXfyL5HECyOJf4kk/iWS+JdI4l8iiX+JJP4lkviXSOJFIYkXhSReFJJ4YV72ZV8WgCc+8Ym8IJL415DEv4Yk/jUk8a8hiX8NSbyoJPHfTRIvyIu/+IvzGq/xGlxzzTUA/MiP/Mhnf+mXfunbnD179lauuuqqq6666qr/ryjHjx/nqquuuuqqq676/+vw8HD3H/7hH37nt37rt757c3Pz+KMf/eiXvummm3jsYx/LuXPn2Nvb4wWRxAsjiRdGEi8KSbwwkviXSOJFIYl/iST+JZJ4UUjiRSGJF4UkXpiXfdmXBeCJT3wi/50k8a8hiX8NSfxnkcSLShIvKkm8qCTxQJubm7zGa7wGD3nIQwD4h3/4h9/+zM/8zNf+sz/7s5/hqquuuuqqq676/45y/Phxrrrqqquuuuqqq46Oji796Z/+6c+cPXv2GQ9+8INf+uTJk8dvuukmZrMZd955J89NEv8SSbwwknhRSOKFkcS/RBL/Ekm8KCTxL5HEi0ISLwpJvCgk8cK87Mu+LABPfOITeWEk8a8hif9skvjXkMSLShL/GpJ4UUniRSWJF5UkNjc3edSjHsVrvMZrsLm5yX333Xfrl3zJl7zNj/7oj37O0dHRJa666qqrrrrqqquAcvz4ca666qqrrrrqqqvud+utt/71n/3Zn/3M4eHh7su93Mu99k033cRjH/tYZrMZd955J/eTxL9EEi+MJP4lkviXSOJfIol/iSReFJL4l0jiRSGJF4Uk/iWS+Je87Mu+LABPfOIT+ZdI4l9DEv8akvjXksS/hiReVJL415DEi0oSLypJvCge8pCH8Lqv+7pcc801APzIj/zIZ3/pl37p25w9e/ZWrrrqqquuuuqqq56Ncvz4ca666qqrrrrqqqse6PDwcPcf/uEffue3fuu3vvshD3nIS998880Pvummm3jsYx/L0572NNbrNZL4l0jihZHEv0QS/xJJ/Esk8S+RxItCEv8SSbwoJPEvkcSLQhL/kpd92ZcF4IlPfCIvCkn8a0jiX0MS/5NI4l9DEi8qSbyoJPGCbG5u8uqv/uo88pGPBOC+++679eM+7uNe+s/+7M9+hquuuuqqq6666qrnRTl+/DhXXXXVVVddddVVz8/R0dGl3/qt3/oegGuuuebBJ0+ePP6whz2M2WzGnXfeyb9EEi+MJP4lkviXSOJfIol/iST+JZJ4UUjiRSGJf4kkXhSS+Je87Mu+LABPfOITeVFJ4l9DEv8akvjXkMS/hiT+NSTxryGJF5UkXlSSeG4v9mIvxqu/+quzubnJfffdd+vP//zPf/WXfumXvs3R0dElrrrqqquuuuqqq54/yvHjx7nqqquuuuqqq656Yf7hH/7hd/7sz/7sZw4PD3df7uVe7rVvuukmHvOYxzCbzbjzzjt5QSTxwkjiXyKJf4kk/iWS+JdI4l8iiReFJP4lknhRSOJFIYl/ycu+7MsC8KQnPYl/DUn8a0jiX0MS/xqS+NeQxL+GJP41JPGiksS/1jXXXMPrvM7rcNNNNwHwIz/yI5/9pV/6pW/zD//wD7/DVVddddVVV1111QtHOX78OFddddVVV1111VX/ksPDw91/+Id/+J3f+q3f+u6HPOQhL33zzTc/+KabbmJnZ4dz586xXq95IEn8SyTxL5HEv0QS/xJJ/Esk8S+RxItCEv8SSbwoJPGikMS/5GVf9mUBeNKTnoQk/jUk8a8hiX8NSfxrSOJfQxL/GpL4zyKJF8XW1hav9mqvxou/+IvT9z333XffrV/yJV/yNr/927/9PVx11VVXXXXVVVe9aCjHjx/nqquuuuqqq6666kV1dHR06R/+4R9+5/DwcPfFX/zFX/vMmTM89KEPZTabceedd3I/SfxLJPEvkcS/RBL/Ekn8SyTxL5HEi0IS/xJJvCgk8aKQxL/kZV/2ZQF40pOeBIAk/jUk8a8hiX8NSfxrSOJfQxL/GpJ4UUniP9KLvdiL8Wqv9mpsbm5y33333frzP//zX/2lX/qlb3P27Nlbueqqq6666qqrrnrRUY4fP85VV1111VVXXXXVv8bh4eHuP/zDP/zOb//2b3/P4eHh7su93Mu99k033cRjHvMYzp49y/7+PpL4l0jiXyKJf4kk/iWS+JdI4l8iiX+JJF4UknhRSOJFIYl/ycu+7MsC8KQnPYn7SeJfQxL/GpL415DEv4Yk/jUk8a8hiReVJF5Uknh+zpw5w+u8zutw4403AvAP//APv/3xH//xL/MP//APv8NVV1111VVXXXXVvx560IMexFVXXXXVVVddddW/x5kzZx70uZ/7ub99zTXXPBjg8Y9/PH/6p3/K3t4eL4wk/iWS+JdI4l8iiX+JJP4lkviXSOJFIYkXhSReFJL4l7zf+70fAD/3cz/Hc7PNv4Zt/jVs869hm38N2/xr2OZfwzYvKtu8qGwDsLm5yYMf/GBe7MVeDID77rvv1q//+q9/n3/4h3/4ba666qqrrrrqqqv+7SjHjx/nqquuuuqqq6666t/j6Ojo0p/92Z/9zOHh4e6Lv/iLv/aZM2d42MMeRt/33HnnnbwgkviXSOKFkcS/RBL/Ekm8KCTxL5HEi0ISLwpJ/Esk8aJ42Zd9WQCe9KQn8dwk8a8hiX8NSfxrSOJfQxL/GpL415DEi0oSLypJvNiLvRiv9mqvxjXXXAPAj/zIj3z2l37pl77N2bNnb+Wqq6666qqrrrrq34dy/Phxrrrqqquuuuqqq/69Dg8Pd//hH/7hd377t3/7ezY3N48/6lGPeumbbrqJxzzmMZw7d479/X0eSBIvCkm8MJL4l0jiXyKJF4Uk/iWSeFFI4l8iiReFJF4UL/uyLwvAk570JJ4fSfxrSOJfQxL/GpL415DEv4Yk/jUk8aKSxL9kc3OTV3u1V+PBD34wAP/wD//w25/1WZ/1On/6p3/6M1x11VVXXXXVVVf9x6AcP36cq6666qqrrrrqqv8oh4eHu3/6p3/6M2fPnr31wQ9+8EufPHny+I033shsNuPOO+/kfpL4l0jiXyKJf4kk/iWS+JdI4kUhiX+JJF4UknhRSOJF8bIv+7IAPOlJT+IFkcS/hiT+NSTxryGJfw1J/GtI4l9DEi8qSTw/m5ubPOIRj+DVXu3V2Nzc5L777rv1S77kS97mR3/0Rz/n8PBwl6uuuuqqq6666qr/OJTjx49z1VVXXXXVVVdd9R/t1ltv/Zs/+7M/+5nDw8Pdl3u5l3vtm266icc+9rH0fc+dd96JJP4lkviXSOJfIol/iST+JZJ4UUjiXyKJF4UkXhSSeFG87Mu+LABPetKTeGEk8a8hiX8NSfxrSOJfQxL/GpL415DEi0oSD/TgBz+Y137t1+aaa64B4Ed+5Ec++0u/9Evf5uzZs7dy1VVXXXXVVVdd9R+Pcvz4ca666qqrrrrqqqv+MxweHu7+wz/8w+/89m//9vc85CEPeembbrrpwTfddBOPecxjeNrTnsYwDLwwkviXSOJfIol/iST+JZJ4UUjiXyKJF4UkXhSSeFG87Mu+LABPetKT+JdI4l9DEv8akvjXkMS/hiT+NSTxryGJF5UkNjc3ebVXezUe8YhHAHDffffd+vEf//Ev86d/+qc/w1VXXXXVVVddddV/Hsrx48e56qqrrrrqqquu+s90eHi4+1u/9Vvfc/bs2Vsf/OAHv/TJkyePP/ShD2U2m3HnnXfygkjiXyKJf4kk/iWS+JdI4l8iiReFJF4UknhRSOJF8bIv+7IAPOlJT+JFIYl/DUn8a0jiX0MS/xqS+NeQxL+GJF4Uj33sY3nVV31VNjc3ue+++279+Z//+a/+0i/90rc5PDzc5aqrrrrqqquuuuo/F+X48eNcddVVV1111VVX/Ve49dZb/+bP/uzPfubw8HD35V7u5V77xhtv5DGPeQyz2Yw777yT5yaJf4kk/iWS+JdI4l8iiX+JJF4UknhRSOJFIYkXxcu+7MsC8KQnPYkXlST+NSTxryGJfw1J/GtI4l9DEv9Rzpw5w2u/9mtzww03APAjP/Ijn/2lX/qlb/MP//APv8NVV1111VVXXXXVfw3K8ePHueqqq6666qqrrvqvcnh4uPsP//APv/Pbv/3b3/OQhzzkpW+66aYH33jjjdx4443ceeedDMPA/STxL5HEv0QS/xJJ/Esk8S+RxItCEi8KSfxLJPGietmXfVkAnvzkJ/OvIYl/DUn8a0jiX0MS/xqS+NeQxItKEs9tY2ODV33VV+Wxj30sXddx33333folX/Ilb/Pbv/3b38NVV1111VVXXXXVfy3K8ePHueqqq6666qqrrvqvdnh4uPsP//APv3N4eLj74i/+4q+9s7PDQx/6UGazGXfeeScAkviXSOKFkcS/RBIvCkn8SyTxopDEv0QSLwpJvCgk8TIv8zIAPOlJT0IS/xqS+NeQxL+GJP41JPGvIYl/DUm8qCRxv8c+9rG86qu+Kpubm9x33323/vzP//xXf+mXfunbnD179lauuuqqq6666qqr/utRjh8/zlVXXXXVVVddddV/h8PDw91/+Id/+J3f/u3f/p7Dw8Pdl3u5l3vtG2+8kcc85jGcO3eO/f19XhhJ/Esk8S+RxItCEv8SSfxLJPGikMSLQhIvCkm8zMu8DABPetKTAJDEv4Yk/jUk8a8hiX8NSfxrSOJfQxIvqmuuuYbXeq3X4oYbbgDgt37rt777sz7rs17nH/7hH36Hq6666qqrrrrqqv8+6EEPehBXXXXVVVddddVV/xNcc801D/6cz/mc37rmmmseDPCEJzyBP/3TP2V/f5/nRxL/Ekn8SyTxL5HEi0IS/xJJvCgk8aKQxItCEu/7vu8LwM///M/zQLb517DNv4Zt/jVs869hm38N2/xr2OYF2djY4EEPehCPfexjAbjvvvtu/fqv//r3+Yd/+Iff5qqrrrrqqquuuuq/H+X48eNcddVVV1111VVX/U9weHi4+2d/9mc/c3h4uPviL/7ir3369Gke+tCH0vc9d911F89NEv8SSfxLJPEvkcSLQhL/Ekm8KCTxopDEi0ISL/MyLwPAk570JB5IEv8akvjXkMS/hiT+NSTxryGJfw1JPD+PecxjeNVXfVXOnDkDwI/8yI989pd+6Ze+zdmzZ2/lqquuuuqqq6666n8GyvHjx7nqqquuuuqqq676n+Lw8HD3H/7hH37nt3/7t7/n8PBw92Vf9mVf+8Ybb+Qxj3kM586dY39/n/tJ4l8iiX+JJP4lkviXSOJFIYkXhSReFJJ4UUjiZV7mZQB40pOexHOTxL+GJP41JPGvIYl/DUn8a0jiX0MS99vY2OBVXuVVePCDHwzAP/zDP/z2Z33WZ73On/7pn/4MV1111VVXXXXVVf+zUI4fP85VV1111VVXXXXV/zSHh4e7//AP//A7Z8+efcaDH/zglz558uTxG2+8kb7vueuuuwCQxL9EEv8SSfxLJPEvkcSLQhIvCkm8KCTxopDEy7zMywDwpCc9iedHEv8akvjXkMS/hiT+NSTxryGJf43NzU0e/vCH86qv+qpsbm5y33333folX/Ilb/OjP/qjn3N4eLjLVVddddVVV1111f88lOPHj3PVVVddddVVV131P9Wtt97613/2Z3/2M4eHh7sv+7Iv+9o33ngjj3nMY+j7nrvuuot/iST+JZL4l0jiXyKJF4Uk/iWSeFFI4kUhCYCXeZmXAeBJT3oSL4gk/jUk8a8hiX8NSfxrSOJfQxIvigc96EG85mu+JmfOnAHgR37kRz77S7/0S9/m7Nmzt3LVVVddddVVV131Pxd60IMexFVXXXXVVVddddX/Btdcc82DP/zDP/y7XuzFXuy1Afb39/npn/5p9vf3eX4k8S+RxItCEv8SSbwoJPEvkcSLQhIvCkkAvO/7vi8AP//zP8+/xDb/Grb517DNv5Zt/jVs86KyzfOzsbHBy73cy3HmzBkA/uEf/uG3v/7rv/597rvvvlu56qqrrrrqqquu+p+Pcvz4ca666qqrrrrqqqv+Nzg8PNz9rd/6re85e/bsMx784Ae/9MmTJ48/9KEPZTabcdddd/HcJPEvkcS/RBIvCkn8SyTxopDEi0ISLwpJALzMy7wMAE960pP4l0jiX0MS/xqS+NeSxL+GJF5Uknhuj3nMY3iVV3kVNjc3ue+++279+Z//+a/++q//+vc5PDzc5aqrrrrqqquuuup/B8rx48e56qqrrrrqqquu+t/k1ltv/es/+7M/+5nDw8Pdl33Zl33tG2+8kUc/+tHMZjPuuusu7ieJf4kk/iWSeFFI4l8iiReFJF4UknhRSALgZV7mZQB40pOexItCEv8akvjXkIQk/jUk8a8hiReVJABOnz7NG7/xG3PmzBkAfuRHfuSzv/RLv/Rt/uEf/uF3uOqqq6666qqrrvrfhXL8+HGuuuqqq6666qqr/rc5PDzc/Yd/+Iff+e3f/u3vechDHvLSN91004NvvPFGbrjhBu666y6GYUAS/xJJ/Esk8aKQxL9EEi8KSbwoJPGikATAy7zMywDwpCc9iReVJP41JCGJfw1J/GtI4l9DEi+KjY0NXuVVXoXHPOYxANx33323fsmXfMnb/PZv//b3cNVVV1111VVXXfW/E+X48eNcddVVV1111VVX/W91eHi4+w//8A+/c3h4uPviL/7ir72zs8NDH/pQZrMZd911F/8SSfxLJPEvkcSLQhIvCkm8KCTxopAEwMu8zMsA8OQnP5l/DUn8a0niX0MS/xqS+NeQxAvz6Ec/mld+5VdmY2OD++6779af//mf/+ov/dIvfZuzZ8/eylVXXXXVVVddddX/XpTjx49z1VVXXXXVVVdd9b/Z4eHh7j/8wz/8zm//9m9/z+Hh4e7LvuzLvvaNN97Iox/9aM6dO8f+/j4viCT+JZL4l0jiRSGJf4kkXhSSeFFI4n4v8zIvA8CTn/xkJPGvIYl/LUn8a0jiX0MS/xqSeG6nT5/mNV7jNbjhhhsA+K3f+q3v/qzP+qzX+Yd/+Iff4aqrrrrqqquuuup/P/SgBz2Iq6666qqrrrrqqv9Lrrnmmgd/zud8zm9dc801DwZ44hOfyJ/92Z+xv7/Pc5PEv0QS/xJJvCgk8S+RxItCEi8KSdzvfd/3fQH4hV/4Be5nm38N2/xr2eZfwzb/Grb517DNxsYGj3nMY7jlllsAuO+++279+q//+vf5h3/4h9/mqquuuuqqq6666v8OyvHjx7nqqquuuuqqq676v+Tw8HD3z/7sz37m8PBw98Vf/MVf+/Tp0zzkIQ+h73vuuusu7ieJF4Uk/iWS+JdI4kUhiReFJF4Ukrjfy7zMywDw5Cc/mftJ4l9DEv9akvjXkMS/hiT+NR7zmMfwyq/8yhw7dgyAH/mRH/nsL/3SL32bs2fP3spVV1111VVXXXXV/y2U48ePc9VVV1111VVXXfV/zeHh4e4//MM//M5v//Zvf8/h4eHuy77sy772jTfeyKMf/WjOnTvH/v4+kviXSOJFIYl/iSReFJJ4UUjiRSGJ+73My7wMAE9+8pN5IEn8a0jiX0sS/xqS+NeQxL9kY2ODV3qlV+KWW24B4B/+4R9++7M+67Ne50//9E9/hquuuuqqq6666qr/myjHjx/nqquuuuqqq6666v+qw8PD3X/4h3/4nX/4h3/4nRd7sRd77ZMnTx5/9KMfjSTuuusu/iWS+JdI4kUhiReFJF4UknhRSOJ+L/MyLwPAk5/8ZJ6bJP41JPGvJYl/DUn8a0ji+dnY2OBhD3sYr/RKr8TGxgb33XffrV/yJV/yNj/6oz/6OYeHh7tcddVVV1111VVX/d9FOX78OFddddVVV1111VX/1509e/bWP/uzP/uZw8PD3Rd/8Rd/7RtuuIFHPepRzGYz7rrrLl4QSfxLJPGikMS/RBIvCkm8KCTxQC/zMi8DwJOf/GSeH0n8a0jiX0sS/xqS+NeQxAM9+tGP5pVe6ZU4ffo0AD/yIz/y2V/6pV/6NmfPnr2Vq6666qqrrrrqqv/7KMePH+eqq6666qqrrrrq/4PDw8Pdf/iHf/id3/7t3/6ehzzkIS990003PfiGG27gUY96FLfeeivDMPDcJPEvkcSLQhL/Ekm8KCTxopDEA73My7wMAE9+8pN5QSTxryGJfy1J/GtI4l9DEhsbG7zSK70St9xyCwD/8A//8Nuf9Vmf9Tp/+qd/+jNcddVVV1111VVX/f9BOX78OFddddVVV1111VX/nxweHu7+1m/91vecPXv2GQ9+8INf+uTJk8cf8pCHMJvNuOuuu3ggSfxLJPEvkcSLQhIvCkm8KCTxQC/zMi8DwJOf/GReGElI4kUliX8tSfxrSOJF9ahHPYpXeqVXYmNjg/vuu+/Wn//5n//qr//6r3+fw8PDXa666qqrrrrqqqv+f6EcP36cq6666qqrrrrqqv+Pbr311r/+sz/7s585PDzcfdmXfdnXvuGGG3jUox7FbDbjrrvuQhIvCkn8SyTxopDEi0ISLwpJPNDLvMzLAPDkJz+ZF4UkXlSSkMS/hiT+NSTxwpw+fZo3eIM34PTp0wD8yI/8yGd/6Zd+6dv8wz/8w+9w1VVXXXXVVVdd9f8T5fjx41x11VVXXXXVVVf9f3V4eLj7D//wD7/z27/929/zkIc85KVvuummB99www3ccMMN3H333QzDwL9EEv8SSbwoJPGikMSLQhIP9DIv8zIAPPnJT+ZFJYl/DUn8a0hCEi8qSUjigTY2NnjFV3xFHv3oRwNw33333folX/Ilb/Pbv/3b38NVV1111VVXXXXV/2+U48ePc9VVV1111VVXXfX/3eHh4e5v/dZvfQ/Ai7/4i7/29vY2D37wg5nNZtx11128IJJ4UUjiRSGJf4kkXhSSeG4v8zIvA8BTnvIU/jUk8a8hiX8tSfxrSALgUY96FK/0Sq/ExsYG9913360///M//9Vf+qVf+jZnz569lauuuuqqq6666qqrKMePH+eqq6666qqrrrrqqiv+4R/+4Xd++7d/+3sODw93X/ZlX/a1b7jhBh71qEcxDAPnz5/nuUniRSGJf4kkXhSSeFFI4rm9zMu8DABPfvKTkcS/hiT+NSTxryWJF9WpU6d4tVd7Na6//noAfuu3fuu7P+uzPut1/uEf/uF3uOqqq6666qqrrrrqfuhBD3oQV1111VVXXXXVVVc9r2uuuebBn/M5n/Nb11xzzYMBnvjEJ/IXf/EX7O/vcz9J/Esk8aKQxItCEi8KSTy3933f9wXgF3/xF7mfbf41bPOvYZt/Ldu8IBsbGzzqUY/i5ptvBuC+++679eu//uvf5x/+4R9+m6uuuuqqq6666qqrnhvl+PHjXHXVVVddddVVV131vA4PD3f/9E//9KcPDw93X/zFX/y1T58+zYMf/GBmsxl33XUXAJL4l0jiRSGJF4UkXhSSeG4v8zIvA8CTn/xk7ieJfw1J/GtI4l9LEs/Pox71KF7xFV+RY8eOAfAjP/Ijn/2lX/qlb3P27Nlbueqqq6666qqrrrrq+aEcP36cq6666qqrrrrqqquev6Ojo0v/8A//8Du//du//T2Hh4e7L/uyL/vaN9xwA4961KM4f/48BwcH/Esk8aKQxItCEi8KSTy3l3mZlwHgyU9+Mg8kiX8NSfxrSOJfSxL329jY4LVe67W4/vrrAfiHf/iH3/6QD/mQh/zDP/zD73DVVVddddVVV1111QtDOX78OFddddVVV1111VVXvXCHh4e7//AP//A7//AP//A7L/ZiL/baJ0+ePP6oRz0KgIODA4Zh4AWRxL9EEi8KSbwoJPH8vMzLvAwAT37yk3lukpDEi0oS/xqS+Nfa3NzkoQ99KK/4iq9I13Xcd999t37Jl3zJ2/zoj/7o53DVVVddddVVV1111YuCcvz4ca666qqrrrrqqquuetGcPXv21j/90z/96cPDw90Xf/EXf+0bbriBBz/4wcxmM+6++26eH0n8SyTxopDEi0ISz8/LvMzLAPDkJz+ZF0QSLypJSOJFJQlJvCge+chH8gqv8AqcPn0agB/5kR/57C/90i99m7Nnz97KVVddddVVV1111VUvKsrx48e56qqrrrrqqquuuupFd3R0dOkf/uEffue3f/u3v+chD3nIS990000PvuGGG3jkIx/JM57xDIZh4H6SeFFI4kUhiReFJJ6fl3mZlwHgyU9+Mi+MJP41JPGvIYkXZGNjg1d4hVfg5ptvBuAf/uEffvuzPuuzXudP//RPf4arrrrqqquuuuqqq/61KMePH+eqq6666qqrrrrqqn+9w8PD3d/6rd/6nrNnzz7jwQ9+8EufPHny+IMf/GBmsxl33303AJJ4UUjiRSGJF4Uknp+XeZmXAeDJT34y/xJJ/GtI4l9DEg+0sbHBQx7yEF7hFV6BjY0N7rvvvlu/67u+62O+67u+62MODw93ueqqq6666qqrrrrq34Jy/Phxrrrqqquuuuqqq676t7v11lv/+k//9E9/+vDwcPdlX/ZlX/uGG27gkY98JLPZjLvvvpsXhST+JZJ4UUjiBXmZl3kZAJ785CfzopDEv4Yk/jUkAXDq1Cle67Vei9OnTwPwIz/yI5/9pV/6pW9z6623/jVXXXXVVVddddVVV/17UI4fP85VV1111VVXXXXVVf8+R0dHl/7hH/7hd377t3/7ex7ykIe89E033fTgG264gUc+8pE84xnPYBgGXhBJvCgk8aKQxAvyMi/zMgA85SlP4UUliX8NSbyoFosFr/AKr8CjHvUoAO67775bv+RLvuRtfvu3f/t7uOqqq6666qqrrrrqPwLl+PHjXHXVVVddddVVV131H+Pw8HD3t37rt74H4MVf/MVfezab8aAHPYi+77n77rt5fiTxopDEi0ISL8jLvMzLAPCUpzwFSbyoJPGvIYl/ySMf+Uhe4RVegY2NDe67775bf/7nf/6rv/RLv/Rtzp49eytXXXXVVVddddVVV/1HoRw/fpyrrrrqqquuuuqqq/5j/cM//MPv/NZv/dZ3Hx4e7r7sy77sa99www088pGPZBgGzp8/zwNJ4kUhiReFJF6Ql3mZlwHgKU95CgCSeFFJQhIvKkk8P6dOneJVXuVVuO666wD4kR/5kc/+0i/90rf5h3/4h9/hqquuuuqqq6666qr/aJTjx49z1VVXXXXVVVddddV/vKOjo0v/8A//8Du//du//T2v+Iqv+NYnT548/uAHP5jt7W0uXLjAMAwASOJfIokXlSRekJd5mZcB4ClPeQr3k8S/hiReVJKQBMBiseAVXuEVeOQjH0nXddx33323fsmXfMnb/PZv//b3cNVVV1111VVXXXXVfxbK8ePHueqqq6666qqrrrrqP8/h4eHun/3Zn/3M4eHh7ou/+Iu/9qlTp3jQgx5E3/fcc889vCgk8aKQxAvzMi/zMgA85SlP4YEk8a8hiX+NRz7ykbzCK7wCGxsbAPzIj/zIZ3/pl37p25w9e/ZWrrrqqquuuuqqq676z0Q5fvw4V1111VVXXXXVVVf95zo8PNz9h3/4h9/5rd/6re8+PDzcfdmXfdnXvuGGG3jEIx7BhQsXODg44IWRxItCEi/My7zMywDwlKc8hecmiX8NSfxLFosFr/mar8l1110HwD/8wz/89od8yIc85B/+4R9+h6uuuuqqq6666qqr/itQjh8/zlVXXXXVVVddddVV/zWOjo4u/cM//MPv/MM//MPvvNiLvdhrnzx58vgjH/lIAPb39xmGgedHEi8KSbwwL/MyLwPAU57yFJ4fSfxrSOL5WSwWPOQhD+HlX/7l6bqO++6779Yv+ZIveZsf/dEf/Ryuuuqqq6666qqrrvqvRDl+/DhXXXXVVVddddVVV/3XOnv27K1/9md/9jOHh4e7L/7iL/7a119/PQ960IOYzWbcfffdPJAkXhSS+Je8zMu8DABPecpTeEEkIYkXlSQe6BGPeAQv//Ivz6lTpwD4kR/5kc/+0i/90rc5e/bsrVx11VVXXXXVVVdd9V+Ncvz4ca666qqrrrrqqquu+q93eHi4+w//8A+/81u/9Vvfvbm5efxRj3rUS19//fU84hGP4MKFCxwcHAAgiReFJP4lL/MyLwPAU57yFP4lknhRSWJjY4OXe7mX4+abbwbgH/7hH377Mz/zM1/7z/7sz36Gq6666qqrrrrqqqv+u1COHz/OVVddddVVV1111VX/fY6Oji796Z/+6c+cPXv2GQ9+8INf+uTJk8dvuOEG+r7n7rvvRhIvCkn8S17mZV4GgKc85Sm8KCTxL1ksFjzkIQ/h5V7u5djY2OC+++679bu+67s+5ru+67s+5ujo6BJXXXXVVVddddVVV/13ohw/fpyrrrrqqquuuuqqq/773XrrrX/9Z3/2Zz9zeHi4+7Iv+7Kvff311/OIRzyCvu+55557+JdI4l/yMi/zMgA85SlP4UUliRfk5MmTvMZrvAanTp0C4Ed+5Ec++0u/9Evf5tZbb/1rrrrqqquuuuqqq676n4By/Phxrrrqqquuuuqqq676n+Hw8HD3H/7hH37nt37rt777IQ95yEvfdNNND77++ut55CMfyTOe8QyGYeD5kcSL4mVe5mUAeOpTn4okXlSSeKDFYsHLvdzL8chHPhKA++6779aP+7iPe+k/+7M/+xmuuuqqq6666qqrrvqfhHL8+HGuuuqqq6666qqrrvqf5ejo6NJv/dZvfQ/ANddc8+ATJ04cf/CDH0zf99xzzz08N0m8KF7mZV4GgKc85SkASOJFJQmARzziEbzcy70cGxsb3Hfffbf+/M///Fd/6Zd+6dscHR1d4qqrrrrqqquuuuqq/2kox48f56qrrrrqqquuuuqq/5n+4R/+4Xf+7M/+7GcODw93X/ZlX/a1r7/+eh75yEcyDAMXLlzgfpJ4UbzMy7wMAE95ylO4nyReFCdPnuSVX/mVufbaawH4kR/5kc/+0i/90rf5h3/4h9/hqquuuuqqq6666qr/qdCDHvQgrrrqqquuuuqqq676n+/MmTMP+tzP/dzfvuaaax4M8OQnP5m//Mu/5ODgAEm8KN73fd8XgF/+5V/mudnm+VksFrzkS74kJ0+eBOC+++679eu//uvf5x/+4R9+m6uuuuqqq6666qqr/qejHD9+nKuuuuqqq6666qqr/uc7Ojq69Gd/9mc/c3h4uPviL/7ir33q1Cke/OAHM5vNuOeee3hRvMzLvAwAT3nKU3huknhuD3/4w3m5l3s5FosF9913360///M//9Vf+qVf+jZnz569lauuuuqqq6666qqr/jegHD9+nKuuuuqqq6666qqr/nc4PDzc/Yd/+Iff+e3f/u3vOTw83H3Zl33Z177++ut5xCMewfnz5zk4OOAFkcTLvMzLAPCUpzyF50cSAIvFgld/9Vfn2muvBeAf/uEffvvjP/7jX+Yf/uEffoerrrrqqquuuuqqq/43QQ960IO46qqrrrrqqquuuup/pzNnzjzocz/3c3/7mmuueTDAk5/8ZP7qr/6Kg4MDnpsk3ud93geAX/7lX+b5WSwW3HjjjTz84Q8H4L777rv167/+69/nH/7hH36bq6666qqrrrrqqqv+N6IcP36cq6666qqrrrrqqqv+dzo6Orr0Z3/2Zz9zeHi4++Iv/uKvferUKR70oAfR9z333HMPDySJl3mZlwHgKU95Cs/t4Q9/OC/7si/LyZMnAfiRH/mRz/7SL/3Stzl79uytXHXVVVddddVVV131vxXl+PHjXHXVVVddddVVV131v9fh4eHuP/zDP/zOb//2b3/P5ubm8Uc96lEvff311/OIRzyC8+fPc3BwgCQAXuZlXgaApzzlKdxvsVjwsi/7stx4440A/MM//MNvf9Znfdbr/Omf/unPcNVVV1111VVXXXXV/3aU48ePc9VVV1111VVXXXXV/36Hh4e7f/qnf/ozZ8+evfXBD37wS584ceL49ddfT9/33HPPPQC8zMu8DABPfepTWSwWPPjBD+ZlX/ZlWSwW3Hfffbd+yZd8ydv86I/+6OccHh7uctVVV1111VVXXXXV/wWU48ePc9VVV1111VVXXXXV/x233nrr3/zZn/3ZzxweHu6+7Mu+7Gtff/31POIRj6Dve66//noAVqsVr/iKr8jJkycB+JEf+ZHP/tIv/dK3OXv27K1cddVVV1111VVXXfV/CXrQgx7EVVddddVVV1111VX/N11zzTUP/vAP//DverEXe7HX5vm47777bv2sz/qs17nvvvtu5aqrrrrqqquuuuqq/4sox48f56qrrrrqqquuuuqq/5sODw93f+u3fut7AK655poHb25uHge47777bv35n//5r/7SL/3Stzk8PNzlqquuuuqqq6666qr/q9CDHvQgrrrqqquuuuqqq676v++aa6558JkzZx58zTXXPPi3fuu3vpurrrrqqquuuuqqq/4/QA960IO46qqrrrrqqquuuuqqq6666qqrrrrqqqv+T6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q/iHwH4w+tvGVQZvwAAAABJRU5ErkJggg==) +![Rendered example of polygon 1](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAADMPklEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a8+6EEP4qqrrrrqqquuuuqqq6666qqrrrrqqquu+j+JylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8VwVVXXXXVVVddddVV/29cc801D+aqq6666qqrrrrqqv9PqFx11VVXXXXVVVdd9X/aNddc8+DXfu3Xfq/XeZ3XeW8e4Ld+67e++x/+4R9+5x/+4R9+m6uuuuqqq6666qqr/q9CD3rQg7jqqquuuuqqq6666v+Oa6655sFnzpx58Iu92Iu91ju90zt9Nv+C++6779Z/+Id/+O1/+Id/+J3f+q3f+m6uuuqqq6666qqrrvq/BD3oQQ/iqquuuuqqq6666qr/3a655poHv/Zrv/Z7vfiLv/hrv9iLvdhr8wAXLlzgz/7sz3jKU57CA73iK74iJ06c4OEPfzj3u++++249e/bsrb/1W7/1Pffdd9+t//AP//DbXHXVVVddddVVV131vxl60IMexFVXXXXVVVddddVV//tcc801D37t137t93qd13md977mmmsezANcuHCBP/uzP+PP/uzPuHDhAi/MyZMneYVXeAUe9rCH8fCHP5wHuu+++279rd/6re/+h3/4h9/5h3/4h9/mqquuuuqqq6666qr/bdCDHvQgrrrqqquuuuqqq676n++aa6558JkzZx78Yi/2Yq/1Tu/0Tp/NA1y4cIGnPvWpXLhwgV/5lV/h3+rkyZM87GEP4+EPfziv8AqvwAPdd999t/7DP/zDb//DP/zD7/zWb/3Wd3PVVVddddVVV1111f8G6EEPehBXXXXVVVddddVV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5poHv/Zrv/Z7vfiLv/hrv9iLvdhr8wAXL17kz/7sz3ja057GU5/6VK76j2Gb/4lOnDjByZMnedjDHsbDHvYwHvawh3G/++6779azZ8/e+vd///e//Q//8A+/8w//8A+/zVVXXXXVVVddddX/LehBD3oQV1111VVXXXXVVf8XXHPNNQ9+7dd+7fd6ndd5nfe+5pprHswDXLx4kT/7sz/jz//8z7l48SJX/e9gm/9oJ06c4GEPexiv8AqvwMMe9jAe6L777rv1H/7hH377t37rt77nH/7hH36bq6666qqrrrrqqv/90IMe9CCuuuqqq6666qqr/je65pprHvzar/3a7wXwTu/0Tp/NA1y8eJE/+7M/A+DXfu3XuOr/N9s8PydOnOBhD3sYD3vYw3iFV3gFHui+++679R/+4R9++x/+4R9+57d+67e+m6uuuuqqq6666qr/ndCDHvQgrrrqqquuuuqqq/63uOaaax782q/92u/14i/+4q/9Yi/2Yq/NA1y8eJE/+7M/42lPexpPfepTueqqf40TJ04A8PIv//I87GEP42EPexj3u++++249e/bsrX//93//2//wD//wO//wD//w21x11VVXXXXVVVf974Ae9KAHcdVVV1111VVXXfU/2TXXXPPg137t136v13md13nva6655sE8wMWLF/nzP/9z/vzP/5yLFy/yv41trvqf6cSJEzzsYQ/j5V/+5XnYwx7GA9133323/sM//MNv/9Zv/db3/MM//MNvc9VVV1111VVXXfU/F3rQgx7EVVddddVVV1111f8k11xzzYNf+7Vf+70A3umd3umzeYCLFy/y53/+5wD82q/9Glf929jmqhfdiRMneNjDHsbDHvYwXv7lX54Huu+++279h3/4h9/+h3/4h9/5rd/6re/mqquuuuqqq6666n8W9KAHPYirrrrqqquuuuqq/27XXHPNg1/7tV/7vV78xV/8tV/sxV7stXmAixcv8ud//uc89alP5WlPexpX/c9nm/+rTpw4AcDLv/zL87CHPYyHPexh3O++++679ezZs7f+/d///W//wz/8w+/8wz/8w29z1VVXXXXVVVdd9d8LPehBD+Kqq6666qqrrrrqv8M111zz4Nd+7dd+r9d5ndd572uuuebBPMDFixf58z//c/78z/+cixcvctX/b7b5n+rEiRM87GEP4+Vf/uV5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D3rQg7jqqquuuuqqq6666v+ua6655sGv/dqv/V7v9E7v9Nk8wD/8wz/89md+5me+DlddddVVV1111VVX/V+GHvSgB3HVVVddddVVV1111f9911xzzYPf8R3f8bMAfuu3fut7/uEf/uG3ueqqq6666qqrrrrq/zr0oAc9iKuuuuqqq6666qqrrrrqqquuuuqqq6666v8kKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/ispVV1111VVXXXXVVVddddVVV1111VVXXfV/FZWrrrrqqquuuuqqq6666qqrrrrqqquuuur/KipXXXXVVVddddVVV1111VVXXXXVVVddddX/VVSuuuqqq6666qqrrrrqqquuuuqqq6666qr/q6hcddVVV1111VVXXXXVVVddddVVV1111VX/V1G56qqrrrrqqquuuuqqq6666qqrrrrqqqv+r6Jy1VVXXXXVVVddddVVV1111VVXXXXVVVf9X0Xlqquuuuqqq6666qqrrrrqqquuuuqqq676v4rKVVddddVVV1111VVXXXXVVVddddVVV131fxWVq6666qqrrrrqqquuuuqqq6666qqrrrrq/yoqV1111VVXXXXVVVddddVVV1111VVXXXXV/1VUrrrqqquuuuqqq6666qqrrrrqqquuuuqq/6uoXHXVVVddddVVV1111VVXXXXVVVddddVV/1dRueqqq6666qqrrrrqqquuuuqqq6666qqr/q+ictVVV1111VVXXXXVVVddddVVV1111VVX/V9F5aqrrrrqqquuuuqqq6666qqrrrrqqquu+r+KylVXXXXVVVddddVVV1111VVXXXXVVVdd9X8Vlauuuuqqq6666qqrrrrqqquuuuqqq6666v8qKlddddVVV1111VVXXXXVVVddddVVV1111f9VVK666qqrrrrqqquuuuqqq6666qqrrrrqqv+rqFx11VVXXXXVVVddddVVV1111VVXXXXVVf9XUbnqqquuuuqqq6666qqrrrrqqquuuuqqq/6vonLVVVddddVVV1111VVXXXXVVVddddVVV/1fReWqq6666qqrrrrqqquuuuqqq6666qqrrvq/in8ElsK8J4u35H8AAAAASUVORK5CYII=) diff --git a/docs/kcl/std.json b/docs/kcl/std.json index 29d2118ce2..bf8310168f 100644 --- a/docs/kcl/std.json +++ b/docs/kcl/std.json @@ -89825,10 +89825,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" ] }, - "value": {}, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" + ] + }, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" + ] + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -90046,6 +90207,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -90202,6 +90402,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ] }, @@ -93540,6 +93765,10 @@ "nullable": true } } + }, + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" } } }, @@ -93567,10 +93796,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" + ] + }, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" ] }, - "value": {}, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" + ] + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -93788,6 +94178,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -93944,6 +94373,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ] }, @@ -97282,6 +97736,10 @@ "nullable": true } } + }, + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" } } }, @@ -97313,10 +97771,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" + ] + }, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" ] }, - "value": {}, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" + ] + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -97534,6 +98153,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -97690,6 +98348,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ] }, @@ -101028,6 +101711,10 @@ "nullable": true } } + }, + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" } } }, @@ -105194,7 +105881,8 @@ "// Loft a square and a circle on the `XY` plane using offset.\nsquareSketch = startSketchOn('XY')\n |> startProfileAt([-100, 200], %)\n |> line([200, 0], %)\n |> line([0, -200], %)\n |> line([-200, 0], %)\n |> lineTo([profileStartX(%), profileStartY(%)], %)\n |> close(%)\n\ncircleSketch = startSketchOn(offsetPlane('XY', 150))\n |> circle({ center: [0, 100], radius: 50 }, %)\n\nloft([squareSketch, circleSketch])", "// Loft a square and a circle on the `XZ` plane using offset.\nsquareSketch = startSketchOn('XZ')\n |> startProfileAt([-100, 200], %)\n |> line([200, 0], %)\n |> line([0, -200], %)\n |> line([-200, 0], %)\n |> lineTo([profileStartX(%), profileStartY(%)], %)\n |> close(%)\n\ncircleSketch = startSketchOn(offsetPlane('XZ', 150))\n |> circle({ center: [0, 100], radius: 50 }, %)\n\nloft([squareSketch, circleSketch])", "// Loft a square and a circle on the `YZ` plane using offset.\nsquareSketch = startSketchOn('YZ')\n |> startProfileAt([-100, 200], %)\n |> line([200, 0], %)\n |> line([0, -200], %)\n |> line([-200, 0], %)\n |> lineTo([profileStartX(%), profileStartY(%)], %)\n |> close(%)\n\ncircleSketch = startSketchOn(offsetPlane('YZ', 150))\n |> circle({ center: [0, 100], radius: 50 }, %)\n\nloft([squareSketch, circleSketch])", - "// Loft a square and a circle on the `-XZ` plane using offset.\nsquareSketch = startSketchOn('-XZ')\n |> startProfileAt([-100, 200], %)\n |> line([200, 0], %)\n |> line([0, -200], %)\n |> line([-200, 0], %)\n |> lineTo([profileStartX(%), profileStartY(%)], %)\n |> close(%)\n\ncircleSketch = startSketchOn(offsetPlane('-XZ', -150))\n |> circle({ center: [0, 100], radius: 50 }, %)\n\nloft([squareSketch, circleSketch])" + "// Loft a square and a circle on the `-XZ` plane using offset.\nsquareSketch = startSketchOn('-XZ')\n |> startProfileAt([-100, 200], %)\n |> line([200, 0], %)\n |> line([0, -200], %)\n |> line([-200, 0], %)\n |> lineTo([profileStartX(%), profileStartY(%)], %)\n |> close(%)\n\ncircleSketch = startSketchOn(offsetPlane('-XZ', -150))\n |> circle({ center: [0, 100], radius: 50 }, %)\n\nloft([squareSketch, circleSketch])", + "// A circle on the XY plane\nstartSketchOn(\"XY\")\n |> startProfileAt([0, 0], %)\n |> circle({ radius: 10, center: [0, 0] }, %)\n\n// Triangle on the plane 4 units above\nstartSketchOn(offsetPlane(\"XY\", 4))\n |> startProfileAt([0, 0], %)\n |> line([10, 0], %)\n |> line([0, 10], %)\n |> close(%)" ] }, { @@ -127507,10 +128195,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" ] }, - "value": {}, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" + ] + }, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" + ] + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -127728,6 +128577,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -127884,6 +128772,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ] }, @@ -131222,6 +132135,10 @@ "nullable": true } } + }, + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" } } }, @@ -131246,10 +132163,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" ] }, - "value": {}, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" + ] + }, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" + ] + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -131467,6 +132545,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -131623,6 +132740,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ], "definitions": { @@ -131640,10 +132782,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" + ] + }, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" + ] + }, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" ] }, - "value": {}, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -131861,6 +133164,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -132017,6 +133359,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ] }, @@ -135355,6 +136722,10 @@ "nullable": true } } + }, + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" } } }, @@ -135380,10 +136751,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" + ] + }, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" + ] + }, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" ] }, - "value": {}, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -135601,6 +137133,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -135757,6 +137328,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ], "definitions": { @@ -135787,1041 +137383,589 @@ "maxItems": 3, "minItems": 3 }, - "TagEngineInfo": { - "description": "Engine information for a tag.", - "type": "object", - "required": [ - "id", - "sketch" - ], - "properties": { - "id": { - "description": "The id of the tagged object.", - "type": "string", - "format": "uuid" - }, - "sketch": { - "description": "The sketch the tag is on.", - "type": "string", - "format": "uuid" - }, - "path": { - "description": "The path the tag is on.", - "allOf": [ - { - "$ref": "#/components/schemas/Path" - } - ], - "nullable": true - }, - "surface": { - "description": "The surface information for the tag.", - "allOf": [ - { - "$ref": "#/components/schemas/ExtrudeSurface" - } - ], - "nullable": true - } - } - }, - "Path": { - "description": "A path.", + "KclValue": { + "description": "Any KCL value.", "oneOf": [ { - "description": "A path that goes to a point.", "type": "object", "required": [ - "__geoMeta", - "from", - "to", - "type" + "__meta", + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "ToPoint" + "Uuid" ] }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "value": { + "type": "string", + "format": "uuid" }, - "to": { - "description": "The to point.", + "__meta": { "type": "array", "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "tag": { - "description": "The tag of the path.", - "allOf": [ - { - "$ref": "#/components/schemas/TagDeclarator" - } - ], - "nullable": true - }, - "__geoMeta": { - "description": "Metadata.", - "allOf": [ - { - "$ref": "#/components/schemas/GeoMeta" - } - ] + "$ref": "#/components/schemas/Metadata" + } } } }, { - "description": "A arc that is tangential to the last path segment that goes to a point", "type": "object", "required": [ - "__geoMeta", - "ccw", - "center", - "from", - "to", - "type" + "__meta", + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "TangentialArcTo" + "Bool" ] }, - "center": { - "description": "the arc's center", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "ccw": { - "description": "arc's direction", + "value": { "type": "boolean" }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "to": { - "description": "The to point.", + "__meta": { "type": "array", "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "tag": { - "description": "The tag of the path.", - "allOf": [ - { - "$ref": "#/components/schemas/TagDeclarator" - } - ], - "nullable": true - }, - "__geoMeta": { - "description": "Metadata.", - "allOf": [ - { - "$ref": "#/components/schemas/GeoMeta" - } - ] + "$ref": "#/components/schemas/Metadata" + } } } }, { - "description": "A arc that is tangential to the last path segment", "type": "object", "required": [ - "__geoMeta", - "ccw", - "center", - "from", - "to", - "type" + "__meta", + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "TangentialArc" + "Number" ] }, - "center": { - "description": "the arc's center", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "ccw": { - "description": "arc's direction", - "type": "boolean" - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "value": { + "type": "number", + "format": "double" }, - "to": { - "description": "The to point.", + "__meta": { "type": "array", "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "tag": { - "description": "The tag of the path.", - "allOf": [ - { - "$ref": "#/components/schemas/TagDeclarator" - } - ], - "nullable": true - }, - "__geoMeta": { - "description": "Metadata.", - "allOf": [ - { - "$ref": "#/components/schemas/GeoMeta" - } - ] + "$ref": "#/components/schemas/Metadata" + } } } }, { - "description": "a complete arc", "type": "object", "required": [ - "__geoMeta", - "ccw", - "center", - "from", - "radius", - "to", - "type" + "__meta", + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "Circle" + "Int" ] }, - "center": { - "description": "the arc's center", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "radius": { - "description": "the arc's radius", - "type": "number", - "format": "double" - }, - "ccw": { - "description": "arc's direction", - "type": "boolean" - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "value": { + "type": "integer", + "format": "int64" }, - "to": { - "description": "The to point.", + "__meta": { "type": "array", "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "tag": { - "description": "The tag of the path.", - "allOf": [ - { - "$ref": "#/components/schemas/TagDeclarator" - } - ], - "nullable": true - }, - "__geoMeta": { - "description": "Metadata.", - "allOf": [ - { - "$ref": "#/components/schemas/GeoMeta" - } - ] + "$ref": "#/components/schemas/Metadata" + } } } }, { - "description": "A path that is horizontal.", "type": "object", "required": [ - "__geoMeta", - "from", - "to", + "__meta", "type", - "x" + "value" ], "properties": { "type": { "type": "string", "enum": [ - "Horizontal" + "String" ] }, - "x": { - "description": "The x coordinate.", - "type": "number", - "format": "double" - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "value": { + "type": "string" }, - "to": { - "description": "The to point.", + "__meta": { "type": "array", "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "tag": { - "description": "The tag of the path.", - "allOf": [ - { - "$ref": "#/components/schemas/TagDeclarator" - } - ], - "nullable": true - }, - "__geoMeta": { - "description": "Metadata.", - "allOf": [ - { - "$ref": "#/components/schemas/GeoMeta" - } - ] + "$ref": "#/components/schemas/Metadata" + } } } }, { - "description": "An angled line to.", "type": "object", "required": [ - "__geoMeta", - "from", - "to", - "type" + "__meta", + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "AngledLineTo" + "Array" ] }, - "x": { - "description": "The x coordinate.", - "type": "number", - "format": "double", - "nullable": true - }, - "y": { - "description": "The y coordinate.", - "type": "number", - "format": "double", - "nullable": true - }, - "from": { - "description": "The from point.", + "value": { "type": "array", "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "$ref": "#/components/schemas/KclValue" + } }, - "to": { - "description": "The to point.", + "__meta": { "type": "array", "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "tag": { - "description": "The tag of the path.", - "allOf": [ - { - "$ref": "#/components/schemas/TagDeclarator" - } - ], - "nullable": true - }, - "__geoMeta": { - "description": "Metadata.", - "allOf": [ - { - "$ref": "#/components/schemas/GeoMeta" - } - ] + "$ref": "#/components/schemas/Metadata" + } } } }, { - "description": "A base path.", "type": "object", "required": [ - "__geoMeta", - "from", - "to", - "type" + "__meta", + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "Base" + "Object" ] }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } }, - "to": { - "description": "The to point.", + "__meta": { "type": "array", "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TagIdentifier" + ] }, - "tag": { - "description": "The tag of the path.", + "value": { + "type": "string" + }, + "info": { "allOf": [ { - "$ref": "#/components/schemas/TagDeclarator" + "$ref": "#/components/schemas/TagEngineInfo" } ], "nullable": true }, - "__geoMeta": { - "description": "Metadata.", - "allOf": [ - { - "$ref": "#/components/schemas/GeoMeta" - } - ] + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } } } }, { - "description": "A circular arc, not necessarily tangential to the current point.", "type": "object", "required": [ - "__geoMeta", - "center", - "from", - "radius", - "to", - "type" + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "Arc" + "TagDeclarator" ] }, - "center": { - "description": "Center of the circle that this arc is drawn on.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 - }, - "radius": { - "description": "Radius of the circle that this arc is drawn on.", - "type": "number", - "format": "double" - }, - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "value": { + "type": "string" }, - "to": { - "description": "The to point.", + "digest": { "type": "array", "items": { - "type": "number", - "format": "double" + "type": "integer", + "format": "uint8", + "minimum": 0.0 }, - "maxItems": 2, - "minItems": 2 - }, - "tag": { - "description": "The tag of the path.", - "allOf": [ - { - "$ref": "#/components/schemas/TagDeclarator" - } - ], + "maxItems": 32, + "minItems": 32, "nullable": true }, - "__geoMeta": { - "description": "Metadata.", - "allOf": [ - { - "$ref": "#/components/schemas/GeoMeta" - } - ] + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } - } - ] - }, - "TagDeclarator": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "string" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - "GeoMeta": { - "description": "Geometry metadata.", - "type": "object", - "required": [ - "id", - "sourceRange" - ], - "properties": { - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" }, - "sourceRange": { - "description": "The source range.", - "allOf": [ - { - "$ref": "#/components/schemas/SourceRange" - } - ] - } - } - }, - "ExtrudeSurface": { - "description": "An extrude surface.", - "oneOf": [ { - "description": "An extrude plane.", + "description": "A plane.", "type": "object", "required": [ - "faceId", + "__meta", "id", - "sourceRange", - "type" + "origin", + "type", + "value", + "xAxis", + "yAxis", + "zAxis" ], "properties": { "type": { "type": "string", "enum": [ - "extrudePlane" + "Plane" ] }, - "faceId": { - "description": "The face id for the extrude plane.", + "id": { + "description": "The id of the plane.", "type": "string", "format": "uuid" }, - "tag": { - "description": "The tag.", + "value": { + "$ref": "#/components/schemas/PlaneType" + }, + "origin": { + "description": "Origin of the plane.", "allOf": [ { - "$ref": "#/components/schemas/TagDeclarator" + "$ref": "#/components/schemas/Point3d" } - ], - "nullable": true + ] }, - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" + "xAxis": { + "description": "What should the plane’s X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] }, - "sourceRange": { - "description": "The source range.", + "yAxis": { + "description": "What should the plane’s Y axis be?", "allOf": [ { - "$ref": "#/components/schemas/SourceRange" + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" } ] + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } } } }, { - "description": "An extruded arc.", + "description": "A face.", "type": "object", "required": [ - "faceId", + "__meta", "id", - "sourceRange", - "type" + "solid", + "type", + "value", + "xAxis", + "yAxis", + "zAxis" ], "properties": { "type": { "type": "string", "enum": [ - "extrudeArc" + "Face" ] }, - "faceId": { - "description": "The face id for the extrude plane.", + "id": { + "description": "The id of the face.", "type": "string", "format": "uuid" }, - "tag": { - "description": "The tag.", + "value": { + "description": "The tag of the face.", + "type": "string" + }, + "xAxis": { + "description": "What should the face’s X axis be?", "allOf": [ { - "$ref": "#/components/schemas/TagDeclarator" + "$ref": "#/components/schemas/Point3d" } - ], - "nullable": true + ] }, - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" + "yAxis": { + "description": "What should the face’s Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] }, - "sourceRange": { - "description": "The source range.", + "zAxis": { + "description": "The z-axis (normal).", "allOf": [ { - "$ref": "#/components/schemas/SourceRange" + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "solid": { + "description": "The solid the face is on.", + "allOf": [ + { + "$ref": "#/components/schemas/Solid" } ] + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } } } }, { - "description": "Geometry metadata.", "type": "object", "required": [ - "faceId", - "id", - "sourceRange", - "type" + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "chamfer" + "Sketch" ] }, - "faceId": { - "description": "The id for the chamfer surface.", - "type": "string", - "format": "uuid" - }, - "tag": { - "description": "The tag.", - "allOf": [ - { - "$ref": "#/components/schemas/TagDeclarator" - } - ], - "nullable": true - }, - "id": { - "description": "The id of the geometry.", + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { "type": "string", - "format": "uuid" - }, - "sourceRange": { - "description": "The source range.", - "allOf": [ - { - "$ref": "#/components/schemas/SourceRange" - } + "enum": [ + "Sketches" ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } } } }, { - "description": "Geometry metadata.", + "description": "An solid is a collection of extrude surfaces.", "type": "object", "required": [ - "faceId", + "__meta", + "height", "id", - "sourceRange", - "type" + "sketch", + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "fillet" + "Solid" ] }, - "faceId": { - "description": "The id for the fillet surface.", + "id": { + "description": "The id of the solid.", "type": "string", "format": "uuid" }, - "tag": { - "description": "The tag.", + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ExtrudeSurface" + } + }, + "sketch": { + "description": "The sketch.", "allOf": [ { - "$ref": "#/components/schemas/TagDeclarator" + "$ref": "#/components/schemas/Sketch" } - ], - "nullable": true - }, - "id": { - "description": "The id of the geometry.", - "type": "string", - "format": "uuid" + ] }, - "sourceRange": { - "description": "The source range.", - "allOf": [ - { - "$ref": "#/components/schemas/SourceRange" - } - ] + "height": { + "description": "The height of the solid.", + "type": "number", + "format": "double" + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "edgeCuts": { + "description": "Chamfers or fillets on this solid.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EdgeCut" + } + }, + "__meta": { + "description": "Metadata.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } } } - } - ] - }, - "PlaneType": { - "description": "Type for a plane.", - "oneOf": [ - { - "type": "string", - "enum": [ - "XY", - "XZ", - "YZ" - ] }, { - "description": "A custom plane.", - "type": "string", - "enum": [ - "Custom" - ] - } - ] - }, - "Point3d": { - "type": "object", - "required": [ - "x", - "y", - "z" - ], - "properties": { - "x": { - "type": "number", - "format": "double" - }, - "y": { - "type": "number", - "format": "double" - }, - "z": { - "type": "number", - "format": "double" - } - } - }, - "Solid": { - "description": "An solid is a collection of extrude surfaces.", - "type": "object", - "required": [ - "__meta", - "height", - "id", - "sketch", - "value" - ], - "properties": { - "id": { - "description": "The id of the solid.", - "type": "string", - "format": "uuid" - }, - "value": { - "description": "The extrude surfaces.", - "type": "array", - "items": { - "$ref": "#/components/schemas/ExtrudeSurface" - } - }, - "sketch": { - "description": "The sketch.", - "allOf": [ - { - "$ref": "#/components/schemas/Sketch" - } - ] - }, - "height": { - "description": "The height of the solid.", - "type": "number", - "format": "double" - }, - "startCapId": { - "description": "The id of the extrusion start cap", - "type": "string", - "format": "uuid", - "nullable": true - }, - "endCapId": { - "description": "The id of the extrusion end cap", - "type": "string", - "format": "uuid", - "nullable": true - }, - "edgeCuts": { - "description": "Chamfers or fillets on this solid.", - "type": "array", - "items": { - "$ref": "#/components/schemas/EdgeCut" - } - }, - "__meta": { - "description": "Metadata.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - "Sketch": { - "description": "A sketch is a collection of paths.", - "type": "object", - "required": [ - "__meta", - "id", - "on", - "paths", - "start" - ], - "properties": { - "id": { - "description": "The id of the sketch (this will change when the engine's reference to it changes).", - "type": "string", - "format": "uuid" - }, - "paths": { - "description": "The paths in the sketch.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Path" - } - }, - "on": { - "description": "What the sketch is on (can be a plane or a face).", - "allOf": [ - { - "$ref": "#/components/schemas/SketchSurface" - } - ] - }, - "start": { - "description": "The starting path.", - "allOf": [ - { - "$ref": "#/components/schemas/BasePath" - } - ] - }, - "tags": { - "description": "Tag identifiers that have been declared in this sketch.", "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/TagIdentifier" + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Solids" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Solid" + } + } } }, - "__meta": { - "description": "Metadata.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - "SketchSurface": { - "description": "A sketch type.", - "oneOf": [ { - "description": "A plane.", + "description": "Data for an imported geometry.", "type": "object", "required": [ "__meta", "id", - "origin", "type", - "value", - "xAxis", - "yAxis", - "zAxis" + "value" ], "properties": { "type": { "type": "string", "enum": [ - "plane" + "ImportedGeometry" ] }, "id": { - "description": "The id of the plane.", + "description": "The ID of the imported geometry.", "type": "string", "format": "uuid" }, "value": { - "$ref": "#/components/schemas/PlaneType" - }, - "origin": { - "description": "Origin of the plane.", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] + "description": "The original file paths.", + "type": "array", + "items": { + "type": "string" + } }, - "xAxis": { - "description": "What should the plane’s X axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "expression", + "memory", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Function" ] }, - "yAxis": { - "description": "What should the plane’s Y axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] + "expression": { + "$ref": "#/components/schemas/FunctionExpression" }, - "zAxis": { - "description": "The z-axis (normal).", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] + "memory": { + "$ref": "#/components/schemas/ProgramMemory" }, "__meta": { "type": "array", @@ -136832,65 +137976,21 @@ } }, { - "description": "A face.", "type": "object", "required": [ "__meta", - "id", - "solid", "type", - "value", - "xAxis", - "yAxis", - "zAxis" + "value" ], "properties": { "type": { "type": "string", "enum": [ - "face" + "KclNone" ] }, - "id": { - "description": "The id of the face.", - "type": "string", - "format": "uuid" - }, "value": { - "description": "The tag of the face.", - "type": "string" - }, - "xAxis": { - "description": "What should the face’s X axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "yAxis": { - "description": "What should the face’s Y axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "zAxis": { - "description": "The z-axis (normal).", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "solid": { - "description": "The solid the face is on.", - "allOf": [ - { - "$ref": "#/components/schemas/Solid" - } - ] + "$ref": "#/components/schemas/KclNone" }, "__meta": { "type": "array", @@ -136902,1317 +138002,1450 @@ } ] }, - "BasePath": { - "description": "A base path.", + "TagEngineInfo": { + "description": "Engine information for a tag.", "type": "object", "required": [ - "__geoMeta", - "from", - "to" + "id", + "sketch" ], "properties": { - "from": { - "description": "The from point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "id": { + "description": "The id of the tagged object.", + "type": "string", + "format": "uuid" }, - "to": { - "description": "The to point.", - "type": "array", - "items": { - "type": "number", - "format": "double" - }, - "maxItems": 2, - "minItems": 2 + "sketch": { + "description": "The sketch the tag is on.", + "type": "string", + "format": "uuid" }, - "tag": { - "description": "The tag of the path.", + "path": { + "description": "The path the tag is on.", "allOf": [ { - "$ref": "#/components/schemas/TagDeclarator" + "$ref": "#/components/schemas/Path" } ], "nullable": true }, - "__geoMeta": { - "description": "Metadata.", - "allOf": [ - { - "$ref": "#/components/schemas/GeoMeta" - } - ] - } - } - }, - "TagIdentifier": { - "type": "object", - "required": [ - "__meta", - "value" - ], - "properties": { - "value": { - "type": "string" - }, - "info": { + "surface": { + "description": "The surface information for the tag.", "allOf": [ { - "$ref": "#/components/schemas/TagEngineInfo" + "$ref": "#/components/schemas/ExtrudeSurface" } ], "nullable": true - }, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } } } }, - "EdgeCut": { - "description": "A fillet or a chamfer.", + "Path": { + "description": "A path.", "oneOf": [ { - "description": "A fillet.", + "description": "A path that goes to a point.", "type": "object", "required": [ - "edgeId", - "id", - "radius", + "__geoMeta", + "from", + "to", "type" ], "properties": { "type": { "type": "string", "enum": [ - "fillet" + "ToPoint" ] }, - "id": { - "description": "The id of the engine command that called this fillet.", - "type": "string", - "format": "uuid" - }, - "radius": { - "type": "number", - "format": "double" + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - "edgeId": { - "description": "The engine id of the edge to fillet.", - "type": "string", - "format": "uuid" + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, "tag": { + "description": "The tag of the path.", "allOf": [ { "$ref": "#/components/schemas/TagDeclarator" } ], "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] } } }, { - "description": "A chamfer.", + "description": "A arc that is tangential to the last path segment that goes to a point", "type": "object", "required": [ - "edgeId", - "id", - "length", + "__geoMeta", + "ccw", + "center", + "from", + "to", "type" ], "properties": { "type": { "type": "string", "enum": [ - "chamfer" + "TangentialArcTo" ] }, - "id": { - "description": "The id of the engine command that called this chamfer.", - "type": "string", - "format": "uuid" + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - "length": { - "type": "number", - "format": "double" + "ccw": { + "description": "arc's direction", + "type": "boolean" }, - "edgeId": { - "description": "The engine id of the edge to chamfer.", - "type": "string", - "format": "uuid" + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, "tag": { + "description": "The tag of the path.", "allOf": [ { "$ref": "#/components/schemas/TagDeclarator" } ], "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] } } - } - ] - }, - "FunctionExpression": { - "type": "object", - "required": [ - "body", - "params" - ], - "properties": { - "params": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Parameter" - } - }, - "body": { - "$ref": "#/components/schemas/Program" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - "Parameter": { - "description": "Parameter of a KCL function.", - "type": "object", - "required": [ - "identifier", - "optional" - ], - "properties": { - "identifier": { - "description": "The parameter's label or name.", - "allOf": [ - { - "$ref": "#/components/schemas/Identifier" - } - ] - }, - "optional": { - "description": "Is the parameter optional?", - "type": "boolean" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - } - } - }, - "Identifier": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - "Program": { - "description": "A KCL program top level, or function body.", - "type": "object", - "required": [ - "body" - ], - "properties": { - "body": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BodyItem" - } }, - "nonCodeMeta": { - "$ref": "#/components/schemas/NonCodeMeta" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - "BodyItem": { - "oneOf": [ { + "description": "A arc that is tangential to the last path segment", "type": "object", "required": [ - "items", - "path", - "raw_path", + "__geoMeta", + "ccw", + "center", + "from", + "to", "type" ], "properties": { "type": { "type": "string", "enum": [ - "ImportStatement" + "TangentialArc" ] }, - "items": { + "center": { + "description": "the arc's center", "type": "array", "items": { - "$ref": "#/components/schemas/ImportItem" - } + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - "path": { - "type": "string" + "ccw": { + "description": "arc's direction", + "type": "boolean" }, - "raw_path": { - "type": "string" + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - "digest": { + "to": { + "description": "The to point.", "type": "array", "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "type": "number", + "format": "double" }, - "maxItems": 32, - "minItems": 32, - "nullable": true + "maxItems": 2, + "minItems": 2 }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] } } }, { + "description": "a complete arc", "type": "object", "required": [ - "expression", + "__geoMeta", + "ccw", + "center", + "from", + "radius", + "to", "type" ], "properties": { "type": { "type": "string", "enum": [ - "ExpressionStatement" + "Circle" ] }, - "expression": { - "$ref": "#/components/schemas/Expr" + "center": { + "description": "the arc's center", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - "digest": { + "radius": { + "description": "the arc's radius", + "type": "number", + "format": "double" + }, + "ccw": { + "description": "arc's direction", + "type": "boolean" + }, + "from": { + "description": "The from point.", "type": "array", "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "type": "number", + "format": "double" }, - "maxItems": 32, - "minItems": 32, - "nullable": true + "maxItems": 2, + "minItems": 2 }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] } } }, { + "description": "A path that is horizontal.", "type": "object", "required": [ - "declarations", - "kind", - "type" + "__geoMeta", + "from", + "to", + "type", + "x" ], "properties": { "type": { "type": "string", "enum": [ - "VariableDeclaration" + "Horizontal" ] }, - "declarations": { + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double" + }, + "from": { + "description": "The from point.", "type": "array", "items": { - "$ref": "#/components/schemas/VariableDeclarator" - } - }, - "visibility": { - "$ref": "#/components/schemas/ItemVisibility" - }, - "kind": { - "$ref": "#/components/schemas/VariableKind" + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - "digest": { + "to": { + "description": "The to point.", "type": "array", "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "type": "number", + "format": "double" }, - "maxItems": 32, - "minItems": 32, - "nullable": true + "maxItems": 2, + "minItems": 2 }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] } } }, { + "description": "An angled line to.", "type": "object", "required": [ - "argument", + "__geoMeta", + "from", + "to", "type" ], "properties": { "type": { "type": "string", "enum": [ - "ReturnStatement" + "AngledLineTo" ] }, - "argument": { - "$ref": "#/components/schemas/Expr" + "x": { + "description": "The x coordinate.", + "type": "number", + "format": "double", + "nullable": true }, - "digest": { + "y": { + "description": "The y coordinate.", + "type": "number", + "format": "double", + "nullable": true + }, + "from": { + "description": "The from point.", "type": "array", "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "type": "number", + "format": "double" }, - "maxItems": 32, - "minItems": 32, - "nullable": true + "maxItems": 2, + "minItems": 2 }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] } } - } - ] - }, - "ImportItem": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "description": "Name of the item to import.", - "allOf": [ - { - "$ref": "#/components/schemas/Identifier" - } - ] - }, - "alias": { - "description": "Rename the item using an identifier after \"as\".", - "allOf": [ - { - "$ref": "#/components/schemas/Identifier" - } - ], - "nullable": true - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - "Expr": { - "description": "An expression can be evaluated to yield a single KCL value.", - "oneOf": [ { + "description": "A base path.", "type": "object", "required": [ - "raw", - "type", - "value" + "__geoMeta", + "from", + "to", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "Literal" + "Base" ] }, - "value": { - "$ref": "#/components/schemas/LiteralValue" - }, - "raw": { - "type": "string" - }, - "digest": { + "from": { + "description": "The from point.", "type": "array", "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "type": "number", + "format": "double" }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - { - "type": "object", - "required": [ - "name", - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Identifier" - ] - }, - "name": { - "type": "string" + "maxItems": 2, + "minItems": 2 }, - "digest": { + "to": { + "description": "The to point.", "type": "array", "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "type": "number", + "format": "double" }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - { - "type": "object", - "required": [ - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "TagDeclarator" - ] - }, - "value": { - "type": "string" + "maxItems": 2, + "minItems": 2 }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], "nullable": true }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] } } }, { + "description": "A circular arc, not necessarily tangential to the current point.", "type": "object", "required": [ - "left", - "operator", - "right", + "__geoMeta", + "center", + "from", + "radius", + "to", "type" ], "properties": { "type": { "type": "string", "enum": [ - "BinaryExpression" + "Arc" ] }, - "operator": { - "$ref": "#/components/schemas/BinaryOperator" - }, - "left": { - "$ref": "#/components/schemas/BinaryPart" - }, - "right": { - "$ref": "#/components/schemas/BinaryPart" - }, - "digest": { + "center": { + "description": "Center of the circle that this arc is drawn on.", "type": "array", "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "type": "number", + "format": "double" }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "maxItems": 2, + "minItems": 2 }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - { - "type": "object", - "required": [ - "body", - "params", - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "FunctionExpression" - ] + "radius": { + "description": "Radius of the circle that this arc is drawn on.", + "type": "number", + "format": "double" }, - "params": { + "from": { + "description": "The from point.", "type": "array", "items": { - "$ref": "#/components/schemas/Parameter" - } - }, - "body": { - "$ref": "#/components/schemas/Program" + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 }, - "digest": { + "to": { + "description": "The to point.", "type": "array", "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 + "type": "number", + "format": "double" }, - "maxItems": 32, - "minItems": 32, - "nullable": true + "maxItems": 2, + "minItems": 2 }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] } } + } + ] + }, + "TagDeclarator": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "GeoMeta": { + "description": "Geometry metadata.", + "type": "object", + "required": [ + "id", + "sourceRange" + ], + "properties": { + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" }, + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } + }, + "ExtrudeSurface": { + "description": "An extrude surface.", + "oneOf": [ { + "description": "An extrude plane.", "type": "object", "required": [ - "arguments", - "callee", - "optional", + "faceId", + "id", + "sourceRange", "type" ], "properties": { "type": { "type": "string", "enum": [ - "CallExpression" + "extrudePlane" ] }, - "callee": { - "$ref": "#/components/schemas/Identifier" - }, - "arguments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Expr" - } - }, - "optional": { - "type": "boolean" + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], "nullable": true }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] } } }, { + "description": "An extruded arc.", "type": "object", "required": [ - "body", + "faceId", + "id", + "sourceRange", "type" ], "properties": { "type": { "type": "string", "enum": [ - "PipeExpression" + "extrudeArc" ] }, - "body": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Expr" - } - }, - "nonCodeMeta": { - "$ref": "#/components/schemas/NonCodeMeta" + "faceId": { + "description": "The face id for the extrude plane.", + "type": "string", + "format": "uuid" }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], "nullable": true }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] } } }, { + "description": "Geometry metadata.", "type": "object", "required": [ + "faceId", + "id", + "sourceRange", "type" ], "properties": { "type": { "type": "string", "enum": [ - "PipeSubstitution" + "chamfer" ] }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, + "faceId": { + "description": "The id for the chamfer surface.", + "type": "string", + "format": "uuid" + }, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], "nullable": true }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] } } }, { + "description": "Geometry metadata.", "type": "object", "required": [ - "elements", + "faceId", + "id", + "sourceRange", "type" ], "properties": { "type": { "type": "string", "enum": [ - "ArrayExpression" + "fillet" ] }, - "elements": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Expr" - } - }, - "nonCodeMeta": { - "$ref": "#/components/schemas/NonCodeMeta" + "faceId": { + "description": "The id for the fillet surface.", + "type": "string", + "format": "uuid" }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, + "tag": { + "description": "The tag.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], "nullable": true }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "id": { + "description": "The id of the geometry.", + "type": "string", + "format": "uuid" }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] } } + } + ] + }, + "PlaneType": { + "description": "Type for a plane.", + "oneOf": [ + { + "type": "string", + "enum": [ + "XY", + "XZ", + "YZ" + ] }, { - "type": "object", - "required": [ - "endElement", - "endInclusive", - "startElement", - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "ArrayRangeExpression" - ] - }, - "startElement": { - "$ref": "#/components/schemas/Expr" - }, - "endElement": { - "$ref": "#/components/schemas/Expr" - }, - "endInclusive": { - "description": "Is the `end_element` included in the range?", - "type": "boolean" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "description": "A custom plane.", + "type": "string", + "enum": [ + "Custom" + ] + } + ] + }, + "Point3d": { + "type": "object", + "required": [ + "x", + "y", + "z" + ], + "properties": { + "x": { + "type": "number", + "format": "double" + }, + "y": { + "type": "number", + "format": "double" + }, + "z": { + "type": "number", + "format": "double" + } + } + }, + "Solid": { + "description": "An solid is a collection of extrude surfaces.", + "type": "object", + "required": [ + "__meta", + "height", + "id", + "sketch", + "value" + ], + "properties": { + "id": { + "description": "The id of the solid.", + "type": "string", + "format": "uuid" + }, + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ExtrudeSurface" + } + }, + "sketch": { + "description": "The sketch.", + "allOf": [ + { + "$ref": "#/components/schemas/Sketch" + } + ] + }, + "height": { + "description": "The height of the solid.", + "type": "number", + "format": "double" + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "edgeCuts": { + "description": "Chamfers or fillets on this solid.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EdgeCut" + } + }, + "__meta": { + "description": "Metadata.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + "Sketch": { + "description": "A sketch is a collection of paths.", + "type": "object", + "required": [ + "__meta", + "id", + "on", + "paths", + "start" + ], + "properties": { + "id": { + "description": "The id of the sketch (this will change when the engine's reference to it changes).", + "type": "string", + "format": "uuid" + }, + "paths": { + "description": "The paths in the sketch.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Path" + } + }, + "on": { + "description": "What the sketch is on (can be a plane or a face).", + "allOf": [ + { + "$ref": "#/components/schemas/SketchSurface" + } + ] + }, + "start": { + "description": "The starting path.", + "allOf": [ + { + "$ref": "#/components/schemas/BasePath" } + ] + }, + "tags": { + "description": "Tag identifiers that have been declared in this sketch.", + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/TagIdentifier" } }, + "__meta": { + "description": "Metadata.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + "SketchSurface": { + "description": "A sketch type.", + "oneOf": [ { + "description": "A plane.", "type": "object", "required": [ - "properties", - "type" + "__meta", + "id", + "origin", + "type", + "value", + "xAxis", + "yAxis", + "zAxis" ], "properties": { "type": { "type": "string", "enum": [ - "ObjectExpression" + "plane" ] }, - "properties": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ObjectProperty" - } + "id": { + "description": "The id of the plane.", + "type": "string", + "format": "uuid" }, - "nonCodeMeta": { - "$ref": "#/components/schemas/NonCodeMeta" + "value": { + "$ref": "#/components/schemas/PlaneType" }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true + "origin": { + "description": "Origin of the plane.", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "xAxis": { + "description": "What should the plane’s X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "yAxis": { + "description": "What should the plane’s Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } } } }, { + "description": "A face.", "type": "object", "required": [ - "computed", - "object", - "property", - "type" + "__meta", + "id", + "solid", + "type", + "value", + "xAxis", + "yAxis", + "zAxis" ], "properties": { "type": { "type": "string", "enum": [ - "MemberExpression" + "face" ] }, - "object": { - "$ref": "#/components/schemas/MemberObject" + "id": { + "description": "The id of the face.", + "type": "string", + "format": "uuid" }, - "property": { - "$ref": "#/components/schemas/LiteralIdentifier" + "value": { + "description": "The tag of the face.", + "type": "string" }, - "computed": { - "type": "boolean" + "xAxis": { + "description": "What should the face’s X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true + "yAxis": { + "description": "What should the face’s Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "solid": { + "description": "The solid the face is on.", + "allOf": [ + { + "$ref": "#/components/schemas/Solid" + } + ] + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } } } + } + ] + }, + "BasePath": { + "description": "A base path.", + "type": "object", + "required": [ + "__geoMeta", + "from", + "to" + ], + "properties": { + "from": { + "description": "The from point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "to": { + "description": "The to point.", + "type": "array", + "items": { + "type": "number", + "format": "double" + }, + "maxItems": 2, + "minItems": 2 + }, + "tag": { + "description": "The tag of the path.", + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true + }, + "__geoMeta": { + "description": "Metadata.", + "allOf": [ + { + "$ref": "#/components/schemas/GeoMeta" + } + ] + } + } + }, + "TagIdentifier": { + "type": "object", + "required": [ + "__meta", + "value" + ], + "properties": { + "value": { + "type": "string" + }, + "info": { + "allOf": [ + { + "$ref": "#/components/schemas/TagEngineInfo" + } + ], + "nullable": true }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + "EdgeCut": { + "description": "A fillet or a chamfer.", + "oneOf": [ { + "description": "A fillet.", "type": "object", "required": [ - "argument", - "operator", + "edgeId", + "id", + "radius", "type" ], "properties": { "type": { "type": "string", "enum": [ - "UnaryExpression" + "fillet" ] }, - "operator": { - "$ref": "#/components/schemas/UnaryOperator" - }, - "argument": { - "$ref": "#/components/schemas/BinaryPart" + "id": { + "description": "The id of the engine command that called this fillet.", + "type": "string", + "format": "uuid" }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true + "radius": { + "type": "number", + "format": "double" }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "edgeId": { + "description": "The engine id of the edge to fillet.", + "type": "string", + "format": "uuid" }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], + "nullable": true } } }, { + "description": "A chamfer.", "type": "object", "required": [ - "cond", - "else_ifs", - "final_else", - "then_val", + "edgeId", + "id", + "length", "type" ], "properties": { "type": { "type": "string", "enum": [ - "IfExpression" + "chamfer" ] }, - "cond": { - "$ref": "#/components/schemas/Expr" - }, - "then_val": { - "$ref": "#/components/schemas/Program" + "id": { + "description": "The id of the engine command that called this chamfer.", + "type": "string", + "format": "uuid" }, - "else_ifs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ElseIf" - } + "length": { + "type": "number", + "format": "double" }, - "final_else": { - "$ref": "#/components/schemas/Program" + "edgeId": { + "description": "The engine id of the edge to chamfer.", + "type": "string", + "format": "uuid" }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, + "tag": { + "allOf": [ + { + "$ref": "#/components/schemas/TagDeclarator" + } + ], "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - { - "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "None" - ] - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 } } } ] }, - "LiteralValue": { - "anyOf": [ - { - "type": "integer", - "format": "int64" + "FunctionExpression": { + "type": "object", + "required": [ + "body", + "params" + ], + "properties": { + "params": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Parameter" + } }, - { - "type": "number", - "format": "double" + "body": { + "$ref": "#/components/schemas/Program" }, - { - "type": "string" + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true }, - { - "type": "boolean" + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } - ] + } }, - "BinaryOperator": { - "oneOf": [ - { - "description": "Add two numbers.", - "type": "string", - "enum": [ - "+" - ] - }, - { - "description": "Subtract two numbers.", - "type": "string", - "enum": [ - "-" - ] - }, - { - "description": "Multiply two numbers.", - "type": "string", - "enum": [ - "*" + "Parameter": { + "description": "Parameter of a KCL function.", + "type": "object", + "required": [ + "identifier", + "optional" + ], + "properties": { + "identifier": { + "description": "The parameter's label or name.", + "allOf": [ + { + "$ref": "#/components/schemas/Identifier" + } ] }, - { - "description": "Divide two numbers.", - "type": "string", - "enum": [ - "/" - ] + "optional": { + "description": "Is the parameter optional?", + "type": "boolean" }, - { - "description": "Modulo two numbers.", - "type": "string", - "enum": [ - "%" - ] + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + } + } + }, + "Identifier": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" }, - { - "description": "Raise a number to a power.", - "type": "string", - "enum": [ - "^" - ] + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true }, - { - "description": "Are two numbers equal?", - "type": "string", - "enum": [ - "==" - ] + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 }, - { - "description": "Are two numbers not equal?", - "type": "string", - "enum": [ - "!=" - ] + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "Program": { + "description": "A KCL program top level, or function body.", + "type": "object", + "required": [ + "body" + ], + "properties": { + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BodyItem" + } }, - { - "description": "Is left greater than right", - "type": "string", - "enum": [ - ">" - ] + "nonCodeMeta": { + "$ref": "#/components/schemas/NonCodeMeta" }, - { - "description": "Is left greater than or equal to right", - "type": "string", - "enum": [ - ">=" - ] + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true }, - { - "description": "Is left less than right", - "type": "string", - "enum": [ - "<" - ] + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 }, - { - "description": "Is left less than or equal to right", - "type": "string", - "enum": [ - "<=" - ] + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } - ] + } }, - "BinaryPart": { + "BodyItem": { "oneOf": [ { "type": "object", "required": [ - "raw", - "type", - "value" + "items", + "path", + "raw_path", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "Literal" + "ImportStatement" ] }, - "value": { - "$ref": "#/components/schemas/LiteralValue" + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ImportItem" + } }, - "raw": { + "path": { + "type": "string" + }, + "raw_path": { "type": "string" }, "digest": { @@ -138241,18 +139474,18 @@ { "type": "object", "required": [ - "name", + "expression", "type" ], "properties": { "type": { "type": "string", "enum": [ - "Identifier" + "ExpressionStatement" ] }, - "name": { - "type": "string" + "expression": { + "$ref": "#/components/schemas/Expr" }, "digest": { "type": "array", @@ -138280,26 +139513,28 @@ { "type": "object", "required": [ - "left", - "operator", - "right", + "declarations", + "kind", "type" ], "properties": { "type": { "type": "string", "enum": [ - "BinaryExpression" + "VariableDeclaration" ] }, - "operator": { - "$ref": "#/components/schemas/BinaryOperator" + "declarations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VariableDeclarator" + } }, - "left": { - "$ref": "#/components/schemas/BinaryPart" + "visibility": { + "$ref": "#/components/schemas/ItemVisibility" }, - "right": { - "$ref": "#/components/schemas/BinaryPart" + "kind": { + "$ref": "#/components/schemas/VariableKind" }, "digest": { "type": "array", @@ -138327,29 +139562,18 @@ { "type": "object", "required": [ - "arguments", - "callee", - "optional", + "argument", "type" ], "properties": { "type": { "type": "string", "enum": [ - "CallExpression" + "ReturnStatement" ] }, - "callee": { - "$ref": "#/components/schemas/Identifier" - }, - "arguments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Expr" - } - }, - "optional": { - "type": "boolean" + "argument": { + "$ref": "#/components/schemas/Expr" }, "digest": { "type": "array", @@ -138373,26 +139597,77 @@ "minimum": 0.0 } } + } + ] + }, + "ImportItem": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "description": "Name of the item to import.", + "allOf": [ + { + "$ref": "#/components/schemas/Identifier" + } + ] + }, + "alias": { + "description": "Rename the item using an identifier after \"as\".", + "allOf": [ + { + "$ref": "#/components/schemas/Identifier" + } + ], + "nullable": true + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "Expr": { + "description": "An expression can be evaluated to yield a single KCL value.", + "oneOf": [ { "type": "object", "required": [ - "argument", - "operator", - "type" + "raw", + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "UnaryExpression" + "Literal" ] }, - "operator": { - "$ref": "#/components/schemas/UnaryOperator" + "value": { + "$ref": "#/components/schemas/LiteralValue" }, - "argument": { - "$ref": "#/components/schemas/BinaryPart" + "raw": { + "type": "string" }, "digest": { "type": "array", @@ -138420,26 +139695,18 @@ { "type": "object", "required": [ - "computed", - "object", - "property", + "name", "type" ], "properties": { "type": { "type": "string", "enum": [ - "MemberExpression" + "Identifier" ] }, - "object": { - "$ref": "#/components/schemas/MemberObject" - }, - "property": { - "$ref": "#/components/schemas/LiteralIdentifier" - }, - "computed": { - "type": "boolean" + "name": { + "type": "string" }, "digest": { "type": "array", @@ -138467,33 +139734,18 @@ { "type": "object", "required": [ - "cond", - "else_ifs", - "final_else", - "then_val", - "type" + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "IfExpression" + "TagDeclarator" ] }, - "cond": { - "$ref": "#/components/schemas/Expr" - }, - "then_val": { - "$ref": "#/components/schemas/Program" - }, - "else_ifs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ElseIf" - } - }, - "final_else": { - "$ref": "#/components/schemas/Program" + "value": { + "type": "string" }, "digest": { "type": "array", @@ -138517,52 +139769,30 @@ "minimum": 0.0 } } - } - ] - }, - "UnaryOperator": { - "oneOf": [ - { - "description": "Negate a number.", - "type": "string", - "enum": [ - "-" - ] }, - { - "description": "Negate a boolean.", - "type": "string", - "enum": [ - "!" - ] - } - ] - }, - "MemberObject": { - "oneOf": [ { "type": "object", "required": [ - "computed", - "object", - "property", + "left", + "operator", + "right", "type" ], "properties": { "type": { "type": "string", "enum": [ - "MemberExpression" + "BinaryExpression" ] }, - "object": { - "$ref": "#/components/schemas/MemberObject" + "operator": { + "$ref": "#/components/schemas/BinaryOperator" }, - "property": { - "$ref": "#/components/schemas/LiteralIdentifier" + "left": { + "$ref": "#/components/schemas/BinaryPart" }, - "computed": { - "type": "boolean" + "right": { + "$ref": "#/components/schemas/BinaryPart" }, "digest": { "type": "array", @@ -138590,18 +139820,25 @@ { "type": "object", "required": [ - "name", + "body", + "params", "type" ], "properties": { "type": { "type": "string", "enum": [ - "Identifier" + "FunctionExpression" ] }, - "name": { - "type": "string" + "params": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Parameter" + } + }, + "body": { + "$ref": "#/components/schemas/Program" }, "digest": { "type": "array", @@ -138625,26 +139862,33 @@ "minimum": 0.0 } } - } - ] - }, - "LiteralIdentifier": { - "oneOf": [ + }, { "type": "object", "required": [ - "name", + "arguments", + "callee", + "optional", "type" ], "properties": { "type": { "type": "string", "enum": [ - "Identifier" + "CallExpression" ] }, - "name": { - "type": "string" + "callee": { + "$ref": "#/components/schemas/Identifier" + }, + "arguments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Expr" + } + }, + "optional": { + "type": "boolean" }, "digest": { "type": "array", @@ -138672,22 +139916,24 @@ { "type": "object", "required": [ - "raw", - "type", - "value" + "body", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "Literal" + "PipeExpression" ] }, - "value": { - "$ref": "#/components/schemas/LiteralValue" + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Expr" + } }, - "raw": { - "type": "string" + "nonCodeMeta": { + "$ref": "#/components/schemas/NonCodeMeta" }, "digest": { "type": "array", @@ -138711,203 +139957,326 @@ "minimum": 0.0 } } - } - ] - }, - "ElseIf": { - "type": "object", - "required": [ - "cond", - "then_val" - ], - "properties": { - "cond": { - "$ref": "#/components/schemas/Expr" - }, - "then_val": { - "$ref": "#/components/schemas/Program" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - "NonCodeMeta": { - "type": "object", - "required": [ - "nonCodeNodes", - "startNodes" - ], - "properties": { - "nonCodeNodes": { + { "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NonCodeNode" + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "PipeSubstitution" + ] + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, - "startNodes": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NonCodeNode" + { + "type": "object", + "required": [ + "elements", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ArrayExpression" + ] + }, + "elements": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Expr" + } + }, + "nonCodeMeta": { + "$ref": "#/components/schemas/NonCodeMeta" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } } }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - } - } - }, - "NonCodeNode": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "$ref": "#/components/schemas/NonCodeValue" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + { + "type": "object", + "required": [ + "endElement", + "endInclusive", + "startElement", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ArrayRangeExpression" + ] + }, + "startElement": { + "$ref": "#/components/schemas/Expr" + }, + "endElement": { + "$ref": "#/components/schemas/Expr" + }, + "endInclusive": { + "description": "Is the `end_element` included in the range?", + "type": "boolean" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - "NonCodeValue": { - "oneOf": [ { - "description": "A shebang. This is a special type of comment that is at the top of the file. It looks like this: ```python,no_run #!/usr/bin/env python ```", "type": "object", "required": [ - "type", - "value" + "properties", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "shebang" + "ObjectExpression" ] }, - "value": { - "type": "string" + "properties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ObjectProperty" + } + }, + "nonCodeMeta": { + "$ref": "#/components/schemas/NonCodeMeta" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, { - "description": "An inline comment. Here are examples: `1 + 1 // This is an inline comment`. `1 + 1 /* Here's another */`.", "type": "object", "required": [ - "style", - "type", - "value" + "computed", + "object", + "property", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "inlineComment" + "MemberExpression" ] }, - "value": { - "type": "string" + "object": { + "$ref": "#/components/schemas/MemberObject" }, - "style": { - "$ref": "#/components/schemas/CommentStyle" + "property": { + "$ref": "#/components/schemas/LiteralIdentifier" + }, + "computed": { + "type": "boolean" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, { - "description": "A block comment. An example of this is the following: ```python,no_run /* This is a block comment */ 1 + 1 ``` Now this is important. The block comment is attached to the next line. This is always the case. Also the block comment doesn't have a new line above it. If it did it would be a `NewLineBlockComment`.", "type": "object", "required": [ - "style", - "type", - "value" + "argument", + "operator", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "blockComment" + "UnaryExpression" ] }, - "value": { - "type": "string" + "operator": { + "$ref": "#/components/schemas/UnaryOperator" }, - "style": { - "$ref": "#/components/schemas/CommentStyle" + "argument": { + "$ref": "#/components/schemas/BinaryPart" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, { - "description": "A block comment that has a new line above it. The user explicitly added a new line above the block comment.", "type": "object", "required": [ - "style", - "type", - "value" + "cond", + "else_ifs", + "final_else", + "then_val", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "newLineBlockComment" + "IfExpression" ] }, - "value": { - "type": "string" + "cond": { + "$ref": "#/components/schemas/Expr" }, - "style": { - "$ref": "#/components/schemas/CommentStyle" + "then_val": { + "$ref": "#/components/schemas/Program" + }, + "else_ifs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ElseIf" + } + }, + "final_else": { + "$ref": "#/components/schemas/Program" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", "type": "object", "required": [ "type" @@ -138916,216 +140285,135 @@ "type": { "type": "string", "enum": [ - "newLine" + "None" ] + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } } ] }, - "CommentStyle": { + "LiteralValue": { + "anyOf": [ + { + "type": "integer", + "format": "int64" + }, + { + "type": "number", + "format": "double" + }, + { + "type": "string" + }, + { + "type": "boolean" + } + ] + }, + "BinaryOperator": { "oneOf": [ { - "description": "Like // foo", + "description": "Add two numbers.", "type": "string", "enum": [ - "line" + "+" ] }, { - "description": "Like /* foo */", + "description": "Subtract two numbers.", "type": "string", "enum": [ - "block" + "-" ] - } - ] - }, - "ObjectProperty": { - "type": "object", - "required": [ - "key", - "value" - ], - "properties": { - "key": { - "$ref": "#/components/schemas/Identifier" }, - "value": { - "$ref": "#/components/schemas/Expr" + { + "description": "Multiply two numbers.", + "type": "string", + "enum": [ + "*" + ] }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true + { + "description": "Divide two numbers.", + "type": "string", + "enum": [ + "/" + ] }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + { + "description": "Modulo two numbers.", + "type": "string", + "enum": [ + "%" + ] }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - "VariableDeclarator": { - "type": "object", - "required": [ - "id", - "init" - ], - "properties": { - "id": { - "description": "The identifier of the variable.", - "allOf": [ - { - "$ref": "#/components/schemas/Identifier" - } + { + "description": "Raise a number to a power.", + "type": "string", + "enum": [ + "^" ] }, - "init": { - "description": "The value of the variable.", - "allOf": [ - { - "$ref": "#/components/schemas/Expr" - } + { + "description": "Are two numbers equal?", + "type": "string", + "enum": [ + "==" ] }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - "ItemVisibility": { - "type": "string", - "enum": [ - "default", - "export" - ] - }, - "VariableKind": { - "oneOf": [ { - "description": "Declare a named constant.", + "description": "Are two numbers not equal?", "type": "string", "enum": [ - "const" + "!=" ] }, { - "description": "Declare a function.", + "description": "Is left greater than right", "type": "string", "enum": [ - "fn" + ">" ] - } - ] - }, - "ProgramMemory": { - "type": "object", - "required": [ - "currentEnv", - "environments" - ], - "properties": { - "environments": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Environment" - } }, - "currentEnv": { - "type": "integer", - "format": "uint", - "minimum": 0.0 + { + "description": "Is left greater than or equal to right", + "type": "string", + "enum": [ + ">=" + ] }, - "return": { - "allOf": [ - { - "$ref": "#/components/schemas/KclValue" - } - ], - "nullable": true - } - } - }, - "Environment": { - "type": "object", - "required": [ - "bindings" - ], - "properties": { - "bindings": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/KclValue" - } + { + "description": "Is left less than right", + "type": "string", + "enum": [ + "<" + ] }, - "parent": { - "type": "integer", - "format": "uint", - "minimum": 0.0, - "nullable": true + { + "description": "Is left less than or equal to right", + "type": "string", + "enum": [ + "<=" + ] } - } + ] }, - "KclValue": { - "description": "Any KCL value.", + "BinaryPart": { "oneOf": [ { "type": "object", "required": [ - "__meta", - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "UserVal" - ] - }, - "value": {}, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { - "type": "object", - "required": [ - "__meta", + "raw", "type", "value" ], @@ -139133,42 +140421,52 @@ "type": { "type": "string", "enum": [ - "TagIdentifier" + "Literal" ] }, "value": { - "type": "string" + "$ref": "#/components/schemas/LiteralValue" }, - "info": { - "allOf": [ - { - "$ref": "#/components/schemas/TagEngineInfo" - } - ], - "nullable": true + "raw": { + "type": "string" }, - "__meta": { + "digest": { "type": "array", "items": { - "$ref": "#/components/schemas/Metadata" - } + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, { "type": "object", "required": [ - "type", - "value" + "name", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "TagDeclarator" + "Identifier" ] }, - "value": { + "name": { "type": "string" }, "digest": { @@ -139195,627 +140493,954 @@ } }, { - "description": "A plane.", "type": "object", "required": [ - "__meta", - "id", - "origin", - "type", - "value", - "xAxis", - "yAxis", - "zAxis" + "left", + "operator", + "right", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "Plane" - ] - }, - "id": { - "description": "The id of the plane.", - "type": "string", - "format": "uuid" - }, - "value": { - "$ref": "#/components/schemas/PlaneType" - }, - "origin": { - "description": "Origin of the plane.", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } + "BinaryExpression" ] }, - "xAxis": { - "description": "What should the plane’s X axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] + "operator": { + "$ref": "#/components/schemas/BinaryOperator" }, - "yAxis": { - "description": "What should the plane’s Y axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] + "left": { + "$ref": "#/components/schemas/BinaryPart" }, - "zAxis": { - "description": "The z-axis (normal).", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] + "right": { + "$ref": "#/components/schemas/BinaryPart" }, - "__meta": { + "digest": { "type": "array", "items": { - "$ref": "#/components/schemas/Metadata" - } + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, { - "description": "A face.", "type": "object", "required": [ - "__meta", - "id", - "solid", - "type", - "value", - "xAxis", - "yAxis", - "zAxis" + "arguments", + "callee", + "optional", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "Face" - ] - }, - "id": { - "description": "The id of the face.", - "type": "string", - "format": "uuid" - }, - "value": { - "description": "The tag of the face.", - "type": "string" - }, - "xAxis": { - "description": "What should the face’s X axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } + "CallExpression" ] }, - "yAxis": { - "description": "What should the face’s Y axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] + "callee": { + "$ref": "#/components/schemas/Identifier" }, - "zAxis": { - "description": "The z-axis (normal).", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] + "arguments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Expr" + } }, - "solid": { - "description": "The solid the face is on.", - "allOf": [ - { - "$ref": "#/components/schemas/Solid" - } - ] + "optional": { + "type": "boolean" }, - "__meta": { + "digest": { "type": "array", "items": { - "$ref": "#/components/schemas/Metadata" - } + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, { - "description": "An solid is a collection of extrude surfaces.", "type": "object", "required": [ - "__meta", - "height", - "id", - "sketch", - "type", - "value" + "argument", + "operator", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "Solid" + "UnaryExpression" ] }, - "id": { - "description": "The id of the solid.", - "type": "string", - "format": "uuid" + "operator": { + "$ref": "#/components/schemas/UnaryOperator" }, - "value": { - "description": "The extrude surfaces.", + "argument": { + "$ref": "#/components/schemas/BinaryPart" + }, + "digest": { "type": "array", "items": { - "$ref": "#/components/schemas/ExtrudeSurface" - } - }, - "sketch": { - "description": "The sketch.", - "allOf": [ - { - "$ref": "#/components/schemas/Sketch" - } - ] - }, - "height": { - "description": "The height of the solid.", - "type": "number", - "format": "double" - }, - "startCapId": { - "description": "The id of the extrusion start cap", - "type": "string", - "format": "uuid", - "nullable": true - }, - "endCapId": { - "description": "The id of the extrusion end cap", - "type": "string", - "format": "uuid", + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, "nullable": true }, - "edgeCuts": { - "description": "Chamfers or fillets on this solid.", - "type": "array", - "items": { - "$ref": "#/components/schemas/EdgeCut" - } + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 }, - "__meta": { - "description": "Metadata.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, { "type": "object", "required": [ - "type", - "value" + "computed", + "object", + "property", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "Solids" + "MemberExpression" ] }, - "value": { + "object": { + "$ref": "#/components/schemas/MemberObject" + }, + "property": { + "$ref": "#/components/schemas/LiteralIdentifier" + }, + "computed": { + "type": "boolean" + }, + "digest": { "type": "array", "items": { - "$ref": "#/components/schemas/Solid" - } + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } }, { - "description": "Data for an imported geometry.", "type": "object", "required": [ - "__meta", - "id", - "type", - "value" + "cond", + "else_ifs", + "final_else", + "then_val", + "type" ], "properties": { "type": { "type": "string", "enum": [ - "ImportedGeometry" + "IfExpression" ] }, - "id": { - "description": "The ID of the imported geometry.", - "type": "string", - "format": "uuid" + "cond": { + "$ref": "#/components/schemas/Expr" }, - "value": { - "description": "The original file paths.", + "then_val": { + "$ref": "#/components/schemas/Program" + }, + "else_ifs": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/ElseIf" } }, - "__meta": { + "final_else": { + "$ref": "#/components/schemas/Program" + }, + "digest": { "type": "array", "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + } + ] + }, + "UnaryOperator": { + "oneOf": [ + { + "description": "Negate a number.", + "type": "string", + "enum": [ + "-" + ] + }, + { + "description": "Negate a boolean.", + "type": "string", + "enum": [ + "!" + ] + } + ] + }, + "MemberObject": { + "oneOf": [ + { "type": "object", "required": [ - "__meta", - "expression", - "memory", + "computed", + "object", + "property", "type" ], "properties": { "type": { "type": "string", "enum": [ - "Function" + "MemberExpression" ] }, - "expression": { - "$ref": "#/components/schemas/FunctionExpression" + "object": { + "$ref": "#/components/schemas/MemberObject" }, - "memory": { - "$ref": "#/components/schemas/ProgramMemory" + "property": { + "$ref": "#/components/schemas/LiteralIdentifier" }, - "__meta": { + "computed": { + "type": "boolean" + }, + "digest": { "type": "array", "items": { - "$ref": "#/components/schemas/Metadata" - } + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Identifier" + ] + }, + "name": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } } } ] - } - } - }, - "required": true - }, - "unpublished": false, - "deprecated": false, - "examples": [ - "arr = [1, 2, 3]\nnew_arr = push(arr, 4)\nassertEqual(new_arr[3], 4, 0.00001, \"4 was added to the end of the array\")" - ] - }, - { - "name": "reduce", - "summary": "Take a starting value. Then, for each element of an array, calculate the next value,", - "description": "using the previous value and the element.", - "tags": [], - "args": [ - { - "name": "array", - "type": "[KclValue]", - "schema": { - "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", - "title": "Array_of_KclValue", - "type": "array", - "items": { - "$ref": "#/components/schemas/KclValue" }, - "definitions": { - "KclValue": { - "description": "Any KCL value.", - "oneOf": [ - { - "type": "object", - "required": [ - "__meta", - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "UserVal" - ] - }, - "value": {}, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { - "type": "object", - "required": [ - "__meta", - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "TagIdentifier" - ] - }, - "value": { - "type": "string" - }, - "info": { - "allOf": [ - { - "$ref": "#/components/schemas/TagEngineInfo" - } - ], - "nullable": true - }, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { - "type": "object", - "required": [ - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "TagDeclarator" - ] - }, - "value": { - "type": "string" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { + "LiteralIdentifier": { + "oneOf": [ + { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Identifier" + ] + }, + "name": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { "type": "integer", - "format": "uint", + "format": "uint8", "minimum": 0.0 }, - "end": { + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + { + "type": "object", + "required": [ + "raw", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Literal" + ] + }, + "value": { + "$ref": "#/components/schemas/LiteralValue" + }, + "raw": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { "type": "integer", - "format": "uint", + "format": "uint8", "minimum": 0.0 - } - } - }, - { - "description": "A plane.", - "type": "object", - "required": [ - "__meta", - "id", - "origin", - "type", - "value", - "xAxis", - "yAxis", - "zAxis" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Plane" - ] - }, - "id": { - "description": "The id of the plane.", - "type": "string", - "format": "uuid" - }, - "value": { - "$ref": "#/components/schemas/PlaneType" - }, - "origin": { - "description": "Origin of the plane.", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "xAxis": { - "description": "What should the plane’s X axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "yAxis": { - "description": "What should the plane’s Y axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "zAxis": { - "description": "The z-axis (normal).", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] }, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 } + } + } + ] + }, + "ElseIf": { + "type": "object", + "required": [ + "cond", + "then_val" + ], + "properties": { + "cond": { + "$ref": "#/components/schemas/Expr" + }, + "then_val": { + "$ref": "#/components/schemas/Program" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 }, - { - "description": "A face.", - "type": "object", - "required": [ - "__meta", - "id", - "solid", - "type", - "value", - "xAxis", - "yAxis", - "zAxis" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Face" - ] - }, - "id": { - "description": "The id of the face.", - "type": "string", - "format": "uuid" - }, - "value": { - "description": "The tag of the face.", - "type": "string" - }, - "xAxis": { - "description": "What should the face’s X axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "yAxis": { - "description": "What should the face’s Y axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "zAxis": { - "description": "The z-axis (normal).", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "solid": { - "description": "The solid the face is on.", - "allOf": [ - { - "$ref": "#/components/schemas/Solid" - } - ] - }, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "NonCodeMeta": { + "type": "object", + "required": [ + "nonCodeNodes", + "startNodes" + ], + "properties": { + "nonCodeNodes": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NonCodeNode" } - }, - { - "description": "An solid is a collection of extrude surfaces.", - "type": "object", - "required": [ - "__meta", - "height", - "id", - "sketch", - "type", - "value" - ], - "properties": { + } + }, + "startNodes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NonCodeNode" + } + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + } + } + }, + "NonCodeNode": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "$ref": "#/components/schemas/NonCodeValue" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "NonCodeValue": { + "oneOf": [ + { + "description": "A shebang. This is a special type of comment that is at the top of the file. It looks like this: ```python,no_run #!/usr/bin/env python ```", + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "shebang" + ] + }, + "value": { + "type": "string" + } + } + }, + { + "description": "An inline comment. Here are examples: `1 + 1 // This is an inline comment`. `1 + 1 /* Here's another */`.", + "type": "object", + "required": [ + "style", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "inlineComment" + ] + }, + "value": { + "type": "string" + }, + "style": { + "$ref": "#/components/schemas/CommentStyle" + } + } + }, + { + "description": "A block comment. An example of this is the following: ```python,no_run /* This is a block comment */ 1 + 1 ``` Now this is important. The block comment is attached to the next line. This is always the case. Also the block comment doesn't have a new line above it. If it did it would be a `NewLineBlockComment`.", + "type": "object", + "required": [ + "style", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "blockComment" + ] + }, + "value": { + "type": "string" + }, + "style": { + "$ref": "#/components/schemas/CommentStyle" + } + } + }, + { + "description": "A block comment that has a new line above it. The user explicitly added a new line above the block comment.", + "type": "object", + "required": [ + "style", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "newLineBlockComment" + ] + }, + "value": { + "type": "string" + }, + "style": { + "$ref": "#/components/schemas/CommentStyle" + } + } + }, + { + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "newLine" + ] + } + } + } + ] + }, + "CommentStyle": { + "oneOf": [ + { + "description": "Like // foo", + "type": "string", + "enum": [ + "line" + ] + }, + { + "description": "Like /* foo */", + "type": "string", + "enum": [ + "block" + ] + } + ] + }, + "ObjectProperty": { + "type": "object", + "required": [ + "key", + "value" + ], + "properties": { + "key": { + "$ref": "#/components/schemas/Identifier" + }, + "value": { + "$ref": "#/components/schemas/Expr" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "VariableDeclarator": { + "type": "object", + "required": [ + "id", + "init" + ], + "properties": { + "id": { + "description": "The identifier of the variable.", + "allOf": [ + { + "$ref": "#/components/schemas/Identifier" + } + ] + }, + "init": { + "description": "The value of the variable.", + "allOf": [ + { + "$ref": "#/components/schemas/Expr" + } + ] + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + "ItemVisibility": { + "type": "string", + "enum": [ + "default", + "export" + ] + }, + "VariableKind": { + "oneOf": [ + { + "description": "Declare a named constant.", + "type": "string", + "enum": [ + "const" + ] + }, + { + "description": "Declare a function.", + "type": "string", + "enum": [ + "fn" + ] + } + ] + }, + "ProgramMemory": { + "type": "object", + "required": [ + "currentEnv", + "environments" + ], + "properties": { + "environments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Environment" + } + }, + "currentEnv": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "return": { + "allOf": [ + { + "$ref": "#/components/schemas/KclValue" + } + ], + "nullable": true + } + } + }, + "Environment": { + "type": "object", + "required": [ + "bindings" + ], + "properties": { + "bindings": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, + "parent": { + "type": "integer", + "format": "uint", + "minimum": 0.0, + "nullable": true + } + } + }, + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" + } + } + }, + "required": true + }, + "unpublished": false, + "deprecated": false, + "examples": [ + "arr = [1, 2, 3]\nnew_arr = push(arr, 4)\nassertEqual(new_arr[3], 4, 0.00001, \"4 was added to the end of the array\")" + ] + }, + { + "name": "reduce", + "summary": "Take a starting value. Then, for each element of an array, calculate the next value,", + "description": "using the previous value and the element.", + "tags": [], + "args": [ + { + "name": "array", + "type": "[KclValue]", + "schema": { + "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema", + "title": "Array_of_KclValue", + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + }, + "definitions": { + "KclValue": { + "description": "Any KCL value.", + "oneOf": [ + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { "type": { "type": "string", "enum": [ - "Solid" + "Uuid" ] }, - "id": { - "description": "The id of the solid.", + "value": { "type": "string", "format": "uuid" }, - "value": { - "description": "The extrude surfaces.", + "__meta": { "type": "array", "items": { - "$ref": "#/components/schemas/ExtrudeSurface" + "$ref": "#/components/schemas/Metadata" } - }, - "sketch": { - "description": "The sketch.", - "allOf": [ - { - "$ref": "#/components/schemas/Sketch" - } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" ] }, - "height": { - "description": "The height of the solid.", - "type": "number", - "format": "double" + "value": { + "type": "boolean" }, - "startCapId": { - "description": "The id of the extrusion start cap", + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { "type": "string", - "format": "uuid", - "nullable": true + "enum": [ + "Number" + ] }, - "endCapId": { - "description": "The id of the extrusion end cap", - "type": "string", - "format": "uuid", - "nullable": true + "value": { + "type": "number", + "format": "double" }, - "edgeCuts": { - "description": "Chamfers or fillets on this solid.", + "__meta": { "type": "array", "items": { - "$ref": "#/components/schemas/EdgeCut" + "$ref": "#/components/schemas/Metadata" } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" }, "__meta": { - "description": "Metadata.", "type": "array", "items": { "$ref": "#/components/schemas/Metadata" @@ -139826,6 +141451,7 @@ { "type": "object", "required": [ + "__meta", "type", "value" ], @@ -139833,23 +141459,24 @@ "type": { "type": "string", "enum": [ - "Solids" + "String" ] }, "value": { + "type": "string" + }, + "__meta": { "type": "array", "items": { - "$ref": "#/components/schemas/Solid" + "$ref": "#/components/schemas/Metadata" } } } }, { - "description": "Data for an imported geometry.", "type": "object", "required": [ "__meta", - "id", "type", "value" ], @@ -139857,19 +141484,13 @@ "type": { "type": "string", "enum": [ - "ImportedGeometry" + "Array" ] }, - "id": { - "description": "The ID of the imported geometry.", - "type": "string", - "format": "uuid" - }, "value": { - "description": "The original file paths.", "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/KclValue" } }, "__meta": { @@ -139884,22 +141505,21 @@ "type": "object", "required": [ "__meta", - "expression", - "memory", - "type" + "type", + "value" ], "properties": { "type": { "type": "string", "enum": [ - "Function" + "Object" ] }, - "expression": { - "$ref": "#/components/schemas/FunctionExpression" - }, - "memory": { - "$ref": "#/components/schemas/ProgramMemory" + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } }, "__meta": { "type": "array", @@ -139908,25 +141528,455 @@ } } } - } - ] - }, - "Metadata": { - "description": "Metadata.", - "type": "object", - "required": [ - "sourceRange" - ], - "properties": { - "sourceRange": { - "description": "The source range.", - "allOf": [ - { - "$ref": "#/components/schemas/SourceRange" - } - ] - } - } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TagIdentifier" + ] + }, + "value": { + "type": "string" + }, + "info": { + "allOf": [ + { + "$ref": "#/components/schemas/TagEngineInfo" + } + ], + "nullable": true + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TagDeclarator" + ] + }, + "value": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + { + "description": "A plane.", + "type": "object", + "required": [ + "__meta", + "id", + "origin", + "type", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Plane" + ] + }, + "id": { + "description": "The id of the plane.", + "type": "string", + "format": "uuid" + }, + "value": { + "$ref": "#/components/schemas/PlaneType" + }, + "origin": { + "description": "Origin of the plane.", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "xAxis": { + "description": "What should the plane’s X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the plane’s Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "description": "A face.", + "type": "object", + "required": [ + "__meta", + "id", + "solid", + "type", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Face" + ] + }, + "id": { + "description": "The id of the face.", + "type": "string", + "format": "uuid" + }, + "value": { + "description": "The tag of the face.", + "type": "string" + }, + "xAxis": { + "description": "What should the face’s X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the face’s Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "solid": { + "description": "The solid the face is on.", + "allOf": [ + { + "$ref": "#/components/schemas/Solid" + } + ] + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, + { + "description": "An solid is a collection of extrude surfaces.", + "type": "object", + "required": [ + "__meta", + "height", + "id", + "sketch", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Solid" + ] + }, + "id": { + "description": "The id of the solid.", + "type": "string", + "format": "uuid" + }, + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ExtrudeSurface" + } + }, + "sketch": { + "description": "The sketch.", + "allOf": [ + { + "$ref": "#/components/schemas/Sketch" + } + ] + }, + "height": { + "description": "The height of the solid.", + "type": "number", + "format": "double" + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "edgeCuts": { + "description": "Chamfers or fillets on this solid.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EdgeCut" + } + }, + "__meta": { + "description": "Metadata.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Solids" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Solid" + } + } + } + }, + { + "description": "Data for an imported geometry.", + "type": "object", + "required": [ + "__meta", + "id", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ImportedGeometry" + ] + }, + "id": { + "description": "The ID of the imported geometry.", + "type": "string", + "format": "uuid" + }, + "value": { + "description": "The original file paths.", + "type": "array", + "items": { + "type": "string" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "expression", + "memory", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Function" + ] + }, + "expression": { + "$ref": "#/components/schemas/FunctionExpression" + }, + "memory": { + "$ref": "#/components/schemas/ProgramMemory" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + } + ] + }, + "Metadata": { + "description": "Metadata.", + "type": "object", + "required": [ + "sourceRange" + ], + "properties": { + "sourceRange": { + "description": "The source range.", + "allOf": [ + { + "$ref": "#/components/schemas/SourceRange" + } + ] + } + } }, "SourceRange": { "type": "array", @@ -143246,6 +145296,10 @@ "nullable": true } } + }, + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" } } }, @@ -143270,10 +145324,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" + ] + }, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" ] }, - "value": {}, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" + ] + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -143491,6 +145706,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -143647,6 +145901,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ], "definitions": { @@ -143664,10 +145943,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" + ] + }, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" + ] + }, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" ] }, - "value": {}, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -143885,6 +146325,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -144041,6 +146520,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ] }, @@ -147379,6 +149883,10 @@ "nullable": true } } + }, + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" } } }, @@ -147406,10 +149914,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" ] }, - "value": {}, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" + ] + }, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" + ] + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -147627,6 +150296,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -147783,6 +150491,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ] }, @@ -151121,6 +153854,10 @@ "nullable": true } } + }, + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" } } }, @@ -151146,10 +153883,171 @@ "type": { "type": "string", "enum": [ - "UserVal" + "Uuid" ] }, - "value": {}, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" + ] + }, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" + ] + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, "__meta": { "type": "array", "items": { @@ -151367,6 +154265,45 @@ } } }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, { "description": "An solid is a collection of extrude surfaces.", "type": "object", @@ -151523,6 +154460,31 @@ } } } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } } ], "definitions": { @@ -151553,6 +154515,625 @@ "maxItems": 3, "minItems": 3 }, + "KclValue": { + "description": "Any KCL value.", + "oneOf": [ + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Uuid" + ] + }, + "value": { + "type": "string", + "format": "uuid" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Bool" + ] + }, + "value": { + "type": "boolean" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Number" + ] + }, + "value": { + "type": "number", + "format": "double" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Int" + ] + }, + "value": { + "type": "integer", + "format": "int64" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "String" + ] + }, + "value": { + "type": "string" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Object" + ] + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/KclValue" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TagIdentifier" + ] + }, + "value": { + "type": "string" + }, + "info": { + "allOf": [ + { + "$ref": "#/components/schemas/TagEngineInfo" + } + ], + "nullable": true + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "TagDeclarator" + ] + }, + "value": { + "type": "string" + }, + "digest": { + "type": "array", + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 32, + "minItems": 32, + "nullable": true + }, + "start": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "end": { + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + } + }, + { + "description": "A plane.", + "type": "object", + "required": [ + "__meta", + "id", + "origin", + "type", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Plane" + ] + }, + "id": { + "description": "The id of the plane.", + "type": "string", + "format": "uuid" + }, + "value": { + "$ref": "#/components/schemas/PlaneType" + }, + "origin": { + "description": "Origin of the plane.", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "xAxis": { + "description": "What should the plane’s X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the plane’s Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "description": "A face.", + "type": "object", + "required": [ + "__meta", + "id", + "solid", + "type", + "value", + "xAxis", + "yAxis", + "zAxis" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Face" + ] + }, + "id": { + "description": "The id of the face.", + "type": "string", + "format": "uuid" + }, + "value": { + "description": "The tag of the face.", + "type": "string" + }, + "xAxis": { + "description": "What should the face’s X axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "yAxis": { + "description": "What should the face’s Y axis be?", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "zAxis": { + "description": "The z-axis (normal).", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + }, + "solid": { + "description": "The solid the face is on.", + "allOf": [ + { + "$ref": "#/components/schemas/Solid" + } + ] + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketch" + ] + }, + "value": { + "$ref": "#/components/schemas/Sketch" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Sketches" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Sketch" + } + } + } + }, + { + "description": "An solid is a collection of extrude surfaces.", + "type": "object", + "required": [ + "__meta", + "height", + "id", + "sketch", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Solid" + ] + }, + "id": { + "description": "The id of the solid.", + "type": "string", + "format": "uuid" + }, + "value": { + "description": "The extrude surfaces.", + "type": "array", + "items": { + "$ref": "#/components/schemas/ExtrudeSurface" + } + }, + "sketch": { + "description": "The sketch.", + "allOf": [ + { + "$ref": "#/components/schemas/Sketch" + } + ] + }, + "height": { + "description": "The height of the solid.", + "type": "number", + "format": "double" + }, + "startCapId": { + "description": "The id of the extrusion start cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "endCapId": { + "description": "The id of the extrusion end cap", + "type": "string", + "format": "uuid", + "nullable": true + }, + "edgeCuts": { + "description": "Chamfers or fillets on this solid.", + "type": "array", + "items": { + "$ref": "#/components/schemas/EdgeCut" + } + }, + "__meta": { + "description": "Metadata.", + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Solids" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Solid" + } + } + } + }, + { + "description": "Data for an imported geometry.", + "type": "object", + "required": [ + "__meta", + "id", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ImportedGeometry" + ] + }, + "id": { + "description": "The ID of the imported geometry.", + "type": "string", + "format": "uuid" + }, + "value": { + "description": "The original file paths.", + "type": "array", + "items": { + "type": "string" + } + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "expression", + "memory", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "Function" + ] + }, + "expression": { + "$ref": "#/components/schemas/FunctionExpression" + }, + "memory": { + "$ref": "#/components/schemas/ProgramMemory" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + }, + { + "type": "object", + "required": [ + "__meta", + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "KclNone" + ] + }, + "value": { + "$ref": "#/components/schemas/KclNone" + }, + "__meta": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Metadata" + } + } + } + } + ] + }, "TagEngineInfo": { "description": "Engine information for a tag.", "type": "object", @@ -154862,399 +158443,9 @@ } } }, - "KclValue": { - "description": "Any KCL value.", - "oneOf": [ - { - "type": "object", - "required": [ - "__meta", - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "UserVal" - ] - }, - "value": {}, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { - "type": "object", - "required": [ - "__meta", - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "TagIdentifier" - ] - }, - "value": { - "type": "string" - }, - "info": { - "allOf": [ - { - "$ref": "#/components/schemas/TagEngineInfo" - } - ], - "nullable": true - }, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { - "type": "object", - "required": [ - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "TagDeclarator" - ] - }, - "value": { - "type": "string" - }, - "digest": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32, - "nullable": true - }, - "start": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "end": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - } - }, - { - "description": "A plane.", - "type": "object", - "required": [ - "__meta", - "id", - "origin", - "type", - "value", - "xAxis", - "yAxis", - "zAxis" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Plane" - ] - }, - "id": { - "description": "The id of the plane.", - "type": "string", - "format": "uuid" - }, - "value": { - "$ref": "#/components/schemas/PlaneType" - }, - "origin": { - "description": "Origin of the plane.", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "xAxis": { - "description": "What should the plane’s X axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "yAxis": { - "description": "What should the plane’s Y axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "zAxis": { - "description": "The z-axis (normal).", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { - "description": "A face.", - "type": "object", - "required": [ - "__meta", - "id", - "solid", - "type", - "value", - "xAxis", - "yAxis", - "zAxis" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Face" - ] - }, - "id": { - "description": "The id of the face.", - "type": "string", - "format": "uuid" - }, - "value": { - "description": "The tag of the face.", - "type": "string" - }, - "xAxis": { - "description": "What should the face’s X axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "yAxis": { - "description": "What should the face’s Y axis be?", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "zAxis": { - "description": "The z-axis (normal).", - "allOf": [ - { - "$ref": "#/components/schemas/Point3d" - } - ] - }, - "solid": { - "description": "The solid the face is on.", - "allOf": [ - { - "$ref": "#/components/schemas/Solid" - } - ] - }, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { - "description": "An solid is a collection of extrude surfaces.", - "type": "object", - "required": [ - "__meta", - "height", - "id", - "sketch", - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Solid" - ] - }, - "id": { - "description": "The id of the solid.", - "type": "string", - "format": "uuid" - }, - "value": { - "description": "The extrude surfaces.", - "type": "array", - "items": { - "$ref": "#/components/schemas/ExtrudeSurface" - } - }, - "sketch": { - "description": "The sketch.", - "allOf": [ - { - "$ref": "#/components/schemas/Sketch" - } - ] - }, - "height": { - "description": "The height of the solid.", - "type": "number", - "format": "double" - }, - "startCapId": { - "description": "The id of the extrusion start cap", - "type": "string", - "format": "uuid", - "nullable": true - }, - "endCapId": { - "description": "The id of the extrusion end cap", - "type": "string", - "format": "uuid", - "nullable": true - }, - "edgeCuts": { - "description": "Chamfers or fillets on this solid.", - "type": "array", - "items": { - "$ref": "#/components/schemas/EdgeCut" - } - }, - "__meta": { - "description": "Metadata.", - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { - "type": "object", - "required": [ - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Solids" - ] - }, - "value": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Solid" - } - } - } - }, - { - "description": "Data for an imported geometry.", - "type": "object", - "required": [ - "__meta", - "id", - "type", - "value" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "ImportedGeometry" - ] - }, - "id": { - "description": "The ID of the imported geometry.", - "type": "string", - "format": "uuid" - }, - "value": { - "description": "The original file paths.", - "type": "array", - "items": { - "type": "string" - } - }, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - }, - { - "type": "object", - "required": [ - "__meta", - "expression", - "memory", - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "Function" - ] - }, - "expression": { - "$ref": "#/components/schemas/FunctionExpression" - }, - "memory": { - "$ref": "#/components/schemas/ProgramMemory" - }, - "__meta": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Metadata" - } - } - } - } - ] + "KclNone": { + "description": "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application).", + "type": "object" } } }, diff --git a/docs/kcl/types/KclNone.md b/docs/kcl/types/KclNone.md new file mode 100644 index 0000000000..96a7c11cae --- /dev/null +++ b/docs/kcl/types/KclNone.md @@ -0,0 +1,16 @@ +--- +title: "KclNone" +excerpt: "KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application)." +layout: manual +--- + +KCL value for an optional parameter which was not given an argument. (remember, parameters are in the function declaration, arguments are in the function call/application). + +**Type:** `object` + + + + + + + diff --git a/docs/kcl/types/KclValue.md b/docs/kcl/types/KclValue.md index 91914ffd40..6cfeac72eb 100644 --- a/docs/kcl/types/KclValue.md +++ b/docs/kcl/types/KclValue.md @@ -23,8 +23,110 @@ Any KCL value. | Property | Type | Description | Required | |----------|------|-------------|----------| -| `type` |enum: `UserVal`| | No | -| `value` |``| | No | +| `type` |enum: `Uuid`| | No | +| `value` |`string`| | No | +| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No | + + +---- + +**Type:** `object` + + + + + +## Properties + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| `type` |enum: `Bool`| | No | +| `value` |`boolean`| | No | +| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No | + + +---- + +**Type:** `object` + + + + + +## Properties + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| `type` |enum: `Number`| | No | +| `value` |`number`| | No | +| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No | + + +---- + +**Type:** `object` + + + + + +## Properties + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| `type` |enum: `Int`| | No | +| `value` |`integer`| | No | +| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No | + + +---- + +**Type:** `object` + + + + + +## Properties + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| `type` |enum: `String`| | No | +| `value` |`string`| | No | +| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No | + + +---- + +**Type:** `object` + + + + + +## Properties + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| `type` |enum: `Array`| | No | +| `value` |`[` [`KclValue`](/docs/kcl/types/KclValue) `]`| | No | +| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No | + + +---- + +**Type:** `object` + + + + + +## Properties + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| `type` |enum: `Object`| | No | +| `value` |`object`| | No | | `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No | @@ -111,6 +213,38 @@ A face. | `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No | +---- + +**Type:** `object` + + + + + +## Properties + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| `type` |enum: [`Sketch`](/docs/kcl/types/Sketch)| | No | +| `value` |[`Sketch`](/docs/kcl/types/Sketch)| Any KCL value. | No | + + +---- + +**Type:** `object` + + + + + +## Properties + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| `type` |enum: `Sketches`| | No | +| `value` |`[` [`Sketch`](/docs/kcl/types/Sketch) `]`| | No | + + ---- An solid is a collection of extrude surfaces. @@ -190,6 +324,23 @@ Data for an imported geometry. ---- +**Type:** `object` + + + + + +## Properties + +| Property | Type | Description | Required | +|----------|------|-------------|----------| +| `type` |enum: [`KclNone`](/docs/kcl/types/KclNone)| | No | +| `value` |[`KclNone`](/docs/kcl/types/KclNone)| Any KCL value. | No | +| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No | + + +---- + diff --git a/src/components/AvailableVarsHelpers.tsx b/src/components/AvailableVarsHelpers.tsx index 48a5a50c89..6dbfb492c4 100644 --- a/src/components/AvailableVarsHelpers.tsx +++ b/src/components/AvailableVarsHelpers.tsx @@ -146,7 +146,7 @@ export function useCalc({ const _programMem: ProgramMemory = ProgramMemory.empty() for (const { key, value } of availableVarInfo.variables) { const error = _programMem.set(key, { - type: 'UserVal', + type: 'String', value, __meta: [], }) diff --git a/src/components/ModelingSidebar/ModelingPanes/MemoryPane.tsx b/src/components/ModelingSidebar/ModelingPanes/MemoryPane.tsx index af73f28391..6d737595a7 100644 --- a/src/components/ModelingSidebar/ModelingPanes/MemoryPane.tsx +++ b/src/components/ModelingSidebar/ModelingPanes/MemoryPane.tsx @@ -89,9 +89,9 @@ export const processMemory = (programMemory: ProgramMemory) => { const processedMemory: any = {} for (const [key, val] of programMemory?.visibleEntries()) { if ( - (val.type === 'UserVal' && val.value.type === 'Sketch') || + val.type === 'Sketch' || // @ts-ignore - (val.type !== 'Function' && val.type !== 'UserVal') + val.type !== 'Function' ) { const sg = sketchFromKclValue(val, key) if (val.type === 'Solid') { @@ -110,8 +110,6 @@ export const processMemory = (programMemory: ProgramMemory) => { processedMemory[key] = `__function(${(val as any)?.expression?.params ?.map?.(({ identifier }: any) => identifier?.name || '') .join(', ')})__` - } else { - processedMemory[key] = val.value } } return processedMemory diff --git a/src/lang/artifact.test.ts b/src/lang/artifact.test.ts index 52a8746de8..d961dd6ed8 100644 --- a/src/lang/artifact.test.ts +++ b/src/lang/artifact.test.ts @@ -18,8 +18,7 @@ const mySketch001 = startSketchOn('XY') // @ts-ignore const sketch001 = execState.memory.get('mySketch001') expect(sketch001).toEqual({ - type: 'UserVal', - __meta: [{ sourceRange: [46, 71, 0] }], + type: 'Sketch', value: { type: 'Sketch', on: expect.any(Object), diff --git a/src/lang/executor.test.ts b/src/lang/executor.test.ts index 39773481b7..e10bbbd766 100644 --- a/src/lang/executor.test.ts +++ b/src/lang/executor.test.ts @@ -58,7 +58,13 @@ const newVar = myVar + 1` ` const mem = await exe(code) // geo is three js buffer geometry and is very bloated to have in tests - const minusGeo = mem.get('mySketch')?.value?.paths + const sk = mem.get('mySketch') + expect(sk?.type).toEqual('Sketch') + if (sk?.type !== 'Sketch') { + return + } + + const minusGeo = sk?.value?.paths expect(minusGeo).toEqual([ { type: 'ToPoint', @@ -150,7 +156,7 @@ const newVar = myVar + 1` ].join('\n') const mem = await exe(code) expect(mem.get('mySk1')).toEqual({ - type: 'UserVal', + type: 'Sketch', value: { type: 'Sketch', on: expect.any(Object), @@ -215,7 +221,6 @@ const newVar = myVar + 1` id: expect.any(String), __meta: [{ sourceRange: [39, 63, 0] }], }, - __meta: [{ sourceRange: [39, 63, 0] }], }) }) it('execute array expression', async () => { @@ -225,7 +230,7 @@ const newVar = myVar + 1` const mem = await exe(code) // TODO path to node is probably wrong here, zero indexes are not correct expect(mem.get('three')).toEqual({ - type: 'UserVal', + type: 'Int', value: 3, __meta: [ { @@ -234,8 +239,17 @@ const newVar = myVar + 1` ], }) expect(mem.get('yo')).toEqual({ - type: 'UserVal', - value: [1, '2', 3, 9], + type: 'Array', + value: [ + { type: 'Int', value: 1, __meta: [{ sourceRange: [28, 29, 0] }] }, + { type: 'String', value: '2', __meta: [{ sourceRange: [31, 34, 0] }] }, + { type: 'Int', value: 3, __meta: [{ sourceRange: [14, 15, 0] }] }, + { + type: 'Number', + value: 9, + __meta: [{ sourceRange: [43, 44, 0] }, { sourceRange: [47, 48, 0] }], + }, + ], __meta: [ { sourceRange: [27, 49, 0], @@ -253,8 +267,25 @@ const newVar = myVar + 1` ].join('\n') const mem = await exe(code) expect(mem.get('yo')).toEqual({ - type: 'UserVal', - value: { aStr: 'str', anum: 2, identifier: 3, binExp: 9 }, + type: 'Object', + value: { + aStr: { + type: 'String', + value: 'str', + __meta: [{ sourceRange: [34, 39, 0] }], + }, + anum: { type: 'Int', value: 2, __meta: [{ sourceRange: [47, 48, 0] }] }, + identifier: { + type: 'Int', + value: 3, + __meta: [{ sourceRange: [14, 15, 0] }], + }, + binExp: { + type: 'Number', + value: 9, + __meta: [{ sourceRange: [77, 78, 0] }, { sourceRange: [81, 82, 0] }], + }, + }, __meta: [ { sourceRange: [27, 83, 0], @@ -268,11 +299,11 @@ const newVar = myVar + 1` ) const mem = await exe(code) expect(mem.get('myVar')).toEqual({ - type: 'UserVal', + type: 'String', value: '123', __meta: [ { - sourceRange: [41, 50, 0], + sourceRange: [19, 24, 0], }, ], }) @@ -356,7 +387,26 @@ describe('testing math operators', () => { it('with unaryExpression in ArrayExpression', async () => { const code = 'const myVar = [1,-legLen(5, 4)]' const mem = await exe(code) - expect(mem.get('myVar')?.value).toEqual([1, -3]) + expect(mem.get('myVar')?.value).toEqual([ + { + __meta: [ + { + sourceRange: [15, 16, 0], + }, + ], + type: 'Int', + value: 1, + }, + { + __meta: [ + { + sourceRange: [17, 30, 0], + }, + ], + type: 'Number', + value: -3, + }, + ]) }) it('with unaryExpression in ArrayExpression in CallExpression, checking nothing funny happens when used in a sketch', async () => { const code = [ diff --git a/src/lang/kclSamples.test.ts b/src/lang/kclSamples.test.ts index 1e1a7d0218..0981abbfaa 100644 --- a/src/lang/kclSamples.test.ts +++ b/src/lang/kclSamples.test.ts @@ -55,18 +55,13 @@ describe('Test KCL Samples from public Github repository', () => { }) // Run through all of the files in the manifest json. This will allow us to be automatically updated // with the latest changes in github. We won't be hard coding the filenames - it( - 'should run through all the files', - async () => { - for (let i = 0; i < files.length; i++) { - const file: KclSampleFile = files[i] - const code = await getKclSampleCodeFromGithub(file.filename) - const parsed = parse(code) - assert(!(parsed instanceof Error)) - } - }, - files.length * 1000 - ) + files.forEach((file: KclSampleFile) => { + it(`should parse ${file.filename} without errors`, async () => { + const code = await getKclSampleCodeFromGithub(file.filename) + const parsed = parse(code) + assert(!(parsed instanceof Error)) + }, 1000) + }) }) describe('when performing enginelessExecutor', () => { diff --git a/src/lang/wasm.ts b/src/lang/wasm.ts index 89e4b9ff80..80a49b4be9 100644 --- a/src/lang/wasm.ts +++ b/src/lang/wasm.ts @@ -336,7 +336,7 @@ export class ProgramMemory { */ hasSketchOrSolid(): boolean { for (const node of this.visibleEntries().values()) { - if (node.type === 'Solid' || node.value?.type === 'Sketch') { + if (node.type === 'Solid' || node.type === 'Sketch') { return true } } diff --git a/src/lib/useCalculateKclExpression.ts b/src/lib/useCalculateKclExpression.ts index c581e8c6ff..e244c61f55 100644 --- a/src/lib/useCalculateKclExpression.ts +++ b/src/lib/useCalculateKclExpression.ts @@ -91,7 +91,7 @@ export function useCalculateKclExpression({ const _programMem: ProgramMemory = ProgramMemory.empty() for (const { key, value } of availableVarInfo.variables) { const error = _programMem.set(key, { - type: 'UserVal', + type: 'String', value, __meta: [], }) diff --git a/src/wasm-lib/kcl/src/ast/types.rs b/src/wasm-lib/kcl/src/ast/types.rs index 01a2d99377..59a03554c8 100644 --- a/src/wasm-lib/kcl/src/ast/types.rs +++ b/src/wasm-lib/kcl/src/ast/types.rs @@ -27,7 +27,7 @@ pub use crate::ast::types::{ use crate::{ docs::StdLibFn, errors::KclError, - executor::{ExecState, ExecutorContext, KclValue, Metadata, SourceRange, TagIdentifier, UserVal}, + executor::{ExecState, ExecutorContext, KclValue, Metadata, SourceRange, TagIdentifier}, parser::PIPE_OPERATOR, std::kcl_stdlib::KclStdLibFn, }; @@ -59,6 +59,14 @@ pub struct Node { pub module_id: ModuleId, } +impl Node { + pub fn metadata(&self) -> Metadata { + Metadata { + source_range: SourceRange([self.start, self.end, self.module_id.0 as usize]), + } + } +} + impl schemars::JsonSchema for Node { fn schema_name() -> String { T::schema_name() @@ -1708,34 +1716,26 @@ impl Literal { impl From> for KclValue { fn from(literal: Node) -> Self { - KclValue::UserVal(UserVal { - value: JValue::from(literal.value.clone()), - meta: vec![Metadata { - source_range: literal.into(), - }], - }) + let meta = vec![literal.metadata()]; + match literal.inner.value { + LiteralValue::IInteger(value) => KclValue::Int { value, meta }, + LiteralValue::Fractional(value) => KclValue::Number { value, meta }, + LiteralValue::String(value) => KclValue::String { value, meta }, + LiteralValue::Bool(value) => KclValue::Bool { value, meta }, + } } } impl From<&Node> for KclValue { fn from(literal: &Node) -> Self { - KclValue::UserVal(UserVal { - value: JValue::from(literal.value.clone()), - meta: vec![Metadata { - source_range: literal.into(), - }], - }) + Self::from(literal.to_owned()) } } impl From<&BoxNode> for KclValue { fn from(literal: &BoxNode) -> Self { - KclValue::UserVal(UserVal { - value: JValue::from(literal.value.clone()), - meta: vec![Metadata { - source_range: literal.into(), - }], - }) + let b: &Node = literal; + Self::from(b) } } @@ -3010,17 +3010,6 @@ impl ConstraintLevels { } } -pub(crate) fn human_friendly_type(j: &JValue) -> &'static str { - match j { - JValue::Null => "null", - JValue::Bool(_) => "boolean (true/false value)", - JValue::Number(_) => "number", - JValue::String(_) => "string (text)", - JValue::Array(_) => "array (list)", - JValue::Object(_) => "object", - } -} - #[cfg(test)] mod tests { use pretty_assertions::assert_eq; diff --git a/src/wasm-lib/kcl/src/ast/types/execute.rs b/src/wasm-lib/kcl/src/ast/types/execute.rs index b90ee9da75..a9eb0eef81 100644 --- a/src/wasm-lib/kcl/src/ast/types/execute.rs +++ b/src/wasm-lib/kcl/src/ast/types/execute.rs @@ -1,18 +1,21 @@ +use std::collections::HashMap; + use super::{ - human_friendly_type, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, - CallExpression, Expr, IfExpression, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Node, - ObjectExpression, TagDeclarator, UnaryExpression, UnaryOperator, + ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, CallExpression, Expr, + IfExpression, KclNone, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Node, ObjectExpression, + TagDeclarator, UnaryExpression, UnaryOperator, }; use crate::{ errors::{KclError, KclErrorDetails}, executor::{ - BodyType, ExecState, ExecutorContext, KclValue, Metadata, Sketch, SourceRange, StatementKind, TagEngineInfo, - TagIdentifier, UserVal, + BodyType, ExecState, ExecutorContext, KclValue, Metadata, SourceRange, StatementKind, TagEngineInfo, + TagIdentifier, }, std::FunctionKind, }; use async_recursion::async_recursion; -use serde_json::Value as JValue; + +const FLOAT_TO_INT_MAX_DELTA: f64 = 0.01; impl BinaryPart { #[async_recursion] @@ -42,25 +45,18 @@ impl Node { } }; - let array_json = array.get_json_value()?; + let KclValue::Array { value: array, meta: _ } = array else { + return Err(KclError::Semantic(KclErrorDetails { + message: format!("MemberExpression array is not an array: {:?}", array), + source_ranges: vec![self.clone().into()], + })); + }; - if let serde_json::Value::Array(array) = array_json { - if let Some(value) = array.get(index) { - Ok(KclValue::UserVal(UserVal { - value: value.clone(), - meta: vec![Metadata { - source_range: self.into(), - }], - })) - } else { - Err(KclError::UndefinedValue(KclErrorDetails { - message: format!("index {} not found in array", index), - source_ranges: vec![self.clone().into()], - })) - } + if let Some(value) = array.get(index) { + Ok(value.to_owned()) } else { - Err(KclError::Semantic(KclErrorDetails { - message: format!("MemberExpression array is not an array: {:?}", array), + Err(KclError::UndefinedValue(KclErrorDetails { + message: format!("index {} not found in array", index), source_ranges: vec![self.clone().into()], })) } @@ -77,18 +73,11 @@ impl Node { } }; - let object_json = object.get_json_value()?; - // Check the property and object match -- e.g. ints for arrays, strs for objects. - match (object_json, property) { - (JValue::Object(map), Property::String(property)) => { + match (object, property) { + (KclValue::Object { value: map, meta: _ }, Property::String(property)) => { if let Some(value) = map.get(&property) { - Ok(KclValue::UserVal(UserVal { - value: value.clone(), - meta: vec![Metadata { - source_range: self.into(), - }], - })) + Ok(value.to_owned()) } else { Err(KclError::UndefinedValue(KclErrorDetails { message: format!("Property '{property}' not found in object"), @@ -96,22 +85,20 @@ impl Node { })) } } - (JValue::Object(_), p) => Err(KclError::Semantic(KclErrorDetails { - message: format!( - "Only strings can be used as the property of an object, but you're using a {}", - p.type_name() - ), - source_ranges: vec![self.clone().into()], - })), - (JValue::Array(arr), Property::Number(index)) => { - let value_of_arr: Option<&JValue> = arr.get(index); + (KclValue::Object { .. }, p) => { + let t = p.type_name(); + let article = article_for(t); + Err(KclError::Semantic(KclErrorDetails { + message: format!( + "Only strings can be used as the property of an object, but you're using {article} {t}", + ), + source_ranges: vec![self.clone().into()], + })) + } + (KclValue::Array { value: arr, meta: _ }, Property::Number(index)) => { + let value_of_arr = arr.get(index); if let Some(value) = value_of_arr { - Ok(KclValue::UserVal(UserVal { - value: value.clone(), - meta: vec![Metadata { - source_range: self.into(), - }], - })) + Ok(value.to_owned()) } else { Err(KclError::UndefinedValue(KclErrorDetails { message: format!("The array doesn't have any item at index {index}"), @@ -119,17 +106,36 @@ impl Node { })) } } - (JValue::Array(_), p) => Err(KclError::Semantic(KclErrorDetails { - message: format!( - "Only integers >= 0 can be used as the index of an array, but you're using a {}", - p.type_name() - ), - source_ranges: vec![self.clone().into()], - })), + (KclValue::Array { .. }, p) => { + let t = p.type_name(); + let article = article_for(t); + Err(KclError::Semantic(KclErrorDetails { + message: format!( + "Only integers >= 0 can be used as the index of an array, but you're using {article} {t}", + ), + source_ranges: vec![self.clone().into()], + })) + } + (KclValue::Solid(solid), Property::String(prop)) if prop == "sketch" => Ok(KclValue::Sketch { + value: Box::new(solid.sketch), + }), + (KclValue::Sketch { value: sk }, Property::String(prop)) if prop == "tags" => Ok(KclValue::Object { + meta: vec![Metadata { + source_range: SourceRange::from(self.clone()), + }], + value: sk + .tags + .iter() + .map(|(k, tag)| (k.to_owned(), KclValue::TagIdentifier(Box::new(tag.to_owned())))) + .collect(), + }), (being_indexed, _) => { - let t = human_friendly_type(&being_indexed); + let t = being_indexed.human_friendly_type(); + let article = article_for(t); Err(KclError::Semantic(KclErrorDetails { - message: format!("Only arrays and objects can be indexed, but you're trying to index a {t}"), + message: format!( + "Only arrays and objects can be indexed, but you're trying to index {article} {t}" + ), source_ranges: vec![self.clone().into()], })) } @@ -140,81 +146,134 @@ impl Node { impl Node { #[async_recursion] pub async fn get_result(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result { - let left_json_value = self.left.get_result(exec_state, ctx).await?.get_json_value()?; - let right_json_value = self.right.get_result(exec_state, ctx).await?.get_json_value()?; + let left_value = self.left.get_result(exec_state, ctx).await?; + let right_value = self.right.get_result(exec_state, ctx).await?; + let mut meta = left_value.metadata(); + meta.extend(right_value.metadata()); // First check if we are doing string concatenation. if self.operator == BinaryOperator::Add { - if let (Some(left), Some(right)) = ( - parse_json_value_as_string(&left_json_value), - parse_json_value_as_string(&right_json_value), - ) { - let value = serde_json::Value::String(format!("{}{}", left, right)); - return Ok(KclValue::UserVal(UserVal { - value, - meta: vec![Metadata { - source_range: self.into(), - }], - })); + if let (KclValue::String { value: left, meta: _ }, KclValue::String { value: right, meta: _ }) = + (&left_value, &right_value) + { + return Ok(KclValue::String { + value: format!("{}{}", left, right), + meta, + }); } } - let left = parse_json_number_as_f64(&left_json_value, self.left.clone().into())?; - let right = parse_json_number_as_f64(&right_json_value, self.right.clone().into())?; - - let value: serde_json::Value = match self.operator { - BinaryOperator::Add => (left + right).into(), - BinaryOperator::Sub => (left - right).into(), - BinaryOperator::Mul => (left * right).into(), - BinaryOperator::Div => (left / right).into(), - BinaryOperator::Mod => (left % right).into(), - BinaryOperator::Pow => (left.powf(right)).into(), - BinaryOperator::Eq => (left == right).into(), - BinaryOperator::Neq => (left != right).into(), - BinaryOperator::Gt => (left > right).into(), - BinaryOperator::Gte => (left >= right).into(), - BinaryOperator::Lt => (left < right).into(), - BinaryOperator::Lte => (left <= right).into(), + let left = parse_number_as_f64(&left_value, self.left.clone().into())?; + let right = parse_number_as_f64(&right_value, self.right.clone().into())?; + + let value = match self.operator { + BinaryOperator::Add => KclValue::Number { + value: left + right, + meta, + }, + BinaryOperator::Sub => KclValue::Number { + value: left - right, + meta, + }, + BinaryOperator::Mul => KclValue::Number { + value: left * right, + meta, + }, + BinaryOperator::Div => KclValue::Number { + value: left / right, + meta, + }, + BinaryOperator::Mod => KclValue::Number { + value: left % right, + meta, + }, + BinaryOperator::Pow => KclValue::Number { + value: left.powf(right), + meta, + }, + BinaryOperator::Neq => KclValue::Bool { + value: left != right, + meta, + }, + BinaryOperator::Gt => KclValue::Bool { + value: left > right, + meta, + }, + BinaryOperator::Gte => KclValue::Bool { + value: left >= right, + meta, + }, + BinaryOperator::Lt => KclValue::Bool { + value: left < right, + meta, + }, + BinaryOperator::Lte => KclValue::Bool { + value: left <= right, + meta, + }, + BinaryOperator::Eq => KclValue::Bool { + value: left == right, + meta, + }, }; - Ok(KclValue::UserVal(UserVal { - value, - meta: vec![Metadata { - source_range: self.into(), - }], - })) + Ok(value) } } impl Node { pub async fn get_result(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result { if self.operator == UnaryOperator::Not { - let value = self.argument.get_result(exec_state, ctx).await?.get_json_value()?; - let Some(bool_value) = json_as_bool(&value) else { + let value = self.argument.get_result(exec_state, ctx).await?; + let KclValue::Bool { + value: bool_value, + meta: _, + } = value + else { return Err(KclError::Semantic(KclErrorDetails { - message: format!("Cannot apply unary operator ! to non-boolean value: {}", value), + message: format!( + "Cannot apply unary operator ! to non-boolean value: {}", + value.human_friendly_type() + ), source_ranges: vec![self.into()], })); }; - let negated = !bool_value; - return Ok(KclValue::UserVal(UserVal { - value: serde_json::Value::Bool(negated), - meta: vec![Metadata { - source_range: self.into(), - }], - })); + let meta = vec![Metadata { + source_range: self.into(), + }]; + let negated = KclValue::Bool { + value: !bool_value, + meta, + }; + + return Ok(negated); } - let num = parse_json_number_as_f64( - &self.argument.get_result(exec_state, ctx).await?.get_json_value()?, - self.into(), - )?; - Ok(KclValue::UserVal(UserVal { - value: (-(num)).into(), - meta: vec![Metadata { - source_range: self.into(), - }], - })) + let value = &self.argument.get_result(exec_state, ctx).await?; + match value { + KclValue::Number { value, meta: _ } => { + let meta = vec![Metadata { + source_range: self.into(), + }]; + Ok(KclValue::Number { value: -value, meta }) + } + KclValue::Int { value, meta: _ } => { + let meta = vec![Metadata { + source_range: self.into(), + }]; + Ok(KclValue::Number { + value: (-value) as f64, + meta, + }) + } + _ => Err(KclError::Semantic(KclErrorDetails { + message: format!( + "You can only negate numbers, but this is a {}", + value.human_friendly_type() + ), + source_ranges: vec![self.into()], + })), + } } } @@ -325,13 +384,10 @@ impl Node { // TODO: This could probably be done in a better way, but as of now this was my only idea // and it works. match result { - KclValue::UserVal(ref mut uval) => { - uval.mutate(|sketch: &mut Sketch| { - for (_, tag) in sketch.tags.iter() { - exec_state.memory.update_tag(&tag.value, tag.clone())?; - } - Ok::<_, KclError>(()) - })?; + KclValue::Sketch { value: ref mut sketch } => { + for (_, tag) in sketch.tags.iter() { + exec_state.memory.update_tag(&tag.value, tag.clone())?; + } } KclValue::Solid(ref mut solid) => { for value in &solid.value { @@ -425,10 +481,10 @@ impl Node { } else { fn_memory.add( ¶m.identifier.name, - KclValue::UserVal(UserVal { - value: serde_json::value::Value::Null, - meta: Default::default(), - }), + KclValue::KclNone { + value: KclNone::new(), + meta: vec![self.into()], + }, param.identifier.clone().into(), )?; } @@ -531,15 +587,13 @@ impl Node { .execute_expr(element, exec_state, &metadata, StatementKind::Expression) .await?; - results.push(value.get_json_value()?); + results.push(value); } - Ok(KclValue::UserVal(UserVal { - value: results.into(), - meta: vec![Metadata { - source_range: self.into(), - }], - })) + Ok(KclValue::Array { + value: results, + meta: vec![self.into()], + }) } } @@ -549,15 +603,19 @@ impl Node { let metadata = Metadata::from(&self.start_element); let start = ctx .execute_expr(&self.start_element, exec_state, &metadata, StatementKind::Expression) - .await? - .get_json_value()?; - let start = parse_json_number_as_i64(&start, (&self.start_element).into())?; + .await?; + let start = start.as_int().ok_or(KclError::Semantic(KclErrorDetails { + source_ranges: vec![self.into()], + message: format!("Expected int but found {}", start.human_friendly_type()), + }))?; let metadata = Metadata::from(&self.end_element); let end = ctx .execute_expr(&self.end_element, exec_state, &metadata, StatementKind::Expression) - .await? - .get_json_value()?; - let end = parse_json_number_as_i64(&end, (&self.end_element).into())?; + .await?; + let end = end.as_int().ok_or(KclError::Semantic(KclErrorDetails { + source_ranges: vec![self.into()], + message: format!("Expected int but found {}", end.human_friendly_type()), + }))?; if end < start { return Err(KclError::Semantic(KclErrorDetails { @@ -567,94 +625,76 @@ impl Node { } let range: Vec<_> = if self.end_inclusive { - (start..=end).map(JValue::from).collect() + (start..=end).collect() } else { - (start..end).map(JValue::from).collect() + (start..end).collect() }; - Ok(KclValue::UserVal(UserVal { - value: range.into(), - meta: vec![Metadata { - source_range: self.into(), - }], - })) + let meta = vec![Metadata { + source_range: self.into(), + }]; + Ok(KclValue::Array { + value: range + .into_iter() + .map(|num| KclValue::Int { + value: num, + meta: meta.clone(), + }) + .collect(), + meta, + }) } } impl Node { #[async_recursion] pub async fn execute(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result { - let mut object = serde_json::Map::new(); + let mut object = HashMap::with_capacity(self.properties.len()); for property in &self.properties { let metadata = Metadata::from(&property.value); let result = ctx .execute_expr(&property.value, exec_state, &metadata, StatementKind::Expression) .await?; - object.insert(property.key.name.clone(), result.get_json_value()?); + object.insert(property.key.name.clone(), result); } - Ok(KclValue::UserVal(UserVal { - value: object.into(), + Ok(KclValue::Object { + value: object, meta: vec![Metadata { source_range: self.into(), }], - })) + }) } } -fn parse_json_number_as_i64(j: &serde_json::Value, source_range: SourceRange) -> Result { - if let serde_json::Value::Number(n) = &j { - n.as_i64().ok_or_else(|| { - KclError::Syntax(KclErrorDetails { - source_ranges: vec![source_range], - message: format!("Invalid integer: {}", j), - }) - }) +fn article_for(s: &str) -> &'static str { + if s.starts_with(['a', 'e', 'i', 'o', 'u']) { + "an" } else { - Err(KclError::Syntax(KclErrorDetails { - source_ranges: vec![source_range], - message: format!("Invalid integer: {}", j), - })) + "a" } } -pub fn parse_json_number_as_f64(j: &serde_json::Value, source_range: SourceRange) -> Result { - if let serde_json::Value::Number(n) = &j { - n.as_f64().ok_or_else(|| { - KclError::Syntax(KclErrorDetails { - source_ranges: vec![source_range], - message: format!("Invalid number: {}", j), - }) - }) +pub fn parse_number_as_f64(v: &KclValue, source_range: SourceRange) -> Result { + if let KclValue::Number { value: n, .. } = &v { + Ok(*n) + } else if let KclValue::Int { value: n, .. } = &v { + Ok(*n as f64) } else { - Err(KclError::Syntax(KclErrorDetails { + let actual_type = v.human_friendly_type(); + let article = if actual_type.starts_with(['a', 'e', 'i', 'o', 'u']) { + "an" + } else { + "a" + }; + Err(KclError::Semantic(KclErrorDetails { source_ranges: vec![source_range], - message: format!("Invalid number: {}", j), + message: format!("Expected a number, but found {article} {actual_type}",), })) } } -pub fn parse_json_value_as_string(j: &serde_json::Value) -> Option { - if let serde_json::Value::String(n) = &j { - Some(n.clone()) - } else { - None - } -} - -/// JSON value as bool. If it isn't a bool, returns None. -pub fn json_as_bool(j: &serde_json::Value) -> Option { - match j { - JValue::Null => None, - JValue::Bool(b) => Some(*b), - JValue::Number(_) => None, - JValue::String(_) => None, - JValue::Array(_) => None, - JValue::Object(_) => None, - } -} - impl Node { #[async_recursion] pub async fn get_result(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result { @@ -724,15 +764,7 @@ impl Property { } else { // Actually evaluate memory to compute the property. let prop = exec_state.memory.get(name, property_src)?; - let KclValue::UserVal(prop) = prop else { - return Err(KclError::Semantic(KclErrorDetails { - source_ranges: property_sr, - message: format!( - "{name} is not a valid property/index, you can only use a string or int (>= 0) here", - ), - })); - }; - jvalue_to_prop(&prop.value, property_sr, name) + jvalue_to_prop(prop, property_sr, name) } } LiteralIdentifier::Literal(literal) => { @@ -759,35 +791,37 @@ impl Property { } } -fn jvalue_to_prop(value: &JValue, property_sr: Vec, name: &str) -> Result { +fn jvalue_to_prop(value: &KclValue, property_sr: Vec, name: &str) -> Result { let make_err = |message: String| { Err::(KclError::Semantic(KclErrorDetails { source_ranges: property_sr, message, })) }; - const MUST_BE_POSINT: &str = "indices must be whole positive numbers"; - const TRY_INT: &str = "try using the int() function to make this a whole number"; match value { - JValue::Number(ref num) => { - let maybe_uint = num.as_u64().and_then(|x| usize::try_from(x).ok()); - if let Some(uint) = maybe_uint { + KclValue::Int { value:num, meta: _ } => { + let maybe_int: Result = (*num).try_into(); + if let Ok(uint) = maybe_int { Ok(Property::Number(uint)) - } else if let Some(iint) = num.as_i64() { - make_err(format!("'{iint}' is not a valid index, {MUST_BE_POSINT}")) - } else if let Some(fnum) = num.as_f64() { - if fnum < 0.0 { - make_err(format!("'{fnum}' is not a valid index, {MUST_BE_POSINT}")) - } else if fnum.fract() == 0.0 { - make_err(format!("'{fnum:.1}' is stored as a fractional number but indices must be whole numbers, {TRY_INT}")) - } else { - make_err(format!("'{fnum}' is not a valid index, {MUST_BE_POSINT}, {TRY_INT}")) - } + } + else { + make_err(format!("'{num}' is negative, so you can't index an array with it")) + } + } + KclValue::Number{value: num, meta:_} => { + let num = *num; + if num < 0.0 { + return make_err(format!("'{num}' is negative, so you can't index an array with it")) + } + let nearest_int = num.round(); + let delta = num-nearest_int; + if delta < FLOAT_TO_INT_MAX_DELTA { + Ok(Property::Number(nearest_int as usize)) } else { - make_err(format!("'{num}' is not a valid index, {MUST_BE_POSINT}")) + make_err(format!("'{num}' is not an integer, so you can't index an array with it")) } } - JValue::String(ref x) => Ok(Property::String(x.to_owned())), + KclValue::String{value: x, meta:_} => Ok(Property::String(x.to_owned())), _ => { make_err(format!("{name} is not a valid property/index, you can only use a string to get the property of an object, or an int (>= 0) to get an item in an array")) } diff --git a/src/wasm-lib/kcl/src/ast/types/none.rs b/src/wasm-lib/kcl/src/ast/types/none.rs index 6e60243311..618ee7be5c 100644 --- a/src/wasm-lib/kcl/src/ast/types/none.rs +++ b/src/wasm-lib/kcl/src/ast/types/none.rs @@ -4,10 +4,7 @@ use databake::*; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::{ - ast::types::ConstraintLevel, - executor::{KclValue, UserVal}, -}; +use crate::{ast::types::ConstraintLevel, executor::KclValue}; use super::Node; @@ -16,7 +13,7 @@ const KCL_NONE_ID: &str = "KCL_NONE_ID"; /// KCL value for an optional parameter which was not given an argument. /// (remember, parameters are in the function declaration, /// arguments are in the function call/application). -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Bake, Default)] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Bake, Default, Copy)] #[databake(path = kcl_lib::ast::types)] #[ts(export)] #[serde(tag = "type")] @@ -58,22 +55,15 @@ where } } -impl From<&KclNone> for UserVal { +impl From<&KclNone> for KclValue { fn from(none: &KclNone) -> Self { - UserVal { - value: serde_json::to_value(none).expect("can always serialize a None"), + KclValue::KclNone { + value: *none, meta: Default::default(), } } } -impl From<&KclNone> for KclValue { - fn from(none: &KclNone) -> Self { - let val = UserVal::from(none); - KclValue::UserVal(val) - } -} - impl From<&Node> for KclValue { fn from(none: &Node) -> Self { Self::from(&none.inner) diff --git a/src/wasm-lib/kcl/src/executor.rs b/src/wasm-lib/kcl/src/executor.rs index ecbd4f4b97..cfc7a46f32 100644 --- a/src/wasm-lib/kcl/src/executor.rs +++ b/src/wasm-lib/kcl/src/executor.rs @@ -19,7 +19,6 @@ use kittycad_modeling_cmds::length_unit::LengthUnit; use parse_display::{Display, FromStr}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use serde_json::Value as JValue; use tower_lsp::lsp_types::{Position as LspPosition, Range as LspRange}; type Point2D = kcmc::shared::Point2d; @@ -27,8 +26,8 @@ type Point3D = kcmc::shared::Point3d; use crate::{ ast::types::{ - human_friendly_type, BodyItem, Expr, FunctionExpression, ItemVisibility, KclNone, ModuleId, Node, NodeRef, - Program, TagDeclarator, TagNode, + BodyItem, Expr, FunctionExpression, ItemVisibility, KclNone, ModuleId, Node, NodeRef, Program, TagDeclarator, + TagNode, }, engine::{EngineManager, ExecutionKind}, errors::{KclError, KclErrorDetails}, @@ -201,33 +200,18 @@ impl Environment { Self { // Prelude bindings: HashMap::from([ - ( - "ZERO".to_string(), - KclValue::UserVal(UserVal { - value: serde_json::Value::Number(serde_json::value::Number::from(0)), - meta: Default::default(), - }), - ), + ("ZERO".to_string(), KclValue::from_number(0.0, Default::default())), ( "QUARTER_TURN".to_string(), - KclValue::UserVal(UserVal { - value: serde_json::Value::Number(serde_json::value::Number::from(90)), - meta: Default::default(), - }), + KclValue::from_number(90.0, Default::default()), ), ( "HALF_TURN".to_string(), - KclValue::UserVal(UserVal { - value: serde_json::Value::Number(serde_json::value::Number::from(180)), - meta: Default::default(), - }), + KclValue::from_number(180.0, Default::default()), ), ( "THREE_QUARTER_TURN".to_string(), - KclValue::UserVal(UserVal { - value: serde_json::Value::Number(serde_json::value::Number::from(270)), - meta: Default::default(), - }), + KclValue::from_number(270.0, Default::default()), ), ]), parent: None, @@ -264,22 +248,15 @@ impl Environment { } for (_, val) in self.bindings.iter_mut() { - let KclValue::UserVal(v) = val else { continue }; - let meta = v.meta.clone(); - let maybe_sg: Result = serde_json::from_value(v.value.clone()); - let Ok(mut sketch) = maybe_sg else { - continue; - }; + let KclValue::Sketch { value } = val else { continue }; + let mut sketch = value.to_owned(); if sketch.original_id == sg.original_id { for tag in sg.tags.iter() { sketch.tags.insert(tag.0.clone(), tag.1.clone()); } } - *val = KclValue::UserVal(UserVal { - meta, - value: serde_json::to_value(sketch).expect("can always turn Sketch into JSON"), - }); + *val = KclValue::Sketch { value: sketch }; } } } @@ -360,12 +337,52 @@ impl IdGenerator { #[ts(export)] #[serde(tag = "type")] pub enum KclValue { - UserVal(UserVal), + Uuid { + value: ::uuid::Uuid, + #[serde(rename = "__meta")] + meta: Vec, + }, + Bool { + value: bool, + #[serde(rename = "__meta")] + meta: Vec, + }, + Number { + value: f64, + #[serde(rename = "__meta")] + meta: Vec, + }, + Int { + value: i64, + #[serde(rename = "__meta")] + meta: Vec, + }, + String { + value: String, + #[serde(rename = "__meta")] + meta: Vec, + }, + Array { + value: Vec, + #[serde(rename = "__meta")] + meta: Vec, + }, + Object { + value: HashMap, + #[serde(rename = "__meta")] + meta: Vec, + }, TagIdentifier(Box), TagDeclarator(crate::ast::types::BoxNode), Plane(Box), Face(Box), + Sketch { + value: Box, + }, + Sketches { + value: Vec>, + }, Solid(Box), Solids { value: Vec>, @@ -380,31 +397,55 @@ pub enum KclValue { #[serde(rename = "__meta")] meta: Vec, }, + KclNone { + value: KclNone, + #[serde(rename = "__meta")] + meta: Vec, + }, } impl KclValue { - pub(crate) fn new_user_val(meta: Vec, val: T) -> Self { - Self::UserVal(UserVal::new(meta, val)) + pub(crate) fn metadata(&self) -> Vec { + match self { + KclValue::Uuid { value: _, meta } => meta.clone(), + KclValue::Bool { value: _, meta } => meta.clone(), + KclValue::Number { value: _, meta } => meta.clone(), + KclValue::Int { value: _, meta } => meta.clone(), + KclValue::String { value: _, meta } => meta.clone(), + KclValue::Array { value: _, meta } => meta.clone(), + KclValue::Object { value: _, meta } => meta.clone(), + KclValue::TagIdentifier(x) => x.meta.clone(), + KclValue::TagDeclarator(x) => vec![x.metadata()], + KclValue::Plane(x) => x.meta.clone(), + KclValue::Face(x) => x.meta.clone(), + KclValue::Sketch { value } => value.meta.clone(), + KclValue::Sketches { value } => value.iter().flat_map(|sketch| &sketch.meta).copied().collect(), + KclValue::Solid(x) => x.meta.clone(), + KclValue::Solids { value } => value.iter().flat_map(|sketch| &sketch.meta).copied().collect(), + KclValue::ImportedGeometry(x) => x.meta.clone(), + KclValue::Function { meta, .. } => meta.clone(), + KclValue::KclNone { meta, .. } => meta.clone(), + } } pub(crate) fn get_solid_set(&self) -> Result { match self { KclValue::Solid(e) => Ok(SolidSet::Solid(e.clone())), KclValue::Solids { value } => Ok(SolidSet::Solids(value.clone())), - KclValue::UserVal(value) => { - let value = value.value.clone(); - match value { - JValue::Null | JValue::Bool(_) | JValue::Number(_) | JValue::String(_) => Err(anyhow::anyhow!( - "Failed to deserialize solid set from JSON {}", - human_friendly_type(&value) - )), - JValue::Array(_) => serde_json::from_value::>>(value) - .map(SolidSet::from) - .map_err(|e| anyhow::anyhow!("Failed to deserialize array of solids from JSON: {}", e)), - JValue::Object(_) => serde_json::from_value::>(value) - .map(SolidSet::from) - .map_err(|e| anyhow::anyhow!("Failed to deserialize solid from JSON: {}", e)), - } + KclValue::Array { value, .. } => { + let solids: Vec<_> = value + .iter() + .enumerate() + .map(|(i, v)| { + v.as_solid().map(|v| v.to_owned()).map(Box::new).ok_or_else(|| { + anyhow::anyhow!( + "expected this array to only contain solids, but element {i} was actually {}", + v.human_friendly_type() + ) + }) + }) + .collect::>()?; + Ok(SolidSet::Solids(solids)) } _ => anyhow::bail!("Not a solid or solids: {:?}", self), } @@ -414,43 +455,44 @@ impl KclValue { /// on for program logic. pub(crate) fn human_friendly_type(&self) -> &'static str { match self { - KclValue::UserVal(u) => human_friendly_type(&u.value), + KclValue::Uuid { .. } => "Unique ID (uuid)", KclValue::TagDeclarator(_) => "TagDeclarator", KclValue::TagIdentifier(_) => "TagIdentifier", KclValue::Solid(_) => "Solid", KclValue::Solids { .. } => "Solids", + KclValue::Sketch { .. } => "Sketch", + KclValue::Sketches { .. } => "Sketches", KclValue::ImportedGeometry(_) => "ImportedGeometry", KclValue::Function { .. } => "Function", KclValue::Plane(_) => "Plane", KclValue::Face(_) => "Face", + KclValue::Bool { .. } => "boolean (true/false value)", + KclValue::Number { .. } => "number", + KclValue::Int { .. } => "integer", + KclValue::String { .. } => "string (text)", + KclValue::Array { .. } => "array (list)", + KclValue::Object { .. } => "object", + KclValue::KclNone { .. } => "None", } } pub(crate) fn is_function(&self) -> bool { - match self { - KclValue::UserVal(..) - | KclValue::TagIdentifier(..) - | KclValue::TagDeclarator(..) - | KclValue::Plane(..) - | KclValue::Face(..) - | KclValue::Solid(..) - | KclValue::Solids { .. } - | KclValue::ImportedGeometry(..) => false, - KclValue::Function { .. } => true, - } + matches!(self, KclValue::Function { .. }) } } impl From for KclValue { fn from(sg: SketchSet) -> Self { - KclValue::UserVal(UserVal::new(sg.meta(), sg)) + match sg { + SketchSet::Sketch(value) => KclValue::Sketch { value }, + SketchSet::Sketches(value) => KclValue::Sketches { value }, + } } } impl From>> for KclValue { fn from(sg: Vec>) -> Self { - let meta = sg.iter().flat_map(|sg| sg.meta.clone()).collect(); - KclValue::UserVal(UserVal::new(meta, sg)) + KclValue::Sketches { value: sg } } } @@ -815,52 +857,6 @@ pub enum PlaneType { Custom, } -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] -#[ts(export)] -#[serde(tag = "type", rename_all = "camelCase")] -pub struct UserVal { - #[ts(type = "any")] - pub value: serde_json::Value, - #[serde(rename = "__meta")] - pub meta: Vec, -} - -impl UserVal { - pub fn new(meta: Vec, val: T) -> Self { - Self { - meta, - value: serde_json::to_value(val).expect("all KCL values should be compatible with JSON"), - } - } - - /// If the UserVal matches the type `T`, return it. - pub fn get(&self) -> Option<(T, Vec)> { - let meta = self.meta.clone(); - // TODO: This clone might cause performance problems, it'll happen a lot. - let res: Result = serde_json::from_value(self.value.clone()); - if let Ok(t) = res { - Some((t, meta)) - } else { - None - } - } - - /// If the UserVal matches the type `T`, then mutate it via the given closure. - /// If the closure returns Err, the mutation won't be applied. - pub fn mutate(&mut self, mutate: F) -> Result<(), E> - where - T: serde::de::DeserializeOwned + Serialize, - F: FnOnce(&mut T) -> Result<(), E>, - { - let Some((mut val, meta)) = self.get::() else { - return Ok(()); - }; - mutate(&mut val)?; - *self = Self::new(meta, val); - Ok(()) - } -} - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, ts_rs::TS, JsonSchema)] #[ts(export)] #[serde(tag = "type", rename_all = "camelCase")] @@ -922,108 +918,177 @@ pub type MemoryFunction = impl From for Vec { fn from(item: KclValue) -> Self { match item { - KclValue::UserVal(u) => u.meta.iter().map(|m| m.source_range).collect(), - KclValue::TagDeclarator(t) => vec![(&t).into()], - KclValue::TagIdentifier(t) => t.meta.iter().map(|m| m.source_range).collect(), - KclValue::Solid(e) => e.meta.iter().map(|m| m.source_range).collect(), - KclValue::Solids { value } => value - .iter() - .flat_map(|eg| eg.meta.iter().map(|m| m.source_range)) - .collect(), - KclValue::ImportedGeometry(i) => i.meta.iter().map(|m| m.source_range).collect(), - KclValue::Function { meta, .. } => meta.iter().map(|m| m.source_range).collect(), - KclValue::Plane(p) => p.meta.iter().map(|m| m.source_range).collect(), - KclValue::Face(f) => f.meta.iter().map(|m| m.source_range).collect(), + KclValue::TagDeclarator(t) => vec![SourceRange([t.start, t.end, t.module_id.0 as usize])], + KclValue::TagIdentifier(t) => to_vec_sr(&t.meta), + KclValue::Solid(e) => to_vec_sr(&e.meta), + KclValue::Solids { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(), + KclValue::Sketch { value } => to_vec_sr(&value.meta), + KclValue::Sketches { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(), + KclValue::ImportedGeometry(i) => to_vec_sr(&i.meta), + KclValue::Function { meta, .. } => to_vec_sr(&meta), + KclValue::Plane(p) => to_vec_sr(&p.meta), + KclValue::Face(f) => to_vec_sr(&f.meta), + KclValue::Bool { meta, .. } => to_vec_sr(&meta), + KclValue::Number { meta, .. } => to_vec_sr(&meta), + KclValue::Int { meta, .. } => to_vec_sr(&meta), + KclValue::String { meta, .. } => to_vec_sr(&meta), + KclValue::Array { meta, .. } => to_vec_sr(&meta), + KclValue::Object { meta, .. } => to_vec_sr(&meta), + KclValue::Uuid { meta, .. } => to_vec_sr(&meta), + KclValue::KclNone { meta, .. } => to_vec_sr(&meta), } } } +fn to_vec_sr(meta: &[Metadata]) -> Vec { + meta.iter().map(|m| m.source_range).collect() +} + impl From<&KclValue> for Vec { fn from(item: &KclValue) -> Self { match item { - KclValue::UserVal(u) => u.meta.iter().map(|m| m.source_range).collect(), - KclValue::TagDeclarator(ref t) => vec![t.into()], - KclValue::TagIdentifier(t) => t.meta.iter().map(|m| m.source_range).collect(), - KclValue::Solid(e) => e.meta.iter().map(|m| m.source_range).collect(), - KclValue::Solids { value } => value - .iter() - .flat_map(|eg| eg.meta.iter().map(|m| m.source_range)) - .collect(), - KclValue::ImportedGeometry(i) => i.meta.iter().map(|m| m.source_range).collect(), - KclValue::Function { meta, .. } => meta.iter().map(|m| m.source_range).collect(), - KclValue::Plane(p) => p.meta.iter().map(|m| m.source_range).collect(), - KclValue::Face(f) => f.meta.iter().map(|m| m.source_range).collect(), + KclValue::TagDeclarator(t) => vec![SourceRange([t.start, t.end, t.module_id.0 as usize])], + KclValue::TagIdentifier(t) => to_vec_sr(&t.meta), + KclValue::Solid(e) => to_vec_sr(&e.meta), + KclValue::Solids { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(), + KclValue::Sketch { value } => to_vec_sr(&value.meta), + KclValue::Sketches { value } => value.iter().flat_map(|eg| to_vec_sr(&eg.meta)).collect(), + KclValue::ImportedGeometry(i) => to_vec_sr(&i.meta), + KclValue::Function { meta, .. } => to_vec_sr(meta), + KclValue::Plane(p) => to_vec_sr(&p.meta), + KclValue::Face(f) => to_vec_sr(&f.meta), + KclValue::Bool { meta, .. } => to_vec_sr(meta), + KclValue::Number { meta, .. } => to_vec_sr(meta), + KclValue::Int { meta, .. } => to_vec_sr(meta), + KclValue::String { meta, .. } => to_vec_sr(meta), + KclValue::Uuid { meta, .. } => to_vec_sr(meta), + KclValue::Array { meta, .. } => to_vec_sr(meta), + KclValue::Object { meta, .. } => to_vec_sr(meta), + KclValue::KclNone { meta, .. } => to_vec_sr(meta), } } } impl KclValue { - pub fn get_json_value(&self) -> Result { - if let KclValue::UserVal(user_val) = self { - Ok(user_val.value.clone()) + /// Put the number into a KCL value. + pub fn from_number(f: f64, meta: Vec) -> Self { + Self::Number { value: f, meta } + } + + /// Put the point into a KCL value. + pub fn from_point2d(p: [f64; 2], meta: Vec) -> Self { + Self::Array { + value: vec![ + Self::Number { + value: p[0], + meta: meta.clone(), + }, + Self::Number { + value: p[1], + meta: meta.clone(), + }, + ], + meta, + } + } + + pub(crate) fn as_usize(&self) -> Option { + match self { + KclValue::Int { value, .. } => Some(*value as usize), + _ => None, + } + } + + pub fn as_int(&self) -> Option { + if let KclValue::Int { value, meta: _ } = &self { + Some(*value) } else { - serde_json::to_value(self).map_err(|err| { - KclError::Semantic(KclErrorDetails { - message: format!("Cannot convert memory item to json value: {:?}", err), - source_ranges: self.clone().into(), - }) - }) + None } } - /// Get a JSON value and deserialize it into some concrete type. - pub fn get_json(&self) -> Result { - let json = self.get_json_value()?; + pub fn as_object(&self) -> Option<&HashMap> { + if let KclValue::Object { value, meta: _ } = &self { + Some(value) + } else { + None + } + } - serde_json::from_value(json).map_err(|e| { - KclError::Type(KclErrorDetails { - message: format!("Failed to deserialize struct from JSON: {}", e), - source_ranges: self.clone().into(), - }) - }) + pub fn as_str(&self) -> Option<&str> { + if let KclValue::String { value, meta: _ } = &self { + Some(value) + } else { + None + } } - /// Get a JSON value and deserialize it into some concrete type. - /// If it's a KCL None, return None. Otherwise return Some. - pub fn get_json_opt(&self) -> Result, KclError> { - let json = self.get_json_value()?; - if let JValue::Object(ref o) = json { - if let Some(JValue::String(s)) = o.get("type") { - if s == "KclNone" { - return Ok(None); - } - } + pub fn as_array(&self) -> Option<&[KclValue]> { + if let KclValue::Array { value, meta: _ } = &self { + Some(value) + } else { + None } + } - serde_json::from_value(json) - .map_err(|e| { - KclError::Type(KclErrorDetails { - message: format!("Failed to deserialize struct from JSON: {}", e), - source_ranges: self.clone().into(), - }) - }) - .map(Some) + pub fn as_point2d(&self) -> Option<[f64; 2]> { + let arr = self.as_array()?; + if arr.len() != 2 { + return None; + } + let x = arr[0].as_f64()?; + let y = arr[1].as_f64()?; + Some([x, y]) } - pub fn as_user_val(&self) -> Option<&UserVal> { - if let KclValue::UserVal(x) = self { - Some(x) + pub fn as_uuid(&self) -> Option { + if let KclValue::Uuid { value, meta: _ } = &self { + Some(*value) } else { None } } - /// If this value is of type u32, return it. + pub fn as_solid(&self) -> Option<&Solid> { + if let KclValue::Solid(value) = &self { + Some(value) + } else { + None + } + } + + pub fn as_f64(&self) -> Option { + if let KclValue::Number { value, meta: _ } = &self { + Some(*value) + } else if let KclValue::Int { value, meta: _ } = &self { + Some(*value as f64) + } else { + None + } + } + + pub fn as_bool(&self) -> Option { + if let KclValue::Bool { value, meta: _ } = &self { + Some(*value) + } else { + None + } + } + + /// If this value fits in a u32, return it. pub fn get_u32(&self, source_ranges: Vec) -> Result { - let err = KclError::Semantic(KclErrorDetails { - message: "Expected an integer >= 0".to_owned(), - source_ranges, - }); - self.as_user_val() - .and_then(|uv| uv.value.as_number()) - .and_then(|n| n.as_u64()) - .and_then(|n| u32::try_from(n).ok()) - .ok_or(err) + let u = self.as_int().and_then(|n| u64::try_from(n).ok()).ok_or_else(|| { + KclError::Semantic(KclErrorDetails { + message: "Expected an integer >= 0".to_owned(), + source_ranges: source_ranges.clone(), + }) + })?; + u32::try_from(u).map_err(|_| { + KclError::Semantic(KclErrorDetails { + message: "Number was too big".to_owned(), + source_ranges, + }) + }) } /// If this value is of type function, return it. @@ -1048,16 +1113,6 @@ impl KclValue { pub fn get_tag_identifier(&self) -> Result { match self { KclValue::TagIdentifier(t) => Ok(*t.clone()), - KclValue::UserVal(_) => { - if let Some(identifier) = self.get_json_opt::()? { - Ok(identifier) - } else { - Err(KclError::Semantic(KclErrorDetails { - message: format!("Not a tag identifier: {:?}", self), - source_ranges: self.clone().into(), - })) - } - } _ => Err(KclError::Semantic(KclErrorDetails { message: format!("Not a tag identifier: {:?}", self), source_ranges: self.clone().into(), @@ -1089,19 +1144,13 @@ impl KclValue { /// If this KCL value is a bool, retrieve it. pub fn get_bool(&self) -> Result { - let Self::UserVal(uv) = self else { + let Self::Bool { value: b, .. } = self else { return Err(KclError::Type(KclErrorDetails { source_ranges: self.into(), message: format!("Expected bool, found {}", self.human_friendly_type()), })); }; - let JValue::Bool(b) = uv.value else { - return Err(KclError::Type(KclErrorDetails { - source_ranges: self.into(), - message: format!("Expected bool, found {}", human_friendly_type(&uv.value)), - })); - }; - Ok(b) + Ok(*b) } /// If this memory item is a function, call it with the given arguments, return its val as Ok. @@ -1555,7 +1604,7 @@ impl From for kittycad_modeling_cmds::shared::Point3d { } /// Metadata. -#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq, Copy)] #[ts(export)] #[serde(rename_all = "camelCase")] pub struct Metadata { @@ -1563,6 +1612,12 @@ pub struct Metadata { pub source_range: SourceRange, } +impl From for Vec { + fn from(meta: Metadata) -> Self { + vec![meta.source_range] + } +} + impl From for Metadata { fn from(source_range: SourceRange) -> Self { Self { source_range } @@ -2655,74 +2710,8 @@ mod tests { } /// Convenience function to get a JSON value from memory and unwrap. - fn mem_get_json(memory: &ProgramMemory, name: &str) -> serde_json::Value { - memory - .get(name, SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - } - - #[tokio::test(flavor = "multi_thread")] - async fn test_execute_assign_two_variables() { - let ast = r#"const myVar = 5 -const newVar = myVar + 1"#; - let memory = parse_execute(ast).await.unwrap(); - assert_eq!( - serde_json::json!(5), - memory - .get("myVar", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - assert_eq!( - serde_json::json!(6.0), - memory - .get("newVar", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - } - - #[tokio::test(flavor = "multi_thread")] - async fn test_execute_angled_line_that_intersects() { - let ast_fn = |offset: &str| -> String { - format!( - r#"const part001 = startSketchOn('XY') - |> startProfileAt([0, 0], %) - |> lineTo([2, 2], %, $yo) - |> lineTo([3, 1], %) - |> angledLineThatIntersects({{ - angle: 180, - intersectTag: yo, - offset: {}, -}}, %, $yo2) -const intersect = segEndX(yo2)"#, - offset - ) - }; - - let memory = parse_execute(&ast_fn("-1")).await.unwrap(); - assert_eq!( - serde_json::json!(1.0 + 2.0f64.sqrt()), - memory - .get("intersect", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - - let memory = parse_execute(&ast_fn("0")).await.unwrap(); - assert_eq!( - serde_json::json!(1.0000000000000002), - memory - .get("intersect", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); + fn mem_get_json(memory: &ProgramMemory, name: &str) -> KclValue { + memory.get(name, SourceRange::default()).unwrap().to_owned() } #[tokio::test(flavor = "multi_thread")] @@ -3120,200 +3109,41 @@ let shape = layer() |> patternTransform(10, transform, %) ); } - #[tokio::test(flavor = "multi_thread")] - async fn test_execute_function_with_parameter_redefined_outside() { - let ast = r#" -fn myIdentity = (x) => { - return x -} - -const x = 33 - -const two = myIdentity(2)"#; - - let memory = parse_execute(ast).await.unwrap(); - assert_eq!( - serde_json::json!(2), - memory - .get("two", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - assert_eq!( - serde_json::json!(33), - memory - .get("x", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - } - - #[tokio::test(flavor = "multi_thread")] - async fn test_execute_function_referencing_variable_in_parent_scope() { - let ast = r#" -const x = 22 -const y = 3 - -fn add = (x) => { - return x + y -} - -const answer = add(2)"#; - - let memory = parse_execute(ast).await.unwrap(); - assert_eq!( - serde_json::json!(5.0), - memory - .get("answer", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - assert_eq!( - serde_json::json!(22), - memory - .get("x", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - } - - #[tokio::test(flavor = "multi_thread")] - async fn test_execute_function_redefining_variable_in_parent_scope() { - let ast = r#" -const x = 1 - -fn foo = () => { - const x = 2 - return x -} - -const answer = foo()"#; - - let memory = parse_execute(ast).await.unwrap(); - assert_eq!( - serde_json::json!(2), - memory - .get("answer", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - assert_eq!( - serde_json::json!(1), - memory - .get("x", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - } - - #[tokio::test(flavor = "multi_thread")] - async fn test_execute_pattern_transform_function_redefining_variable_in_parent_scope() { - let ast = r#" -const scale = 100 -fn transform = (replicaId) => { - // Redefine same variable as in parent scope. - const scale = 2 - return { - translate: [0, 0, replicaId * 10], - scale: [scale, 1, 0], - } -} - -fn layer = () => { - return startSketchOn("XY") - |> circle({ center: [0, 0], radius: 1 }, %, $tag1) - |> extrude(10, %) -} - -// The 10 layers are replicas of each other, with a transform applied to each. -let shape = layer() |> patternTransform(10, transform, %)"#; - - let memory = parse_execute(ast).await.unwrap(); - // TODO: Assert that scale 2 was used. - assert_eq!( - serde_json::json!(100), - memory - .get("scale", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); - } + // ADAM: Move some of these into simulation tests. #[tokio::test(flavor = "multi_thread")] async fn test_math_execute_with_functions() { let ast = r#"const myVar = 2 + min(100, -1 + legLen(5, 3))"#; let memory = parse_execute(ast).await.unwrap(); - assert_eq!( - serde_json::json!(5.0), - memory - .get("myVar", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); + assert_eq!(5.0, mem_get_json(&memory, "myVar").as_f64().unwrap()); } #[tokio::test(flavor = "multi_thread")] async fn test_math_execute() { let ast = r#"const myVar = 1 + 2 * (3 - 4) / -5 + 6"#; let memory = parse_execute(ast).await.unwrap(); - assert_eq!( - serde_json::json!(7.4), - memory - .get("myVar", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); + assert_eq!(7.4, mem_get_json(&memory, "myVar").as_f64().unwrap()); } #[tokio::test(flavor = "multi_thread")] async fn test_math_execute_start_negative() { let ast = r#"const myVar = -5 + 6"#; let memory = parse_execute(ast).await.unwrap(); - assert_eq!( - serde_json::json!(1.0), - memory - .get("myVar", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); + assert_eq!(1.0, mem_get_json(&memory, "myVar").as_f64().unwrap()); } #[tokio::test(flavor = "multi_thread")] async fn test_math_execute_with_pi() { let ast = r#"const myVar = pi() * 2"#; let memory = parse_execute(ast).await.unwrap(); - assert_eq!( - serde_json::json!(std::f64::consts::TAU), - memory - .get("myVar", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); + assert_eq!(std::f64::consts::TAU, mem_get_json(&memory, "myVar").as_f64().unwrap()); } #[tokio::test(flavor = "multi_thread")] async fn test_math_define_decimal_without_leading_zero() { let ast = r#"let thing = .4 + 7"#; let memory = parse_execute(ast).await.unwrap(); - assert_eq!( - serde_json::json!(7.4), - memory - .get("thing", SourceRange::default()) - .unwrap() - .get_json_value() - .unwrap() - ); + assert_eq!(7.4, mem_get_json(&memory, "thing").as_f64().unwrap()); } #[tokio::test(flavor = "multi_thread")] @@ -3353,10 +3183,10 @@ fn check = (x) => { check(false) "#; let mem = parse_execute(ast).await.unwrap(); - assert_eq!(serde_json::json!(false), mem_get_json(&mem, "notTrue")); - assert_eq!(serde_json::json!(true), mem_get_json(&mem, "notFalse")); - assert_eq!(serde_json::json!(true), mem_get_json(&mem, "c")); - assert_eq!(serde_json::json!(false), mem_get_json(&mem, "d")); + assert_eq!(false, mem_get_json(&mem, "notTrue").as_bool().unwrap()); + assert_eq!(true, mem_get_json(&mem, "notFalse").as_bool().unwrap()); + assert_eq!(true, mem_get_json(&mem, "c").as_bool().unwrap()); + assert_eq!(false, mem_get_json(&mem, "d").as_bool().unwrap()); } #[tokio::test(flavor = "multi_thread")] @@ -3369,7 +3199,7 @@ let notNull = !myNull assert_eq!( parse_execute(code1).await.unwrap_err().downcast::().unwrap(), KclError::Semantic(KclErrorDetails { - message: "Cannot apply unary operator ! to non-boolean value: null".to_owned(), + message: "Cannot apply unary operator ! to non-boolean value: number".to_owned(), source_ranges: vec![SourceRange([56, 63, 0])], }) ); @@ -3378,7 +3208,7 @@ let notNull = !myNull assert_eq!( parse_execute(code2).await.unwrap_err().downcast::().unwrap(), KclError::Semantic(KclErrorDetails { - message: "Cannot apply unary operator ! to non-boolean value: 0".to_owned(), + message: "Cannot apply unary operator ! to non-boolean value: integer".to_owned(), source_ranges: vec![SourceRange([14, 16, 0])], }) ); @@ -3389,7 +3219,7 @@ let notEmptyString = !"" assert_eq!( parse_execute(code3).await.unwrap_err().downcast::().unwrap(), KclError::Semantic(KclErrorDetails { - message: "Cannot apply unary operator ! to non-boolean value: \"\"".to_owned(), + message: "Cannot apply unary operator ! to non-boolean value: string (text)".to_owned(), source_ranges: vec![SourceRange([22, 25, 0])], }) ); @@ -3401,7 +3231,7 @@ let notMember = !obj.a assert_eq!( parse_execute(code4).await.unwrap_err().downcast::().unwrap(), KclError::Semantic(KclErrorDetails { - message: "Cannot apply unary operator ! to non-boolean value: 1".to_owned(), + message: "Cannot apply unary operator ! to non-boolean value: integer".to_owned(), source_ranges: vec![SourceRange([36, 42, 0])], }) ); @@ -3412,7 +3242,7 @@ let notArray = !a"; assert_eq!( parse_execute(code5).await.unwrap_err().downcast::().unwrap(), KclError::Semantic(KclErrorDetails { - message: "Cannot apply unary operator ! to non-boolean value: []".to_owned(), + message: "Cannot apply unary operator ! to non-boolean value: array (list)".to_owned(), source_ranges: vec![SourceRange([27, 29, 0])], }) ); @@ -3423,7 +3253,7 @@ let notObject = !x"; assert_eq!( parse_execute(code6).await.unwrap_err().downcast::().unwrap(), KclError::Semantic(KclErrorDetails { - message: "Cannot apply unary operator ! to non-boolean value: {}".to_owned(), + message: "Cannot apply unary operator ! to non-boolean value: object".to_owned(), source_ranges: vec![SourceRange([28, 30, 0])], }) ); @@ -3451,7 +3281,7 @@ let notTagDeclarator = !myTagDeclarator"; assert!( tag_declarator_err .message() - .starts_with("Cannot apply unary operator ! to non-boolean value: {\"type\":\"TagDeclarator\","), + .starts_with("Cannot apply unary operator ! to non-boolean value: TagDeclarator"), "Actual error: {:?}", tag_declarator_err ); @@ -3465,7 +3295,7 @@ let notTagIdentifier = !myTag"; assert!( tag_identifier_err .message() - .starts_with("Cannot apply unary operator ! to non-boolean value: {\"type\":\"TagIdentifier\","), + .starts_with("Cannot apply unary operator ! to non-boolean value: TagIdentifier"), "Actual error: {:?}", tag_identifier_err ); @@ -3603,10 +3433,10 @@ let w = f() + f() fn test_assign_args_to_params() { // Set up a little framework for this test. fn mem(number: usize) -> KclValue { - KclValue::UserVal(UserVal { - value: number.into(), + KclValue::Int { + value: number as i64, meta: Default::default(), - }) + } } fn ident(s: &'static str) -> Node { Node::no_src(Identifier { diff --git a/src/wasm-lib/kcl/src/std/args.rs b/src/wasm-lib/kcl/src/std/args.rs index 34c233c5ab..431e76b8cf 100644 --- a/src/wasm-lib/kcl/src/std/args.rs +++ b/src/wasm-lib/kcl/src/std/args.rs @@ -1,21 +1,21 @@ -use std::any::type_name; +use std::{any::type_name, num::NonZeroU32}; use anyhow::Result; use kcmc::{websocket::OkWebSocketResponseData, ModelingCmd}; use kittycad_modeling_cmds as kcmc; -use serde::de::DeserializeOwned; -use serde_json::Value as JValue; use crate::{ - ast::types::{execute::parse_json_number_as_f64, TagNode}, + ast::types::TagNode, errors::{KclError, KclErrorDetails}, executor::{ ExecState, ExecutorContext, ExtrudeSurface, KclValue, Metadata, Sketch, SketchSet, SketchSurface, Solid, - SolidSet, SourceRange, TagIdentifier, UserVal, + SolidSet, SourceRange, TagIdentifier, }, - std::{shapes::SketchOrSurface, sketch::FaceTag, FnAsArg}, + std::{shapes::SketchOrSurface, sketch::FaceTag, types::Uint, FnAsArg}, }; +use super::shapes::PolygonType; + #[derive(Debug, Clone)] pub struct Args { pub args: Vec, @@ -181,39 +181,58 @@ impl Args { Ok(()) } - fn make_user_val_from_json(&self, j: serde_json::Value) -> KclValue { - KclValue::UserVal(crate::executor::UserVal { - value: j, - meta: vec![Metadata { - source_range: self.source_range, - }], + pub(crate) fn make_user_val_from_point(&self, p: [f64; 2]) -> Result { + let meta = Metadata { + source_range: self.source_range, + }; + let x = KclValue::Number { + value: p[0], + meta: vec![meta], + }; + let y = KclValue::Number { + value: p[1], + meta: vec![meta], + }; + Ok(KclValue::Array { + value: vec![x, y], + meta: vec![meta], }) } - pub(crate) fn make_null_user_val(&self) -> KclValue { - self.make_user_val_from_json(serde_json::Value::Null) + pub(crate) fn make_user_val_from_f64(&self, f: f64) -> KclValue { + KclValue::from_number( + f, + vec![Metadata { + source_range: self.source_range, + }], + ) } pub(crate) fn make_user_val_from_i64(&self, n: i64) -> KclValue { - self.make_user_val_from_json(serde_json::Value::Number(serde_json::Number::from(n))) - } - - pub(crate) fn make_user_val_from_f64(&self, f: f64) -> Result { - f64_to_jnum(f, vec![self.source_range]).map(|x| self.make_user_val_from_json(x)) - } - - pub(crate) fn make_user_val_from_point(&self, p: [f64; 2]) -> Result { - let x = f64_to_jnum(p[0], vec![self.source_range])?; - let y = f64_to_jnum(p[1], vec![self.source_range])?; - let array = serde_json::Value::Array(vec![x, y]); - Ok(self.make_user_val_from_json(array)) + KclValue::Int { + value: n, + meta: vec![Metadata { + source_range: self.source_range, + }], + } } pub(crate) fn make_user_val_from_f64_array(&self, f: Vec) -> Result { - f.into_iter() - .map(|n| f64_to_jnum(n, vec![self.source_range])) - .collect::, _>>() - .map(|arr| self.make_user_val_from_json(serde_json::Value::Array(arr))) + let array = f + .into_iter() + .map(|n| KclValue::Number { + value: n, + meta: vec![Metadata { + source_range: self.source_range, + }], + }) + .collect::>(); + Ok(KclValue::Array { + value: array, + meta: vec![Metadata { + source_range: self.source_range, + }], + }) } pub(crate) fn get_number(&self) -> Result { @@ -221,11 +240,19 @@ impl Args { } pub(crate) fn get_number_array(&self) -> Result, KclError> { - let mut numbers: Vec = Vec::new(); - for arg in &self.args { - let parsed = arg.get_json_value()?; - numbers.push(parse_json_number_as_f64(&parsed, self.source_range)?); - } + let numbers = self + .args + .iter() + .map(|arg| { + let Some(num) = f64::from_mem_item(arg) else { + return Err(KclError::Semantic(KclErrorDetails { + source_ranges: arg.metadata().iter().map(|x| x.source_range).collect(), + message: format!("Expected a number but found {}", arg.human_friendly_type()), + })); + }; + Ok(num) + }) + .collect::>()?; Ok(numbers) } @@ -474,6 +501,25 @@ pub trait FromKclValue<'a>: Sized { fn from_mem_item(arg: &'a KclValue) -> Option; } +impl<'a> FromArgs<'a> for Vec { + fn from_args(args: &'a Args, i: usize) -> Result { + let Some(arg) = args.args.get(i) else { + return Err(KclError::Semantic(KclErrorDetails { + message: format!("Expected an argument at index {i}"), + source_ranges: vec![args.source_range], + })); + }; + let KclValue::Array { value: array, meta: _ } = arg else { + let message = format!("Expected an array but found {}", arg.human_friendly_type()); + return Err(KclError::Type(KclErrorDetails { + source_ranges: arg.metadata().into_iter().map(|m| m.source_range).collect(), + message, + })); + }; + Ok(array.to_owned()) + } +} + impl<'a, T> FromArgs<'a> for T where T: FromKclValue<'a> + Sized, @@ -511,7 +557,7 @@ where let Some(val) = T::from_mem_item(arg) else { return Err(KclError::Semantic(KclErrorDetails { message: format!( - "Argument at index {i} was supposed to be type {} but found {}", + "Argument at index {i} was supposed to be type Option<{}> but found {}", type_name::(), arg.human_friendly_type() ), @@ -563,31 +609,50 @@ where } } -impl<'a> FromKclValue<'a> for &'a str { +impl<'a> FromKclValue<'a> for [f64; 2] { fn from_mem_item(arg: &'a KclValue) -> Option { - arg.as_user_val().and_then(|uv| uv.value.as_str()) - } -} - -impl<'a> FromKclValue<'a> for i64 { - fn from_mem_item(arg: &'a KclValue) -> Option { - arg.as_user_val() - .and_then(|uv| uv.value.as_number()) - .and_then(|num| num.as_i64()) + let KclValue::Array { value, meta: _ } = arg else { + return None; + }; + if value.len() != 2 { + return None; + } + let v0 = value.first()?; + let v1 = value.get(1)?; + let array = [v0.as_f64()?, v1.as_f64()?]; + Some(array) } } -impl<'a> FromKclValue<'a> for UserVal { +impl<'a> FromKclValue<'a> for [usize; 3] { fn from_mem_item(arg: &'a KclValue) -> Option { - arg.as_user_val().map(|x| x.to_owned()) + let KclValue::Array { value, meta: _ } = arg else { + return None; + }; + if value.len() != 3 { + return None; + } + let v0 = value.first()?; + let v1 = value.get(1)?; + let v2 = value.get(2)?; + let array = [v0.as_usize()?, v1.as_usize()?, v2.as_usize()?]; + Some(array) } } -impl<'a> FromKclValue<'a> for Vec { +impl<'a> FromKclValue<'a> for [f64; 3] { fn from_mem_item(arg: &'a KclValue) -> Option { - arg.as_user_val() - .and_then(|uv| uv.value.as_array()) - .map(ToOwned::to_owned) + let KclValue::Array { value, meta: _ } = arg else { + return None; + }; + if value.len() != 3 { + return None; + } + let v0 = value.first()?; + let v1 = value.get(1)?; + let v2 = value.get(2)?; + let array = [v0.as_f64()?, v1.as_f64()?, v2.as_f64()?]; + Some(array) } } @@ -609,90 +674,767 @@ impl<'a> FromKclValue<'a> for KclValue { } } -macro_rules! impl_from_arg_via_json { - ($typ:path) => { - impl<'a> FromKclValue<'a> for $typ { - fn from_mem_item(arg: &'a KclValue) -> Option { - from_user_val(arg) +macro_rules! fields { + ($obj:ident, $typ:ident, $($field:ident),+) => { + $( + let $field = $obj.get(stringify!($field))?.$typ()?; + )+ + }; + ($obj:ident, $typ:ident, $($field:ident $key:literal),+) => { + $( + let $field = $obj.get($key)?.$typ()?; + )+ + }; +} + +macro_rules! fields_opt { + ($obj:ident, $typ:ident, $($field:ident),+) => { + $( + let $field = $obj.get(stringify!($field)).and_then(|x|x.$typ()); + )+ + }; +} + +macro_rules! fields_recurse { + ($obj:ident, $field:ident) => { + let $field = $obj.get(stringify!($field)).and_then(FromKclValue::from_mem_item)?; + }; + ($obj:ident, $field:ident $k:literal) => { + let $field = $obj.get($k).and_then(FromKclValue::from_mem_item)?; + }; +} + +macro_rules! fields_recurse_opt { + ($obj:ident, $field:ident) => { + let $field = $obj.get(stringify!($field)).and_then(FromKclValue::from_mem_item); + }; + ($obj:ident, $field:ident, $k:literal) => { + let $field = $obj.get($k).and_then(FromKclValue::from_mem_item); + }; +} + +impl<'a> FromKclValue<'a> for crate::std::import::ImportFormat { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_str, typ "type"); + match typ { + "fbx" => Some(Self::Fbx {}), + "gltf" => Some(Self::Gltf {}), + "sldprt" => Some(Self::Sldprt {}), + "step" => Some(Self::Step {}), + "stl" => { + fields_recurse_opt!(obj, coords); + fields_recurse!(obj, units); + Some(Self::Stl { coords, units }) } + "obj" => { + fields_recurse_opt!(obj, coords); + fields_recurse!(obj, units); + Some(Self::Obj { coords, units }) + } + "ply" => { + fields_recurse_opt!(obj, coords); + fields_recurse!(obj, units); + Some(Self::Ply { coords, units }) + } + _ => None, } - }; + } } -impl<'a, T> FromKclValue<'a> for Vec -where - T: serde::de::DeserializeOwned + FromKclValue<'a>, -{ +impl<'a> FromKclValue<'a> for super::sketch::AngledLineThatIntersectsData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields_recurse!(obj, angle); + fields_recurse!(obj, intersect_tag "intersectTag"); + fields_recurse_opt!(obj, offset); + Some(Self { + angle, + intersect_tag, + offset, + }) + } +} + +impl<'a> FromKclValue<'a> for super::shapes::PolygonData { fn from_mem_item(arg: &'a KclValue) -> Option { - from_user_val(arg) + let obj = arg.as_object()?; + fields_recurse!(obj, radius); + fields_recurse!(obj, num_sides "numSides"); + fields_recurse!(obj, center); + fields_recurse!(obj, inscribed); + let polygon_type = if inscribed { + PolygonType::Inscribed + } else { + PolygonType::Circumscribed + }; + Some(Self { + radius, + num_sides, + center, + polygon_type, + inscribed, + }) + } +} + +impl<'a> FromKclValue<'a> for crate::std::polar::PolarCoordsData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields_recurse!(obj, angle); + fields_recurse!(obj, length); + Some(Self { angle, length }) + } +} + +impl<'a> FromKclValue<'a> for crate::std::loft::LoftData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields_recurse_opt!(obj, v_degree); + fields_recurse_opt!(obj, bez_approximate_rational); + fields_recurse_opt!(obj, base_curve_index); + fields_recurse_opt!(obj, tolerance); + Some(Self { + v_degree, + bez_approximate_rational, + base_curve_index, + tolerance, + }) + } +} + +impl<'a> FromKclValue<'a> for crate::std::planes::StandardPlane { + fn from_mem_item(arg: &'a KclValue) -> Option { + let s = arg.as_str()?; + match s { + "XY" | "xy" => Some(Self::XY), + "-XY" | "-xy" => Some(Self::NegXY), + "XZ" | "xz" => Some(Self::XZ), + "-XZ" | "-xz" => Some(Self::NegXZ), + "YZ" | "yz" => Some(Self::YZ), + "-YZ" | "-yz" => Some(Self::NegYZ), + _ => None, + } + } +} + +impl<'a> FromKclValue<'a> for kittycad_modeling_cmds::units::UnitLength { + fn from_mem_item(arg: &'a KclValue) -> Option { + let s = arg.as_str()?; + s.parse().ok() + } +} + +impl<'a> FromKclValue<'a> for kittycad_modeling_cmds::coord::System { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields_recurse!(obj, forward); + fields_recurse!(obj, up); + Some(Self { forward, up }) + } +} + +impl<'a> FromKclValue<'a> for kittycad_modeling_cmds::coord::AxisDirectionPair { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields_recurse!(obj, axis); + fields_recurse!(obj, direction); + Some(Self { axis, direction }) + } +} + +impl<'a> FromKclValue<'a> for kittycad_modeling_cmds::coord::Axis { + fn from_mem_item(arg: &'a KclValue) -> Option { + let s = arg.as_str()?; + match s { + "y" => Some(Self::Y), + "z" => Some(Self::Z), + _ => None, + } + } +} + +impl<'a> FromKclValue<'a> for PolygonType { + fn from_mem_item(arg: &'a KclValue) -> Option { + let s = arg.as_str()?; + match s { + "inscribed" => Some(Self::Inscribed), + _ => Some(Self::Circumscribed), + } + } +} + +impl<'a> FromKclValue<'a> for kittycad_modeling_cmds::coord::Direction { + fn from_mem_item(arg: &'a KclValue) -> Option { + let s = arg.as_str()?; + match s { + "positive" => Some(Self::Positive), + "negative" => Some(Self::Negative), + _ => None, + } + } +} + +impl<'a> FromKclValue<'a> for super::patterns::CircularPattern3dData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, instances); + fields!(obj, as_f64, arc_degrees "arcDegrees"); + fields!(obj, as_bool, rotate_duplicates "rotateDuplicates"); + let instances = Uint::new(instances); + fields_recurse!(obj, axis); + fields_recurse!(obj, center); + Some(Self { + instances, + axis, + center, + arc_degrees, + rotate_duplicates, + }) + } +} + +impl<'a> FromKclValue<'a> for super::patterns::CircularPattern2dData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, instances); + fields!(obj, as_f64, arc_degrees "arcDegrees"); + fields!(obj, as_bool, rotate_duplicates "rotateDuplicates"); + let instances = Uint::new(instances); + fields_recurse!(obj, center); + Some(Self { + instances, + center, + arc_degrees, + rotate_duplicates, + }) + } +} + +impl<'a> FromKclValue<'a> for super::patterns::LinearPattern3dData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, instances, distance); + let instances = Uint::new(instances); + fields_recurse!(obj, axis); + Some(Self { + instances, + distance, + axis, + }) + } +} + +impl<'a> FromKclValue<'a> for super::patterns::LinearPattern2dData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, instances, distance); + let instances = Uint::new(instances); + fields_recurse!(obj, axis); + Some(Self { + instances, + distance, + axis, + }) + } +} + +impl<'a> FromKclValue<'a> for super::sketch::BezierData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_point2d, to, control1, control2); + Some(Self { to, control1, control2 }) + } +} + +impl<'a> FromKclValue<'a> for super::shell::ShellData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, thickness); + fields_recurse!(obj, faces); + Some(Self { thickness, faces }) + } +} + +impl<'a> FromKclValue<'a> for super::chamfer::ChamferData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, length); + fields_recurse!(obj, tags); + Some(Self { length, tags }) + } +} + +impl<'a> FromKclValue<'a> for super::fillet::FilletData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, radius); + fields_opt!(obj, as_f64, tolerance); + fields_recurse!(obj, tags); + Some(Self { + radius, + tolerance, + tags, + }) + } +} + +impl<'a> FromKclValue<'a> for super::helix::HelixData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, revolutions); + fields_opt!(obj, as_f64, length); + fields_opt!(obj, as_bool, ccw); + let ccw = ccw.unwrap_or_default(); + let angle_start = obj.get("angleStart").or_else(|| obj.get("angle_start"))?.as_f64()?; + Some(Self { + revolutions, + angle_start, + ccw, + length, + }) + } +} + +impl<'a> FromKclValue<'a> for FaceTag { + fn from_mem_item(arg: &'a KclValue) -> Option { + let case1 = || match arg.as_str() { + Some("start" | "START") => Some(Self::StartOrEnd(super::sketch::StartOrEnd::Start)), + Some("end" | "END") => Some(Self::StartOrEnd(super::sketch::StartOrEnd::End)), + _ => None, + }; + let case2 = || { + let tag = TagIdentifier::from_mem_item(arg)?; + Some(Self::Tag(Box::new(tag))) + }; + case1().or_else(case2) } } -macro_rules! impl_from_arg_for_array { - ($n:literal) => { - impl<'a, T> FromKclValue<'a> for [T; $n] - where - T: serde::de::DeserializeOwned + FromKclValue<'a>, - { +impl<'a> FromKclValue<'a> for super::sketch::AngledLineToData { + fn from_mem_item(arg: &'a KclValue) -> Option { + // Deserialize from an {angle, to} object. + let case1 = || { + let obj = arg.as_object()?; + fields!(obj, as_f64, angle, to); + Some(Self { angle, to }) + }; + // Deserialize from an [angle, to] array. + let case2 = || { + let [angle, to] = arg.as_point2d()?; + Some(Self { angle, to }) + }; + case1().or_else(case2) + } +} + +impl<'a> FromKclValue<'a> for super::sketch::ArcData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, radius); + let case1 = || { + let angle_start = obj.get("angleStart").or_else(|| obj.get("angle_start"))?.as_f64()?; + let angle_end = obj.get("angleEnd").or_else(|| obj.get("angle_end"))?.as_f64()?; + Some(Self::AnglesAndRadius { + angle_start, + angle_end, + radius, + }) + }; + let case2 = || { + let obj = arg.as_object()?; + fields!(obj, as_point2d, center, to); + Some(Self::CenterToRadius { center, to, radius }) + }; + case1().or_else(case2) + } +} + +impl<'a> FromKclValue<'a> for super::revolve::RevolveData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + let angle = obj.get("angle").and_then(|x| x.as_f64()); + let tolerance = obj.get("tolerance").and_then(|x| x.as_f64()); + fields_recurse!(obj, axis); + Some(Self { angle, axis, tolerance }) + } +} + +impl<'a> FromKclValue<'a> for super::shapes::CircleData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_point2d, center); + fields!(obj, as_f64, radius); + Some(Self { center, radius }) + } +} + +impl<'a> FromKclValue<'a> for super::sketch::TangentialArcData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_f64, radius, offset); + Some(Self::RadiusAndOffset { radius, offset }) + } +} + +impl<'a> FromKclValue<'a> for crate::executor::Point3d { + fn from_mem_item(arg: &'a KclValue) -> Option { + // Case 1: object with x/y/z fields + if let Some(obj) = arg.as_object() { + fields!(obj, as_f64, x, y, z); + return Some(Self { x, y, z }); + } + // Case 2: Array of 3 numbers. + let [x, y, z]: [f64; 3] = FromKclValue::from_mem_item(arg)?; + Some(Self { x, y, z }) + } +} + +impl<'a> FromKclValue<'a> for super::sketch::PlaneData { + fn from_mem_item(arg: &'a KclValue) -> Option { + // Case 0: actual plane + if let KclValue::Plane(p) = arg { + return Some(Self::Plane { + origin: Box::new(p.origin), + x_axis: Box::new(p.x_axis), + y_axis: Box::new(p.y_axis), + z_axis: Box::new(p.z_axis), + }); + } + // Case 1: predefined plane + if let Some(s) = arg.as_str() { + return match s { + "XY" | "xy" => Some(Self::XY), + "-XY" | "-xy" => Some(Self::NegXY), + "XZ" | "xz" => Some(Self::XZ), + "-XZ" | "-xz" => Some(Self::NegXZ), + "YZ" | "yz" => Some(Self::YZ), + "-YZ" | "-yz" => Some(Self::NegYZ), + _ => None, + }; + } + // Case 2: custom plane + let obj = arg.as_object()?; + fields!(obj, as_object, plane); + let origin = plane + .get("origin") + .and_then(FromKclValue::from_mem_item) + .map(Box::new)?; + let x_axis = plane + .get("xAxis") + .or_else(|| plane.get("x_axis")) + .and_then(FromKclValue::from_mem_item) + .map(Box::new)?; + let y_axis = plane + .get("yAxis") + .or_else(|| plane.get("y_axis")) + .and_then(FromKclValue::from_mem_item) + .map(Box::new)?; + let z_axis = plane + .get("zAxis") + .or_else(|| plane.get("z_axis")) + .and_then(FromKclValue::from_mem_item) + .map(Box::new)?; + Some(Self::Plane { + origin, + x_axis, + y_axis, + z_axis, + }) + } +} + +impl<'a> FromKclValue<'a> for crate::executor::ExtrudePlane { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_uuid, face_id "faceId"); + let tag = FromKclValue::from_mem_item(obj.get("tag")?); + fields_recurse!(obj, geo_meta "geoMeta"); + Some(Self { face_id, tag, geo_meta }) + } +} + +impl<'a> FromKclValue<'a> for crate::executor::ExtrudeArc { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_uuid, face_id "faceId"); + let tag = FromKclValue::from_mem_item(obj.get("tag")?); + fields_recurse!(obj, geo_meta "geoMeta"); + Some(Self { face_id, tag, geo_meta }) + } +} + +impl<'a> FromKclValue<'a> for crate::executor::GeoMeta { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_uuid, id); + fields_recurse!(obj, source_range "sourceRange"); + let source_range = SourceRange(source_range); + Some(Self { + id, + metadata: Metadata { source_range }, + }) + } +} + +impl<'a> FromKclValue<'a> for crate::executor::ChamferSurface { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_uuid, face_id "faceId"); + let tag = FromKclValue::from_mem_item(obj.get("tag")?); + fields_recurse!(obj, geo_meta "geoMeta"); + Some(Self { face_id, tag, geo_meta }) + } +} + +impl<'a> FromKclValue<'a> for crate::executor::FilletSurface { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_uuid, face_id "faceId"); + let tag = FromKclValue::from_mem_item(obj.get("tag")?); + fields_recurse!(obj, geo_meta "geoMeta"); + Some(Self { face_id, tag, geo_meta }) + } +} + +impl<'a> FromKclValue<'a> for ExtrudeSurface { + fn from_mem_item(arg: &'a KclValue) -> Option { + let case1 = crate::executor::ExtrudePlane::from_mem_item; + let case2 = crate::executor::ExtrudeArc::from_mem_item; + let case3 = crate::executor::ChamferSurface::from_mem_item; + let case4 = crate::executor::FilletSurface::from_mem_item; + case1(arg) + .map(Self::ExtrudePlane) + .or_else(|| case2(arg).map(Self::ExtrudeArc)) + .or_else(|| case3(arg).map(Self::Chamfer)) + .or_else(|| case4(arg).map(Self::Fillet)) + } +} + +impl<'a> FromKclValue<'a> for crate::executor::EdgeCut { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields!(obj, as_str, typ "type"); + let tag = Box::new(obj.get("tag").and_then(FromKclValue::from_mem_item)); + fields!(obj, as_uuid, edge_id "edgeId"); + fields!(obj, as_uuid, id); + match typ { + "fillet" => { + fields!(obj, as_f64, radius); + Some(Self::Fillet { + edge_id, + tag, + id, + radius, + }) + } + "chamfer" => { + fields!(obj, as_f64, length); + Some(Self::Chamfer { + id, + length, + edge_id, + tag, + }) + } + _ => None, + } + } +} + +macro_rules! impl_from_kcl_for_vec { + ($typ:path) => { + impl<'a> FromKclValue<'a> for Vec<$typ> { fn from_mem_item(arg: &'a KclValue) -> Option { - from_user_val(arg) + arg.as_array()? + .iter() + .map(|value| FromKclValue::from_mem_item(value)) + .collect::>() } } }; } -fn from_user_val(arg: &KclValue) -> Option { - let v = match arg { - KclValue::UserVal(v) => v.value.clone(), - other => serde_json::to_value(other).ok()?, - }; - serde_json::from_value(v).ok() -} - -impl_from_arg_via_json!(super::sketch::AngledLineData); -impl_from_arg_via_json!(super::sketch::AngledLineToData); -impl_from_arg_via_json!(super::sketch::AngledLineThatIntersectsData); -impl_from_arg_via_json!(super::shapes::CircleData); -impl_from_arg_via_json!(super::shapes::PolygonData); -impl_from_arg_via_json!(super::sketch::ArcData); -impl_from_arg_via_json!(super::sketch::TangentialArcData); -impl_from_arg_via_json!(super::sketch::BezierData); -impl_from_arg_via_json!(super::chamfer::ChamferData); -impl_from_arg_via_json!(super::patterns::LinearPattern3dData); -impl_from_arg_via_json!(super::patterns::CircularPattern3dData); -impl_from_arg_via_json!(super::patterns::LinearPattern2dData); -impl_from_arg_via_json!(super::patterns::CircularPattern2dData); -impl_from_arg_via_json!(super::helix::HelixData); -impl_from_arg_via_json!(super::shell::ShellData); -impl_from_arg_via_json!(super::fillet::FilletData); -impl_from_arg_via_json!(super::revolve::RevolveData); -impl_from_arg_via_json!(super::sketch::SketchData); -impl_from_arg_via_json!(crate::std::import::ImportFormat); -impl_from_arg_via_json!(crate::std::polar::PolarCoordsData); -impl_from_arg_via_json!(crate::std::loft::LoftData); -impl_from_arg_via_json!(crate::std::planes::StandardPlane); -impl_from_arg_via_json!(crate::std::mirror::Mirror2dData); -impl_from_arg_via_json!(Sketch); -impl_from_arg_via_json!(FaceTag); -impl_from_arg_via_json!(String); -impl_from_arg_via_json!(crate::ast::types::KclNone); -impl_from_arg_via_json!(u32); -impl_from_arg_via_json!(u64); -impl_from_arg_via_json!(f64); -impl_from_arg_via_json!(bool); - -impl_from_arg_for_array!(2); -impl_from_arg_for_array!(3); +impl_from_kcl_for_vec!(FaceTag); +impl_from_kcl_for_vec!(crate::executor::EdgeCut); +impl_from_kcl_for_vec!(crate::executor::Metadata); +impl_from_kcl_for_vec!(super::fillet::EdgeReference); +impl_from_kcl_for_vec!(ExtrudeSurface); +impl_from_kcl_for_vec!(Sketch); -impl<'a> FromKclValue<'a> for SketchSet { +impl<'a> FromKclValue<'a> for crate::executor::SourceRange { + fn from_mem_item(arg: &'a KclValue) -> Option { + FromKclValue::from_mem_item(arg).map(crate::executor::SourceRange) + } +} + +impl<'a> FromKclValue<'a> for crate::executor::Metadata { + fn from_mem_item(arg: &'a KclValue) -> Option { + FromKclValue::from_mem_item(arg).map(|sr| Self { source_range: sr }) + } +} + +impl<'a> FromKclValue<'a> for crate::executor::Solid { + fn from_mem_item(arg: &'a KclValue) -> Option { + arg.as_solid().cloned() + } +} + +impl<'a> FromKclValue<'a> for super::sketch::SketchData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let case1 = super::sketch::PlaneData::from_mem_item; + let case2 = crate::executor::Solid::from_mem_item; + case1(arg) + .map(Self::Plane) + .or_else(|| case2(arg).map(Box::new).map(Self::Solid)) + } +} + +impl<'a> FromKclValue<'a> for super::revolve::AxisAndOrigin { + fn from_mem_item(arg: &'a KclValue) -> Option { + // Case 1: predefined planes. + if let Some(s) = arg.as_str() { + return match s { + "X" | "x" => Some(Self::X), + "Y" | "y" => Some(Self::Y), + "-X" | "-x" => Some(Self::NegX), + "-Y" | "-y" => Some(Self::NegY), + _ => None, + }; + } + // Case 2: custom planes. + let obj = arg.as_object()?; + fields!(obj, as_object, custom); + fields!(custom, as_point2d, axis, origin); + Some(Self::Custom { axis, origin }) + } +} + +impl<'a> FromKclValue<'a> for super::fillet::EdgeReference { + fn from_mem_item(arg: &'a KclValue) -> Option { + let id = arg.as_uuid().map(Self::Uuid); + let tag = || TagIdentifier::from_mem_item(arg).map(Box::new).map(Self::Tag); + id.or_else(tag) + } +} + +impl<'a> FromKclValue<'a> for super::revolve::AxisOrEdgeReference { + fn from_mem_item(arg: &'a KclValue) -> Option { + let case1 = super::revolve::AxisAndOrigin::from_mem_item; + let case2 = super::fillet::EdgeReference::from_mem_item; + case1(arg).map(Self::Axis).or_else(|| case2(arg).map(Self::Edge)) + } +} + +impl<'a> FromKclValue<'a> for super::mirror::Mirror2dData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let obj = arg.as_object()?; + fields_recurse!(obj, axis); + Some(Self { axis }) + } +} + +impl<'a> FromKclValue<'a> for super::sketch::AngledLineData { + fn from_mem_item(arg: &'a KclValue) -> Option { + let case1 = |arg: &KclValue| { + let obj = arg.as_object()?; + fields!(obj, as_f64, angle, length); + Some(Self::AngleAndLengthNamed { angle, length }) + }; + let case2 = |arg: &KclValue| { + let array = arg.as_array()?; + let ang = array.first()?.as_f64()?; + let len = array.get(1)?.as_f64()?; + Some(Self::AngleAndLengthPair([ang, len])) + }; + case1(arg).or_else(|| case2(arg)) + } +} + +impl<'a> FromKclValue<'a> for i64 { fn from_mem_item(arg: &'a KclValue) -> Option { - let KclValue::UserVal(uv) = arg else { + let KclValue::Int { value, meta: _ } = arg else { return None; }; - if let Some((x, _meta)) = uv.get::() { - Some(SketchSet::from(x)) - } else { - uv.get::>().map(|x| x.0).map(SketchSet::from) + Some(*value) + } +} + +impl<'a> FromKclValue<'a> for u32 { + fn from_mem_item(arg: &'a KclValue) -> Option { + let KclValue::Int { value, meta: _ } = arg else { + return None; + }; + Some(*value as u32) + } +} + +impl<'a> FromKclValue<'a> for NonZeroU32 { + fn from_mem_item(arg: &'a KclValue) -> Option { + u32::from_mem_item(arg).and_then(|x| x.try_into().ok()) + } +} + +impl<'a> FromKclValue<'a> for u64 { + fn from_mem_item(arg: &'a KclValue) -> Option { + let KclValue::Int { value, meta: _ } = arg else { + return None; + }; + Some(*value as u64) + } +} +impl<'a> FromKclValue<'a> for f64 { + fn from_mem_item(arg: &'a KclValue) -> Option { + match arg { + KclValue::Number { value, meta: _ } => Some(*value), + KclValue::Int { value, meta: _ } => Some(*value as f64), + _ => None, + } + } +} +impl<'a> FromKclValue<'a> for Sketch { + fn from_mem_item(arg: &'a KclValue) -> Option { + let KclValue::Sketch { value } = arg else { + return None; + }; + Some(value.as_ref().to_owned()) + } +} +impl<'a> FromKclValue<'a> for String { + fn from_mem_item(arg: &'a KclValue) -> Option { + let KclValue::String { value, meta: _ } = arg else { + return None; + }; + Some(value.to_owned()) + } +} +impl<'a> FromKclValue<'a> for crate::ast::types::KclNone { + fn from_mem_item(arg: &'a KclValue) -> Option { + let KclValue::KclNone { value, meta: _ } = arg else { + return None; + }; + Some(value.to_owned()) + } +} +impl<'a> FromKclValue<'a> for bool { + fn from_mem_item(arg: &'a KclValue) -> Option { + let KclValue::Bool { value, meta: _ } = arg else { + return None; + }; + Some(*value) + } +} + +impl<'a> FromKclValue<'a> for SketchSet { + fn from_mem_item(arg: &'a KclValue) -> Option { + match arg { + KclValue::Sketch { value: sketch } => Some(SketchSet::from(sketch.to_owned())), + KclValue::Sketches { value } => Some(SketchSet::from(value.to_owned())), + KclValue::Array { .. } => { + let v: Option> = FromKclValue::from_mem_item(arg); + Some(SketchSet::Sketches(v?.iter().cloned().map(Box::new).collect())) + } + _ => None, } } } @@ -717,16 +1459,11 @@ impl<'a> FromKclValue<'a> for SolidSet { arg.get_solid_set().ok() } } + impl<'a> FromKclValue<'a> for SketchOrSurface { fn from_mem_item(arg: &'a KclValue) -> Option { match arg { - KclValue::UserVal(uv) => { - if let Some((sg, _meta)) = uv.get() { - Some(Self::Sketch(sg)) - } else { - None - } - } + KclValue::Sketch { value: sg } => Some(Self::Sketch(sg.to_owned())), KclValue::Plane(sg) => Some(Self::SketchSurface(SketchSurface::Plane(sg.clone()))), KclValue::Face(sg) => Some(Self::SketchSurface(SketchSurface::Face(sg.clone()))), _ => None, @@ -743,13 +1480,18 @@ impl<'a> FromKclValue<'a> for SketchSurface { } } -fn f64_to_jnum(f: f64, source_ranges: Vec) -> Result { - serde_json::Number::from_f64(f) - .ok_or_else(|| { - KclError::Type(KclErrorDetails { - message: format!("Failed to convert `{f}` to a number"), - source_ranges, - }) - }) - .map(serde_json::Value::Number) +impl From for Metadata { + fn from(value: Args) -> Self { + Self { + source_range: value.source_range, + } + } +} + +impl From for Vec { + fn from(value: Args) -> Self { + vec![Metadata { + source_range: value.source_range, + }] + } } diff --git a/src/wasm-lib/kcl/src/std/array.rs b/src/wasm-lib/kcl/src/std/array.rs index ee41092ca5..f96966f57c 100644 --- a/src/wasm-lib/kcl/src/std/array.rs +++ b/src/wasm-lib/kcl/src/std/array.rs @@ -1,47 +1,25 @@ use derive_docs::stdlib; -use serde_json::Value as JValue; use super::{args::FromArgs, Args, FnAsArg}; use crate::{ errors::{KclError, KclErrorDetails}, - executor::{ExecState, KclValue, SourceRange, UserVal}, + executor::{ExecState, KclValue, SourceRange}, function_param::FunctionParam, }; /// Apply a function to each element of an array. pub async fn map(exec_state: &mut ExecState, args: Args) -> Result { - let (array, f): (Vec, FnAsArg<'_>) = FromArgs::from_args(&args, 0)?; - let array: Vec = array - .into_iter() - .map(|jval| { - KclValue::UserVal(UserVal { - value: jval, - meta: vec![args.source_range.into()], - }) - }) - .collect(); + let (array, f): (Vec, FnAsArg<'_>) = FromArgs::from_args(&args, 0)?; + let meta = vec![args.source_range.into()]; let map_fn = FunctionParam { inner: f.func, fn_expr: f.expr, - meta: vec![args.source_range.into()], + meta: meta.clone(), ctx: args.ctx.clone(), memory: *f.memory, }; let new_array = inner_map(array, map_fn, exec_state, &args).await?; - let unwrapped = new_array - .clone() - .into_iter() - .map(|k| match k { - KclValue::UserVal(user_val) => Ok(user_val.value), - _ => Err(()), - }) - .collect::, _>>(); - if let Ok(unwrapped) = unwrapped { - let uv = UserVal::new(vec![args.source_range.into()], unwrapped); - return Ok(KclValue::UserVal(uv)); - } - let uv = UserVal::new(vec![args.source_range.into()], new_array); - Ok(KclValue::UserVal(uv)) + Ok(KclValue::Array { value: new_array, meta }) } /// Apply a function to every element of a list. @@ -110,16 +88,7 @@ async fn call_map_closure<'a>( /// For each item in an array, update a value. pub async fn reduce(exec_state: &mut ExecState, args: Args) -> Result { - let (array, start, f): (Vec, KclValue, FnAsArg<'_>) = FromArgs::from_args(&args, 0)?; - let array: Vec = array - .into_iter() - .map(|jval| { - KclValue::UserVal(UserVal { - value: jval, - meta: vec![args.source_range.into()], - }) - }) - .collect(); + let (array, start, f): (Vec, KclValue, FnAsArg<'_>) = FromArgs::from_args(&args, 0)?; let reduce_fn = FunctionParam { inner: f.func, fn_expr: f.expr, @@ -206,50 +175,26 @@ async fn call_reduce_closure<'a>( #[stdlib { name = "push", }] -async fn inner_push(array: Vec, elem: KclValue, args: &Args) -> Result { +async fn inner_push(mut array: Vec, elem: KclValue, args: &Args) -> Result { // Unwrap the KclValues to JValues for manipulation - let mut unwrapped_array = array - .into_iter() - .map(|k| match k { - KclValue::UserVal(user_val) => Ok(user_val.value), - _ => Err(KclError::Semantic(KclErrorDetails { - message: "Expected a UserVal in array".to_string(), - source_ranges: vec![args.source_range], - })), - }) - .collect::, _>>()?; - - // Unwrap the element - let unwrapped_elem = match elem { - KclValue::UserVal(user_val) => user_val.value, - _ => { - return Err(KclError::Semantic(KclErrorDetails { - message: "Expected a UserVal as element".to_string(), - source_ranges: vec![args.source_range], - })); - } - }; - - // Append the element to the array - unwrapped_array.push(unwrapped_elem); - - // Wrap the new array into a UserVal with the source range metadata - let uv = UserVal::new(vec![args.source_range.into()], unwrapped_array); - - // Return the new array wrapped as a KclValue::UserVal - Ok(KclValue::UserVal(uv)) + array.push(elem); + Ok(KclValue::Array { + value: array, + meta: vec![args.source_range.into()], + }) } pub async fn push(_exec_state: &mut ExecState, args: Args) -> Result { // Extract the array and the element from the arguments - let (array_jvalues, elem): (Vec, KclValue) = FromArgs::from_args(&args, 0)?; - - // Convert the array of JValue into Vec - let array: Vec = array_jvalues - .into_iter() - .map(|jval| KclValue::UserVal(UserVal::new(vec![args.source_range.into()], jval))) - .collect(); - - // Call the inner_push function + let (val, elem): (KclValue, KclValue) = FromArgs::from_args(&args, 0)?; + + let meta = vec![args.source_range]; + let KclValue::Array { value: array, meta: _ } = val else { + let actual_type = val.human_friendly_type(); + return Err(KclError::Semantic(KclErrorDetails { + source_ranges: meta, + message: format!("You can't push to a value of type {actual_type}, only an array"), + })); + }; inner_push(array, elem, &args).await } diff --git a/src/wasm-lib/kcl/src/std/assert.rs b/src/wasm-lib/kcl/src/std/assert.rs index 5a71efe73c..6f7a849237 100644 --- a/src/wasm-lib/kcl/src/std/assert.rs +++ b/src/wasm-lib/kcl/src/std/assert.rs @@ -24,7 +24,7 @@ async fn _assert(value: bool, message: &str, args: &Args) -> Result<(), KclError pub async fn assert(_exec_state: &mut ExecState, args: Args) -> Result { let (data, description): (bool, String) = args.get_data()?; inner_assert(data, &description, &args).await?; - Ok(args.make_null_user_val()) + Ok(args.make_user_val_from_f64(0.0)) // TODO: Add a new Void enum for fns that don't return anything. } /// Check a value at runtime, and raise an error if the argument provided @@ -44,7 +44,7 @@ async fn inner_assert(data: bool, message: &str, args: &Args) -> Result<(), KclE pub async fn assert_lt(_exec_state: &mut ExecState, args: Args) -> Result { let (left, right, description): (f64, f64, String) = args.get_data()?; inner_assert_lt(left, right, &description, &args).await?; - Ok(args.make_null_user_val()) + Ok(args.make_user_val_from_f64(0.0)) // TODO: Add a new Void enum for fns that don't return anything. } /// Check that a numerical value is less than to another at runtime, @@ -63,7 +63,7 @@ async fn inner_assert_lt(left: f64, right: f64, message: &str, args: &Args) -> R pub async fn assert_gt(_exec_state: &mut ExecState, args: Args) -> Result { let (left, right, description): (f64, f64, String) = args.get_data()?; inner_assert_gt(left, right, &description, &args).await?; - Ok(args.make_null_user_val()) + Ok(args.make_user_val_from_f64(0.0)) // TODO: Add a new Void enum for fns that don't return anything. } /// Check that a numerical value equals another at runtime, @@ -96,7 +96,7 @@ async fn inner_assert_equal(left: f64, right: f64, epsilon: f64, message: &str, pub async fn assert_equal(_exec_state: &mut ExecState, args: Args) -> Result { let (left, right, epsilon, description): (f64, f64, f64, String) = args.get_data()?; inner_assert_equal(left, right, epsilon, &description, &args).await?; - Ok(args.make_null_user_val()) + Ok(args.make_user_val_from_f64(0.0)) // TODO: Add a new Void enum for fns that don't return anything. } /// Check that a numerical value is greater than another at runtime, @@ -115,7 +115,7 @@ async fn inner_assert_gt(left: f64, right: f64, message: &str, args: &Args) -> R pub async fn assert_lte(_exec_state: &mut ExecState, args: Args) -> Result { let (left, right, description): (f64, f64, String) = args.get_data()?; inner_assert_lte(left, right, &description, &args).await?; - Ok(args.make_null_user_val()) + Ok(args.make_user_val_from_f64(0.0)) // TODO: Add a new Void enum for fns that don't return anything. } /// Check that a numerical value is less than or equal to another at runtime, @@ -135,7 +135,7 @@ async fn inner_assert_lte(left: f64, right: f64, message: &str, args: &Args) -> pub async fn assert_gte(_exec_state: &mut ExecState, args: Args) -> Result { let (left, right, description): (f64, f64, String) = args.get_data()?; inner_assert_gte(left, right, &description, &args).await?; - Ok(args.make_null_user_val()) + Ok(args.make_user_val_from_f64(0.0)) // TODO: Add a new Void enum for fns that don't return anything. } /// Check that a numerical value is greater than or equal to another at runtime, diff --git a/src/wasm-lib/kcl/src/std/extrude.rs b/src/wasm-lib/kcl/src/std/extrude.rs index f4e2776055..d8f2b82444 100644 --- a/src/wasm-lib/kcl/src/std/extrude.rs +++ b/src/wasm-lib/kcl/src/std/extrude.rs @@ -233,7 +233,7 @@ pub(crate) async fn do_post_extrude( tag: path.get_base().tag.clone(), geo_meta: GeoMeta { id: path.get_base().geo_meta.id, - metadata: path.get_base().geo_meta.metadata.clone(), + metadata: path.get_base().geo_meta.metadata, }, }); Some(extrude_surface) @@ -244,7 +244,7 @@ pub(crate) async fn do_post_extrude( tag: path.get_base().tag.clone(), geo_meta: GeoMeta { id: path.get_base().geo_meta.id, - metadata: path.get_base().geo_meta.metadata.clone(), + metadata: path.get_base().geo_meta.metadata, }, }); Some(extrude_surface) @@ -259,7 +259,7 @@ pub(crate) async fn do_post_extrude( tag: path.get_base().tag.clone(), geo_meta: GeoMeta { id: path.get_base().geo_meta.id, - metadata: path.get_base().geo_meta.metadata.clone(), + metadata: path.get_base().geo_meta.metadata, }, }); Some(extrude_surface) diff --git a/src/wasm-lib/kcl/src/std/fillet.rs b/src/wasm-lib/kcl/src/std/fillet.rs index 758bcbad47..029fee7181 100644 --- a/src/wasm-lib/kcl/src/std/fillet.rs +++ b/src/wasm-lib/kcl/src/std/fillet.rs @@ -14,7 +14,7 @@ use uuid::Uuid; use crate::{ ast::types::TagNode, errors::{KclError, KclErrorDetails}, - executor::{EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, Solid, TagIdentifier, UserVal}, + executor::{EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, Solid, TagIdentifier}, settings::types::UnitLength, std::Args, }; @@ -186,15 +186,10 @@ pub async fn get_opposite_edge(exec_state: &mut ExecState, args: Args) -> Result let tag: TagIdentifier = args.get_data()?; let edge = inner_get_opposite_edge(tag, exec_state, args.clone()).await?; - Ok(KclValue::UserVal(UserVal { - value: serde_json::to_value(edge).map_err(|e| { - KclError::Type(KclErrorDetails { - message: format!("Failed to convert Uuid to json: {}", e), - source_ranges: vec![args.source_range], - }) - })?, + Ok(KclValue::Uuid { + value: edge, meta: vec![args.source_range.into()], - })) + }) } /// Get the opposite edge to the edge given. @@ -264,15 +259,10 @@ pub async fn get_next_adjacent_edge(exec_state: &mut ExecState, args: Args) -> R let tag: TagIdentifier = args.get_data()?; let edge = inner_get_next_adjacent_edge(tag, exec_state, args.clone()).await?; - Ok(KclValue::UserVal(UserVal { - value: serde_json::to_value(edge).map_err(|e| { - KclError::Type(KclErrorDetails { - message: format!("Failed to convert Uuid to json: {}", e), - source_ranges: vec![args.source_range], - }) - })?, + Ok(KclValue::Uuid { + value: edge, meta: vec![args.source_range.into()], - })) + }) } /// Get the next adjacent edge to the edge given. @@ -354,15 +344,10 @@ pub async fn get_previous_adjacent_edge(exec_state: &mut ExecState, args: Args) let tag: TagIdentifier = args.get_data()?; let edge = inner_get_previous_adjacent_edge(tag, exec_state, args.clone()).await?; - Ok(KclValue::UserVal(UserVal { - value: serde_json::to_value(edge).map_err(|e| { - KclError::Type(KclErrorDetails { - message: format!("Failed to convert Uuid to json: {}", e), - source_ranges: vec![args.source_range], - }) - })?, + Ok(KclValue::Uuid { + value: edge, meta: vec![args.source_range.into()], - })) + }) } /// Get the previous adjacent edge to the edge given. diff --git a/src/wasm-lib/kcl/src/std/math.rs b/src/wasm-lib/kcl/src/std/math.rs index a81c1ce835..734352e40b 100644 --- a/src/wasm-lib/kcl/src/std/math.rs +++ b/src/wasm-lib/kcl/src/std/math.rs @@ -40,7 +40,7 @@ pub async fn cos(_exec_state: &mut ExecState, args: Args) -> Result Result Result Result { pub async fn pi(_exec_state: &mut ExecState, args: Args) -> Result { let result = inner_pi()?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Return the value of `pi`. Archimedes’ constant (Ï€). @@ -155,7 +155,7 @@ pub async fn sqrt(_exec_state: &mut ExecState, args: Args) -> Result Result Result Result Result Result Result Result Result Result Result Result Result Result Result { pub async fn e(_exec_state: &mut ExecState, args: Args) -> Result { let result = inner_e()?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Return the value of Euler’s number `e`. @@ -648,7 +648,7 @@ fn inner_e() -> Result { pub async fn tau(_exec_state: &mut ExecState, args: Args) -> Result { let result = inner_tau()?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Return the value of `tau`. The full circle constant (Ï„). Equal to 2Ï€. @@ -678,7 +678,7 @@ pub async fn to_radians(_exec_state: &mut ExecState, args: Args) -> Result Result Result { let (hypotenuse, leg) = args.get_hypotenuse_leg()?; let result = inner_leg_length(hypotenuse, leg); - args.make_user_val_from_f64(result) + Ok(KclValue::from_number(result, vec![args.into()])) } /// Compute the length of the given leg. @@ -264,7 +264,7 @@ fn inner_leg_length(hypotenuse: f64, leg: f64) -> f64 { pub async fn leg_angle_x(_exec_state: &mut ExecState, args: Args) -> Result { let (hypotenuse, leg) = args.get_hypotenuse_leg()?; let result = inner_leg_angle_x(hypotenuse, leg); - args.make_user_val_from_f64(result) + Ok(KclValue::from_number(result, vec![args.into()])) } /// Compute the angle of the given leg for x. @@ -284,7 +284,7 @@ fn inner_leg_angle_x(hypotenuse: f64, leg: f64) -> f64 { pub async fn leg_angle_y(_exec_state: &mut ExecState, args: Args) -> Result { let (hypotenuse, leg) = args.get_hypotenuse_leg()?; let result = inner_leg_angle_y(hypotenuse, leg); - args.make_user_val_from_f64(result) + Ok(KclValue::from_number(result, vec![args.into()])) } /// Compute the angle of the given leg for y. diff --git a/src/wasm-lib/kcl/src/std/patterns.rs b/src/wasm-lib/kcl/src/std/patterns.rs index 25c5726715..80e4be3d20 100644 --- a/src/wasm-lib/kcl/src/std/patterns.rs +++ b/src/wasm-lib/kcl/src/std/patterns.rs @@ -14,13 +14,10 @@ use kittycad_modeling_cmds::{ }; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use serde_json::Value as JValue; use crate::{ errors::{KclError, KclErrorDetails}, - executor::{ - ExecState, Geometries, Geometry, KclValue, Point3d, Sketch, SketchSet, Solid, SolidSet, SourceRange, UserVal, - }, + executor::{ExecState, Geometries, Geometry, KclValue, Point3d, Sketch, SketchSet, Solid, SolidSet, SourceRange}, function_param::FunctionParam, std::{types::Uint, Args}, }; @@ -361,10 +358,10 @@ async fn make_transform<'a>( exec_state: &mut ExecState, ) -> Result { // Call the transform fn for this repetition. - let repetition_num = KclValue::UserVal(UserVal { - value: JValue::Number(i.into()), + let repetition_num = KclValue::Int { + value: i.into(), meta: vec![source_range.into()], - }); + }; let transform_fn_args = vec![repetition_num]; let transform_fn_return = transform_function.call(exec_state, transform_fn_args).await?; @@ -376,7 +373,7 @@ async fn make_transform<'a>( source_ranges: source_ranges.clone(), }) })?; - let KclValue::UserVal(transform) = transform_fn_return else { + let KclValue::Object { value: transform, meta } = transform_fn_return else { return Err(KclError::Semantic(KclErrorDetails { message: "Transform function must return a transform object".to_string(), source_ranges: source_ranges.clone(), @@ -384,9 +381,9 @@ async fn make_transform<'a>( }; // Apply defaults to the transform. - let replicate = match transform.value.get("replicate") { - Some(JValue::Bool(true)) => true, - Some(JValue::Bool(false)) => false, + let replicate = match transform.get("replicate") { + Some(KclValue::Bool { value: true, .. }) => true, + Some(KclValue::Bool { value: false, .. }) => false, Some(_) => { return Err(KclError::Semantic(KclErrorDetails { message: "The 'replicate' key must be a bool".to_string(), @@ -395,38 +392,43 @@ async fn make_transform<'a>( } None => true, }; - let scale = match transform.value.get("scale") { + let scale = match transform.get("scale") { Some(x) => array_to_point3d(x, source_ranges.clone())?, None => Point3d { x: 1.0, y: 1.0, z: 1.0 }, }; - let translate = match transform.value.get("translate") { + let translate = match transform.get("translate") { Some(x) => array_to_point3d(x, source_ranges.clone())?, None => Point3d { x: 0.0, y: 0.0, z: 0.0 }, }; let mut rotation = Rotation::default(); - if let Some(rot) = transform.value.get("rotation") { + if let Some(rot) = transform.get("rotation") { + let KclValue::Object { value: rot, meta: _ } = rot else { + return Err(KclError::Semantic(KclErrorDetails { + message: "The 'rotation' key must be an object (with optional fields 'angle', 'axis' and 'origin')" + .to_string(), + source_ranges: source_ranges.clone(), + })); + }; if let Some(axis) = rot.get("axis") { rotation.axis = array_to_point3d(axis, source_ranges.clone())?.into(); } if let Some(angle) = rot.get("angle") { match angle { - JValue::Number(number) => { - if let Some(number) = number.as_f64() { - rotation.angle = Angle::from_degrees(number); - } + KclValue::Number { value: number, meta: _ } => { + rotation.angle = Angle::from_degrees(*number); } _ => { return Err(KclError::Semantic(KclErrorDetails { message: "The 'rotation.angle' key must be a number (of degrees)".to_string(), - source_ranges: source_ranges.clone(), + source_ranges: meta.iter().map(|m| m.source_range).collect(), })); } } } if let Some(origin) = rot.get("origin") { rotation.origin = match origin { - JValue::String(s) if s == "local" => OriginType::Local, - JValue::String(s) if s == "global" => OriginType::Global, + KclValue::String { value: s, meta: _ } if s == "local" => OriginType::Local, + KclValue::String { value: s, meta: _ } if s == "global" => OriginType::Global, other => { let origin = array_to_point3d(other, source_ranges.clone())?.into(); OriginType::Custom { origin } @@ -443,8 +445,8 @@ async fn make_transform<'a>( Ok(t) } -fn array_to_point3d(json: &JValue, source_ranges: Vec) -> Result { - let JValue::Array(arr) = json else { +fn array_to_point3d(val: &KclValue, source_ranges: Vec) -> Result { + let KclValue::Array { value: arr, meta } = val else { return Err(KclError::Semantic(KclErrorDetails { message: "Expected an array of 3 numbers (i.e. a 3D point)".to_string(), source_ranges, @@ -457,17 +459,21 @@ fn array_to_point3d(json: &JValue, source_ranges: Vec) -> Result for PlaneData { /// Offset a plane by a distance along its normal. pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result { let (std_plane, offset): (StandardPlane, f64) = args.get_data_and_float()?; - - let plane = inner_offset_plane(std_plane, offset, exec_state).await?; - - Ok(KclValue::UserVal(UserVal::new( - vec![Metadata { - source_range: args.source_range, - }], - plane, - ))) + let plane_data = inner_offset_plane(std_plane, offset, exec_state).await?; + let plane = Plane::from_plane_data(plane_data, exec_state); + Ok(KclValue::Plane(Box::new(plane))) } /// Offset a plane by a distance along its normal. @@ -129,6 +123,20 @@ pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result startProfileAt([0, 0], %) +/// |> circle({radius: 10, center: [0, 0]}, %) +/// +/// // Triangle on the plane 4 units above +/// startSketchOn(offsetPlane("XY", 4)) +/// |> startProfileAt([0, 0], %) +/// |> line([10, 0], %) +/// |> line([0, 10], %) +/// |> close(%) +/// ``` + #[stdlib { name = "offsetPlane", }] diff --git a/src/wasm-lib/kcl/src/std/segment.rs b/src/wasm-lib/kcl/src/std/segment.rs index d5a13f8d0e..965cd274fb 100644 --- a/src/wasm-lib/kcl/src/std/segment.rs +++ b/src/wasm-lib/kcl/src/std/segment.rs @@ -60,7 +60,7 @@ pub async fn segment_end_x(exec_state: &mut ExecState, args: Args) -> Result Result Result Result Result Result Result { pub async fn segment_length(exec_state: &mut ExecState, args: Args) -> Result { let tag: TagIdentifier = args.get_data()?; let result = inner_segment_length(&tag, exec_state, args.clone())?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Compute the length of the provided line segment. @@ -376,7 +376,7 @@ pub async fn segment_angle(exec_state: &mut ExecState, args: Args) -> Result Result { let (tag, to, sketch) = args.get_tag_to_number_sketch()?; let result = inner_angle_to_match_length_x(&tag, to, sketch, exec_state, args.clone())?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Returns the angle to match the given length for x. @@ -478,7 +478,7 @@ fn inner_angle_to_match_length_x( pub async fn angle_to_match_length_y(exec_state: &mut ExecState, args: Args) -> Result { let (tag, to, sketch) = args.get_tag_to_number_sketch()?; let result = inner_angle_to_match_length_y(&tag, to, sketch, exec_state, args.clone())?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Returns the angle to match the given length for y. diff --git a/src/wasm-lib/kcl/src/std/shapes.rs b/src/wasm-lib/kcl/src/std/shapes.rs index 43a28df698..32fd72b7d2 100644 --- a/src/wasm-lib/kcl/src/std/shapes.rs +++ b/src/wasm-lib/kcl/src/std/shapes.rs @@ -48,7 +48,9 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result Result Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_line_to(to, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a line from the current origin to some absolute (x, y) point. @@ -164,7 +166,9 @@ pub async fn x_line_to(exec_state: &mut ExecState, args: Args) -> Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_x_line_to(to, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a line parallel to the X axis, that ends at the given X. @@ -212,7 +216,9 @@ pub async fn y_line_to(exec_state: &mut ExecState, args: Args) -> Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_y_line_to(to, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a line parallel to the Y axis, that ends at the given Y. @@ -252,7 +258,9 @@ pub async fn line(exec_state: &mut ExecState, args: Args) -> Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_line(delta, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a line relative to the current origin to a specified (x, y) away @@ -333,7 +341,9 @@ pub async fn x_line(exec_state: &mut ExecState, args: Args) -> Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_x_line(length, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a line relative to the current origin to a specified distance away @@ -376,7 +386,9 @@ pub async fn y_line(exec_state: &mut ExecState, args: Args) -> Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_y_line(length, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a line relative to the current origin to a specified distance away @@ -430,7 +442,9 @@ pub async fn angled_line(exec_state: &mut ExecState, args: Args) -> Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_angled_line(data, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a line segment relative to the current origin using the polar @@ -515,7 +529,9 @@ pub async fn angled_line_of_x_length(exec_state: &mut ExecState, args: Args) -> let (data, sketch, tag): (AngledLineData, Sketch, Option) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_angled_line_of_x_length(data, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Create a line segment from the current 2-dimensional sketch origin @@ -573,9 +589,9 @@ async fn inner_angled_line_of_x_length( #[serde(rename_all = "camelCase")] pub struct AngledLineToData { /// The angle of the line. - angle: f64, + pub angle: f64, /// The point to draw to. - to: f64, + pub to: f64, } /// Draw an angled line to a given x coordinate. @@ -583,7 +599,9 @@ pub async fn angled_line_to_x(exec_state: &mut ExecState, args: Args) -> Result< let (data, sketch, tag): (AngledLineToData, Sketch, Option) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_angled_line_to_x(data, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Create a line segment from the current 2-dimensional sketch origin @@ -641,7 +659,9 @@ pub async fn angled_line_of_y_length(exec_state: &mut ExecState, args: Args) -> let new_sketch = inner_angled_line_of_y_length(data, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Create a line segment from the current 2-dimensional sketch origin @@ -700,7 +720,9 @@ pub async fn angled_line_to_y(exec_state: &mut ExecState, args: Args) -> Result< let (data, sketch, tag): (AngledLineToData, Sketch, Option) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_angled_line_to_y(data, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Create a line segment from the current 2-dimensional sketch origin @@ -771,7 +793,9 @@ pub async fn angled_line_that_intersects(exec_state: &mut ExecState, args: Args) let (data, sketch, tag): (AngledLineThatIntersectsData, Sketch, Option) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_angled_line_that_intersects(data, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw an angled line from the current origin, constructing a line segment @@ -828,7 +852,9 @@ pub async fn start_sketch_at(exec_state: &mut ExecState, args: Args) -> Result Result< args.get_data_and_sketch_surface()?; let sketch = inner_start_profile_at(start, sketch_surface, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(sketch.meta.clone(), sketch)) + Ok(KclValue::Sketch { + value: Box::new(sketch), + }) } /// Start a new profile at a given point. @@ -1262,7 +1290,7 @@ pub(crate) async fn inner_start_profile_at( pub async fn profile_start_x(_exec_state: &mut ExecState, args: Args) -> Result { let sketch: Sketch = args.get_sketch()?; let x = inner_profile_start_x(sketch)?; - args.make_user_val_from_f64(x) + Ok(args.make_user_val_from_f64(x)) } /// Extract the provided 2-dimensional sketch's profile's origin's 'x' @@ -1286,7 +1314,7 @@ pub(crate) fn inner_profile_start_x(sketch: Sketch) -> Result { pub async fn profile_start_y(_exec_state: &mut ExecState, args: Args) -> Result { let sketch: Sketch = args.get_sketch()?; let x = inner_profile_start_y(sketch)?; - args.make_user_val_from_f64(x) + Ok(args.make_user_val_from_f64(x)) } /// Extract the provided 2-dimensional sketch's profile's origin's 'y' @@ -1309,15 +1337,7 @@ pub(crate) fn inner_profile_start_y(sketch: Sketch) -> Result { pub async fn profile_start(_exec_state: &mut ExecState, args: Args) -> Result { let sketch: Sketch = args.get_sketch()?; let point = inner_profile_start(sketch)?; - Ok(KclValue::UserVal(UserVal { - value: serde_json::to_value(point).map_err(|e| { - KclError::Type(KclErrorDetails { - message: format!("Failed to convert point to json: {}", e), - source_ranges: vec![args.source_range], - }) - })?, - meta: Default::default(), - })) + Ok(KclValue::from_point2d(point, args.into())) } /// Extract the provided 2-dimensional sketch's profile's origin @@ -1345,7 +1365,9 @@ pub async fn close(exec_state: &mut ExecState, args: Args) -> Result Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_arc(data, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a curved line segment along an imaginary circle. @@ -1573,7 +1597,9 @@ pub async fn tangential_arc(exec_state: &mut ExecState, args: Args) -> Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_tangential_arc(data, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a curved line segment along part of an imaginary circle. @@ -1701,7 +1727,9 @@ pub async fn tangential_arc_to(exec_state: &mut ExecState, args: Args) -> Result let (to, sketch, tag): ([f64; 2], Sketch, Option) = super::args::FromArgs::from_args(&args, 0)?; let new_sketch = inner_tangential_arc_to(to, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a tangential arc to point some distance away.. @@ -1709,7 +1737,9 @@ pub async fn tangential_arc_to_relative(exec_state: &mut ExecState, args: Args) let (delta, sketch, tag): ([f64; 2], Sketch, Option) = super::args::FromArgs::from_args(&args, 0)?; let new_sketch = inner_tangential_arc_to_relative(delta, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Starting at the current sketch's origin, draw a curved line segment along @@ -1873,11 +1903,11 @@ async fn inner_tangential_arc_to_relative( #[serde(rename_all = "camelCase")] pub struct BezierData { /// The to point. - to: [f64; 2], + pub to: [f64; 2], /// The first control point. - control1: [f64; 2], + pub control1: [f64; 2], /// The second control point. - control2: [f64; 2], + pub control2: [f64; 2], } /// Draw a bezier curve. @@ -1885,7 +1915,9 @@ pub async fn bezier_curve(exec_state: &mut ExecState, args: Args) -> Result) = args.get_data_and_sketch_and_tag()?; let new_sketch = inner_bezier_curve(data, sketch, tag, exec_state, args).await?; - Ok(KclValue::new_user_val(new_sketch.meta.clone(), new_sketch)) + Ok(KclValue::Sketch { + value: Box::new(new_sketch), + }) } /// Draw a smooth, continuous, curved line segment from the current origin to @@ -1965,7 +1997,9 @@ pub async fn hole(exec_state: &mut ExecState, args: Args) -> Result Result { let result = inner_mm(&args)?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Millimeters conversion factor for current projects units. @@ -55,7 +55,7 @@ fn inner_mm(args: &Args) -> Result { pub async fn inch(_exec_state: &mut ExecState, args: Args) -> Result { let result = inner_inch(&args)?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Inches conversion factor for current projects units. @@ -96,7 +96,7 @@ fn inner_inch(args: &Args) -> Result { pub async fn ft(_exec_state: &mut ExecState, args: Args) -> Result { let result = inner_ft(&args)?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Feet conversion factor for current projects units. @@ -138,7 +138,7 @@ fn inner_ft(args: &Args) -> Result { pub async fn m(_exec_state: &mut ExecState, args: Args) -> Result { let result = inner_m(&args)?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Meters conversion factor for current projects units. @@ -180,7 +180,7 @@ fn inner_m(args: &Args) -> Result { pub async fn cm(_exec_state: &mut ExecState, args: Args) -> Result { let result = inner_cm(&args)?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Centimeters conversion factor for current projects units. @@ -222,7 +222,7 @@ fn inner_cm(args: &Args) -> Result { pub async fn yd(_exec_state: &mut ExecState, args: Args) -> Result { let result = inner_yd(&args)?; - args.make_user_val_from_f64(result) + Ok(args.make_user_val_from_f64(result)) } /// Yards conversion factor for current projects units. diff --git a/src/wasm-lib/kcl/tests/add_lots/program_memory.snap b/src/wasm-lib/kcl/tests/add_lots/program_memory.snap index d15686eaca..c91b27db5b 100644 --- a/src/wasm-lib/kcl/tests/add_lots/program_memory.snap +++ b/src/wasm-lib/kcl/tests/add_lots/program_memory.snap @@ -8,27 +8,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "f": { @@ -89,27 +85,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] } }, @@ -130,14 +122,1420 @@ snapshot_kind: text ] }, "x": { - "type": "UserVal", - "type": "UserVal", + "type": "Number", "value": 10100.0, "__meta": [ { "sourceRange": [ - 38, - 834, + 40, + 41, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 47, + 48, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 54, + 55, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 61, + 62, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 68, + 69, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 75, + 76, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 82, + 83, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 89, + 90, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 96, + 97, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 103, + 104, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 110, + 112, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 118, + 120, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 126, + 128, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 134, + 136, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 142, + 144, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 150, + 152, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 158, + 160, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 166, + 168, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 174, + 176, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 182, + 184, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 190, + 192, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 198, + 200, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 206, + 208, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 214, + 216, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 222, + 224, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 230, + 232, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 238, + 240, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 246, + 248, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 254, + 256, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 262, + 264, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 270, + 272, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 278, + 280, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 286, + 288, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 294, + 296, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 302, + 304, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 310, + 312, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 318, + 320, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 326, + 328, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 334, + 336, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 342, + 344, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 350, + 352, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 358, + 360, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 366, + 368, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 374, + 376, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 382, + 384, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 390, + 392, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 398, + 400, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 406, + 408, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 414, + 416, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 422, + 424, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 430, + 432, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 438, + 440, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 446, + 448, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 454, + 456, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 462, + 464, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 470, + 472, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 478, + 480, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 486, + 488, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 494, + 496, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 502, + 504, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 510, + 512, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 518, + 520, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 526, + 528, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 534, + 536, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 542, + 544, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 550, + 552, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 558, + 560, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 566, + 568, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 574, + 576, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 582, + 584, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 590, + 592, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 598, + 600, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 606, + 608, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 614, + 616, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 622, + 624, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 630, + 632, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 638, + 640, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 646, + 648, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 654, + 656, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 662, + 664, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 670, + 672, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 678, + 680, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 686, + 688, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 694, + 696, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 702, + 704, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 710, + 712, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 718, + 720, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 726, + 728, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 734, + 736, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 742, + 744, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 750, + 752, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 758, + 760, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 766, + 768, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 774, + 776, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 782, + 784, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 790, + 792, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 798, + 800, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 806, + 808, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 814, + 816, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 822, + 824, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, + 0 + ] + }, + { + "sourceRange": [ + 830, + 833, + 0 + ] + }, + { + "sourceRange": [ + 29, + 30, 0 ] } diff --git a/src/wasm-lib/kcl/tests/array_elem_push/program_memory.snap b/src/wasm-lib/kcl/tests/array_elem_push/program_memory.snap index 7eb65a5fca..1e67c7f256 100644 --- a/src/wasm-lib/kcl/tests/array_elem_push/program_memory.snap +++ b/src/wasm-lib/kcl/tests/array_elem_push/program_memory.snap @@ -8,36 +8,67 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "arr": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 1, - 2, - 3 + { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 7, + 8, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 2, + "__meta": [ + { + "sourceRange": [ + 10, + 11, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 3, + "__meta": [ + { + "sourceRange": [ + 13, + 14, + 0 + ] + } + ] + } ], "__meta": [ { @@ -50,13 +81,60 @@ snapshot_kind: text ] }, "new_arr1": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 1, - 2, - 3, - 4 + { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 7, + 8, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 2, + "__meta": [ + { + "sourceRange": [ + 10, + 11, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 3, + "__meta": [ + { + "sourceRange": [ + 13, + 14, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 4, + "__meta": [ + { + "sourceRange": [ + 37, + 38, + 0 + ] + } + ] + } ], "__meta": [ { @@ -69,14 +147,73 @@ snapshot_kind: text ] }, "new_arr2": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 1, - 2, - 3, - 4, - 5 + { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 7, + 8, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 2, + "__meta": [ + { + "sourceRange": [ + 10, + 11, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 3, + "__meta": [ + { + "sourceRange": [ + 13, + 14, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 4, + "__meta": [ + { + "sourceRange": [ + 37, + 38, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 5, + "__meta": [ + { + "sourceRange": [ + 66, + 67, + 0 + ] + } + ] + } ], "__meta": [ { diff --git a/src/wasm-lib/kcl/tests/array_range_expr/program_memory.snap b/src/wasm-lib/kcl/tests/array_range_expr/program_memory.snap index 90b6736b8a..5b778464e5 100644 --- a/src/wasm-lib/kcl/tests/array_range_expr/program_memory.snap +++ b/src/wasm-lib/kcl/tests/array_range_expr/program_memory.snap @@ -8,32 +8,27 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "five": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 5, "__meta": [ { @@ -46,8 +41,7 @@ snapshot_kind: text ] }, "four": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 4, "__meta": [ { @@ -60,14 +54,73 @@ snapshot_kind: text ] }, "r1": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 0, - 1, - 2, - 3, - 4 + { + "type": "Int", + "value": 0, + "__meta": [ + { + "sourceRange": [ + 5, + 11, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 5, + 11, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 2, + "__meta": [ + { + "sourceRange": [ + 5, + 11, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 3, + "__meta": [ + { + "sourceRange": [ + 5, + 11, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 4, + "__meta": [ + { + "sourceRange": [ + 5, + 11, + 0 + ] + } + ] + } ], "__meta": [ { @@ -80,14 +133,73 @@ snapshot_kind: text ] }, "r2": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 0, - 1, - 2, - 3, - 4 + { + "type": "Int", + "value": 0, + "__meta": [ + { + "sourceRange": [ + 95, + 107, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 95, + 107, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 2, + "__meta": [ + { + "sourceRange": [ + 95, + 107, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 3, + "__meta": [ + { + "sourceRange": [ + 95, + 107, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 4, + "__meta": [ + { + "sourceRange": [ + 95, + 107, + 0 + ] + } + ] + } ], "__meta": [ { @@ -100,15 +212,86 @@ snapshot_kind: text ] }, "r3": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 0, - 1, - 2, - 3, - 4, - 5 + { + "type": "Int", + "value": 0, + "__meta": [ + { + "sourceRange": [ + 194, + 206, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 194, + 206, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 2, + "__meta": [ + { + "sourceRange": [ + 194, + 206, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 3, + "__meta": [ + { + "sourceRange": [ + 194, + 206, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 4, + "__meta": [ + { + "sourceRange": [ + 194, + 206, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 5, + "__meta": [ + { + "sourceRange": [ + 194, + 206, + 0 + ] + } + ] + } ], "__meta": [ { @@ -121,13 +304,60 @@ snapshot_kind: text ] }, "r4": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 1, - 2, - 3, - 4 + { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 341, + 373, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 2, + "__meta": [ + { + "sourceRange": [ + 341, + 373, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 3, + "__meta": [ + { + "sourceRange": [ + 341, + 373, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 4, + "__meta": [ + { + "sourceRange": [ + 341, + 373, + 0 + ] + } + ] + } ], "__meta": [ { @@ -140,8 +370,7 @@ snapshot_kind: text ] }, "zero": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 0, "__meta": [ { diff --git a/src/wasm-lib/kcl/tests/array_range_negative_expr/program_memory.snap b/src/wasm-lib/kcl/tests/array_range_negative_expr/program_memory.snap index b62ff7e493..4b1b8bfa62 100644 --- a/src/wasm-lib/kcl/tests/array_range_negative_expr/program_memory.snap +++ b/src/wasm-lib/kcl/tests/array_range_negative_expr/program_memory.snap @@ -8,44 +8,171 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "xs": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - -5, - -4, - -3, - -2, - -1, - 0, - 1, - 2, - 3, - 4, - 5 + { + "type": "Int", + "value": -5, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": -4, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": -3, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": -2, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": -1, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 0, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 2, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 3, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 4, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 5, + "__meta": [ + { + "sourceRange": [ + 5, + 19, + 0 + ] + } + ] + } ], "__meta": [ { diff --git a/src/wasm-lib/kcl/tests/comparisons/program_memory.snap b/src/wasm-lib/kcl/tests/comparisons/program_memory.snap index 1d8fb2ed8f..3ed819d9c9 100644 --- a/src/wasm-lib/kcl/tests/comparisons/program_memory.snap +++ b/src/wasm-lib/kcl/tests/comparisons/program_memory.snap @@ -8,27 +8,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] } }, diff --git a/src/wasm-lib/kcl/tests/cube/program_memory.snap b/src/wasm-lib/kcl/tests/cube/program_memory.snap index 5f76caf6be..719ca526fa 100644 --- a/src/wasm-lib/kcl/tests/cube/program_memory.snap +++ b/src/wasm-lib/kcl/tests/cube/program_memory.snap @@ -8,27 +8,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "cube": { @@ -717,27 +713,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] } }, diff --git a/src/wasm-lib/kcl/tests/double_map_fn/program_memory.snap b/src/wasm-lib/kcl/tests/double_map_fn/program_memory.snap index 6ac6c1eaf0..14431a553f 100644 --- a/src/wasm-lib/kcl/tests/double_map_fn/program_memory.snap +++ b/src/wasm-lib/kcl/tests/double_map_fn/program_memory.snap @@ -8,27 +8,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "increment": { @@ -89,27 +85,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] } }, @@ -130,12 +122,47 @@ snapshot_kind: text ] }, "xs": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 0, - 1, - 2 + { + "type": "Int", + "value": 0, + "__meta": [ + { + "sourceRange": [ + 47, + 53, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 47, + 53, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 2, + "__meta": [ + { + "sourceRange": [ + 47, + 53, + 0 + ] + } + ] + } ], "__meta": [ { @@ -148,12 +175,89 @@ snapshot_kind: text ] }, "ys": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 2.0, - 3.0, - 4.0 + { + "type": "Number", + "value": 2.0, + "__meta": [ + { + "sourceRange": [ + 47, + 53, + 0 + ] + }, + { + "sourceRange": [ + 37, + 38, + 0 + ] + }, + { + "sourceRange": [ + 37, + 38, + 0 + ] + } + ] + }, + { + "type": "Number", + "value": 3.0, + "__meta": [ + { + "sourceRange": [ + 47, + 53, + 0 + ] + }, + { + "sourceRange": [ + 37, + 38, + 0 + ] + }, + { + "sourceRange": [ + 37, + 38, + 0 + ] + } + ] + }, + { + "type": "Number", + "value": 4.0, + "__meta": [ + { + "sourceRange": [ + 47, + 53, + 0 + ] + }, + { + "sourceRange": [ + 37, + 38, + 0 + ] + }, + { + "sourceRange": [ + 37, + 38, + 0 + ] + } + ] + } ], "__meta": [ { diff --git a/src/wasm-lib/kcl/tests/helix_ccw/program_memory.snap b/src/wasm-lib/kcl/tests/helix_ccw/program_memory.snap index 6824b22cb0..58924587a2 100644 --- a/src/wasm-lib/kcl/tests/helix_ccw/program_memory.snap +++ b/src/wasm-lib/kcl/tests/helix_ccw/program_memory.snap @@ -8,27 +8,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "part001": { diff --git a/src/wasm-lib/kcl/tests/if_else/program_memory.snap b/src/wasm-lib/kcl/tests/if_else/program_memory.snap index 1a6a881f8f..c72b2632c2 100644 --- a/src/wasm-lib/kcl/tests/if_else/program_memory.snap +++ b/src/wasm-lib/kcl/tests/if_else/program_memory.snap @@ -8,32 +8,27 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "a": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 3, "__meta": [ { @@ -46,8 +41,7 @@ snapshot_kind: text ] }, "b": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 4, "__meta": [ { @@ -60,8 +54,7 @@ snapshot_kind: text ] }, "c": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 5, "__meta": [ { diff --git a/src/wasm-lib/kcl/tests/index_of_array/program_memory.snap b/src/wasm-lib/kcl/tests/index_of_array/program_memory.snap index 06c3f72782..9ce06297de 100644 --- a/src/wasm-lib/kcl/tests/index_of_array/program_memory.snap +++ b/src/wasm-lib/kcl/tests/index_of_array/program_memory.snap @@ -8,36 +8,67 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "array": { - "type": "UserVal", - "type": "UserVal", + "type": "Array", "value": [ - 90, - 91, - 92 + { + "type": "Int", + "value": 90, + "__meta": [ + { + "sourceRange": [ + 44, + 46, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 91, + "__meta": [ + { + "sourceRange": [ + 48, + 50, + 0 + ] + } + ] + }, + { + "type": "Int", + "value": 92, + "__meta": [ + { + "sourceRange": [ + 52, + 54, + 0 + ] + } + ] + } ], "__meta": [ { @@ -50,8 +81,7 @@ snapshot_kind: text ] }, "i": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 1, "__meta": [ { @@ -64,28 +94,26 @@ snapshot_kind: text ] }, "result0": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 91, "__meta": [ { "sourceRange": [ - 93, - 101, + 48, + 50, 0 ] } ] }, "result1": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 91, "__meta": [ { "sourceRange": [ - 277, - 285, + 48, + 50, 0 ] } diff --git a/src/wasm-lib/kcl/tests/outputs/serial_test_example_offset_plane4.png b/src/wasm-lib/kcl/tests/outputs/serial_test_example_offset_plane4.png index 701b46c98e..dea293e351 100644 Binary files a/src/wasm-lib/kcl/tests/outputs/serial_test_example_offset_plane4.png and b/src/wasm-lib/kcl/tests/outputs/serial_test_example_offset_plane4.png differ diff --git a/src/wasm-lib/kcl/tests/outputs/serial_test_example_polygon1.png b/src/wasm-lib/kcl/tests/outputs/serial_test_example_polygon1.png index 3b3c303c7e..7b262d824e 100644 Binary files a/src/wasm-lib/kcl/tests/outputs/serial_test_example_polygon1.png and b/src/wasm-lib/kcl/tests/outputs/serial_test_example_polygon1.png differ diff --git a/src/wasm-lib/kcl/tests/property_of_object/program_memory.snap b/src/wasm-lib/kcl/tests/property_of_object/program_memory.snap index 35a8f4ef15..f03732d627 100644 --- a/src/wasm-lib/kcl/tests/property_of_object/program_memory.snap +++ b/src/wasm-lib/kcl/tests/property_of_object/program_memory.snap @@ -8,35 +8,54 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "obj": { - "type": "UserVal", - "type": "UserVal", + "type": "Object", "value": { - "bar": 0, - "foo": 1 + "bar": { + "type": "Int", + "value": 0, + "__meta": [ + { + "sourceRange": [ + 71, + 72, + 0 + ] + } + ] + }, + "foo": { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 63, + 64, + 0 + ] + } + ] + } }, "__meta": [ { @@ -49,12 +68,47 @@ snapshot_kind: text ] }, "obj2": { - "type": "UserVal", - "type": "UserVal", + "type": "Object", "value": { "inner": { - "bar": 0, - "foo": 1 + "type": "Object", + "value": { + "bar": { + "type": "Int", + "value": 0, + "__meta": [ + { + "sourceRange": [ + 71, + 72, + 0 + ] + } + ] + }, + "foo": { + "type": "Int", + "value": 1, + "__meta": [ + { + "sourceRange": [ + 63, + 64, + 0 + ] + } + ] + } + }, + "__meta": [ + { + "sourceRange": [ + 56, + 74, + 0 + ] + } + ] } }, "__meta": [ @@ -68,64 +122,59 @@ snapshot_kind: text ] }, "one_a": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 1, "__meta": [ { "sourceRange": [ - 122, - 132, + 63, + 64, 0 ] } ] }, "one_b": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 1, "__meta": [ { "sourceRange": [ - 356, - 362, + 63, + 64, 0 ] } ] }, "one_c": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 1, "__meta": [ { "sourceRange": [ - 553, - 570, + 63, + 64, 0 ] } ] }, "one_d": { - "type": "UserVal", - "type": "UserVal", + "type": "Int", "value": 1, "__meta": [ { "sourceRange": [ - 757, - 770, + 63, + 64, 0 ] } ] }, "p": { - "type": "UserVal", - "type": "UserVal", + "type": "String", "value": "foo", "__meta": [ { diff --git a/src/wasm-lib/kcl/tests/sketch_in_object/program_memory.snap b/src/wasm-lib/kcl/tests/sketch_in_object/program_memory.snap index 7ae5862740..67147fe9d7 100644 --- a/src/wasm-lib/kcl/tests/sketch_in_object/program_memory.snap +++ b/src/wasm-lib/kcl/tests/sketch_in_object/program_memory.snap @@ -8,27 +8,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "test": { @@ -295,27 +291,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] } }, @@ -637,27 +629,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] }, "test": { @@ -924,27 +912,23 @@ snapshot_kind: text { "bindings": { "HALF_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 180, + "type": "Number", + "value": 180.0, "__meta": [] }, "QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 90, + "type": "Number", + "value": 90.0, "__meta": [] }, "THREE_QUARTER_TURN": { - "type": "UserVal", - "type": "UserVal", - "value": 270, + "type": "Number", + "value": 270.0, "__meta": [] }, "ZERO": { - "type": "UserVal", - "type": "UserVal", - "value": 0, + "type": "Number", + "value": 0.0, "__meta": [] } }, @@ -982,45 +966,10 @@ snapshot_kind: text ] }, "x": { - "type": "UserVal", - "type": "UserVal", + "type": "Sketch", "value": { - "__meta": [ - { - "sourceRange": [ - 52, - 77, - 0 - ] - } - ], + "type": "Sketch", "id": "[uuid]", - "on": { - "__meta": [], - "id": "[uuid]", - "origin": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "type": "plane", - "value": "XY", - "xAxis": { - "x": 1.0, - "y": 0.0, - "z": 0.0 - }, - "yAxis": { - "x": 0.0, - "y": 1.0, - "z": 0.0 - }, - "zAxis": { - "x": 0.0, - "y": 0.0, - "z": 1.0 - } - }, "paths": [ { "__geoMeta": { @@ -1103,182 +1052,221 @@ snapshot_kind: text "type": "ToPoint" } ], - "start": { - "__geoMeta": { - "id": "[uuid]", - "sourceRange": [ - 52, - 77, - 0 - ] + "on": { + "type": "plane", + "id": "[uuid]", + "value": "XY", + "origin": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "xAxis": { + "x": 1.0, + "y": 0.0, + "z": 0.0 + }, + "yAxis": { + "x": 0.0, + "y": 1.0, + "z": 0.0 + }, + "zAxis": { + "x": 0.0, + "y": 0.0, + "z": 1.0 }, + "__meta": [] + }, + "start": { "from": [ 0.0, 0.0 ], - "tag": null, "to": [ 0.0, 0.0 - ] + ], + "tag": null, + "__geoMeta": { + "id": "[uuid]", + "sourceRange": [ + 52, + 77, + 0 + ] + } }, - "type": "Sketch" - }, - "__meta": [ - { - "sourceRange": [ - 52, - 77, - 0 - ] - } - ] + "__meta": [ + { + "sourceRange": [ + 52, + 77, + 0 + ] + } + ] + } }, "x2": { - "type": "UserVal", - "type": "UserVal", + "type": "Object", "value": { "thing1": { - "thing2": { - "__meta": [ - { - "sourceRange": [ - 242, - 267, - 0 - ] - } - ], - "id": "[uuid]", - "on": { - "__meta": [], - "id": "[uuid]", - "origin": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "type": "plane", - "value": "XY", - "xAxis": { - "x": 1.0, - "y": 0.0, - "z": 0.0 - }, - "yAxis": { - "x": 0.0, - "y": 1.0, - "z": 0.0 - }, - "zAxis": { - "x": 0.0, - "y": 0.0, - "z": 1.0 - } - }, - "paths": [ - { - "__geoMeta": { - "id": "[uuid]", - "sourceRange": [ - 277, - 292, - 0 - ] - }, - "from": [ - 0.0, - 0.0 - ], - "tag": null, - "to": [ - 0.0, - 1.0 - ], - "type": "ToPoint" - }, - { - "__geoMeta": { - "id": "[uuid]", - "sourceRange": [ - 302, - 317, - 0 - ] - }, - "from": [ - 0.0, - 1.0 - ], - "tag": null, - "to": [ - 1.0, - 1.0 + "type": "Object", + "value": { + "thing2": { + "type": "Sketch", + "value": { + "type": "Sketch", + "id": "[uuid]", + "paths": [ + { + "__geoMeta": { + "id": "[uuid]", + "sourceRange": [ + 277, + 292, + 0 + ] + }, + "from": [ + 0.0, + 0.0 + ], + "tag": null, + "to": [ + 0.0, + 1.0 + ], + "type": "ToPoint" + }, + { + "__geoMeta": { + "id": "[uuid]", + "sourceRange": [ + 302, + 317, + 0 + ] + }, + "from": [ + 0.0, + 1.0 + ], + "tag": null, + "to": [ + 1.0, + 1.0 + ], + "type": "ToPoint" + }, + { + "__geoMeta": { + "id": "[uuid]", + "sourceRange": [ + 327, + 343, + 0 + ] + }, + "from": [ + 1.0, + 1.0 + ], + "tag": null, + "to": [ + 1.0, + 0.0 + ], + "type": "ToPoint" + }, + { + "__geoMeta": { + "id": "[uuid]", + "sourceRange": [ + 353, + 361, + 0 + ] + }, + "from": [ + 1.0, + 0.0 + ], + "tag": null, + "to": [ + 0.0, + 0.0 + ], + "type": "ToPoint" + } ], - "type": "ToPoint" - }, - { - "__geoMeta": { + "on": { + "type": "plane", "id": "[uuid]", - "sourceRange": [ - 327, - 343, - 0 - ] + "value": "XY", + "origin": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "xAxis": { + "x": 1.0, + "y": 0.0, + "z": 0.0 + }, + "yAxis": { + "x": 0.0, + "y": 1.0, + "z": 0.0 + }, + "zAxis": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + }, + "__meta": [] }, - "from": [ - 1.0, - 1.0 - ], - "tag": null, - "to": [ - 1.0, - 0.0 - ], - "type": "ToPoint" - }, - { - "__geoMeta": { - "id": "[uuid]", - "sourceRange": [ - 353, - 361, - 0 - ] + "start": { + "from": [ + 0.0, + 0.0 + ], + "to": [ + 0.0, + 0.0 + ], + "tag": null, + "__geoMeta": { + "id": "[uuid]", + "sourceRange": [ + 242, + 267, + 0 + ] + } }, - "from": [ - 1.0, - 0.0 - ], - "tag": null, - "to": [ - 0.0, - 0.0 - ], - "type": "ToPoint" - } - ], - "start": { - "__geoMeta": { - "id": "[uuid]", - "sourceRange": [ - 242, - 267, - 0 + "__meta": [ + { + "sourceRange": [ + 242, + 267, + 0 + ] + } ] - }, - "from": [ - 0.0, - 0.0 - ], - "tag": null, - "to": [ - 0.0, - 0.0 + } + } + }, + "__meta": [ + { + "sourceRange": [ + 199, + 365, + 0 ] - }, - "type": "Sketch" - } + } + ] } }, "__meta": [ diff --git a/src/wasm-lib/tests/executor/inputs/member_expression_sketch.kcl b/src/wasm-lib/tests/executor/inputs/member_expression_sketch.kcl index 5e18848c8f..6d4a3b7659 100644 --- a/src/wasm-lib/tests/executor/inputs/member_expression_sketch.kcl +++ b/src/wasm-lib/tests/executor/inputs/member_expression_sketch.kcl @@ -13,5 +13,5 @@ sq = square([0,0], 10) cb = square([3,3], 4) |> extrude(10, %) -pt1 = sq.paths[0] -pt2 = cb.value[0] +// pt1 = sq.paths[0] +// pt2 = cb.value[0] diff --git a/src/wasm-lib/tests/executor/main.rs b/src/wasm-lib/tests/executor/main.rs index 034adb81d3..9b261acb70 100644 --- a/src/wasm-lib/tests/executor/main.rs +++ b/src/wasm-lib/tests/executor/main.rs @@ -1354,7 +1354,7 @@ secondSketch = startSketchOn(part001, '') assert!(result.is_err()); assert_eq!( result.err().unwrap().to_string(), - r#"semantic: KclErrorDetails { source_ranges: [SourceRange([260, 286, 0])], message: "Argument at index 1 was supposed to be type kcl_lib::std::sketch::FaceTag but found string (text)" }"# + r#"semantic: KclErrorDetails { source_ranges: [SourceRange([260, 286, 0])], message: "Argument at index 1 was supposed to be type Option but found string (text)" }"# ); } diff --git a/src/wasm-lib/tests/executor/no_visuals.rs b/src/wasm-lib/tests/executor/no_visuals.rs index 8f573fbfcb..8714aaafe2 100644 --- a/src/wasm-lib/tests/executor/no_visuals.rs +++ b/src/wasm-lib/tests/executor/no_visuals.rs @@ -73,7 +73,7 @@ gen_test_fail!( ); gen_test_fail!( invalid_index_negative, - "semantic: '-1' is not a valid index, indices must be whole positive numbers" + "semantic: '-1' is negative, so you can't index an array with it" ); gen_test_fail!( invalid_index_fractional, @@ -81,7 +81,7 @@ gen_test_fail!( ); gen_test_fail!( invalid_member_object, - "semantic: Only arrays and objects can be indexed, but you're trying to index a number" + "semantic: Only arrays and objects can be indexed, but you're trying to index an integer" ); gen_test_fail!( invalid_member_object_prop, @@ -107,7 +107,10 @@ gen_test_fail!( // if_else_no_expr, // "syntax: blocks inside an if/else expression must end in an expression" // ); -gen_test_fail!(comparisons_multiple, "syntax: Invalid number: true"); +gen_test_fail!( + comparisons_multiple, + "semantic: Expected a number, but found a boolean (true/false value)" +); gen_test_fail!( import_cycle1, "import cycle: circular import of modules is not allowed: tests/executor/inputs/no_visuals/import_cycle2.kcl -> tests/executor/inputs/no_visuals/import_cycle3.kcl -> tests/executor/inputs/no_visuals/import_cycle1.kcl -> tests/executor/inputs/no_visuals/import_cycle2.kcl" diff --git a/src/wasm-lib/tests/modify/main.rs b/src/wasm-lib/tests/modify/main.rs index bf18aa734a..6bb9389da7 100644 --- a/src/wasm-lib/tests/modify/main.rs +++ b/src/wasm-lib/tests/modify/main.rs @@ -4,7 +4,7 @@ use kcl_lib::{ modify::modify_ast_for_sketch, types::{ModuleId, Node, Program}, }, - executor::{ExecutorContext, IdGenerator, KclValue, PlaneType, Sketch, SourceRange}, + executor::{ExecutorContext, IdGenerator, KclValue, PlaneType, SourceRange}, }; use kittycad_modeling_cmds::{each_cmd as mcmd, length_unit::LengthUnit, shared::Point3d, ModelingCmd}; use pretty_assertions::assert_eq; @@ -18,12 +18,9 @@ async fn setup(code: &str, name: &str) -> Result<(ExecutorContext, Node // We need to get the sketch ID. // Get the sketch ID from memory. - let KclValue::UserVal(user_val) = exec_state.memory.get(name, SourceRange::default()).unwrap() else { + let KclValue::Sketch { value: sketch } = exec_state.memory.get(name, SourceRange::default()).unwrap() else { anyhow::bail!("part001 not found in memory: {:?}", exec_state.memory); }; - let Some((sketch, _meta)) = user_val.get::() else { - anyhow::bail!("part001 was not a Sketch"); - }; let sketch_id = sketch.id; let plane_id = uuid::Uuid::new_v4();