From dcecab1910317e4333b6bcb6d1d437b87350481b Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 16:04:52 +0900 Subject: [PATCH 001/110] =?UTF-8?q?feat=20:=20ai=20Spinner=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20ai=20=EB=B3=80=ED=99=98=EC=97=90=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ControlSection/TextUpload.tsx | 4 ++-- client/src/components/common/aiSpinner.tsx | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 client/src/components/common/aiSpinner.tsx diff --git a/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx b/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx index 27042167..5deeeca1 100644 --- a/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx +++ b/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx @@ -1,10 +1,10 @@ import ArrowBox from "@/components/common/ArrowBox"; -import Spinner from "@/components/common/Spinner"; import { MAX_TEXT_UPLOAD_LIMIT } from "@/constants/textUploadLimit"; import useUpload from "@/hooks/useUpload"; import { Button, Textarea } from "@headlessui/react"; import { createPortal } from "react-dom"; import clovaX from "@/assets/clovaX.png"; +import AiSpinner from "@/components/common/aiSpinner"; export default function TextUpload() { const { @@ -50,7 +50,7 @@ export default function TextUpload() { )} - {aiProcessing && createPortal(, document.body)} + {aiProcessing && createPortal(, document.body)}
clovaX
diff --git a/client/src/components/common/aiSpinner.tsx b/client/src/components/common/aiSpinner.tsx new file mode 100644 index 00000000..f32bff5b --- /dev/null +++ b/client/src/components/common/aiSpinner.tsx @@ -0,0 +1,13 @@ +import robot from "@/assets/lottie/robot.json"; +import Lottie from "lottie-react"; + +export default function AiSpinner() { + return ( +
+
+ +

AI가 회의록을 마인드맵으로 변환하고 있어요

+
+
+ ); +} From 9a7b953d0526334f0eb06af4ef50c2962faadf53 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 16:06:45 +0900 Subject: [PATCH 002/110] =?UTF-8?q?feat=20:=20lottie-react=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/package-lock.json | 20 ++++++++++++++++++++ client/package.json | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/client/package-lock.json b/client/package-lock.json index 3fa8acca..6243041d 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -23,6 +23,7 @@ "canvas": "^2.11.2", "highlight.js": "^11.10.0", "konva": "^9.3.16", + "lottie-react": "^2.4.0", "lowlight": "^3.1.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -6242,6 +6243,25 @@ "loose-envify": "cli.js" } }, + "node_modules/lottie-react": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/lottie-react/-/lottie-react-2.4.0.tgz", + "integrity": "sha512-pDJGj+AQlnlyHvOHFK7vLdsDcvbuqvwPZdMlJ360wrzGFurXeKPr8SiRCjLf3LrNYKANQtSsh5dz9UYQHuqx4w==", + "license": "MIT", + "dependencies": { + "lottie-web": "^5.10.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/lottie-web": { + "version": "5.12.2", + "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz", + "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==", + "license": "MIT" + }, "node_modules/loupe": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", diff --git a/client/package.json b/client/package.json index 3259f2b4..67094e1d 100644 --- a/client/package.json +++ b/client/package.json @@ -30,11 +30,12 @@ "canvas": "^2.11.2", "highlight.js": "^11.10.0", "konva": "^9.3.16", + "lottie-react": "^2.4.0", "lowlight": "^3.1.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-icons": "^5.3.0", "react-error-boundary": "^4.1.2", + "react-icons": "^5.3.0", "react-konva": "^18.2.10", "react-konva-utils": "^1.0.6", "react-router-dom": "^6.27.0", From 0270f45a6a94ac4ab0e90d3027f1cb7cf9840f1c Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 16:07:12 +0900 Subject: [PATCH 003/110] =?UTF-8?q?chore=20:=20tsconfig=20json=20import?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EC=84=A4=EC=A0=95=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/assets/lottie/robot.json | 1 + client/tsconfig.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 client/src/assets/lottie/robot.json diff --git a/client/src/assets/lottie/robot.json b/client/src/assets/lottie/robot.json new file mode 100644 index 00000000..e13db178 --- /dev/null +++ b/client/src/assets/lottie/robot.json @@ -0,0 +1 @@ +{"v":"4.8.0","meta":{"g":"LottieFiles AE 3.5.7","a":"","k":"","d":"","tc":""},"fr":30,"ip":0,"op":91,"w":1000,"h":1000,"nm":"AI Loading Isometric Animation 2","ddd":0,"assets":[],"fonts":{"list":[{"fName":"Avenir-Black","fFamily":"Avenir","fStyle":"Black","ascent":75.5996704101562}]},"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 3 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[262.32,268.941,0],"ix":2},"a":{"a":0,"k":[52.944,36.917,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":0,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":1,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":2,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":3,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":4,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":5,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":6,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.259]},"o":{"x":[0.167],"y":[-0.388]},"t":7,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.225]},"o":{"x":[0.167],"y":[0.775]},"t":8,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.259]},"t":9,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":10,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":11,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":12,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":13,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":14,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[0.741]},"o":{"x":[0.167],"y":[0.388]},"t":15,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[0.225]},"o":{"x":[0.167],"y":[0.775]},"t":16,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.259]},"t":17,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":18,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":19,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":20,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":21,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":22,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":23,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":24,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":25,"s":[0.1443,0.6357,0.5456,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":26,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":27,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":28,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":29,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":30,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":31,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[0.742]},"o":{"x":[0.167],"y":[0.388]},"t":32,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.778]},"o":{"x":[0.167],"y":[-0.778]},"t":33,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.258]},"t":34,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":35,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":36,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":37,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":38,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":39,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.259]},"o":{"x":[0.167],"y":[-0.388]},"t":40,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[1.775]},"o":{"x":[0.167],"y":[-0.775]},"t":41,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.259]},"t":42,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":43,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":44,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":45,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":46,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":47,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":48,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":49,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":50,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":51,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":52,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":53,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":54,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":55,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":56,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.258]},"o":{"x":[0.167],"y":[-0.388]},"t":57,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.221]},"o":{"x":[0.167],"y":[0.779]},"t":58,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.258]},"t":59,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":60,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":61,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":62,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":63,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":64,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[0.741]},"o":{"x":[0.167],"y":[0.388]},"t":65,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[0.228]},"o":{"x":[0.167],"y":[0.772]},"t":66,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.259]},"t":67,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":68,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":69,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":70,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":71,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":72,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":73,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":74,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.389]},"t":75,"s":[0.1443,0.6357,0.5456,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":76,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":77,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":78,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":79,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":80,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":81,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[0.742]},"o":{"x":[0.167],"y":[0.388]},"t":82,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.782]},"o":{"x":[0.167],"y":[-0.782]},"t":83,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.258]},"t":84,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":85,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":86,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":87,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":88,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":89,"s":[0.196,0.604,0.57,1]},{"t":90,"s":[0.1824,0.5776,0.5447,1]}],"ix":3}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.624,-8.286],[-3.659,-4.081],[-3.623,8.286],[3.659,4.081],[3.654,2.204],[-1.674,5.279],[-1.683,1.825],[3.307,-1.057],[3.302,-2.936],[-1.688,-0.053],[-1.698,-3.333],[3.628,-6.407]],"o":[[3.624,-8.286],[-3.659,-4.081],[-3.623,8.286],[3.659,4.081],[3.654,2.204],[-1.674,5.279],[-1.683,1.825],[3.307,-1.057],[3.302,-2.936],[-1.688,-0.053],[-1.698,-3.333],[3.628,-6.407]],"v":[[3.624,-8.286],[-3.659,-4.081],[-3.623,8.286],[3.659,4.081],[3.654,2.204],[-1.674,5.279],[-1.683,1.825],[3.307,-1.057],[3.302,-2.936],[-1.688,-0.053],[-1.698,-3.333],[3.628,-6.407]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[102.229,8.462],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.561,-6.774],[-1.233,-4.901],[-3.432,-1.8679999999999999],[-4.504,1.7739999999999998],[-4.273,5.396],[-2.785,7.181],[-0.2350000000000001,7.003],[2.274,5.428],[4.082,3.52],[3.827,1.374],[2.911,2.6679999999999997],[1.4660000000000002,3.9800000000000004],[-0.957,5],[-2.387,3.2569999999999997],[-2.114,-0.7569999999999999],[-0.15500000000000003,-3.7430000000000003],[1.9539999999999997,-4.867],[3.3480000000000003,-4.967],[4.475,-6.995],[3.5170000000000003,-7.29]],"o":[[-0.28500000000000003,-5.7090000000000005],[-2.821,-2.951],[-4.288,0.5239999999999999],[-4.496,4.398],[-3.407,6.811],[-1.184,7.29],[1.596,5.946000000000001],[3.55,4.188],[4.504,2.806],[3.368,2.084],[1.978,3.593],[-0.139,4.907],[-2.0999999999999996,4.165],[-2.395,0.4730000000000001],[-0.965,-2.9059999999999997],[1.443,-4.665],[2.889,-5.021],[3.809,-4.789],[4.050999999999999,-7.229],[2.239,-7.039]],"v":[[0.824,-6.349],[-2.027,-3.93],[-3.86,-0.672],[-4.5,3.082],[-3.84,6.103],[-1.988,7.242],[0.859,6.371],[2.916,4.806],[4.504,2.806],[3.827,1.374],[2.444,3.13],[0.919,4.296],[-1.529,4.582],[-2.391,1.865],[-1.539,-1.827],[0.895,-4.349],[2.421,-4.944],[3.809,-4.789],[4.475,-6.995],[2.882,-7.167]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[92.113,13.805],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.623,-8.863],[2.711,-7.758],[2.736,0.915],[-3.053,-4.43],[-4.658,-3.503],[-4.623,8.863],[-2.733,7.771],[-2.758,-0.92],[3.009,4.456],[4.658,3.505]],"o":[[4.623,-8.863],[2.711,-7.758],[2.736,0.915],[-3.053,-4.43],[-4.658,-3.503],[-4.623,8.863],[-2.733,7.771],[-2.758,-0.92],[3.009,4.456],[4.658,3.505]],"v":[[4.623,-8.863],[2.711,-7.758],[2.736,0.915],[-3.053,-4.43],[-4.658,-3.503],[-4.623,8.863],[-2.733,7.771],[-2.758,-0.92],[3.009,4.456],[4.658,3.505]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[80.748,20.864],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.823,-8.079],[-0.892,-7.089],[-5.71,8.079],[-3.666,6.9],[-2.653,3.552],[2.611,0.513],[3.645,2.679],[5.71,1.486]],"o":[[0.823,-8.079],[-0.892,-7.089],[-5.71,8.079],[-3.666,6.9],[-2.653,3.552],[2.611,0.513],[3.645,2.679],[5.71,1.486]],"v":[[0.823,-8.079],[-0.892,-7.089],[-5.71,8.079],[-3.666,6.9],[-2.653,3.552],[2.611,0.513],[3.645,2.679],[5.71,1.486]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.986,1.294],[-0.061,-5.092],[-0.009,-5.121],[1.939,-0.972]],"o":[[-1.986,1.294],[-0.061,-5.092],[-0.009,-5.121],[1.939,-0.972]],"v":[[-1.986,1.294],[-0.061,-5.092],[-0.009,-5.121],[1.939,-0.972]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[69.014,29.049],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.42700000000000005,-7.535],[-4.855,-4.485],[-4.821,7.882],[-0.728,5.519],[1.476,4.004],[3.7689999999999997,1.017],[4.8549999999999995,-2.5839999999999996],[4.626,-6.2219999999999995],[3.109,-7.882]],"o":[[-0.762,-6.848],[-4.855,-4.485],[-4.821,7.882],[0.4610000000000001,4.832],[3.137,2.0869999999999997],[4.638999999999999,-1.334],[4.847,-5.225],[3.745,-7.552],[1.442,-7.877]],"v":[[-0.762,-6.848],[-4.855,-4.485],[-4.821,7.882],[-0.728,5.519],[2.306,3.045],[4.204,-0.159],[4.851,-3.908],[4.186,-6.883],[2.275,-7.879]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-2.813,4.791],[-2.837,-3.719],[-0.882,-4.848],[1.229,-5.713],[2.76,-4.129],[2.465,-0.028000000000000025],[0.3460000000000001,2.967]],"o":[[-2.813,4.791],[-2.837,-3.719],[0.32199999999999995,-5.543],[2.452,-5.017],[2.768,-1.2699999999999998],[1.25,2.093],[-0.857,3.662]],"v":[[-2.813,4.791],[-2.837,-3.719],[-0.882,-4.848],[1.837,-5.359],[2.764,-2.703],[1.854,1.03],[-0.857,3.662]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[57.626,35.309],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 5","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.712,-7.76],[2.736,0.913],[-3.052,-4.432],[-4.659,-3.505],[-4.623,8.863],[-2.733,7.771],[-2.758,-0.923],[3.009,4.456],[4.659,3.503],[4.624,-8.863]],"o":[[2.712,-7.76],[2.736,0.913],[-3.052,-4.432],[-4.659,-3.505],[-4.623,8.863],[-2.733,7.771],[-2.758,-0.923],[3.009,4.456],[4.659,3.503],[4.624,-8.863]],"v":[[2.712,-7.76],[2.736,0.913],[-3.052,-4.432],[-4.659,-3.505],[-4.623,8.863],[-2.733,7.771],[-2.758,-0.923],[3.009,4.456],[4.659,3.503],[4.624,-8.863]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[45.556,41.183],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.658,-4.081],[-3.624,8.286],[3.658,4.081],[3.653,2.203],[-1.673,5.278],[-1.683,1.824],[3.309,-1.057],[3.303,-2.935],[-1.689,-0.054],[-1.697,-3.332],[3.629,-6.408],[3.624,-8.286]],"o":[[-3.658,-4.081],[-3.624,8.286],[3.658,4.081],[3.653,2.203],[-1.673,5.278],[-1.683,1.824],[3.309,-1.057],[3.303,-2.935],[-1.689,-0.054],[-1.697,-3.332],[3.629,-6.408],[3.624,-8.286]],"v":[[-3.658,-4.081],[-3.624,8.286],[3.658,4.081],[3.653,2.203],[-1.673,5.278],[-1.683,1.824],[3.309,-1.057],[3.303,-2.935],[-1.689,-0.054],[-1.697,-3.332],[3.629,-6.408],[3.624,-8.286]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[35.049,47.249],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.686,-2.418],[-4.682,-0.471],[-1.004,-2.595],[-0.975,7.827],[1.039,6.664],[1.009,-3.758],[4.686,-5.882],[4.681,-7.827]],"o":[[-4.686,-2.418],[-4.682,-0.471],[-1.004,-2.595],[-0.975,7.827],[1.039,6.664],[1.009,-3.758],[4.686,-5.882],[4.681,-7.827]],"v":[[-4.686,-2.418],[-4.682,-0.471],[-1.004,-2.595],[-0.975,7.827],[1.039,6.664],[1.009,-3.758],[4.686,-5.882],[4.681,-7.827]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[25.213,51.857],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.687,-2.418],[-4.682,-0.471],[-1.004,-2.594],[-0.974,7.827],[1.039,6.664],[1.01,-3.758],[4.687,-5.88],[4.682,-7.827]],"o":[[-4.687,-2.418],[-4.682,-0.471],[-1.004,-2.594],[-0.974,7.827],[1.039,6.664],[1.01,-3.758],[4.687,-5.88],[4.682,-7.827]],"v":[[-4.687,-2.418],[-4.682,-0.471],[-1.004,-2.594],[-0.974,7.827],[1.039,6.664],[1.01,-3.758],[4.687,-5.88],[4.682,-7.827]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[15.232,57.62],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.888,-7.091],[-5.706,8.077],[-3.663,6.898],[-2.65,3.55],[2.608,0.514],[3.648,2.676],[5.706,1.489],[0.818,-8.077]],"o":[[-0.888,-7.091],[-5.706,8.077],[-3.663,6.898],[-2.65,3.55],[2.608,0.514],[3.648,2.676],[5.706,1.489],[0.818,-8.077]],"v":[[-0.888,-7.091],[-5.706,8.077],[-3.663,6.898],[-2.65,3.55],[2.608,0.514],[3.648,2.676],[5.706,1.489],[0.818,-8.077]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-0.057,-5.094],[-0.013,-5.119],[1.943,-0.975],[-1.983,1.292]],"o":[[-0.057,-5.094],[-0.013,-5.119],[1.943,-0.975],[-1.983,1.292]],"v":[[-0.057,-5.094],[-0.013,-5.119],[1.943,-0.975],[-1.983,1.292]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[5.741,65.58],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 10","np":3,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":2,"ty":4,"nm":"Layer 4 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[280.525,237.499,0],"ix":2},"a":{"a":0,"k":[34.593,26.321,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":1,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":2,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":3,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":4,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[0.387]},"o":{"x":[0.167],"y":[0]},"t":5,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.777]},"o":{"x":[0.167],"y":[-0.194]},"t":6,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.259]},"t":7,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":8,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":9,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":10,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":11,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":12,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":13,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":14,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":15,"s":[0.1443,0.6357,0.5456,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":16,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":17,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":18,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":19,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":20,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":21,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[0.741]},"o":{"x":[0.167],"y":[0.388]},"t":22,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.775]},"o":{"x":[0.167],"y":[-0.775]},"t":23,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.259]},"t":24,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":25,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":26,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":27,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":28,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":29,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.258]},"o":{"x":[0.167],"y":[-0.388]},"t":30,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[1.778]},"o":{"x":[0.167],"y":[-0.778]},"t":31,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.258]},"t":32,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":33,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":34,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":35,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":36,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":37,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":38,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":39,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":40,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":41,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":42,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":43,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":44,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":45,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":46,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.259]},"o":{"x":[0.167],"y":[-0.388]},"t":47,"s":[0.0039,0.6157,0.5686,1]},{"i":{"x":[0.833],"y":[0.228]},"o":{"x":[0.167],"y":[0.772]},"t":48,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.259]},"t":49,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":50,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":51,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":52,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":53,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":54,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[0.742]},"o":{"x":[0.167],"y":[0.388]},"t":55,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[0.218]},"o":{"x":[0.167],"y":[0.782]},"t":56,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.258]},"t":57,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":58,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":59,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":60,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":61,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":62,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[1.387]},"o":{"x":[0.167],"y":[-0.388]},"t":63,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[1.389]},"o":{"x":[0.167],"y":[-0.389]},"t":64,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.387]},"t":65,"s":[0.1443,0.6357,0.5456,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":66,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":67,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":68,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":69,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":70,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":71,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[0.74]},"o":{"x":[0.167],"y":[0.388]},"t":72,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.768]},"o":{"x":[0.167],"y":[-0.768]},"t":73,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.26]},"t":74,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":75,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":76,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":77,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":78,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":79,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.258]},"o":{"x":[0.167],"y":[-0.388]},"t":80,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[1.785]},"o":{"x":[0.167],"y":[-0.785]},"t":81,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.258]},"t":82,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":83,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":84,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":85,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":86,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":87,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[0.613]},"o":{"x":[0.167],"y":[0.388]},"t":88,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.389]},"t":89,"s":[0.2748,0.5178,0.7452,1]},{"t":90,"s":[0.3091,0.5374,0.7509,1]}],"ix":3}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.59,-6.765],[-3.604,-5.602],[-3.569,6.765],[3.604,2.623],[3.598,0.645],[-1.561,3.623]],"o":[[-1.59,-6.765],[-3.604,-5.602],[-3.569,6.765],[3.604,2.623],[3.598,0.645],[-1.561,3.623]],"v":[[-1.59,-6.765],[-3.604,-5.602],[-3.569,6.765],[3.604,2.623],[3.598,0.645],[-1.561,3.623]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[65.582,9.919],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.59,-6.765],[-3.604,-5.602],[-3.569,6.765],[3.604,2.624],[3.598,0.645],[-1.561,3.623]],"o":[[-1.59,-6.765],[-3.604,-5.602],[-3.569,6.765],[3.604,2.624],[3.598,0.645],[-1.561,3.623]],"v":[[-1.59,-6.765],[-3.604,-5.602],[-3.569,6.765],[3.604,2.624],[3.598,0.645],[-1.561,3.623]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[56.702,15.046],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.771,-6.8149999999999995],[-1.52,-5.340999999999999],[-3.3499999999999996,-3.26],[-4.614,-0.75],[-5.213,2.031],[-5.087,4.781],[-4.242,6.535],[-2.7720000000000002,7.2219999999999995],[-0.77,6.814],[1.521,5.341],[3.3499999999999996,3.261],[4.614,0.7330000000000001],[5.213,-2.064],[5.08,-4.81],[4.236,-6.539],[2.7720000000000002,-7.223]],"o":[[-0.805,-5.905],[-2.803,-4.004],[-4.266,-1.6139999999999999],[-5.099,1.091],[-5.207,3.968],[-4.593999999999999,6.066],[-3.319,7.111000000000001],[-1.486,7.076],[0.806,5.904000000000001],[2.804,4.0040000000000004],[4.2589999999999995,1.6110000000000002],[5.092,-1.113],[5.208,-4.001],[4.593999999999999,-6.082999999999999],[3.321,-7.111],[1.486,-7.077]],"v":[[-0.01,-6.364],[-2.161,-4.669],[-3.808,-2.441],[-4.853,0.168],[-5.21,3.003],[-4.837,5.417],[-3.78,6.823],[-2.129,7.145],[0.025,6.355],[2.163,4.668],[3.808,2.434],[4.853,-0.194],[5.21,-3.036],[4.837,-5.443],[3.782,-6.832],[2.129,-7.146]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.684,3.9690000000000003],[-1.206,4.8919999999999995],[-2.509,4.467],[-3.134,2.729],[-3.0189999999999997,0.008000000000000007],[-2.1630000000000003,-2.283],[-0.668,-3.976],[1.221,-4.899],[2.517,-4.489],[3.1350000000000002,-2.755],[3.0180000000000002,-0.03400000000000003],[2.17,2.262]],"o":[[-0.644,4.736000000000001],[-2.142,4.752],[-3.009,3.4459999999999997],[-3.14,0.868],[-2.526,-1.578],[-1.231,-3.485],[0.66,-4.742],[2.157,-4.776],[3.009,-3.471],[3.14,-0.894],[2.5180000000000002,1.565],[1.246,3.476]],"v":[[0.02,4.352],[-1.674,4.826],[-2.759,3.957],[-3.137,1.807],[-2.772,-0.789],[-1.697,-2.888],[-0.004,-4.359],[1.689,-4.842],[2.767,-3.986],[3.137,-1.816],[2.765,0.768],[1.704,2.875]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[45.673,19.924],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.366,-7.796],[-4.581,-4.363],[-4.547,8.004],[-2.526,6.837],[-2.539,1.958],[-1.051,1.098],[-0.5700000000000001,0.8540000000000001],[-0.007000000000000006,0.748],[0.43200000000000005,0.998],[2.37,4.011],[4.581,2.734],[2.753,-0.074],[2.307,-0.6299999999999999],[1.615,-0.726],[2.1060000000000003,-1.2810000000000001],[3.264,-2.8209999999999997],[3.916,-4.843],[3.587,-7.467]],"o":[[0.169,-7.105],[-4.581,-4.363],[-4.547,8.004],[-2.526,6.837],[-2.539,1.958],[-0.7959999999999999,0.9510000000000001],[-0.183,0.748],[0.3,0.8640000000000001],[0.557,1.194],[2.37,4.011],[4.581,2.734],[2.54,-0.421],[1.843,-0.745],[1.756,-0.9410000000000001],[2.894,-2.2119999999999997],[3.787,-4.155],[3.911,-6.7379999999999995],[2.292,-8.004]],"v":[[0.169,-7.105],[-4.581,-4.363],[-4.547,8.004],[-2.526,6.837],[-2.539,1.958],[-1.051,1.098],[-0.372,0.799],[0.147,0.802],[0.557,1.194],[2.37,4.011],[4.581,2.734],[2.753,-0.074],[2.044,-0.696],[1.365,-0.631],[2.414,-1.649],[3.526,-3.492],[3.914,-5.556],[2.943,-7.742]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-2.544,0.205],[-2.556,-3.668],[-0.133,-5.067],[1.0779999999999998,-5.607],[1.943,-4.997],[1.78,-3.106],[0.587,-1.6019999999999999]],"o":[[-2.544,0.205],[-2.556,-3.668],[0.5599999999999999,-5.4670000000000005],[1.773,-5.378],[1.946,-3.697],[1.103,-2.06],[-0.107,-1.202]],"v":[[-2.544,0.205],[-2.556,-3.668],[-0.133,-5.067],[1.422,-5.494],[1.944,-4.352],[1.445,-2.585],[-0.107,-1.202]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[34.645,27.106],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.104,-7.947],[2.879,-6.661],[0.043,-0.25],[-2.813,-3.375],[-5.104,-2.052],[-0.984,2.368],[-0.968,7.947],[1.053,6.78],[1.037,1.2]],"o":[[5.104,-7.947],[2.879,-6.661],[0.043,-0.25],[-2.813,-3.375],[-5.104,-2.052],[-0.984,2.368],[-0.968,7.947],[1.053,6.78],[1.037,1.2]],"v":[[5.104,-7.947],[2.879,-6.661],[0.043,-0.25],[-2.813,-3.375],[-5.104,-2.052],[-0.984,2.368],[-0.968,7.947],[1.053,6.78],[1.037,1.2]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[23.405,31.587],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.823,-8.079],[-0.884,-7.093],[-5.71,8.079],[-3.66,6.896],[-2.655,3.561],[2.616,0.518],[3.652,2.674],[5.71,1.486]],"o":[[0.823,-8.079],[-0.884,-7.093],[-5.71,8.079],[-3.66,6.896],[-2.655,3.561],[2.616,0.518],[3.652,2.674],[5.71,1.486]],"v":[[0.823,-8.079],[-0.884,-7.093],[-5.71,8.079],[-3.66,6.896],[-2.655,3.561],[2.616,0.518],[3.652,2.674],[5.71,1.486]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.975,1.288],[-0.053,-5.096],[-0.009,-5.121],[1.943,-0.974]],"o":[[-1.975,1.288],[-0.053,-5.096],[-0.009,-5.121],[1.943,-0.974]],"v":[[-1.975,1.288],[-0.053,-5.096],[-0.009,-5.121],[1.943,-0.974]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[13.801,39.736],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 6","np":3,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.304,-7.652],[-4.249,-4.446],[-4.215,7.921],[-2.2,6.758],[-2.213,2.163],[0.538,0.575],[2.0039999999999996,-0.43100000000000005],[3.533,-2.3970000000000002],[4.25,-4.675000000000001],[4.0969999999999995,-6.897],[3.094,-7.920999999999999]],"o":[[0.516,-7.197],[-4.249,-4.446],[-4.215,7.921],[-2.2,6.758],[-2.213,2.163],[1.326,0.11999999999999994],[3.112,-1.7000000000000002],[4.107,-3.895],[4.246,-6.285],[3.517,-7.721],[1.9829999999999997,-7.893]],"v":[[0.516,-7.197],[-4.249,-4.446],[-4.215,7.921],[-2.2,6.758],[-2.213,2.163],[0.538,0.575],[2.558,-1.07],[3.816,-3.148],[4.248,-5.472],[3.804,-7.307],[2.538,-7.903]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-2.218,0.319],[-2.23,-3.747],[0.199,-5.15],[1.3970000000000002,-5.674],[2.2750000000000004,-5.005],[2.106,-3.026],[0.89,-1.476]],"o":[[-2.218,0.319],[-2.23,-3.747],[0.8780000000000001,-5.542000000000001],[2.1,-5.416],[2.279,-3.639],[1.408,-1.942],[0.212,-1.084]],"v":[[-2.218,0.319],[-2.23,-3.747],[0.199,-5.15],[1.749,-5.54],[2.277,-4.334],[1.757,-2.48],[0.212,-1.084]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[4.25,44.545],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 7","np":3,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":3,"ty":4,"nm":"Layer 5 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[291.727,213.107,0],"ix":2},"a":{"a":0,"k":[23.59,19.788,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":0,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":1,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":2,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":3,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":4,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":5,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":6,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.259]},"o":{"x":[0.167],"y":[-0.388]},"t":7,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.225]},"o":{"x":[0.167],"y":[0.775]},"t":8,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.259]},"t":9,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":10,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":11,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":12,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":13,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":14,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[0.741]},"o":{"x":[0.167],"y":[0.388]},"t":15,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[0.225]},"o":{"x":[0.167],"y":[0.775]},"t":16,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.259]},"t":17,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":18,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":19,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":20,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":21,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":22,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":23,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":24,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":25,"s":[0.1443,0.6357,0.5456,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":26,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":27,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":28,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":29,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":30,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":31,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[0.742]},"o":{"x":[0.167],"y":[0.388]},"t":32,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.778]},"o":{"x":[0.167],"y":[-0.778]},"t":33,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.258]},"t":34,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":35,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":36,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":37,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":38,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":39,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.259]},"o":{"x":[0.167],"y":[-0.388]},"t":40,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[1.775]},"o":{"x":[0.167],"y":[-0.775]},"t":41,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.259]},"t":42,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":43,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":44,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":45,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":46,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":47,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":48,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":49,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":50,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":51,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":52,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":53,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":54,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":55,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":56,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.258]},"o":{"x":[0.167],"y":[-0.388]},"t":57,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.221]},"o":{"x":[0.167],"y":[0.779]},"t":58,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.258]},"t":59,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":60,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":61,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":62,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":63,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":64,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[0.741]},"o":{"x":[0.167],"y":[0.388]},"t":65,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[0.228]},"o":{"x":[0.167],"y":[0.772]},"t":66,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.259]},"t":67,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":68,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":69,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":70,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":71,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":72,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":73,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":74,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.389]},"t":75,"s":[0.1443,0.6357,0.5456,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":76,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":77,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":78,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":79,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":80,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":81,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[0.742]},"o":{"x":[0.167],"y":[0.388]},"t":82,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.782]},"o":{"x":[0.167],"y":[-0.782]},"t":83,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.258]},"t":84,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":85,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":86,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":87,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":88,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":89,"s":[0.196,0.604,0.57,1]},{"t":90,"s":[0.1824,0.5776,0.5447,1]}],"ix":3}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.659,-4.077],[-3.624,8.281],[3.659,4.077],[3.653,2.199],[-1.674,5.274],[-1.684,1.82],[3.308,-1.062],[3.302,-2.94],[-1.689,-0.058],[-1.698,-3.337],[3.628,-6.412],[3.624,-8.282]],"o":[[-3.659,-4.077],[-3.624,8.281],[3.659,4.077],[3.653,2.199],[-1.674,5.274],[-1.684,1.82],[3.308,-1.062],[3.302,-2.94],[-1.689,-0.058],[-1.698,-3.337],[3.628,-6.412],[3.624,-8.282]],"v":[[-3.659,-4.077],[-3.624,8.281],[3.659,4.077],[3.653,2.199],[-1.674,5.274],[-1.684,1.82],[3.308,-1.062],[3.302,-2.94],[-1.689,-0.058],[-1.698,-3.337],[3.628,-6.412],[3.624,-8.282]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[43.52,8.281],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.567,-8.02],[3.498,-6.826],[0.057,4.591],[-3.455,-2.812],[-5.607,-1.568],[-0.815,8.044],[0.878,7.067],[5.607,-8.044]],"o":[[5.567,-8.02],[3.498,-6.826],[0.057,4.591],[-3.455,-2.812],[-5.607,-1.568],[-0.815,8.044],[0.878,7.067],[5.607,-8.044]],"v":[[5.567,-8.02],[3.498,-6.826],[0.057,4.591],[-3.455,-2.812],[-5.607,-1.568],[-0.815,8.044],[0.878,7.067],[5.607,-8.044]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[33.093,12.917],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.892,-7.088],[-5.71,8.073],[-5.211,7.786],[-3.667,6.893],[-2.657,3.555],[2.608,0.516],[3.645,2.672],[5.71,1.479],[0.815,-8.073]],"o":[[-0.892,-7.088],[-5.71,8.073],[-5.211,7.786],[-3.667,6.893],[-2.657,3.555],[2.608,0.516],[3.645,2.672],[5.71,1.479],[0.815,-8.073]],"v":[[-0.892,-7.088],[-5.71,8.073],[-5.211,7.786],[-3.667,6.893],[-2.657,3.555],[2.608,0.516],[3.645,2.672],[5.71,1.479],[0.815,-8.073]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-0.06,-5.099],[-0.017,-5.123],[1.936,-0.977],[-1.983,1.286]],"o":[[-0.06,-5.099],[-0.017,-5.123],[1.936,-0.977],[-1.983,1.286]],"v":[[-0.06,-5.099],[-0.017,-5.123],[1.936,-0.977],[-1.983,1.286]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[22.76,21.68],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.658,-4.077],[-3.624,8.281],[1.736,5.187],[3.658,4.077],[3.653,2.199],[-1.673,5.274],[-1.683,1.82],[3.307,-1.061],[3.303,-2.939],[-1.689,-0.059],[-1.699,-3.336],[3.629,-6.412],[3.624,-8.281]],"o":[[-3.658,-4.077],[-3.624,8.281],[1.736,5.187],[3.658,4.077],[3.653,2.199],[-1.673,5.274],[-1.683,1.82],[3.307,-1.061],[3.303,-2.939],[-1.689,-0.059],[-1.699,-3.336],[3.629,-6.412],[3.624,-8.281]],"v":[[-3.658,-4.077],[-3.624,8.281],[1.736,5.187],[3.658,4.077],[3.653,2.199],[-1.673,5.274],[-1.683,1.82],[3.307,-1.061],[3.303,-2.939],[-1.689,-0.059],[-1.699,-3.336],[3.629,-6.412],[3.624,-8.281]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[12.539,26.168],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.604,-5.598],[-3.569,6.761],[3.604,2.62],[3.598,0.641],[-1.561,3.62],[-1.59,-6.76]],"o":[[-3.604,-5.598],[-3.569,6.761],[3.604,2.62],[3.598,0.641],[-1.561,3.62],[-1.59,-6.76]],"v":[[-3.604,-5.598],[-3.569,6.761],[3.604,2.62],[3.598,0.641],[-1.561,3.62],[-1.59,-6.76]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[3.604,32.816],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":4,"ty":4,"nm":"Layer 6 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[299.26,188.494,0],"ix":2},"a":{"a":0,"k":[16.334,15.775,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":1,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":2,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":3,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":4,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":5,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":6,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":7,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":8,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":9,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":10,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":11,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[-0.227]},"o":{"x":[0.167],"y":[0]},"t":12,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.485]},"o":{"x":[0.167],"y":[-0.194]},"t":13,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.323]},"t":14,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":15,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":16,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":17,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":18,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":19,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.259]},"o":{"x":[0.167],"y":[-0.388]},"t":20,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[1.775]},"o":{"x":[0.167],"y":[-0.775]},"t":21,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.259]},"t":22,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":23,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":24,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":25,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":26,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":27,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":28,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":29,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":30,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":31,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":32,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":33,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":34,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":35,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":36,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.258]},"o":{"x":[0.167],"y":[-0.388]},"t":37,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.222]},"o":{"x":[0.167],"y":[0.778]},"t":38,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.258]},"t":39,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":40,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":41,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":42,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":43,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":44,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[0.741]},"o":{"x":[0.167],"y":[0.388]},"t":45,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[0.225]},"o":{"x":[0.167],"y":[0.775]},"t":46,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.259]},"t":47,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":48,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":49,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":50,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":51,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":52,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":53,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":54,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":55,"s":[0,0.8667,0.702,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":56,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":57,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":58,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":59,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":60,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":61,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[0.742]},"o":{"x":[0.167],"y":[0.388]},"t":62,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.779]},"o":{"x":[0.167],"y":[-0.779]},"t":63,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.258]},"t":64,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":65,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":66,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":67,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":68,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":69,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.259]},"o":{"x":[0.167],"y":[-0.388]},"t":70,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[1.772]},"o":{"x":[0.167],"y":[-0.772]},"t":71,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.259]},"t":72,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":73,"s":[0.0039,0.6157,0.5686,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":74,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":75,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":76,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":77,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":78,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":79,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.389]},"t":80,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":81,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":82,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":83,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":84,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":85,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":86,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.258]},"o":{"x":[0.167],"y":[-0.388]},"t":87,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.218]},"o":{"x":[0.167],"y":[0.782]},"t":88,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.258]},"t":89,"s":[0.1634,0.5966,0.5172,1]},{"t":90,"s":[0.1824,0.5776,0.5447,1]}],"ix":3}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.703,-6.859],[-1.383,-5.503],[-3.183,-3.3970000000000002],[-4.09,-1.076],[-3.8489999999999998,1.203],[-2.181,1.802],[0.535,0.846],[1.287,0.615],[1.9959999999999998,0.617],[2.275,1.0510000000000002],[2.089,2.36],[0.777,3.865],[-0.9160000000000001,4.8],[-2.186,5.223],[-3.326,5.2940000000000005],[-4.277,7.413],[-3.5540000000000003,7.516],[-2.18,7.277],[-0.567,6.6049999999999995],[1.629,5.178],[3.4059999999999997,3.0860000000000003],[4.277,0.787],[4.022,-1.418],[2.259,-1.8699999999999999],[-0.464,-0.919],[-1.486,-0.657],[-2.087,-1.099],[-1.995,-2.252],[-1.355,-3.3520000000000003],[-0.27599999999999997,-4.328],[1.3659999999999999,-5.175],[2.871,-5.3549999999999995],[3.932,-7.337],[3.296,-7.516],[2.098,-7.4030000000000005]],"o":[[-0.639,-6.0840000000000005],[-2.673,-4.137],[-3.909,-1.8439999999999999],[-4.085,0.5920000000000001],[-2.912,1.821],[-1.195,1.46],[0.9510000000000001,0.698],[1.806,0.575],[2.2159999999999997,0.851],[2.2769999999999997,1.848],[1.3530000000000002,3.38],[-0.463,4.581],[-1.7770000000000001,5.1209999999999996],[-2.96,5.308999999999999],[-3.662,5.219],[-3.9410000000000003,7.505],[-2.669,7.409],[-1.1219999999999999,6.876],[0.878,5.771],[2.911,3.808],[4.103,1.542],[4.272,-0.848],[3.019,-1.922],[1.244,-1.519],[-1.07,-0.7040000000000001],[-1.9689999999999999,-0.84],[-2.089,-1.887],[-1.625,-2.995],[-0.677,-4.021],[0.804,-4.9510000000000005],[2.396,-5.383],[3.295,-5.18],[3.639,-7.462],[2.521,-7.489],[1.1849999999999998,-7.086]],"v":[[0.207,-6.573],[-2.032,-4.818],[-3.546,-2.625],[-4.087,-0.314],[-3.381,1.512],[-1.195,1.46],[0.535,0.846],[1.55,0.589],[2.106,0.738],[2.276,1.328],[1.725,2.872],[0.004,4.312],[-1.346,4.957],[-2.573,5.262],[-3.662,5.219],[-4.277,7.413],[-3.108,7.46],[-1.655,7.075],[0.01,6.273],[2.27,4.497],[3.755,2.314],[4.275,0.04],[3.524,-1.676],[1.244,-1.519],[-0.464,-0.919],[-1.728,-0.753],[-2.088,-1.526],[-1.806,-2.63],[-1.02,-3.688],[0.198,-4.602],[1.884,-5.281],[3.295,-5.18],[3.932,-7.337],[2.908,-7.503],[1.638,-7.238]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[28.381,8.906],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.624,-8.281],[0.02,1.768],[-3.628,-4.094],[-5.549,-2.986],[-5.513,9.373],[-3.652,8.298],[-3.677,-0.183],[-0.622,4.618],[0.648,3.884],[3.649,-4.424],[3.672,4.069],[5.549,2.986],[5.513,-9.373]],"o":[[3.624,-8.281],[0.02,1.768],[-3.628,-4.094],[-5.549,-2.986],[-5.513,9.373],[-3.652,8.298],[-3.677,-0.183],[-0.622,4.618],[0.648,3.884],[3.649,-4.424],[3.672,4.069],[5.549,2.986],[5.513,-9.373]],"v":[[3.624,-8.281],[0.02,1.768],[-3.628,-4.094],[-5.549,-2.986],[-5.513,9.373],[-3.652,8.298],[-3.677,-0.183],[-0.622,4.618],[0.648,3.884],[3.649,-4.424],[3.672,4.069],[5.549,2.986],[5.513,-9.373]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[16.45,15.707],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.687,-2.414],[-4.681,-0.467],[-1.005,-2.59],[-0.975,7.823],[1.039,6.66],[1.01,-3.753],[4.687,-5.876],[4.682,-7.823]],"o":[[-4.687,-2.414],[-4.681,-0.467],[-1.005,-2.59],[-0.975,7.823],[1.039,6.66],[1.01,-3.753],[4.687,-5.876],[4.682,-7.823]],"v":[[-4.687,-2.414],[-4.681,-0.467],[-1.005,-2.59],[-0.975,7.823],[1.039,6.66],[1.01,-3.753],[4.687,-5.876],[4.682,-7.823]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[4.688,21.428],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":5,"ty":4,"nm":"Layer 7 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[267.174,180.476,0],"ix":2},"a":{"a":0,"k":[48.043,35.1,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":21,"nm":"Fill","np":9,"mn":"ADBE Fill","ix":1,"en":1,"ef":[{"ty":10,"nm":"Fill Mask","mn":"ADBE Fill-0001","ix":1,"v":{"a":0,"k":0,"ix":1}},{"ty":7,"nm":"All Masks","mn":"ADBE Fill-0007","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":2,"nm":"Color","mn":"ADBE Fill-0002","ix":3,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":0,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":1,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":2,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":3,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":4,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":5,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":6,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.259]},"o":{"x":[0.167],"y":[-0.388]},"t":7,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.225]},"o":{"x":[0.167],"y":[0.775]},"t":8,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.259]},"t":9,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":10,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":11,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":12,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":13,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":14,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[0.741]},"o":{"x":[0.167],"y":[0.388]},"t":15,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[0.225]},"o":{"x":[0.167],"y":[0.775]},"t":16,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.259]},"t":17,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":18,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":19,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":20,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":21,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":22,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":23,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":24,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":25,"s":[0.1443,0.6357,0.5456,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":26,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":27,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":28,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":29,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":30,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":31,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[0.742]},"o":{"x":[0.167],"y":[0.388]},"t":32,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.778]},"o":{"x":[0.167],"y":[-0.778]},"t":33,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.258]},"t":34,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":35,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":36,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":37,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":38,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":39,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.259]},"o":{"x":[0.167],"y":[-0.388]},"t":40,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[1.775]},"o":{"x":[0.167],"y":[-0.775]},"t":41,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.259]},"t":42,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":43,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":44,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":45,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":46,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":47,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":48,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":49,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":50,"s":[0.3091,0.5374,0.7509,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":51,"s":[0.2748,0.5178,0.7452,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":52,"s":[0.2499,0.498,0.7301,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":53,"s":[0.2346,0.4675,0.6854,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":54,"s":[0.22,0.66,0.6233,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":55,"s":[0.2058,0.6342,0.5985,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":56,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[1.258]},"o":{"x":[0.167],"y":[-0.388]},"t":57,"s":[0.1776,0.5624,0.5303,1]},{"i":{"x":[0.833],"y":[0.221]},"o":{"x":[0.167],"y":[0.779]},"t":58,"s":[0.152,0.608,0.5244,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.258]},"t":59,"s":[0.1634,0.5966,0.5172,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":60,"s":[0.1824,0.5776,0.5447,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":61,"s":[0.196,0.604,0.57,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":62,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":63,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":64,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[0.741]},"o":{"x":[0.167],"y":[0.388]},"t":65,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[0.228]},"o":{"x":[0.167],"y":[0.772]},"t":66,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.259]},"t":67,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":68,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":69,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":70,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":71,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":72,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":73,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":74,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.389]},"t":75,"s":[0.1443,0.6357,0.5456,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":76,"s":[0.171,0.589,0.5124,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":77,"s":[0.1872,0.5928,0.559,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":78,"s":[0.2009,0.6191,0.5842,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":79,"s":[0.215,0.645,0.6092,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":80,"s":[0.23,0.4677,0.69,1]},{"i":{"x":[0.833],"y":[0.612]},"o":{"x":[0.167],"y":[0.388]},"t":81,"s":[0.2448,0.4878,0.7152,1]},{"i":{"x":[0.833],"y":[0.742]},"o":{"x":[0.167],"y":[0.388]},"t":82,"s":[0.26,0.508,0.74,1]},{"i":{"x":[0.833],"y":[1.782]},"o":{"x":[0.167],"y":[-0.782]},"t":83,"s":[0.2944,0.5275,0.7456,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.258]},"t":84,"s":[0.2797,0.5177,0.7403,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":85,"s":[0.2548,0.4978,0.7252,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":86,"s":[0.2397,0.4777,0.7003,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":87,"s":[0.225,0.4575,0.675,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":88,"s":[0.2107,0.6493,0.6127,1]},{"i":{"x":[0.833],"y":[1.388]},"o":{"x":[0.167],"y":[-0.388]},"t":89,"s":[0.196,0.604,0.57,1]},{"t":90,"s":[0.1824,0.5776,0.5447,1]}],"ix":3}},{"ty":7,"nm":"Invert","mn":"ADBE Fill-0006","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Horizontal Feather","mn":"ADBE Fill-0003","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":0,"nm":"Vertical Feather","mn":"ADBE Fill-0004","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Opacity","mn":"ADBE Fill-0005","ix":7,"v":{"a":0,"k":1,"ix":7}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.485,-10.352],[3.15,-9.003],[3.167,-3.067],[-3.174,0.594],[-3.191,-5.342],[-5.526,-3.994],[-5.485,10.352],[-3.15,9.004],[-3.167,2.858],[3.173,-0.803],[3.191,5.343],[5.526,3.995]],"o":[[5.485,-10.352],[3.15,-9.003],[3.167,-3.067],[-3.174,0.594],[-3.191,-5.342],[-5.526,-3.994],[-5.485,10.352],[-3.15,9.004],[-3.167,2.858],[3.173,-0.803],[3.191,5.343],[5.526,3.995]],"v":[[5.485,-10.352],[3.15,-9.003],[3.167,-3.067],[-3.174,0.594],[-3.191,-5.342],[-5.526,-3.994],[-5.485,10.352],[-3.15,9.004],[-3.167,2.858],[3.173,-0.803],[3.191,5.343],[5.526,3.995]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[90.561,10.553],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.801,-7.856],[-1.4389999999999998,-5.692],[-3.9850000000000003,-2.172],[-5.223,2.053],[-4.963,6.262],[-3.2409999999999997,8.331999999999999],[-0.2799999999999999,8.118],[2.6370000000000005,6.282],[4.729,4.0760000000000005],[4.437,1.582],[3.3739999999999997,3.0860000000000003],[1.697,4.608],[-1.113,5.802],[-2.778,3.782],[-2.455,-0.8800000000000001],[-0.18500000000000005,-4.35],[2.26,-5.652],[3.883,-5.765],[5.192,-8.125],[4.072,-8.453000000000001]],"o":[[-0.32900000000000007,-6.626],[-3.274,-3.431],[-4.979,0.602],[-5.215000000000001,5.089],[-3.9570000000000003,7.89],[-1.384,8.453],[1.843,6.892],[4.109,4.853],[5.224,3.244],[3.906,2.409],[2.2889999999999997,4.158],[-0.17100000000000004,5.686999999999999],[-2.4379999999999997,4.829],[-2.788,0.546],[-1.125,-3.3790000000000004],[1.6680000000000001,-5.42],[3.348,-5.827],[4.417,-5.561],[4.694,-8.392],[2.596,-8.172]],"v":[[0.955,-7.367],[-2.356,-4.566],[-4.479,-0.787],[-5.219,3.571],[-4.456,7.069],[-2.312,8.392],[0.997,7.381],[3.373,5.572],[5.224,3.244],[4.437,1.582],[2.828,3.62],[1.062,4.975],[-1.779,5.314],[-2.783,2.164],[-1.786,-2.132],[1.034,-5.053],[2.8,-5.737],[4.417,-5.561],[5.192,-8.125],[3.334,-8.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[77.55,17.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.201,-9.61],[-4.241,-4.736],[-4.2,9.61],[4.241,4.736],[4.235,2.556],[-1.946,6.124],[-1.957,2.116],[3.837,-1.229],[3.83,-3.409],[-1.962,-0.064],[-1.973,-3.87],[4.207,-7.438]],"o":[[4.201,-9.61],[-4.241,-4.736],[-4.2,9.61],[4.241,4.736],[4.235,2.556],[-1.946,6.124],[-1.957,2.116],[3.837,-1.229],[3.83,-3.409],[-1.962,-0.064],[-1.973,-3.87],[4.207,-7.438]],"v":[[4.201,-9.61],[-4.241,-4.736],[-4.2,9.61],[4.241,4.736],[4.235,2.556],[-1.946,6.124],[-1.957,2.116],[3.837,-1.229],[3.83,-3.409],[-1.962,-0.064],[-1.973,-3.87],[4.207,-7.438]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[65.965,24.754],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.433,-9.079],[-5.439,-2.802],[-5.433,-0.547],[-1.164,-3.011],[-1.13,9.079],[1.205,7.731],[1.171,-4.359],[5.439,-6.824]],"o":[[5.433,-9.079],[-5.439,-2.802],[-5.433,-0.547],[-1.164,-3.011],[-1.13,9.079],[1.205,7.731],[1.171,-4.359],[5.439,-6.824]],"v":[[5.433,-9.079],[-5.439,-2.802],[-5.433,-0.547],[-1.164,-3.011],[-1.13,9.079],[1.205,7.731],[1.171,-4.359],[5.439,-6.824]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[54.553,30.1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.635,-2.571],[-2.641,0.475],[-2.635,2.571],[2.641,-0.475]],"o":[[2.635,-2.571],[-2.641,0.475],[-2.635,2.571],[2.641,-0.475]],"v":[[2.635,-2.571],[-2.641,0.475],[-2.635,2.571],[2.641,-0.475]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[45.896,38.049],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.896,-7.901],[-1.7610000000000001,-6.199],[-3.88,-3.783],[-5.349,-0.8699999999999999],[-6.0489999999999995,2.357],[-5.901000000000001,5.546],[-4.916,7.572],[-3.21,8.376],[-0.887,7.901],[1.7690000000000001,6.191],[3.8879999999999995,3.775],[5.35,0.8490000000000001],[6.049,-2.394],[5.9,-5.584],[4.923,-7.5969999999999995],[3.219,-8.376]],"o":[[-0.928,-6.848],[-3.247,-4.644],[-4.941,-1.8850000000000002],[-5.913,1.2610000000000001],[-6.042,4.604],[-5.3260000000000005,7.029],[-3.8470000000000004,8.248],[-1.7199999999999998,8.203999999999999],[0.9380000000000001,6.848],[3.255,4.6450000000000005],[4.949,1.86],[5.912999999999999,-1.2990000000000002],[6.043,-4.649],[5.3260000000000005,-7.058],[3.854,-8.257],[1.7279999999999998,-8.213]],"v":[[-0.009,-7.379],[-2.504,-5.426],[-4.41,-2.83],[-5.631,0.191],[-6.045,3.48],[-5.613,6.288],[-4.381,7.91],[-2.465,8.29],[0.033,7.37],[2.512,5.418],[4.419,2.822],[5.632,-0.221],[6.046,-3.517],[5.613,-6.316],[4.388,-7.927],[2.473,-8.299]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.791,4.605],[-1.3980000000000001,5.676],[-2.905,5.1770000000000005],[-3.634,3.163],[-3.497,0.0020000000000000018],[-2.511,-2.652],[-0.77,-4.622],[1.42,-5.693],[2.92,-5.215],[3.634,-3.1930000000000005],[3.504,-0.04300000000000004],[2.5180000000000002,2.626]],"o":[[-0.741,5.49],[-2.488,5.516],[-3.4859999999999998,3.9930000000000003],[-3.64,1.0079999999999998],[-2.925,-1.84],[-1.4260000000000002,-4.051],[0.763,-5.506],[2.5090000000000003,-5.5489999999999995],[3.493,-4.034],[3.64,-1.0380000000000003],[2.925,1.812],[1.44,4.038]],"v":[[0.025,5.048],[-1.939,5.594],[-3.199,4.591],[-3.637,2.09],[-3.215,-0.917],[-1.965,-3.353],[-0.003,-5.064],[1.961,-5.619],[3.206,-4.624],[3.637,-2.111],[3.215,0.888],[1.979,3.332]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[34.924,42.673],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 6","np":3,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.173,-4.766],[-4.133,9.58],[-1.798,8.233],[-1.815,2.187],[3.818,-1.066],[3.812,-3.262],[-1.821,-0.009],[-1.832,-3.942],[4.173,-7.408],[4.167,-9.58]],"o":[[-4.173,-4.766],[-4.133,9.58],[-1.798,8.233],[-1.815,2.187],[3.818,-1.066],[3.812,-3.262],[-1.821,-0.009],[-1.832,-3.942],[4.173,-7.408],[4.167,-9.58]],"v":[[-4.173,-4.766],[-4.133,9.58],[-1.798,8.233],[-1.815,2.187],[3.818,-1.066],[3.812,-3.262],[-1.821,-0.009],[-1.832,-3.942],[4.173,-7.408],[4.167,-9.58]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[23.277,49.39],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.15,-9.003],[3.179,1.065],[-3.541,-5.14],[-5.402,-4.066],[-5.361,10.28],[-3.164,9.011],[-3.193,-1.076],[3.49,5.169],[5.402,4.066],[5.36,-10.28]],"o":[[3.15,-9.003],[3.179,1.065],[-3.541,-5.14],[-5.402,-4.066],[-5.361,10.28],[-3.164,9.011],[-3.193,-1.076],[3.49,5.169],[5.402,4.066],[5.36,-10.28]],"v":[[3.15,-9.003],[3.179,1.065],[-3.541,-5.14],[-5.402,-4.066],[-5.361,10.28],[-3.164,9.011],[-3.193,-1.076],[3.49,5.169],[5.402,4.066],[5.36,-10.28]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[10.729,56.644],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.188,-6.5],[-1.168,0.703],[-1.147,7.846],[1.188,6.499],[1.147,-7.846]],"o":[[-1.188,-6.5],[-1.168,0.703],[-1.147,7.846],[1.188,6.499],[1.147,-7.846]],"v":[[-1.188,-6.5],[-1.168,0.703],[-1.147,7.846],[1.188,6.499],[1.147,-7.846]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[1.189,62.152],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":6,"ty":4,"nm":"Layer 15 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[309.291,104.08,0],"ix":2},"a":{"a":0,"k":[6.641,26.885,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"o":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"v":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":13,"s":[{"i":[[-6.648,-42.467],[6.632,-50.135],[6.64,19.217],[-6.64,26.885]],"o":[[-6.648,-42.467],[6.632,-50.135],[6.64,19.217],[-6.64,26.885]],"v":[[-6.648,-42.467],[6.632,-50.135],[6.64,19.217],[-6.64,26.885]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":32,"s":[{"i":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"o":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"v":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":47,"s":[{"i":[[-6.648,-42.467],[6.632,-50.135],[6.64,19.217],[-6.64,26.885]],"o":[[-6.648,-42.467],[6.632,-50.135],[6.64,19.217],[-6.64,26.885]],"v":[[-6.648,-42.467],[6.632,-50.135],[6.64,19.217],[-6.64,26.885]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":61,"s":[{"i":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"o":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"v":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":74,"s":[{"i":[[-6.648,-42.467],[6.632,-50.135],[6.64,19.217],[-6.64,26.885]],"o":[[-6.648,-42.467],[6.632,-50.135],[6.64,19.217],[-6.64,26.885]],"v":[[-6.648,-42.467],[6.632,-50.135],[6.64,19.217],[-6.64,26.885]],"c":true}]},{"t":90,"s":[{"i":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"o":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"v":[[-6.64,-19.217],[6.64,-26.885],[6.64,19.217],[-6.64,26.885]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[6.64,26.885],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":7,"ty":4,"nm":"Layer 16 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[286.317,109.748,0],"ix":2},"a":{"a":0,"k":[6.64,34.591,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"o":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"v":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":17,"s":[{"i":[[-6.699,12.827],[6.581,5.16],[6.64,26.923],[-6.64,34.59]],"o":[[-6.699,12.827],[6.581,5.16],[6.64,26.923],[-6.64,34.59]],"v":[[-6.699,12.827],[6.581,5.16],[6.64,26.923],[-6.64,34.59]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":29,"s":[{"i":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"o":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"v":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":43,"s":[{"i":[[-6.699,12.827],[6.581,5.16],[6.64,26.923],[-6.64,34.59]],"o":[[-6.699,12.827],[6.581,5.16],[6.64,26.923],[-6.64,34.59]],"v":[[-6.699,12.827],[6.581,5.16],[6.64,26.923],[-6.64,34.59]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":58,"s":[{"i":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"o":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"v":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76,"s":[{"i":[[-6.699,12.827],[6.581,5.16],[6.64,26.923],[-6.64,34.59]],"o":[[-6.699,12.827],[6.581,5.16],[6.64,26.923],[-6.64,34.59]],"v":[[-6.699,12.827],[6.581,5.16],[6.64,26.923],[-6.64,34.59]],"c":true}]},{"t":90,"s":[{"i":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"o":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"v":[[-6.64,-26.923],[6.64,-34.59],[6.64,26.923],[-6.64,34.59]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[6.64,34.591],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":8,"ty":4,"nm":"Layer 17 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[262.512,137.144,0],"ix":2},"a":{"a":0,"k":[6.64,19.157,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"o":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"v":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":14,"s":[{"i":[[-6.953,-82.488],[6.327,-90.156],[6.64,11.489],[-6.64,19.157]],"o":[[-6.953,-82.488],[6.327,-90.156],[6.64,11.489],[-6.64,19.157]],"v":[[-6.953,-82.488],[6.327,-90.156],[6.64,11.489],[-6.64,19.157]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":31,"s":[{"i":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"o":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"v":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":46,"s":[{"i":[[-6.953,-82.488],[6.327,-90.156],[6.64,11.489],[-6.64,19.157]],"o":[[-6.953,-82.488],[6.327,-90.156],[6.64,11.489],[-6.64,19.157]],"v":[[-6.953,-82.488],[6.327,-90.156],[6.64,11.489],[-6.64,19.157]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62,"s":[{"i":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"o":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"v":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":74,"s":[{"i":[[-6.953,-82.488],[6.327,-90.156],[6.64,11.489],[-6.64,19.157]],"o":[[-6.953,-82.488],[6.327,-90.156],[6.64,11.489],[-6.64,19.157]],"v":[[-6.953,-82.488],[6.327,-90.156],[6.64,11.489],[-6.64,19.157]],"c":true}]},{"t":90,"s":[{"i":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"o":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"v":[[-6.64,-11.488],[6.64,-19.156],[6.64,11.489],[-6.64,19.157]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[6.64,19.157],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":9,"ty":4,"nm":"Layer 18 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[237.968,134.574,0],"ix":2},"a":{"a":0,"k":[6.64,34.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"o":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"v":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":16,"s":[{"i":[[-6.548,26.189],[6.732,18.521],[6.64,26.811],[-6.64,34.479]],"o":[[-6.548,26.189],[6.732,18.521],[6.64,26.811],[-6.64,34.479]],"v":[[-6.548,26.189],[6.732,18.521],[6.64,26.811],[-6.64,34.479]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":28,"s":[{"i":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"o":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"v":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":44,"s":[{"i":[[-6.548,26.189],[6.732,18.521],[6.64,26.811],[-6.64,34.479]],"o":[[-6.548,26.189],[6.732,18.521],[6.64,26.811],[-6.64,34.479]],"v":[[-6.548,26.189],[6.732,18.521],[6.64,26.811],[-6.64,34.479]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":59,"s":[{"i":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"o":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"v":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":77,"s":[{"i":[[-6.548,26.189],[6.732,18.521],[6.64,26.811],[-6.64,34.479]],"o":[[-6.548,26.189],[6.732,18.521],[6.64,26.811],[-6.64,34.479]],"v":[[-6.548,26.189],[6.732,18.521],[6.64,26.811],[-6.64,34.479]],"c":true}]},{"t":90,"s":[{"i":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"o":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"v":[[-6.64,-26.811],[6.64,-34.479],[6.64,26.811],[-6.64,34.479]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[6.64,34.479],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":10,"ty":4,"nm":"Layer 19 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[211.905,140.704,0],"ix":2},"a":{"a":0,"k":[6.641,42.173,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"o":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"v":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":12,"s":[{"i":[[-6.612,9.745],[6.668,2.077],[6.64,34.505],[-6.64,42.173]],"o":[[-6.612,9.745],[6.668,2.077],[6.64,34.505],[-6.64,42.173]],"v":[[-6.612,9.745],[6.668,2.077],[6.64,34.505],[-6.64,42.173]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":31,"s":[{"i":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"o":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"v":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":47,"s":[{"i":[[-6.612,9.745],[6.668,2.077],[6.64,34.505],[-6.64,42.173]],"o":[[-6.612,9.745],[6.668,2.077],[6.64,34.505],[-6.64,42.173]],"v":[[-6.612,9.745],[6.668,2.077],[6.64,34.505],[-6.64,42.173]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":57,"s":[{"i":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"o":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"v":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":73,"s":[{"i":[[-6.612,9.745],[6.668,2.077],[6.64,34.505],[-6.64,42.173]],"o":[[-6.612,9.745],[6.668,2.077],[6.64,34.505],[-6.64,42.173]],"v":[[-6.612,9.745],[6.668,2.077],[6.64,34.505],[-6.64,42.173]],"c":true}]},{"t":90,"s":[{"i":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"o":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"v":[[-6.64,-34.505],[6.64,-42.173],[6.64,34.505],[-6.64,42.173]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[6.64,42.173],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":11,"ty":4,"nm":"Layer 20 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[188.091,169.053,0],"ix":2},"a":{"a":0,"k":[6.64,26.838,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"o":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"v":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":16,"s":[{"i":[[-6.418,-63.045],[6.862,-70.713],[6.64,19.17],[-6.64,26.838]],"o":[[-6.418,-63.045],[6.862,-70.713],[6.64,19.17],[-6.64,26.838]],"v":[[-6.418,-63.045],[6.862,-70.713],[6.64,19.17],[-6.64,26.838]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":29,"s":[{"i":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"o":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"v":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":44,"s":[{"i":[[-6.746,-45.795],[6.534,-53.463],[6.64,19.17],[-6.64,26.838]],"o":[[-6.746,-45.795],[6.534,-53.463],[6.64,19.17],[-6.64,26.838]],"v":[[-6.746,-45.795],[6.534,-53.463],[6.64,19.17],[-6.64,26.838]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":62,"s":[{"i":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"o":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"v":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":76,"s":[{"i":[[-6.746,-45.795],[6.534,-53.463],[6.64,19.17],[-6.64,26.838]],"o":[[-6.746,-45.795],[6.534,-53.463],[6.64,19.17],[-6.64,26.838]],"v":[[-6.746,-45.795],[6.534,-53.463],[6.64,19.17],[-6.64,26.838]],"c":true}]},{"t":90,"s":[{"i":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"o":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"v":[[-6.64,-19.795],[6.64,-27.463],[6.64,19.17],[-6.64,26.838]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[6.64,26.838],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":12,"ty":4,"nm":"Layer 9 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[133.569,338.73,0],"ix":2},"a":{"a":0,"k":[37.993,26.812,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"o":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"v":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":15,"s":[{"i":[[37.993,-26.812],[37.993,-17.062],[-88.743,53.812],[-88.743,44.062]],"o":[[37.993,-26.812],[37.993,-17.062],[-88.743,53.812],[-88.743,44.062]],"v":[[37.993,-26.812],[37.993,-17.062],[-88.743,53.812],[-88.743,44.062]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[{"i":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"o":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"v":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":45,"s":[{"i":[[37.993,-26.812],[37.993,-17.062],[-88.743,53.812],[-88.743,44.062]],"o":[[37.993,-26.812],[37.993,-17.062],[-88.743,53.812],[-88.743,44.062]],"v":[[37.993,-26.812],[37.993,-17.062],[-88.743,53.812],[-88.743,44.062]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"o":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"v":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[37.993,-26.812],[37.993,-17.062],[-88.743,53.812],[-88.743,44.062]],"o":[[37.993,-26.812],[37.993,-17.062],[-88.743,53.812],[-88.743,44.062]],"v":[[37.993,-26.812],[37.993,-17.062],[-88.743,53.812],[-88.743,44.062]],"c":true}]},{"t":90,"s":[{"i":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"o":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"v":[[37.993,-26.812],[37.993,-17.062],[-37.993,26.812],[-37.993,17.062]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[37.993,26.812],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":13,"ty":4,"nm":"Layer 10 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[119.953,327.68,0],"ix":2},"a":{"a":0,"k":[50.658,34.174,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"o":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"v":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":15,"s":[{"i":[[50.657,-34.173],[50.657,-24.423],[-17.908,14.174],[-17.908,4.424]],"o":[[50.657,-34.173],[50.657,-24.423],[-17.908,14.174],[-17.908,4.424]],"v":[[50.657,-34.173],[50.657,-24.423],[-17.908,14.174],[-17.908,4.424]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[{"i":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"o":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"v":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":45,"s":[{"i":[[50.657,-34.173],[50.657,-24.423],[-17.908,14.174],[-17.908,4.424]],"o":[[50.657,-34.173],[50.657,-24.423],[-17.908,14.174],[-17.908,4.424]],"v":[[50.657,-34.173],[50.657,-24.423],[-17.908,14.174],[-17.908,4.424]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"o":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"v":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[50.657,-34.173],[50.657,-24.423],[-17.908,14.174],[-17.908,4.424]],"o":[[50.657,-34.173],[50.657,-24.423],[-17.908,14.174],[-17.908,4.424]],"v":[[50.657,-34.173],[50.657,-24.423],[-17.908,14.174],[-17.908,4.424]],"c":true}]},{"t":90,"s":[{"i":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"o":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"v":[[50.657,-34.173],[50.657,-24.423],[-50.658,34.174],[-50.658,24.424]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[50.657,34.174],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":14,"ty":4,"nm":"Layer 11 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[136.839,298.48,0],"ix":2},"a":{"a":0,"k":[33.772,24.375,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"o":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"v":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":15,"s":[{"i":[[33.771,-24.375],[33.771,-14.625],[-63.022,40.374],[-63.022,30.624]],"o":[[33.771,-24.375],[33.771,-14.625],[-63.022,40.374],[-63.022,30.624]],"v":[[33.771,-24.375],[33.771,-14.625],[-63.022,40.374],[-63.022,30.624]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[{"i":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"o":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"v":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":45,"s":[{"i":[[33.771,-24.375],[33.771,-14.625],[-63.022,40.374],[-63.022,30.624]],"o":[[33.771,-24.375],[33.771,-14.625],[-63.022,40.374],[-63.022,30.624]],"v":[[33.771,-24.375],[33.771,-14.625],[-63.022,40.374],[-63.022,30.624]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"o":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"v":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[33.771,-24.375],[33.771,-14.625],[-63.022,40.374],[-63.022,30.624]],"o":[[33.771,-24.375],[33.771,-14.625],[-63.022,40.374],[-63.022,30.624]],"v":[[33.771,-24.375],[33.771,-14.625],[-63.022,40.374],[-63.022,30.624]],"c":true}]},{"t":90,"s":[{"i":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"o":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"v":[[33.771,-24.375],[33.771,-14.625],[-33.772,24.374],[-33.772,14.624]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[33.771,24.374],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":15,"ty":4,"nm":"Layer 12 Outlines","parent":28,"sr":1,"ks":{"o":{"a":0,"k":60,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[141.06,276.493,0],"ix":2},"a":{"a":0,"k":[29.55,21.888,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"o":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"v":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":15,"s":[{"i":[[29.55,-21.888],[29.55,-12.138],[-9.3,9.138],[-9.3,-0.612]],"o":[[29.55,-21.888],[29.55,-12.138],[-9.3,9.138],[-9.3,-0.612]],"v":[[29.55,-21.888],[29.55,-12.138],[-9.3,9.138],[-9.3,-0.612]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[{"i":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"o":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"v":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":45,"s":[{"i":[[29.55,-21.888],[29.55,-12.138],[-9.3,9.138],[-9.3,-0.612]],"o":[[29.55,-21.888],[29.55,-12.138],[-9.3,9.138],[-9.3,-0.612]],"v":[[29.55,-21.888],[29.55,-12.138],[-9.3,9.138],[-9.3,-0.612]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"o":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"v":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[29.55,-21.888],[29.55,-12.138],[-9.3,9.138],[-9.3,-0.612]],"o":[[29.55,-21.888],[29.55,-12.138],[-9.3,9.138],[-9.3,-0.612]],"v":[[29.55,-21.888],[29.55,-12.138],[-9.3,9.138],[-9.3,-0.612]],"c":true}]},{"t":90,"s":[{"i":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"o":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"v":[[29.55,-21.888],[29.55,-12.138],[-29.55,21.888],[-29.55,12.138]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[29.55,21.888],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":16,"ty":4,"nm":"Shape Layer 7","parent":28,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[96.346,236.039,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"o":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"v":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":17,"ty":5,"nm":"1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 36","parent":28,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":75,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[130.655,-262.64,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":25,"s":[130.655,147.36,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":55,"s":[130.655,-162.64,0],"to":null,"ti":null},{"t":82,"s":[130.655,267.36,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":8,"f":"Avenir-Black","t":"1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0","j":0,"tr":0,"lh":18.3999996185303,"ls":0,"fc":[0.2772,0.3628,0.4428,1]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":18,"ty":4,"nm":"Shape Layer 6","parent":28,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[96.346,236.039,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"o":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"v":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":19,"ty":5,"nm":"1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 37","parent":28,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":75,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[50.655,-222.64,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":25,"s":[50.655,367.36,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":55.188,"s":[50.655,-212.64,0],"to":null,"ti":null},{"t":82,"s":[50.655,297.36,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":10,"f":"Avenir-Black","t":"1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0","j":0,"tr":0,"lh":18.3999996185303,"ls":0,"fc":[0.2772,0.3628,0.4428,1]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":20,"ty":4,"nm":"Shape Layer 4","parent":28,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[96.346,236.039,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"o":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"v":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":21,"ty":5,"nm":"1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 38","parent":28,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":75,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[75.655,-239.64,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":25,"s":[75.655,270.36,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":55,"s":[75.655,-229.64,0],"to":null,"ti":null},{"t":83,"s":[75.655,404.36,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":10,"f":"Avenir-Black","t":"1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0","j":0,"tr":0,"lh":18.3999996185303,"ls":0,"fc":[0.2772,0.3628,0.4428,1]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":22,"ty":4,"nm":"Shape Layer 2","parent":28,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[96.346,236.039,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"o":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"v":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":23,"ty":5,"nm":"1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0","parent":28,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":75,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[116.655,-254.64,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":25,"s":[116.655,166.36,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":55,"s":[116.655,-146.64,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":82.358,"s":[116.655,439.36,0],"to":null,"ti":null},{"t":83,"s":[116.655,276.36,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":12,"f":"Avenir-Black","t":"1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0","j":0,"tr":0,"lh":18.3999996185303,"ls":0,"fc":[0.2772,0.3628,0.4428,1]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":24,"ty":4,"nm":"Shape Layer 5","parent":28,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[96.346,236.039,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"o":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"v":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":25,"ty":5,"nm":"1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0","parent":28,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":75,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[61.655,-191.14,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":27,"s":[61.655,370.36,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":57,"s":[61.655,130.36,0],"to":null,"ti":null},{"t":87,"s":[61.655,510.36,0]}],"ix":2},"a":{"a":0,"k":[3.552,207.424,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":15,"f":"Avenir-Black","t":"1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0","j":0,"tr":0,"lh":22,"ls":0,"fc":[0.2772,0.3628,0.4428,1]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":26,"ty":4,"nm":"Shape Layer 3","parent":28,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[96.346,236.039,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"o":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"v":[[58.5,-80],[-52.5,-24.75],[-51,50.5],[57.5,-5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":27,"ty":5,"nm":"1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ","parent":28,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":75,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[95.655,-115.64,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[95.655,470.36,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":59,"s":[95.655,-113.64,0],"to":null,"ti":null},{"t":87,"s":[95.655,493.36,0]}],"ix":2},"a":{"a":0,"k":[3.552,207.424,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"t":{"d":{"k":[{"s":{"s":20,"f":"Avenir-Black","t":"1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1\r0\r1","j":0,"tr":0,"lh":25,"ls":0,"fc":[0.2772,0.3628,0.4428,1]},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[]},"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":28,"ty":4,"nm":"Virtual Screen Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[37]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[68]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":28,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[37]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":32,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":34,"s":[68]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":36,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":60,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[37]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66,"s":[68]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":68,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":83,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":85,"s":[37]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":87,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":89,"s":[68]},{"t":91,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[578.548,470.718,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[578.548,455.718,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[578.548,488.718,0],"to":null,"ti":null},{"t":90,"s":[578.548,470.718,0]}],"ix":2},"a":{"a":0,"k":[174.895,220.257,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-170.01,-31.108000000000004],[154.606,-218.427],[174.895,-217.122],[174.895,11.993],[169.186,32.591],[-152.062,218.193],[-174.894,216.73299999999998],[-174.894,-13.499]],"o":[[-162.083,-35.682],[163.625,-223.631],[174.895,-206.71],[174.895,22.698],[159.916,37.947],[-162.20800000000003,224.054],[-174.894,205.015],[-174.894,-22.651]],"v":[[-162.083,-35.682],[154.606,-218.427],[174.895,-206.71],[174.895,11.993],[159.916,37.947],[-152.062,218.193],[-174.894,205.015],[-174.894,-13.499]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.64,0.868,1,1],"ix":4},"o":{"a":0,"k":71,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[174.895,220.257],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":29,"ty":4,"nm":"Right Eye","parent":34,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[-10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[-10]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":36,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":60,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[-10]},{"t":66,"s":[0]}],"ix":10},"p":{"a":0,"k":[164.731,139.933,0],"ix":2},"a":{"a":0,"k":[14.266,14.618,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":3,"s":[100,19,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":6,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":30,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":33,"s":[100,19,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":36,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":60,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":63,"s":[100,19,100]},{"t":66,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-14.014999999999999,-2.374],[1.1320000000000006,14.368000000000002],[6.803000000000001,-14.368],[-3.193,-13.083]],"o":[[-11.344,12.697999999999999],[14.015,-3.7239999999999993],[-2.747,-13.182],[-11.647,-10.671]],"v":[[-13.104,2.767],[7.434,5.517],[-2.407,-13.224],[-3.531,-13.022]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.76,0.912,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[14.265,14.619],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":30,"ty":4,"nm":"Left Eye","parent":34,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[-40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[-40]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":36,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":60,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[-40]},{"t":66,"s":[0]}],"ix":10},"p":{"a":0,"k":[224.436,105.644,0],"ix":2},"a":{"a":0,"k":[8.685,14.424,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":3,"s":[100,19,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":6,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":30,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":33,"s":[100,19,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":36,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":60,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":63,"s":[100,19,100]},{"t":66,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.358,4.205],[1.0219999999999998,14.174],[3.7129999999999996,-14.174000000000001],[-3.9699999999999998,-11.488]],"o":[[-2.9859999999999998,13.731000000000002],[8.435,-1.9740000000000002],[-3.396,-12.118],[-8.434,-5.343]],"v":[[-5.327,7.118],[3.799,8.125],[-2.302,-12.435],[-4.579,-10.821]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.76,0.912,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[8.684,14.424],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":31,"ty":4,"nm":"Right Hand Outlines","parent":36,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[-2.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[-4.2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[-6.3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[-8.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[-10.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[-12.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[-14.7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[-16.8]},{"i":{"x":[0.833],"y":[1.02]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[-18.9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.016]},"t":10,"s":[-21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[-18.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[-15.8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[-13.2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[-10.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[-8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[-5.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[-2.8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[-0.2]},{"i":{"x":[0.833],"y":[0.933]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[2.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.35]},"t":20,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":23,"s":[3.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":24,"s":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[2.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[1.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":28,"s":[1]},{"i":{"x":[0.833],"y":[0.567]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[0.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.103]},"t":30,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[-2.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":32,"s":[-4.2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[-6.3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":34,"s":[-8.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[-10.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":36,"s":[-12.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":37,"s":[-14.7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":38,"s":[-16.8]},{"i":{"x":[0.833],"y":[1.02]},"o":{"x":[0.167],"y":[0.167]},"t":39,"s":[-18.9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.016]},"t":40,"s":[-21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":41,"s":[-18.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":42,"s":[-15.8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":43,"s":[-13.2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":44,"s":[-10.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":45,"s":[-8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":46,"s":[-5.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":47,"s":[-2.8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":48,"s":[-0.2]},{"i":{"x":[0.833],"y":[0.933]},"o":{"x":[0.167],"y":[0.167]},"t":49,"s":[2.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.35]},"t":50,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":51,"s":[4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":52,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":53,"s":[3.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":54,"s":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":55,"s":[2.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":56,"s":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":57,"s":[1.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":58,"s":[1]},{"i":{"x":[0.833],"y":[0.567]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[0.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.103]},"t":60,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":61,"s":[-2.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[-4.2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[-6.3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64,"s":[-8.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65,"s":[-10.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66,"s":[-12.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":67,"s":[-14.7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":68,"s":[-16.8]},{"i":{"x":[0.833],"y":[1.02]},"o":{"x":[0.167],"y":[0.167]},"t":69,"s":[-18.9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.016]},"t":70,"s":[-21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":71,"s":[-18.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72,"s":[-15.8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":73,"s":[-13.2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74,"s":[-10.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[-8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":76,"s":[-5.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":77,"s":[-2.8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":78,"s":[-0.2]},{"i":{"x":[0.833],"y":[0.933]},"o":{"x":[0.167],"y":[0.167]},"t":79,"s":[2.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.35]},"t":80,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":81,"s":[4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":82,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":83,"s":[3.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":84,"s":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":85,"s":[2.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":86,"s":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":87,"s":[1.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":88,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":89,"s":[0.5]},{"t":90,"s":[0]}],"ix":10},"p":{"a":0,"k":[8.806,109.872,0],"ix":2},"a":{"a":0,"k":[31.378,25.324,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.118,-19.508],[-8.385,-14.508],[10.232,-4.83],[-20.351,14.604],[-1.697,19.000999999999998]],"o":[[0.118,-19.508],[-8.385,-14.508],[0.4169999999999998,19.508000000000003],[-20.351,14.604],[20.351,-8.241000000000001]],"v":[[0.118,-19.508],[-8.385,-14.508],[5.325,7.339],[-20.351,14.604],[6.227,9.211]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[152.155,86.616],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[62.232,13.477],[-8.849999999999998,-29.746999999999996],[-43.553,-46.138],[-81.29,-33.581],[-60.214999999999996,14.573],[-44.379,19.624],[48.279,42.179],[70.752,47.768]],"o":[[62.232,13.477],[-38.236,-44.961999999999996],[-68.53,-47.769],[-73.982,0.7669999999999995],[-44.376,19.603],[-44.379,19.624],[48.279,42.179],[81.289,22.494]],"v":[[62.232,13.477],[-33.461,-42.489],[-48.794,-46.481],[-77.292,-14.791],[-44.376,19.603],[-44.379,19.624],[48.279,42.179],[75.94,35.324]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.76,0.912,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[81.539,58.63],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-7.774,6.286],[7.215,-5.136],[4.081,-6.518],[-10.933,5.135]],"o":[[-6.216,7.031],[5.657,-5.881],[2.499,-7.031],[-9.35,5.6499999999999995]],"v":[[-6.216,7.031],[7.215,-5.136],[2.499,-7.031],[-10.933,5.135]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[45.243,11.026],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.303,6.864000000000001],[12.988,-1.767],[4.859,-8.287],[-12.988,1.767]],"o":[[-0.444,10.4],[9.128,-5.303],[0.445,-10.4],[-8.574,3.88]],"v":[[-0.444,10.4],[12.988,-1.767],[0.445,-10.4],[-12.988,1.767]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[52.014,16.289],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.545,8.283999999999999],[12.944,1.911],[5.5360000000000005,-9.451999999999998],[-12.944,-1.91]],"o":[[-0.487,14.078],[9.885000000000002,-3.8829999999999996],[0.487,-14.078],[-7.894000000000001,2.716]],"v":[[-0.487,14.078],[12.944,1.911],[0.487,-14.078],[-12.944,-1.91]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[64.514,28.6],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.641,8.822],[9.058,1.651],[7.0920000000000005,-8.67],[-9.058,-1.649]],"o":[[-4.374,13.818],[8.791,-3.346],[4.373,-13.818],[-6.34,3.498]],"v":[[-4.374,13.818],[9.058,1.651],[4.373,-13.818],[-9.058,-1.649]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[73.085,44.329],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.128999999999998,18.854],[57.123,29.076],[-31.219,-27.823999999999998],[-57.123,-25.239]],"o":[[48.873,34.107],[37.709999999999994,16.249000000000002],[-47.423,-34.107],[-39.974,-19.67]],"v":[[48.873,34.107],[57.123,29.076],[-47.423,-34.107],[-57.123,-25.239]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[95.151,38.033],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.086,6.97],[9.331,-5.266],[4.086,-6.97],[-9.331,5.267]],"o":[[-4.086,6.97],[9.331,-5.266],[4.086,-6.97],[-9.331,5.267]],"v":[[-4.086,6.97],[9.331,-5.266],[4.086,-6.97],[-9.331,5.267]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[38.396,9.192],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.29400000000000004,-5.98],[-15.817,9.488],[-6.9559999999999995,0.7629999999999999],[15.817,-7.448]],"o":[[-4.213,-2.43],[-13.438,7.641],[9.826,2.806],[7.793000000000001,-9.488]],"v":[[-4.213,-2.43],[-15.817,9.488],[9.826,2.806],[15.817,-7.448]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.85,0.91,0.899,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[26.678,9.738],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":32,"ty":4,"nm":"Right Hand Support Outlines","parent":36,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[29.444,120.618,0],"ix":2},"a":{"a":0,"k":[30.384,39.289,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-9.993,-25.082],[2.692,-30.386],[-23.909000000000002,-32.05],[-12.152,22.194],[29.127,32.341],[17.363,-21.915999999999997],[0.056,-19.274],[18.253,0.6330000000000009],[9.988,28.394000000000002],[-18.252,2.6910000000000007]],"o":[[0.056,-19.274],[-11.98,-38.857],[-24.005,1.6670000000000016],[17.189999999999998,39.135],[29.221999999999998,-1.3750000000000018],[2.692,-30.386],[10.104999999999999,-13.479000000000001],[18.188,23.728],[-10.114,16.788],[-18.186999999999998,-20.407]],"v":[[0.056,-19.274],[2.692,-30.386],[-23.957,-15.192],[2.519,30.665],[29.174,15.484],[2.692,-30.386],[0.056,-19.274],[18.214,12.178],[-0.063,22.585],[-18.214,-8.854]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[24.255,39.193],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-12.600999999999999,-25.221],[0.083,-30.525],[-26.517000000000003,-32.189],[-14.761,22.055],[26.518,32.202],[14.754,-22.055],[-2.552,-19.413],[15.644,0.4939999999999998],[7.379,28.255000000000003],[-20.861,2.5519999999999996]],"o":[[-2.552,-19.413],[-14.589,-38.995999999999995],[-26.613,1.5280000000000022],[14.581,38.996],[26.613,-1.5140000000000011],[0.083,-30.525],[7.497,-13.618],[15.579,23.589],[-12.723,16.649],[-20.796,-20.546]],"v":[[-2.552,-19.413],[0.083,-30.525],[-26.565,-15.331],[-0.09,30.526],[26.565,15.345],[0.083,-30.525],[-2.552,-19.413],[15.605,12.039],[-2.672,22.446],[-20.823,-8.993]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.3091,0.5374,0.7509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[26.863,39.332],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.764,3.7949999999999995],[6.502,-1.232],[2.644,-4.212],[-10.753,1.232]],"o":[[-4.873,5.379],[4.612,-2.815],[0.623,-5.379],[-8.732,2.399]],"v":[[-4.873,5.379],[6.502,-1.232],[0.623,-5.379],[-10.753,1.232]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[33.366,10.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.55,24.652],[15.851,18.915],[15.965,17.135],[7.198,-15.612],[-16.01,-18.915],[4.6339999999999995,8.272]],"o":[[4.476,25.526],[15.926,18.041],[16.01,1.6609999999999996],[-4.635,-25.526],[-4.177000000000001,-9.001],[4.5889999999999995,23.746000000000002]],"v":[[4.476,25.526],[15.851,18.915],[15.968,16.198],[-4.635,-25.526],[-16.01,-18.915],[4.592,22.809]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[44.502,34.579],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.269,9.248999999999999],[1.872,5.098],[8.912,-2.2830000000000004],[-1.872,-2.607]],"o":[[-9.503,11.709],[6.106,2.638],[9.503,-9.218],[-2.464,4.327999999999999]],"v":[[-9.503,11.709],[1.872,5.098],[9.503,-9.218],[-1.872,-2.607]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[50.85,62.712],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.676,30.740000000000002],[9.032,29.392],[16.755,20.731],[4.968999999999999,-25.041000000000004],[-16.827,-29.392],[9.704,-0.3810000000000002]],"o":[[1.908,33.511],[13.8,26.622],[16.826999999999998,-4.500000000000002],[-9.702,-33.511],[-2.155000000000001,-20.921999999999997],[9.632000000000001,24.85]],"v":[[1.908,33.511],[9.032,29.392],[16.779,12.359],[-9.702,-33.511],[-16.827,-29.392],[9.656,16.478]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[43.691,38.418],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[10.104999999999999,-15.135],[-18.188,-22.063000000000002],[-10.115,15.131999999999998],[18.188,22.072000000000003]],"o":[[-9.993,-26.738],[-18.253,1.0350000000000001],[9.987,26.738],[18.253,-1.0229999999999997]],"v":[[0.056,-20.93],[-18.215,-10.51],[-0.064,20.929],[18.214,10.522]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.52,0.824,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[24.255,40.849],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.0570000000000004,-4.407],[-13.011,2.557],[-1.495,0.1459999999999999],[13.011,0.25]],"o":[[-5.886,-1.6],[-8.181999999999999,-0.2490000000000001],[5.886,4.407],[5.629999999999999,-4.012]],"v":[[-5.886,-1.6],[-13.011,2.557],[5.886,4.407],[13.011,0.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[20.977,4.657],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":33,"ty":4,"nm":"Robot Ear Outlines","parent":34,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[49.47,106.062,0],"ix":2},"a":{"a":0,"k":[85.519,70.536,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-15.623,8.628],[-8.629,-15.622],[15.623,-8.629],[8.628,15.622]],"o":[[-15.623,-8.629],[8.628,-15.622],[15.623,8.628],[-8.629,15.622]],"v":[[-15.623,-0.001],[-0.001,-15.622],[15.623,-0.001],[-0.001,15.622]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.42,0.7873,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[15.873,15.873],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[32.994,28.304],[35.348,27.904],[36.619,24.051000000000002],[-31.862,-27.345],[-34.958,-28.046999999999997],[-36.62,-23.671999999999997],[31.862,27.723]],"o":[[34.48,28.304],[36.877,25.866999999999997],[35.34,23.091],[-33.141,-28.304],[-36.878,-25.488],[-35.339,-22.711],[32.382999999999996,28.115]],"v":[[33.599,28.304],[35.917,27.147],[35.34,23.091],[-31.862,-27.345],[-35.918,-26.766],[-35.339,-22.711],[31.862,27.723]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.0936,0.1312,0.1664,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[50.91,44.518],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[33.601,25.217],[-33.601,-25.217]],"o":[[33.601,25.217],[-33.601,-25.217]],"v":[[33.601,25.217],[-33.601,-25.217]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0,0.5725,0.8941,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[50.91,44.708],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":34,"ty":4,"nm":"Robot Head Outlines","parent":36,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[-0.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[-1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[-1.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[-2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[-2.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[-3.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[-4]},{"i":{"x":[0.833],"y":[1.083]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[-4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.042]},"t":10,"s":[-5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[-4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[-2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[-1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[3]},{"i":{"x":[0.833],"y":[0.958]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.083]},"t":20,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":23,"s":[3.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":24,"s":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[2.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[1.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":28,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[0.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[-0.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":32,"s":[-1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[-1.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":34,"s":[-2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[-2.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":36,"s":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":37,"s":[-3.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":38,"s":[-4]},{"i":{"x":[0.833],"y":[1.083]},"o":{"x":[0.167],"y":[0.167]},"t":39,"s":[-4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.042]},"t":40,"s":[-5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":41,"s":[-4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":42,"s":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":43,"s":[-2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":44,"s":[-1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":45,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":46,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":47,"s":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":48,"s":[3]},{"i":{"x":[0.833],"y":[0.958]},"o":{"x":[0.167],"y":[0.167]},"t":49,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.083]},"t":50,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":51,"s":[4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":52,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":53,"s":[3.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":54,"s":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":55,"s":[2.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":56,"s":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":57,"s":[1.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":58,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[0.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":60,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":61,"s":[-0.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[-1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[-1.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64,"s":[-2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65,"s":[-2.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66,"s":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":67,"s":[-3.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":68,"s":[-4]},{"i":{"x":[0.833],"y":[1.083]},"o":{"x":[0.167],"y":[0.167]},"t":69,"s":[-4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.042]},"t":70,"s":[-5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":71,"s":[-4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72,"s":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":73,"s":[-2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74,"s":[-1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":76,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":77,"s":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":78,"s":[3]},{"i":{"x":[0.833],"y":[0.958]},"o":{"x":[0.167],"y":[0.167]},"t":79,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.083]},"t":80,"s":[5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":81,"s":[4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":82,"s":[4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":83,"s":[3.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":84,"s":[3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":85,"s":[2.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":86,"s":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":87,"s":[1.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":88,"s":[1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":89,"s":[0.5]},{"t":90,"s":[0]}],"ix":10},"p":{"a":0,"k":[84.898,64.367,0],"ix":2},"a":{"a":0,"k":[97.366,191.338,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-9.219,0.5559999999999992],[-5.090999999999999,-13.584999999999999],[9.219,-0.5569999999999995],[5.091,13.584999999999999]],"o":[[-9.218,-11.201],[5.0920000000000005,-7.7059999999999995],[9.219,11.201],[-5.091,7.7059999999999995]],"v":[[-9.218,-5.323],[0.001,-10.645],[9.219,5.322],[0,10.645]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.52,0.824,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[49.662,105.323],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[119.003,-11.620999999999999],[119.102,-46.267],[108.05,-12.009],[-34.925,29.445999999999998],[-119.052,-28.794],[-119.05,-29.447],[-106.83699999999999,6.890000000000001],[40.388,46.199]],"o":[[119.052,-28.753],[119.053,-29.136000000000003],[40.437999999999995,28.684],[-106.787,-10.624],[-119,-46.96],[-119.102,-11.282],[-34.974,46.961],[108.001,5.5070000000000014]],"v":[[119.052,-28.753],[119.102,-46.267],[85.957,1.288],[-82.369,2.991],[-119,-46.96],[-119.05,-29.447],[-82.419,20.506],[85.908,18.803]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.85,0.91,0.899,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[119.352,141.006],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-71.217,34.865],[8.843,43.85],[71.046,-3.9750000000000014],[66.70100000000001,-42.289],[49.007,-19.926000000000002],[-34.175000000000004,13.640999999999998]],"o":[[-32.69799999999999,50.46],[60.045,13.034],[71.24900000000001,-32.073],[58.875,-35.182],[3.0839999999999996,7.712999999999999],[-70.289,22.076999999999998]],"v":[[-71.249,45.929],[38.076,26.256],[71.218,-21.009],[59.029,-50.46],[29.304,-8.067],[-68.751,9.578]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[167.234,116.039],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[88.3,-57.753],[24.439,-85.102],[-52.959,-78.00699999999999],[-55.098,-69.925],[17.779000000000003,-77.42399999999999],[66.362,-28.783],[-17.455,-0.7989999999999995],[-66.037,-49.44],[-65.948,-70.37799999999999],[-117.96300000000001,-37.138],[-106.81200000000001,45.031],[40.41400000000001,84.339],[119.02699999999999,26.520000000000003],[118.553,-4.82],[109.21600000000001,-29.662]],"o":[[48.705,-79.307],[-28.764,-84.42200000000001],[-65.948,-70.37799999999999],[-20.181,-77.039],[65.574,-50.770999999999994],[20.504,-1.184000000000001],[-65.252,-27.451],[-55.098,-69.925],[-84.663,-58.635999999999996],[-119.07600000000001,26.86],[-34.949000000000005,85.102],[108.02600000000001,43.647000000000006],[118.83,2.7279999999999998],[112.19,-24.971],[100.403,-43.565]],"v":[[70.318,-67.542],[-1.808,-84.766],[-73.72,-65.701],[-43.11,-63.24],[41.676,-64.097],[43.433,-14.983],[-41.354,-14.126],[-43.11,-63.24],[-73.72,-65.701],[-119.025,8.694],[-82.394,58.646],[85.933,56.944],[119.076,9.388],[115.639,-14.045],[104.292,-37.43]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.8884,0.9316,0.9237,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[119.377,85.351],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[44.559000000000005,41.734],[118.779,-29.406999999999996],[108.025,-16.48],[-34.949999999999996,24.974999999999998],[-119.07600000000001,-33.268],[-118,-34.496],[-103.71799999999999,-3.8810000000000002],[-84.12899999999999,21.336999999999996]],"o":[[110.678,0.8160000000000025],[119.029,-33.607],[40.413000000000004,24.212],[-106.81299999999999,-15.097],[-118.613,-40.28],[-109.99900000000001,-12.211],[-98.768,2.6849999999999996],[-6.856000000000002,51.43299999999999]],"v":[[73.772,23.655],[119.077,-50.739],[85.932,-3.184],[-82.395,-1.481],[-119.025,-51.433],[-113.516,-22.006],[-100.344,0.595],[-55.863,32.346]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.76,0.912,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[119.327,162.992],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-20.343,-37.928],[-65.414,11.660999999999998],[20.342000000000002,37.927],[65.412,-11.66]],"o":[[-66.199,-10.329],[-17.618,38.313],[66.199,10.328],[17.616000000000003,-38.313]],"v":[[-43.272,-24.129],[-41.516,24.987],[43.271,24.128],[41.514,-24.986]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[119.539,46.239],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":35,"ty":4,"nm":"Left Ear Outlines","parent":34,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[195.976,71.515,0],"ix":2},"a":{"a":0,"k":[0.898,114.616,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-15.623,8.629],[-8.628,-15.623],[15.623,-8.629],[8.628,15.623]],"o":[[-15.623,-8.629],[8.628,-15.623],[15.623,8.629],[-8.628,15.623]],"v":[[-15.623,0],[0,-15.623],[15.623,0],[0,15.623]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.42,0.7873,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[33.923,15.873],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-11.97,48.978],[17.51,-47.282],[11.971,-48.978],[-17.51,47.282]],"o":[[-11.97,48.978],[17.51,-47.282],[11.971,-48.978],[-17.51,47.282]],"v":[[-11.97,48.978],[17.51,-47.282],[11.971,-48.978],[-17.51,47.282]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.0936,0.1312,0.1664,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[17.76,64.003],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-14.74,48.13],[14.74,-48.13]],"o":[[-14.74,48.13],[14.74,-48.13]],"v":[[-14.74,48.13],[14.74,-48.13]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0,0.5725,0.8941,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[17.76,64.003],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":36,"ty":4,"nm":"Body Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[473.333,462.041,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[473.333,480.041,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[473.333,443.041,0],"to":null,"ti":null},{"t":90,"s":[473.333,462.041,0]}],"ix":2},"a":{"a":0,"k":[106.295,130.101,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[88.925,-40.575],[-30.516000000000005,-73.468],[-60.943,-52.385],[23.855,-67.855],[87.194,-4.441000000000001],[-22.078,32.039],[-85.416,-31.372999999999998],[-65.769,-52.548],[-89.574,-37.31],[-103.629,8.843],[-89.145,41.03],[36.169,73.456],[101.287,28.023000000000003],[106.045,5.34],[99.936,-20.006]],"o":[[27.120999999999995,-74.12299999999999],[-65.769,-52.548],[-25.633,-67.354],[86.169,-33.108999999999995],[27.41,31.54],[-84.39099999999999,-2.7060000000000013],[-60.943,-52.385],[-77.32600000000001,-45.229],[-106.045,-5.100999999999999],[-99.57,28.323],[-29.79699999999999,74.123],[91.944,39.887],[105.104,10.399000000000001],[103.897,-12.518],[96.802,-25.86]],"v":[[67.826,-52.028],[-69.221,-50.469],[-55.525,-49.364],[55.012,-50.482],[57.302,13.548],[-53.235,14.667],[-55.525,-49.364],[-69.221,-50.47],[-98.095,-20.647],[-102.598,14.798],[-71.326,50.966],[76.012,49.476],[104.108,15.755],[105.092,-2.582],[99.768,-20.32]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.85,0.91,0.899,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[106.295,74.373],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[77.053,39.938],[103.321,-74.837],[91.16499999999999,-50.679],[-30.591,-16.434000000000005],[-100.383,-62.257000000000005],[-79.813,30.028],[-69.526,49.959999999999994],[26.924000000000003,74.92099999999999]],"o":[[79.216,30.488],[100.50999999999999,-62.557],[35.373999999999995,-17.101],[-89.95500000000001,-49.535000000000004],[-103.321,-75.435],[-77.552,40.17],[-23.841,75.435],[69.86,49.08]],"v":[[79.216,30.488],[103.321,-74.837],[75.217,-41.08],[-72.12,-39.59],[-103.321,-75.435],[-79.813,30.028],[-55.802,57.614],[57.587,56.467]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.64,0.868,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[107.089,164.858],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-26.523000000000003,-49.446],[-85.28,15.202000000000002],[26.521,49.447],[85.279,-15.200999999999997]],"o":[[-86.305,-13.465],[-22.968000000000004,49.947],[86.305,13.467000000000002],[22.965999999999998,-49.947]],"v":[[-56.414,-31.456],[-54.124,32.575],[56.412,31.457],[54.123,-32.574]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.8884,0.9316,0.9237,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[107.184,56.599],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[22.194999999999997,30.228],[76.886,-22.232999999999997],[70.188,-13.481],[-23.512999999999998,12.874000000000002],[-77.223,-22.391],[-74.265,-12.565999999999999],[-47.738,16.364]],"o":[[70.80199999999999,0.20199999999999818],[77.38,-22.622],[27.252999999999997,12.36],[-69.198,-12.6],[-77.405,-24.580999999999996],[-57.74,6.582],[-7.4410000000000025,32.532000000000004]],"v":[[43.751,16.912],[79.484,-31.813],[57.916,-6.094],[-55.474,-4.947],[-79.484,-32.532],[-62.279,1.322],[-31.751,22.777]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.52,0.824,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[106.761,227.42],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":37,"ty":4,"nm":"Left Hand Supp Outlines","parent":36,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[188.548,61.842,0],"ix":2},"a":{"a":0,"k":[30.384,39.289,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-9.993,-25.083],[2.692,-30.387],[-23.909000000000002,-32.051],[-12.152,22.193],[29.127,32.341],[17.363,-21.917],[0.056,-19.275],[18.253,0.6319999999999997],[9.988,28.393],[-18.252,2.6910000000000007]],"o":[[0.056,-19.275],[-11.98,-38.858000000000004],[-24.005,1.6660000000000021],[17.189999999999998,39.134],[29.221999999999998,-1.3750000000000018],[2.692,-30.387],[10.104999999999999,-13.479999999999999],[18.188,23.727],[-10.114,16.787],[-18.186999999999998,-20.407]],"v":[[0.056,-19.275],[2.692,-30.387],[-23.957,-15.193],[2.519,30.664],[29.174,15.484],[2.692,-30.387],[0.056,-19.275],[18.214,12.177],[-0.063,22.584],[-18.214,-8.854]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[24.255,39.193],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-12.600999999999999,-25.221],[0.084,-30.525],[-26.517000000000003,-32.189],[-14.761,22.055],[26.519,32.202],[14.754999999999999,-22.055],[-2.552,-19.413],[15.644,0.4939999999999998],[7.380000000000001,28.255000000000003],[-20.86,2.5519999999999996]],"o":[[-2.552,-19.413],[-14.588000000000001,-38.995999999999995],[-26.613,1.5280000000000022],[14.581,38.996],[26.613999999999997,-1.5140000000000011],[0.084,-30.525],[7.497,-13.618],[15.579,23.589],[-12.722,16.649],[-20.794999999999998,-20.546]],"v":[[-2.552,-19.413],[0.084,-30.525],[-26.565,-15.331],[-0.09,30.526],[26.566,15.345],[0.084,-30.525],[-2.552,-19.413],[15.605,12.039],[-2.671,22.446],[-20.822,-8.993]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[26.863,39.332],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.764,3.7949999999999995],[6.502,-1.232],[2.644,-4.212],[-10.753,1.232]],"o":[[-4.873,5.379],[4.612,-2.815],[0.623,-5.379],[-8.732,2.399]],"v":[[-4.873,5.379],[6.502,-1.232],[0.623,-5.379],[-10.753,1.232]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[33.366,10.286],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.55,24.652],[15.851,18.915],[15.966,17.135],[7.198,-15.612],[-16.01,-18.915],[4.6339999999999995,8.272]],"o":[[4.476,25.526],[15.926,18.041],[16.01,1.6609999999999996],[-4.635,-25.526],[-4.177000000000001,-9.001],[4.59,23.746000000000002]],"v":[[4.476,25.526],[15.851,18.915],[15.968,16.198],[-4.635,-25.526],[-16.01,-18.915],[4.592,22.809]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[44.503,34.579],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.269,9.248999999999999],[1.872,5.098],[8.912,-2.2830000000000004],[-1.872,-2.607]],"o":[[-9.503,11.709],[6.106,2.638],[9.503,-9.218],[-2.464,4.327999999999999]],"v":[[-9.503,11.709],[1.872,5.098],[9.503,-9.218],[-1.872,-2.607]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[50.85,62.712],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.676,30.740000000000002],[9.031,29.392],[16.755,20.731],[4.968,-25.041000000000004],[-16.828,-29.392],[9.704,-0.3810000000000002]],"o":[[1.908,33.511],[13.799,26.622],[16.826999999999998,-4.500000000000002],[-9.703,-33.511],[-2.155999999999999,-20.921999999999997],[9.632000000000001,24.85]],"v":[[1.908,33.511],[9.031,29.392],[16.779,12.359],[-9.703,-33.511],[-16.828,-29.392],[9.656,16.478]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[43.691,38.418],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[10.104999999999999,-15.135],[-18.186999999999998,-22.063000000000002],[-10.114,15.131999999999998],[18.188,22.072000000000003]],"o":[[-9.993,-26.738],[-18.252,1.0350000000000001],[9.988,26.738],[18.253,-1.0229999999999997]],"v":[[0.056,-20.93],[-18.214,-10.51],[-0.063,20.929],[18.214,10.522]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[24.255,40.849],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.0570000000000004,-4.407],[-13.011,2.557],[-1.495,0.1459999999999999],[13.011,0.25]],"o":[[-5.886,-1.6],[-8.181999999999999,-0.2490000000000001],[5.886,4.407],[5.629999999999999,-4.012]],"v":[[-5.886,-1.6],[-13.011,2.557],[5.886,4.407],[13.011,0.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[20.977,4.657],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":38,"ty":4,"nm":"Left Hand Outlines","parent":36,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":1,"s":[0.9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[1.8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[2.7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[3.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[5.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[6.3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[7.2]},{"i":{"x":[0.833],"y":[1.278]},"o":{"x":[0.167],"y":[0.167]},"t":9,"s":[8.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.064]},"t":10,"s":[9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[5.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":12,"s":[1.2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[-2.7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[-6.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":15,"s":[-10.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":16,"s":[-14.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[-18.3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[-22.2]},{"i":{"x":[0.833],"y":[0.981]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[-26.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.025]},"t":20,"s":[-30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[-27]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":22,"s":[-24]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":23,"s":[-21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":24,"s":[-18]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":25,"s":[-15]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[-12]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[-9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":28,"s":[-6]},{"i":{"x":[0.833],"y":[0.892]},"o":{"x":[0.167],"y":[0.167]},"t":29,"s":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.361]},"t":30,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[0.9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":32,"s":[1.8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[2.7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":34,"s":[3.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":36,"s":[5.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":37,"s":[6.3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":38,"s":[7.2]},{"i":{"x":[0.833],"y":[1.278]},"o":{"x":[0.167],"y":[0.167]},"t":39,"s":[8.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.064]},"t":40,"s":[9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":41,"s":[5.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":42,"s":[1.2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":43,"s":[-2.7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":44,"s":[-6.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":45,"s":[-10.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":46,"s":[-14.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":47,"s":[-18.3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":48,"s":[-22.2]},{"i":{"x":[0.833],"y":[0.981]},"o":{"x":[0.167],"y":[0.167]},"t":49,"s":[-26.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.025]},"t":50,"s":[-30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":51,"s":[-27]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":52,"s":[-24]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":53,"s":[-21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":54,"s":[-18]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":55,"s":[-15]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":56,"s":[-12]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":57,"s":[-9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":58,"s":[-6]},{"i":{"x":[0.833],"y":[0.892]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[-3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.361]},"t":60,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":61,"s":[0.9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[1.8]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[2.7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64,"s":[3.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":65,"s":[4.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66,"s":[5.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":67,"s":[6.3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":68,"s":[7.2]},{"i":{"x":[0.833],"y":[1.278]},"o":{"x":[0.167],"y":[0.167]},"t":69,"s":[8.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.064]},"t":70,"s":[9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":71,"s":[5.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":72,"s":[1.2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":73,"s":[-2.7]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":74,"s":[-6.6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[-10.5]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":76,"s":[-14.4]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":77,"s":[-18.3]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":78,"s":[-22.2]},{"i":{"x":[0.833],"y":[0.981]},"o":{"x":[0.167],"y":[0.167]},"t":79,"s":[-26.1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[-0.025]},"t":80,"s":[-30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":81,"s":[-27]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":82,"s":[-24]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":83,"s":[-21]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":84,"s":[-18]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":85,"s":[-15]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":86,"s":[-12]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":87,"s":[-9]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":88,"s":[-6]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":89,"s":[-3]},{"t":90,"s":[0]}],"ix":10},"p":{"a":0,"k":[186.522,48.904,0],"ix":2},"a":{"a":0,"k":[20.629,32.608,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.172,-19.393],[-10.127,-13.562],[9.370999999999999,-5.811999999999999],[-19.095,16.611],[-0.09199999999999964,19.102]],"o":[[-2.172,-19.393],[-10.127,-13.562],[2.0629999999999997,19.393],[-19.095,16.611],[19.094,-10.225999999999999]],"v":[[-2.172,-19.393],[-10.127,-13.562],[5.717,6.791],[-19.095,16.611],[6.803,8.561]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[157.914,74.271],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[63.833,7.689],[-11.247,-28.141999999999996],[-47.428,-40.946000000000005],[-83.704,-24.646],[-57.876999999999995,21.136000000000003],[-41.613,24.563],[52.848,37.654],[75.771,40.946]],"o":[[63.833,7.689],[-42.019,-40.312999999999995],[-72.443,-40.048],[-72.967,8.789],[-41.611,24.542],[-41.613,24.563],[52.848,37.654],[83.70400000000001,14.737000000000002]],"v":[[63.833,7.689],[-37.019,-38.336],[-52.677,-40.758],[-77.83,-6.356],[-41.611,24.542],[-41.613,24.563],[52.848,37.654],[79.677,28.042]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.76,0.912,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[83.954,53.02],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.93,6.851],[6.83,-6.026],[3.572,-7.084],[-10.189,6.026]],"o":[[-5.305,7.435],[5.205,-6.609999999999999],[1.946,-7.435],[-8.563,6.378]],"v":[[-5.305,7.435],[6.83,-6.026],[1.946,-7.435],[-10.189,6.026]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[43.428,10.07],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.589,7.263999999999999],[12.742,-3.07],[3.998,-8.735999999999999],[-12.742,3.069]],"o":[[0.608,10.392],[8.545000000000002,-6.198],[-0.607,-10.392],[-8.137,4.726]],"v":[[0.608,10.392],[12.742,-3.07],[-0.607,-10.392],[-12.742,3.069]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[50.866,14.437],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.691,8.599999999999998],[13.071,0.594],[4.555,-9.962],[-13.071,-0.594]],"o":[[0.936,14.056],[9.443999999999999,-4.861],[-0.936,-14.056],[-7.58,3.4979999999999998]],"v":[[0.936,14.056],[13.071,0.594],[-0.936,-14.056],[-13.071,-0.594]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[64.544,25.423],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.727,9.245000000000001],[9.178,0.728],[6.181,-9.341999999999999],[-9.178,-0.728]],"o":[[-2.957,14.189],[8.408000000000001,-4.216],[2.957,-14.189],[-5.955000000000001,4.119000000000001]],"v":[[-2.957,14.189],[9.178,0.728],[2.957,-14.189],[-9.178,-0.728]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[74.658,40.207],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[23.725,16.598],[59.572,23.235],[-34.061,-24.459000000000003],[-59.572,-19.273]],"o":[[51.872,29.074],[38.964,12.433],[-50.817,-29.074],[-41.94800000000001,-15.463]],"v":[[51.872,29.074],[59.572,23.235],[-50.817,-29.074],[-59.572,-19.273]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[96.17,31.643],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.362,7.346],[8.752,-6.18],[3.361,-7.346],[-8.752,6.182]],"o":[[-3.362,7.346],[8.752,-6.18],[3.361,-7.346],[-8.752,6.182]],"v":[[-3.362,7.346],[8.752,-6.18],[3.361,-7.346],[-8.752,6.182]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9174,0.9426,0.938,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[36.601,8.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1,-6.325],[-14.883,10.63],[-6.945,1.056],[14.883,-9.411]],"o":[[-4.54,-2.398],[-12.701999999999998,8.552000000000001],[9.956,1.395],[6.693,-10.629999999999999]],"v":[[-4.54,-2.398],[-14.883,10.63],[9.956,1.395],[14.883,-9.411]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.85,0.91,0.899,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[25.101,10.881],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":39,"ty":4,"nm":"Virtual Beam Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[37]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[68]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":8,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":28,"s":[37]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":32,"s":[68]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[47]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":34,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":56,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":58,"s":[37]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":60,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[68]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":64,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":82,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":84,"s":[37]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":86,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":88,"s":[68]},{"t":90,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[608.24,705.207,0],"ix":2},"a":{"a":0,"k":[103.04,138.08,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[106.157,184.979],[107.64,185.749],[109.205,184.337],[125.28,54.46],[61.7,90.96]],"o":[[106.157,184.979],[107.64,185.749],[109.205,184.337],[125.28,54.46],[61.7,90.96]],"v":[[106.157,184.979],[107.64,185.749],[109.205,184.337],[125.28,54.46],[61.7,90.96]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[{"i":[[106.344,197.979],[108.065,198.968],[109.017,197.337],[134.53,22.21],[47.95,72.71]],"o":[[106.344,197.979],[108.065,198.968],[109.017,197.337],[134.53,22.21],[47.95,72.71]],"v":[[106.344,197.979],[108.065,198.968],[109.017,197.337],[134.53,22.21],[47.95,72.71]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[106.469,174.416],[108.696,174.621],[109.392,173.212],[119.78,75.335],[76.325,99.085]],"o":[[106.469,174.416],[108.696,174.621],[109.392,173.212],[119.78,75.335],[76.325,99.085]],"v":[[106.469,174.416],[108.696,174.621],[109.392,173.212],[119.78,75.335],[76.325,99.085]],"c":true}]},{"t":90,"s":[{"i":[[106.157,184.979],[107.64,185.749],[109.205,184.337],[125.28,54.46],[61.7,90.96]],"o":[[106.157,184.979],[107.64,185.749],[109.205,184.337],[125.28,54.46],[61.7,90.96]],"v":[[106.157,184.979],[107.64,185.749],[109.205,184.337],[125.28,54.46],[61.7,90.96]],"c":true}]}],"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.76,0.912,1,0.5,0.6136,0.8117,0.9264,1,0.4819,0.7202,0.8581],"ix":9}},"s":{"a":0,"k":[84.5,78],"ix":5},"e":{"a":0,"k":[121.5,175],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[-5.2,-46.96],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":40,"ty":4,"nm":"Computer Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[514.21,659.983,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[514.21,672.983,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[514.21,648.983,0],"to":null,"ti":null},{"t":90,"s":[514.21,659.983,0]}],"ix":2},"a":{"a":0,"k":[289.267,177.11,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.935,-0.358],[0.515,0.649],[-0.935,0.358],[-0.517,-0.649]],"o":[[0.935,0.358],[-0.517,0.649],[-0.935,-0.358],[0.515,-0.649]],"v":[[0.935,0],[-0.001,0.649],[-0.935,0],[-0.001,-0.649]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[382.794,222.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.77,-1.062],[1.529,1.923],[-2.77,1.062],[-1.53,-1.923]],"o":[[2.77,1.062],[-1.53,1.923],[-2.77,-1.062],[1.529,-1.923]],"v":[[2.77,0],[0,1.923],[-2.77,0],[0,-1.923]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.76,0.912,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[382.793,222.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.395,-2.069],[2.98,3.746],[-5.395,2.069],[-2.979,-3.746]],"o":[[5.395,2.069],[-2.979,3.746],[-5.395,-2.069],[2.98,-3.746]],"v":[[5.395,0],[0,3.746],[-5.395,0],[0,-3.746]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.0314,0.3412,0.6275,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[382.793,222.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177,177],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.395,-2.069],[2.98,3.746],[-5.395,2.069],[-2.979,-3.746]],"o":[[5.395,2.069],[-2.979,3.746],[-5.395,-2.069],[2.98,-3.746]],"v":[[5.395,0],[0,3.746],[-5.395,0],[0,-3.746]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.2695,0.3527,0.4305,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[382.793,222.125],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[263.003,-49.967999999999996],[85.949,-151.587],[82.31400000000001,-152.528],[-260.675,45.507],[-263.002,50.208],[-87.029,151.227],[-81.997,152.529],[260.703,-45.321]],"o":[[260.703,-51.296],[84.32,-152.528],[80.685,-151.587],[-263.002,46.849999999999994],[-260.675,51.551],[-84.77499999999999,152.529],[-79.742,151.227],[263.003,-46.649]],"v":[[260.703,-51.296],[85.949,-151.587],[80.685,-151.587],[-260.675,45.507],[-260.675,51.551],[-87.029,151.227],[-79.742,151.227],[260.703,-45.321]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.76,0.912,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[279.74,161.648],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[71.82400000000001,-167.647],[-286.469,39.225],[-288.82,43.976000000000006],[-78.164,165.627],[-70.353,167.64700000000002],[285.48,-37.786],[288.82,-44.536],[78.656,-165.879]],"o":[[68.763,-165.879],[-288.82,40.582],[-286.469,45.334],[-74.665,167.64700000000002],[-66.853,165.627],[288.82,-39.715],[285.48,-46.465],[75.595,-167.647]],"v":[[68.763,-165.879],[-286.469,39.225],[-286.469,45.334],[-78.164,165.627],[-66.853,165.627],[285.48,-37.786],[285.48,-46.465],[78.656,-165.879]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.95,0.95,0.95,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[289.348,167.897],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-288.891,38.394999999999996],[-288.64,50.464],[-79.592,171.186],[-69.695,173.746],[284.932,-31.007],[288.346,-40.901],[289.016,-56.797000000000004],[83.761,-171.003],[73.231,-173.745],[-283.25,25.451],[-287.453,26.878]],"o":[[-289.016,46.943],[-283.709,53.311],[-75.158,173.746],[-65.262,171.186],[288.29900000000004,-32.951],[288.542,-50.21],[284.966,-59.024],[79.015,-173.67899999999997],[68.425,-171.177],[-286.092,26.969],[-288.69,31.674]],"v":[[-288.928,40.919],[-283.709,53.311],[-79.592,171.186],[-65.262,171.186],[284.932,-31.007],[288.421,-44.459],[284.966,-59.024],[83.761,-171.003],[68.425,-171.177],[-283.25,25.451],[-288.113,29.435]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0.9,0.9,0.9,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[289.266,180.224],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true},{"ddd":0,"ind":41,"ty":4,"nm":"Computer Shadow Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[513.975,772.04,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[513.975,736.04,0],"to":null,"ti":null},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[513.975,799.04,0],"to":null,"ti":null},{"t":90,"s":[513.975,772.04,0]}],"ix":2},"a":{"a":0,"k":[294.24,190.92,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"ef":[{"ty":29,"nm":"Gaussian Blur","np":5,"mn":"ADBE Gaussian Blur 2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Blurriness","mn":"ADBE Gaussian Blur 2-0001","ix":1,"v":{"a":0,"k":55.8,"ix":1}},{"ty":7,"nm":"Blur Dimensions","mn":"ADBE Gaussian Blur 2-0002","ix":2,"v":{"a":0,"k":1,"ix":2}},{"ty":7,"nm":"Repeat Edge Pixels","mn":"ADBE Gaussian Blur 2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-123.508,200.676],[340.581,-74.934],[123.508,-207.993],[-330.826,65.178]],"o":[[-123.508,200.676],[340.581,-74.934],[123.508,-207.993],[-330.826,65.178]],"v":[[-123.508,200.676],[340.581,-74.934],[123.508,-207.993],[-330.826,65.178]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":11,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false,"_render":true},{"ty":"tr","p":{"a":0,"k":[294.24,190.92],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform","_render":true}],"nm":"Group 1","np":2,"cix":2,"bm":1,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true}],"ip":0,"op":91,"st":0,"bm":0,"completed":true}],"markers":[],"chars":[{"ch":"1","size":20,"style":"Black","w":59.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[28.8,0],[43.2,0],[43.2,-70.8],[29.2,-70.8],[6.1,-51.3],[14.6,-41.5],[28.8,-54]],"o":[[28.8,0],[43.2,0],[43.2,-70.8],[29.2,-70.8],[6.1,-51.3],[14.6,-41.5],[28.8,-54]],"v":[[28.8,0],[43.2,0],[43.2,-70.8],[29.2,-70.8],[6.1,-51.3],[14.6,-41.5],[28.8,-54]],"c":true},"ix":2},"nm":"1","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"p":{"k":[0,0],"a":0},"s":{"k":[20,20],"a":0},"a":{"k":[0,0],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0},"ty":"tr","_render":true}],"nm":"1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"no","_render":true}],"ip":0,"op":99999,"st":0,"sr":1,"ks":{"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"a":{"k":[0,0],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0}}},"fFamily":"Avenir"},{"ch":"\r","size":20,"style":"Black","w":0,"fFamily":"Avenir"},{"ch":"0","size":20,"style":"Black","w":59.2,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.6830000000000003,-26.933],[6.583,-14.333],[13.200000000000001,-4.383],[24.333000000000002,1.2],[39.2,0.08300000000000018],[48.683,-7.266000000000001],[53.983,-18.266000000000002],[55.9,-31.2],[55.516,-43.866],[52.616,-56.466],[46,-66.41600000000001],[34.866,-72],[20,-70.88300000000001],[10.516,-63.533],[5.216,-52.533],[3.3,-39.6]],"o":[[5.216,-18.266000000000002],[10.516,-7.266000000000001],[20,0.08300000000000018],[34.866,1.2],[46,-4.383],[52.616,-14.333],[55.516,-26.933],[55.9,-39.6],[53.983,-52.533],[48.683,-63.533],[39.2,-70.88300000000001],[24.333000000000002,-72],[13.200000000000001,-66.41600000000001],[6.583,-56.466],[3.6830000000000003,-43.866],[3.3,-31.2]],"v":[[4.45,-22.6],[8.55,-10.8],[16.6,-2.15],[29.6,1.2],[42.6,-2.15],[50.65,-10.8],[54.75,-22.6],[55.9,-35.4],[54.75,-48.2],[50.65,-60],[42.6,-68.65],[29.6,-72],[16.6,-68.65],[8.55,-60],[4.45,-48.2],[3.3,-35.4]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[18.383,-39.5],[19.165999999999997,-47.2],[21.75,-54.033],[26.866,-58.2],[34.366,-57.366],[38.565999999999995,-52],[40.483,-44.7],[40.9,-37.266],[40.815999999999995,-31.3],[40.032999999999994,-23.599999999999998],[37.433,-16.766],[32.266,-12.6],[24.75,-13.433],[20.633,-18.8],[18.716,-26.099999999999998],[18.3,-33.533]],"o":[[18.716,-44.7],[20.633,-52],[24.75,-57.366],[32.266,-58.2],[37.433,-54.033],[40.032999999999994,-47.2],[40.815999999999995,-39.5],[40.9,-33.533],[40.483,-26.099999999999998],[38.565999999999995,-18.8],[34.366,-13.433],[26.866,-12.6],[21.75,-16.766],[19.165999999999997,-23.599999999999998],[18.383,-31.3],[18.3,-37.266]],"v":[[18.55,-42.1],[19.9,-49.6],[23.25,-55.7],[29.6,-58.2],[35.9,-55.7],[39.3,-49.6],[40.65,-42.1],[40.9,-35.4],[40.65,-28.7],[39.3,-21.2],[35.9,-15.1],[29.6,-12.6],[23.25,-15.1],[19.9,-21.2],[18.55,-28.7],[18.3,-35.4]],"c":true},"ix":2},"nm":"0","mn":"ADBE Vector Shape - Group","hd":false,"_render":true},{"p":{"k":[0,0],"a":0},"s":{"k":[20,20],"a":0},"a":{"k":[0,0],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0},"ty":"tr","_render":true}],"nm":"0","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false,"_render":true},{"ty":"no","_render":true}],"ip":0,"op":99999,"st":0,"sr":1,"ks":{"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"a":{"k":[0,0],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0}}},"fFamily":"Avenir"}],"__complete":true} \ No newline at end of file diff --git a/client/tsconfig.json b/client/tsconfig.json index 500f241e..c944fe39 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -15,7 +15,8 @@ "outDir": "./dist", // 번들된 파일을 dist 폴더에 출력 "noEmit": false, // emit을 true로 설정해야 실제 파일이 생성됨 "isolatedModules": true, // 모듈로 분리된 파일을 처리 - "skipDefaultLibCheck": true // 기본 라이브러리 파일 체크 건너뛰기 + "skipDefaultLibCheck": true, // 기본 라이브러리 파일 체크 건너뛰기 + "resolveJsonModule": true }, "include": [ "src/**/*", // 모든 src 파일 포함 From a9d314ac79eb35fa9db5adea13921af503a8ca3e Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 16:19:38 +0900 Subject: [PATCH 004/110] =?UTF-8?q?fix=20:=20aiPending=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20useEffect=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/hooks/useUpload.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/src/hooks/useUpload.ts b/client/src/hooks/useUpload.ts index 95bf5774..8b33f631 100644 --- a/client/src/hooks/useUpload.ts +++ b/client/src/hooks/useUpload.ts @@ -1,6 +1,6 @@ import { MIN_TEXT_UPLOAD_LIMIT } from "@/constants/textUploadLimit"; import { useConnectionStore } from "@/store/useConnectionStore"; -import { useState } from "react"; +import { useEffect, useState } from "react"; export default function useUpload() { const [content, setContent] = useState(""); @@ -12,9 +12,11 @@ export default function useUpload() { const buttonAvailability = role === "owner"; - socket?.on("aiPending", (response) => { - setAiProcessing(response.status); - }); + useEffect(() => { + socket?.on("aiPending", (response) => { + setAiProcessing(response.status); + }); + }, [socket]); function handleAiProcessButton() { if (content.length <= MIN_TEXT_UPLOAD_LIMIT || !buttonAvailability) return; From b734c3d1062852da37332af125516afc019b369d Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 16:22:15 +0900 Subject: [PATCH 005/110] =?UTF-8?q?refactor=20:=20sharedSlice=EC=97=90=20?= =?UTF-8?q?=EC=B5=9C=EA=B7=BC=20=EB=B0=A9=EB=AC=B8=ED=95=9C=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B8=EB=93=9C=EB=A7=B5=20=EC=B6=94=EA=B0=80=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Sidebar/Overview.tsx | 6 ++---- client/src/store/createSharedSlice.ts | 5 +++++ client/src/store/useConnectionStore.ts | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/client/src/components/Sidebar/Overview.tsx b/client/src/components/Sidebar/Overview.tsx index ea4a0849..5c539b7c 100644 --- a/client/src/components/Sidebar/Overview.tsx +++ b/client/src/components/Sidebar/Overview.tsx @@ -1,8 +1,6 @@ -import aiIcon from "@/assets/ai.png"; import OverviewButton from "@/components/Sidebar/OverviewButton"; import useSection from "@/hooks/useSection"; import { useNavigate } from "react-router-dom"; -import { getLatestMindMap } from "@/utils/localstorage"; import useModal from "@/hooks/useModal"; import { createPortal } from "react-dom"; import LatestMindMapModal from "@/components/Sidebar/LatestMindMapModal"; @@ -20,6 +18,7 @@ export default function Overview() { const { getmode, handleViewMode } = useSection(); const socket = useConnectionStore((state) => state.socket); const createConnection = useConnectionStore((state) => state.createConnection); + const latestMindMap = useConnectionStore((state) => state.latest); const { open, closeModal, openModal } = useModal(); const [selectMode, setSelcetMode] = useState("listview"); @@ -29,7 +28,6 @@ export default function Overview() { return; } - const latestMindMap = getLatestMindMap(); if (!latestMindMap) { createConnection(navigate, mode); return; @@ -40,7 +38,7 @@ export default function Overview() { //비회원은 삭제를 안한다 //setConnection function navigateToLatestMindap() { - navigate(`/mindmap/${getLatestMindMap()}?mode=${selectMode}`); + navigate(`/mindmap/${latestMindMap}?mode=${selectMode}`); closeModal(); } diff --git a/client/src/store/createSharedSlice.ts b/client/src/store/createSharedSlice.ts index 80f78bf2..1edaa353 100644 --- a/client/src/store/createSharedSlice.ts +++ b/client/src/store/createSharedSlice.ts @@ -3,9 +3,12 @@ import { NavigateFunction } from "react-router-dom"; import { StateCreator } from "zustand"; export interface SharedSlice { + latest: string; createConnection: (navigate: NavigateFunction, targetMode: string) => void; + updateLatestMindMap: (connectionId: string) => void; } export const createSharedSlice: StateCreator = (set, get) => ({ + latest: "", createConnection: async (navigate: NavigateFunction, targetMode: string) => { try { const newMindMapConnectionId = await get().handleConnection(); @@ -17,4 +20,6 @@ export const createSharedSlice: StateCreator set({ latest: connectionId }), }); diff --git a/client/src/store/useConnectionStore.ts b/client/src/store/useConnectionStore.ts index 61158e11..e4f289a1 100644 --- a/client/src/store/useConnectionStore.ts +++ b/client/src/store/useConnectionStore.ts @@ -24,6 +24,7 @@ export const useConnectionStore = create()( token: state.token, ownedMindMap: state.ownedMindMap, ownedMindMapForGuest: state.ownedMindMapForGuest, + latest: state.latest, }; }, storage: createJSONStorage(() => localStorage), From f0e4b6259f2432e317cf7d4f40818dfd4770c95c Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 16:22:31 +0900 Subject: [PATCH 006/110] =?UTF-8?q?remove=20:=20=EB=A1=9C=EC=BB=AC?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80=20=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=20=EC=A0=84=EC=97=AD=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EC=96=B4=EB=A1=9C=20=EC=9D=B4=EA=B4=80?= =?UTF-8?q?=ED=95=A8=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/utils/localstorage.ts | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 client/src/utils/localstorage.ts diff --git a/client/src/utils/localstorage.ts b/client/src/utils/localstorage.ts deleted file mode 100644 index a9da02c9..00000000 --- a/client/src/utils/localstorage.ts +++ /dev/null @@ -1,23 +0,0 @@ -export const getToken = () => localStorage.getItem("Bearer"); -export const removeToken = () => localStorage.removeItem("Bearer"); -export const setToken = (token: string) => localStorage.setItem("Bearer", token); - -export const setOwner = (mindMapId: string) => { - let mindmaps: string[] = JSON.parse(localStorage.getItem("owner") || "[]"); - mindmaps.push(mindMapId); - localStorage.setItem("owner", JSON.stringify(mindmaps)); -}; - -export const checkOwner = (mindMapId: string) => { - const mindmaps: string[] = JSON.parse(localStorage.getItem("owner")); - if (!mindmaps) return false; - return mindmaps.some((history) => history === mindMapId); -}; - -export const setLatestMindMap = (mindMapId: string) => { - localStorage.setItem("latest", mindMapId); -}; - -export const getLatestMindMap = () => { - return localStorage.getItem("latest"); -}; From 2569f926d73c607f1bafa777bdf3f42d14d5a3ce Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 16:23:07 +0900 Subject: [PATCH 007/110] =?UTF-8?q?refactor=20:=20=EC=97=B0=EA=B2=B0?= =?UTF-8?q?=EC=8B=9C=20=EC=A0=84=EC=97=AD=20=EA=B4=80=EB=A6=AC=20=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EC=96=B4=EC=97=90=20=EC=B5=9C=EA=B7=BC=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B8=EB=93=9C=EB=A7=B5=EC=9C=BC=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/MindMapMainSection/index.tsx | 2 -- client/src/store/NodeListProvider.tsx | 10 +--------- client/src/store/createSocketSlice.ts | 1 + 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/client/src/components/MindMapMainSection/index.tsx b/client/src/components/MindMapMainSection/index.tsx index bdfa98a2..1ab3d87c 100644 --- a/client/src/components/MindMapMainSection/index.tsx +++ b/client/src/components/MindMapMainSection/index.tsx @@ -17,7 +17,6 @@ const modeView = { export default function MindMapMainSection() { const mode = useSection().searchParams.get("mode") as keyof typeof modeView; const { mindMapId } = useParams<{ mindMapId: string }>(); - const { updateMindMapId } = useNodeListContext(); const connectSocket = useConnectionStore((state) => state.connectSocket); const disconnectSocket = useConnectionStore((state) => state.disconnectSocket); const wsError = useConnectionStore((state) => state.wsError); @@ -35,7 +34,6 @@ export default function MindMapMainSection() { useEffect(() => { if (mindMapId) { connectSocket(mindMapId, token); - updateMindMapId(mindMapId); } return () => { disconnectSocket(); diff --git a/client/src/store/NodeListProvider.tsx b/client/src/store/NodeListProvider.tsx index 5c5119d2..8350e89a 100644 --- a/client/src/store/NodeListProvider.tsx +++ b/client/src/store/NodeListProvider.tsx @@ -4,7 +4,6 @@ import { Node, NodeData, SelectedNode } from "@/types/Node"; import Konva from "konva"; import { createContext, ReactNode, useContext, useEffect, useState } from "react"; import { deleteNodes } from "@/konva_mindmap/events/deleteNode"; -import { setLatestMindMap } from "@/utils/localstorage"; import useMindMapTitle from "@/hooks/useMindMapTitle"; import useContent from "@/hooks/useContent"; import { useConnectionStore } from "@/store/useConnectionStore"; @@ -27,7 +26,6 @@ export type NodeListContextType = { selectedGroup: string[]; loading: boolean; deleteSelectedNodes: () => void; - updateMindMapId: (mindMapId: string) => void; content: string; updateContent: (updatedContent: string) => void; }; @@ -48,7 +46,6 @@ export default function NodeListProvider({ children }: { children: ReactNode }) const { title, initializeTitle, updateTitle } = useMindMapTitle(); const { content, updateContent, initializeContent } = useContent(); const [loading, setLoading] = useState(true); - const [mindMapId, setMindMapId] = useState(""); const { selectedGroup, groupRelease, groupSelect } = useGroupSelect(); const socket = useConnectionStore((state) => state.socket); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); @@ -81,7 +78,6 @@ export default function NodeListProvider({ children }: { children: ReactNode }) socket?.on("disconnect", () => { setData({}); overrideHistory(JSON.stringify({})); - setLatestMindMap(mindMapId); }); socket?.on("aiResponse", (response) => { @@ -96,7 +92,7 @@ export default function NodeListProvider({ children }: { children: ReactNode }) }); return () => { - socket?.offAny(); + socket?.off; }; }, [socket]); @@ -136,9 +132,6 @@ export default function NodeListProvider({ children }: { children: ReactNode }) } if (selectedNode.nodeId) deleteNodes(JSON.stringify(data), selectedNode.nodeId, overrideNodeData); } - function updateMindMapId(mindMapId: string) { - setMindMapId(mindMapId); - } return ( { set({ wsError: [...get().wsError, "작업 중 에러가 발생했어요"] }); From bd8c5980026a0f2740ddb1da31384cfe591f1920 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 16:23:35 +0900 Subject: [PATCH 008/110] =?UTF-8?q?remove=20:=20=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EC=95=88=ED=95=98=EB=8A=94=20import=EB=AC=B8=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/MindMapMainSection/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/src/components/MindMapMainSection/index.tsx b/client/src/components/MindMapMainSection/index.tsx index 1ab3d87c..bb35d797 100644 --- a/client/src/components/MindMapMainSection/index.tsx +++ b/client/src/components/MindMapMainSection/index.tsx @@ -1,11 +1,9 @@ import MindMapHeader from "@/components/MindMapHeader"; import MindMapView from "@/components/MindMapMainSection/MindMapView"; import useSection from "@/hooks/useSection"; -import { useNodeListContext } from "@/store/NodeListProvider"; import { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; import ToastContainer from "../common/Toast/ToastContainer"; -import useAuth from "@/hooks/useAuth"; import { useConnectionStore } from "@/store/useConnectionStore"; const modeView = { From eb9e1131630ab9df0cede8b5d207043dadf1f980 Mon Sep 17 00:00:00 2001 From: adkm12 Date: Mon, 2 Dec 2024 17:18:47 +0900 Subject: [PATCH 009/110] =?UTF-8?q?fix=20:=20=EB=A7=88=EC=9D=B8=EB=93=9C?= =?UTF-8?q?=EB=A7=B5=20=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EC=9E=90=EC=8B=9D=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api-server/src/modules/mindmap/mindmap.service.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts index ecd5f28d..29f34bff 100644 --- a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts +++ b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts @@ -84,8 +84,14 @@ export class MindmapService { throw new UnauthorizedException('권한이 없습니다.'); } - await this.mindmapRepository.softRemove({ id: mindmapId }); - await this.userMindmapRoleRepository.softDelete({ mindmap: { id: mindmapId } }); + const mindmap = await this.mindmapRepository.findOne({ + where: { id: mindmapId }, + relations: ['nodes', 'userMindmapRoles'], + }); + if (!mindmap) { + throw new MindmapException('마인드맵을 찾을 수 없습니다.'); + } + await this.mindmapRepository.softRemove(mindmap); } async getDataByMindmapId(mindmapId: number) { From 97a577a81abb42de857989acb96c42ca4b0cb184 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 18:55:26 +0900 Subject: [PATCH 010/110] =?UTF-8?q?refactor=20:=20latest=20sessionStorage?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Sidebar/Overview.tsx | 2 +- client/src/store/createSharedSlice.ts | 4 ---- client/src/store/createSocketSlice.ts | 2 +- client/src/store/useConnectionStore.ts | 7 +++---- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/client/src/components/Sidebar/Overview.tsx b/client/src/components/Sidebar/Overview.tsx index 5c539b7c..7cfe6f1a 100644 --- a/client/src/components/Sidebar/Overview.tsx +++ b/client/src/components/Sidebar/Overview.tsx @@ -18,10 +18,10 @@ export default function Overview() { const { getmode, handleViewMode } = useSection(); const socket = useConnectionStore((state) => state.socket); const createConnection = useConnectionStore((state) => state.createConnection); - const latestMindMap = useConnectionStore((state) => state.latest); const { open, closeModal, openModal } = useModal(); const [selectMode, setSelcetMode] = useState("listview"); + const latestMindMap = sessionStorage.getItem("latest"); const navigateMindmap = (mode: ViewMode) => { if (socket) { handleViewMode(mode); diff --git a/client/src/store/createSharedSlice.ts b/client/src/store/createSharedSlice.ts index 1edaa353..601d363c 100644 --- a/client/src/store/createSharedSlice.ts +++ b/client/src/store/createSharedSlice.ts @@ -3,9 +3,7 @@ import { NavigateFunction } from "react-router-dom"; import { StateCreator } from "zustand"; export interface SharedSlice { - latest: string; createConnection: (navigate: NavigateFunction, targetMode: string) => void; - updateLatestMindMap: (connectionId: string) => void; } export const createSharedSlice: StateCreator = (set, get) => ({ latest: "", @@ -20,6 +18,4 @@ export const createSharedSlice: StateCreator set({ latest: connectionId }), }); diff --git a/client/src/store/createSocketSlice.ts b/client/src/store/createSocketSlice.ts index b3350bad..19863ebe 100644 --- a/client/src/store/createSocketSlice.ts +++ b/client/src/store/createSocketSlice.ts @@ -44,7 +44,7 @@ export const createSocketSlice: StateCreator { set({ wsError: [...get().wsError, "작업 중 에러가 발생했어요"] }); diff --git a/client/src/store/useConnectionStore.ts b/client/src/store/useConnectionStore.ts index e4f289a1..e68f9d2e 100644 --- a/client/src/store/useConnectionStore.ts +++ b/client/src/store/useConnectionStore.ts @@ -1,8 +1,8 @@ -import { createRoleSlice, RoleSlice } from "@/store/createRoleSlice"; -import { createSocketSlice, SocketSlice } from "@/store/createSocketSlice"; +import { createRoleSlice } from "@/store/createRoleSlice"; +import { createSocketSlice } from "@/store/createSocketSlice"; import { createJSONStorage, devtools, persist } from "zustand/middleware"; import { create } from "zustand"; -import { createMindMapOwnershipSlice, MindMapOwnershipSlice } from "@/store/createMindMapOwnershipSlice"; +import { createMindMapOwnershipSlice } from "@/store/createMindMapOwnershipSlice"; import { ConnectionStore } from "@/types/store"; import { createSharedSlice } from "@/store/createSharedSlice"; import { createAuthSlice } from "@/store/createAuthSlice"; @@ -24,7 +24,6 @@ export const useConnectionStore = create()( token: state.token, ownedMindMap: state.ownedMindMap, ownedMindMapForGuest: state.ownedMindMapForGuest, - latest: state.latest, }; }, storage: createJSONStorage(() => localStorage), From 2eabdce9b1b39feed314b7129aca3fed3d946e5c Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Mon, 2 Dec 2024 18:59:52 +0900 Subject: [PATCH 011/110] =?UTF-8?q?refactor=20:=20=EC=9B=90=EB=81=BC?= =?UTF-8?q?=EB=A6=AC=EB=A7=8C=20=EC=B6=A9=EB=8F=8C=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8F=84=EB=A1=9D=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/konva_mindmap/hooks/useCollisionDetection.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/konva_mindmap/hooks/useCollisionDetection.ts b/client/src/konva_mindmap/hooks/useCollisionDetection.ts index 6a983e7f..63703e3b 100644 --- a/client/src/konva_mindmap/hooks/useCollisionDetection.ts +++ b/client/src/konva_mindmap/hooks/useCollisionDetection.ts @@ -16,12 +16,12 @@ export function useCollisionDetection(nodeData: NodeData, updateNode: (id: numbe ); const detectCollisions = useCallback( - (layer: Konva.Layer) => { + (layer) => { const nodes = layer.children.filter((child) => child.attrs.name === "node"); nodes.forEach((base) => { nodes.forEach((target) => { if (base !== target) { - if (isCollided(base.getClientRect(), target.getClientRect())) { + if (isCollided(base.children[0].getClientRect(), target.children[0].getClientRect())) { handleCollision(base, target); } } From 1cbef0edceaf0aeef40c0568b8844adc3b721f2a Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Mon, 2 Dec 2024 23:36:35 +0900 Subject: [PATCH 012/110] =?UTF-8?q?feat=20&=20refactor=20:=20toast=20notif?= =?UTF-8?q?ication=20(error)=20=EB=B0=9B=EB=8A=94=20=EB=B0=B0=EC=97=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20&=20useToast=EC=83=9D=EC=84=B1=20=ED=9B=84?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/MindMapMainSection/index.tsx | 15 ++------- client/src/hooks/useToast.ts | 32 +++++++++++++++++++ client/src/store/createSharedSlice.ts | 13 ++++++++ 3 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 client/src/hooks/useToast.ts diff --git a/client/src/components/MindMapMainSection/index.tsx b/client/src/components/MindMapMainSection/index.tsx index bdfa98a2..117a9f4d 100644 --- a/client/src/components/MindMapMainSection/index.tsx +++ b/client/src/components/MindMapMainSection/index.tsx @@ -2,11 +2,11 @@ import MindMapHeader from "@/components/MindMapHeader"; import MindMapView from "@/components/MindMapMainSection/MindMapView"; import useSection from "@/hooks/useSection"; import { useNodeListContext } from "@/store/NodeListProvider"; -import { useEffect, useState } from "react"; +import { useEffect } from "react"; import { useParams } from "react-router-dom"; import ToastContainer from "../common/Toast/ToastContainer"; -import useAuth from "@/hooks/useAuth"; import { useConnectionStore } from "@/store/useConnectionStore"; +import useToast from "@/hooks/useToast"; const modeView = { voiceupload: "음성 파일 업로드", @@ -20,17 +20,8 @@ export default function MindMapMainSection() { const { updateMindMapId } = useNodeListContext(); const connectSocket = useConnectionStore((state) => state.connectSocket); const disconnectSocket = useConnectionStore((state) => state.disconnectSocket); - const wsError = useConnectionStore((state) => state.wsError); - const [toasts, setToasts] = useState([]); const token = useConnectionStore((state) => state.token); - - useEffect(() => { - if (wsError.length > 0) - setToasts((prevToasts) => [ - ...prevToasts, - { id: new Date().getTime(), message: wsError[wsError.length - 1], status: "fail" }, - ]); - }, [wsError]); + const { toasts, setToasts } = useToast(); useEffect(() => { if (mindMapId) { diff --git a/client/src/hooks/useToast.ts b/client/src/hooks/useToast.ts new file mode 100644 index 00000000..83d73a8a --- /dev/null +++ b/client/src/hooks/useToast.ts @@ -0,0 +1,32 @@ +import { useEffect, useState } from "react"; +import { useConnectionStore } from "@/store/useConnectionStore"; + +export default function useToast() { + const wsError = useConnectionStore((state) => state.wsError); + const nodeError = useConnectionStore((state) => state.nodeError); + const [toasts, setToasts] = useState([]); + + useEffect(() => { + if (wsError.length > 0) { + setToasts((prevToasts) => [ + ...prevToasts, + { id: new Date().getTime(), message: wsError[wsError.length - 1], status: "fail" }, + ]); + } + }, [wsError]); + + useEffect(() => { + if (nodeError.length > 0) { + setToasts((prevToasts) => [ + ...prevToasts, + { + id: new Date().getTime(), + message: nodeError[nodeError.length - 1].message, + status: nodeError[nodeError.length - 1].status, + }, + ]); + } + }, [nodeError]); + + return { toasts, setToasts }; +} diff --git a/client/src/store/createSharedSlice.ts b/client/src/store/createSharedSlice.ts index 80f78bf2..eb6c1e2e 100644 --- a/client/src/store/createSharedSlice.ts +++ b/client/src/store/createSharedSlice.ts @@ -2,10 +2,19 @@ import { ConnectionStore } from "@/types/store"; import { NavigateFunction } from "react-router-dom"; import { StateCreator } from "zustand"; +type NodeError = { + message: string; + status: string; +}; + export interface SharedSlice { createConnection: (navigate: NavigateFunction, targetMode: string) => void; + propagateError: (error: string, status: string) => void; + nodeError: NodeError[]; } export const createSharedSlice: StateCreator = (set, get) => ({ + nodeError: [], + createConnection: async (navigate: NavigateFunction, targetMode: string) => { try { const newMindMapConnectionId = await get().handleConnection(); @@ -17,4 +26,8 @@ export const createSharedSlice: StateCreator { + set({ nodeError: [...get().nodeError, { message, status }] }); + }, }); From e8175afd98b0e867c82ae3eb74f7fa851a8d36ab Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Mon, 2 Dec 2024 23:37:03 +0900 Subject: [PATCH 013/110] =?UTF-8?q?style=20:=20toast=20notification=20UI?= =?UTF-8?q?=20=EC=8A=A4=ED=83=80=EC=9D=BC=20&=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/common/Toast/Toast.tsx | 14 ++++++++++++-- .../src/components/common/Toast/ToastContainer.tsx | 9 ++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/client/src/components/common/Toast/Toast.tsx b/client/src/components/common/Toast/Toast.tsx index e6bba896..c49dc409 100644 --- a/client/src/components/common/Toast/Toast.tsx +++ b/client/src/components/common/Toast/Toast.tsx @@ -15,8 +15,18 @@ export default function Toast({ message, status, onClose }) { clearInterval(progressInterval); }; }, []); - const textColor = status === "success" ? "text-blue-500" : "text-red-400"; - const bgColor = status === "success" ? "bg-blue-500" : "bg-red-400"; + + const textColor = { + success: "text-blue-500", + fail: "text-red-400", + error: "text-yellow-500", // error 추가 + }[status]; + + const bgColor = { + success: "bg-blue-500", + fail: "bg-red-400", + error: "bg-yellow-500", // error 추가 + }[status]; return (
diff --git a/client/src/components/common/Toast/ToastContainer.tsx b/client/src/components/common/Toast/ToastContainer.tsx index 4a259e77..a3c1d694 100644 --- a/client/src/components/common/Toast/ToastContainer.tsx +++ b/client/src/components/common/Toast/ToastContainer.tsx @@ -1,17 +1,12 @@ import Toast from "./Toast"; export default function ToastContainer({ toasts, setToasts }) { - const addToast = (message, status) => { - const id = new Date().getTime(); - setToasts((prevToasts) => [...prevToasts, { id, message, status }]); - }; - const removeToast = (id) => { setToasts((prevToasts) => prevToasts.filter((toast) => toast.id !== id)); }; return ( -
- {toasts.map((toast) => ( +
+ {toasts.toReversed().map((toast) => ( removeToast(toast.id)} /> ))}
From 67989e6a66ed80d65a860891bebf5a973a558621 Mon Sep 17 00:00:00 2001 From: adkm12 Date: Mon, 2 Dec 2024 23:44:20 +0900 Subject: [PATCH 014/110] =?UTF-8?q?feat:=20GET=20/api/connection/:connecti?= =?UTF-8?q?onId=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - redis에 연결 정보가 없거나 잘못된 연결ID로 연결시 connectionId로 redis 데이터 캐싱 --- .../src/modules/connection/connection.controller.ts | 6 ++++++ .../src/modules/connection/connection.service.ts | 13 +++++++++++-- .../src/modules/mindmap/mindmap.service.ts | 5 ++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/BE/apps/api-server/src/modules/connection/connection.controller.ts b/BE/apps/api-server/src/modules/connection/connection.controller.ts index 24a17aff..2dbacc0d 100644 --- a/BE/apps/api-server/src/modules/connection/connection.controller.ts +++ b/BE/apps/api-server/src/modules/connection/connection.controller.ts @@ -22,4 +22,10 @@ export class ConnectionController { async setConnection(@User() user, @Param('mindmapId') mindmapId: number) { return await this.connectionService.setConnection(mindmapId, user.id); } + + @Get(':connectionId') + @UseGuards(AuthGuard('jwt')) + async getConnection(@User() user, @Param('connectionId') connectionId: string) { + return await this.connectionService.getConnection(connectionId, user.id); + } } diff --git a/BE/apps/api-server/src/modules/connection/connection.service.ts b/BE/apps/api-server/src/modules/connection/connection.service.ts index 7c845534..eb073b55 100644 --- a/BE/apps/api-server/src/modules/connection/connection.service.ts +++ b/BE/apps/api-server/src/modules/connection/connection.service.ts @@ -1,6 +1,6 @@ import { MindmapService } from './../mindmap/mindmap.service'; import { UserService } from './../user/user.service'; -import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; +import { Injectable, Logger, NotFoundException, UnauthorizedException } from '@nestjs/common'; import { Redis } from 'ioredis'; import { RedisService } from '@liaoliaots/nestjs-redis'; import { v4 as uuidv4 } from 'uuid'; @@ -30,14 +30,22 @@ export class ConnectionService { return { connectionId, role: 'owner' }; } + async getConnection(connectionId: string, userId: number) { + const mindmap = await this.mindmapService.getMindmapByConnectionId(connectionId); + if (!mindmap) { + throw new NotFoundException('마인드맵을 찾을 수 없습니다.'); + } + await this.setConnection(mindmap.id, userId); + } + async setConnection(mindmapId: number, userId: number) { try { const role = await this.userService.getRole(userId, mindmapId); - const owner = await this.mindmapService.getOwner(mindmapId); if (!role) { throw new UnauthorizedException('권한이 없습니다.'); } + const owner = await this.mindmapService.getOwner(mindmapId); const mindmapData = await this.mindmapService.getDataByMindmapId(mindmapId); await this.GeneralRedis.hset(mindmapData.connectionId, { type: 'user', @@ -51,6 +59,7 @@ export class ConnectionService { await this.GeneralRedis.set(`content:${mindmapData.connectionId}`, mindmapData.content); return { + mindmapId, connectionId: mindmapData.connectionId, role: role, }; diff --git a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts index ecd5f28d..582ef887 100644 --- a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts +++ b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts @@ -64,7 +64,6 @@ export class MindmapService { }); if (!myRoles) { - this.logger.log('myRoles is empty'); return []; } @@ -130,4 +129,8 @@ export class MindmapService { }, ]; } + + async getMindmapByConnectionId(connectionId: string) { + return await this.mindmapRepository.findOne({ where: { connectionId } }); + } } From 0b7f227c574471024baecc4f36abf1efff5af6e1 Mon Sep 17 00:00:00 2001 From: adkm12 Date: Mon, 2 Dec 2024 23:46:16 +0900 Subject: [PATCH 015/110] =?UTF-8?q?feat:=20text=20ai=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/apps/socket-server/src/modules/map/map.gateway.ts | 7 +++++++ .../src/modules/subscriber/subscriber.service.ts | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/BE/apps/socket-server/src/modules/map/map.gateway.ts b/BE/apps/socket-server/src/modules/map/map.gateway.ts index e64f6b69..e536c01c 100644 --- a/BE/apps/socket-server/src/modules/map/map.gateway.ts +++ b/BE/apps/socket-server/src/modules/map/map.gateway.ts @@ -147,6 +147,7 @@ export class MapGateway implements OnGatewayInit, OnGatewayConnection, OnGateway const socketId = room.values().next().value; this.logger.log('소켓 ID : ' + socketId); const clientSocket = this.server.sockets.sockets.get(socketId); + if (clientSocket) { clientSocket.emit('aiResponse', data.nodeData); } else { @@ -159,6 +160,12 @@ export class MapGateway implements OnGatewayInit, OnGatewayConnection, OnGateway this.server.to(data.connectionId).emit('aiPending', { status: false }); } + textAiError(data) { + this.logger.error(`AI 요청 에러 : ${data.error}`); + this.server.to(data.connectionId).emit('error', { error: data.error }); + this.server.to(data.connectionId).emit('aiPending', { status: false }); + } + private logging(client: Socket, message: string) { this.logger.log(`Event: ${message} | User: ${client.data.user ? client.data.user.id : `guest ${client.id}`}`); } diff --git a/BE/apps/socket-server/src/modules/subscriber/subscriber.service.ts b/BE/apps/socket-server/src/modules/subscriber/subscriber.service.ts index 9cfb6f53..c2f86151 100644 --- a/BE/apps/socket-server/src/modules/subscriber/subscriber.service.ts +++ b/BE/apps/socket-server/src/modules/subscriber/subscriber.service.ts @@ -59,6 +59,10 @@ export class SubscriberService implements OnModuleInit { } textAiFinished(data) { + if (data.error) { + this.mapGateway.textAiError(data); + return; + } this.mapGateway.textAiResponse(data); } From ecf37a3063f3e386e5108b56ef1119491bc53523 Mon Sep 17 00:00:00 2001 From: adkm12 Date: Mon, 2 Dec 2024 23:48:36 +0900 Subject: [PATCH 016/110] =?UTF-8?q?feat:=20audio=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=A0=84=EC=86=A1=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - POST api/ai/audio/:mindmapId 추가 - nginx BODY 최대 사이즈 변경 - 소켓 aiPending 요청 추가 - 파일 확장자 validation 파이프 추가 --- BE/apps/api-server/common/constant.ts | 2 + .../src/modules/ai/ai.controller.spec.ts | 18 ++++ .../src/modules/ai/ai.controller.ts | 24 +++++ .../api-server/src/modules/ai/ai.module.ts | 5 +- .../api-server/src/modules/ai/ai.service.ts | 100 ++++++++++-------- .../src/pipes/file.validation.pipe.ts | 21 ++++ BE/apps/api-server/src/pipes/index.ts | 1 + .../src/modules/map/map.gateway.ts | 7 +- BE/package-lock.json | 11 ++ BE/package.json | 3 +- nginx/default.conf | 6 +- nginx/dev.conf | 2 +- 12 files changed, 148 insertions(+), 52 deletions(-) create mode 100644 BE/apps/api-server/common/constant.ts create mode 100644 BE/apps/api-server/src/modules/ai/ai.controller.spec.ts create mode 100644 BE/apps/api-server/src/modules/ai/ai.controller.ts create mode 100644 BE/apps/api-server/src/pipes/file.validation.pipe.ts create mode 100644 BE/apps/api-server/src/pipes/index.ts diff --git a/BE/apps/api-server/common/constant.ts b/BE/apps/api-server/common/constant.ts new file mode 100644 index 00000000..a6f99bb7 --- /dev/null +++ b/BE/apps/api-server/common/constant.ts @@ -0,0 +1,2 @@ +export const MAX_FILE_SIZE = 1024 * 1024 * 100; // 100MB +export const ALLOW_AUDIO_FILE_FORMAT = ['m4a', 'ogg', 'aac', 'mp3']; diff --git a/BE/apps/api-server/src/modules/ai/ai.controller.spec.ts b/BE/apps/api-server/src/modules/ai/ai.controller.spec.ts new file mode 100644 index 00000000..79720add --- /dev/null +++ b/BE/apps/api-server/src/modules/ai/ai.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AiController } from './ai.controller'; + +describe('AiController', () => { + let controller: AiController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [AiController], + }).compile(); + + controller = module.get(AiController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/BE/apps/api-server/src/modules/ai/ai.controller.ts b/BE/apps/api-server/src/modules/ai/ai.controller.ts new file mode 100644 index 00000000..f4f53689 --- /dev/null +++ b/BE/apps/api-server/src/modules/ai/ai.controller.ts @@ -0,0 +1,24 @@ +import { Controller, Logger, Post, UploadedFile, UseGuards, UseInterceptors } from '@nestjs/common'; +import { AiService } from './ai.service'; +import { FileInterceptor } from '@nestjs/platform-express'; +import { AuthGuard } from '@nestjs/passport'; +import { User } from '../../decorators'; +import { ALLOW_AUDIO_FILE_FORMAT, MAX_FILE_SIZE } from 'apps/api-server/common/constant'; +import { FileValidationPipe } from '../../pipes'; + +@Controller('ai') +export class AiController { + private readonly logger = new Logger(AiController.name); + constructor(private readonly aiService: AiService) {} + + @Post('audio/:mindmapId') + @UseGuards(AuthGuard('jwt')) + @UseInterceptors(FileInterceptor('aiAudio', { limits: { fileSize: MAX_FILE_SIZE } })) + async uploadAudioFile( + @User() user, + @UploadedFile(new FileValidationPipe(ALLOW_AUDIO_FILE_FORMAT)) audioFile: Express.Multer.File, + ) { + console.log(user); + console.log(audioFile); + } +} diff --git a/BE/apps/api-server/src/modules/ai/ai.module.ts b/BE/apps/api-server/src/modules/ai/ai.module.ts index f8678857..e2107071 100644 --- a/BE/apps/api-server/src/modules/ai/ai.module.ts +++ b/BE/apps/api-server/src/modules/ai/ai.module.ts @@ -2,10 +2,13 @@ import { Module } from '@nestjs/common'; import { AiService } from './ai.service'; import { HttpModule } from '@nestjs/axios'; import { NodeModule } from '../node/node.module'; +import { AiController } from './ai.controller'; +import { FileValidationPipe } from '../../pipes'; @Module({ imports: [HttpModule, NodeModule], - providers: [AiService], + providers: [AiService, FileValidationPipe], exports: [AiService], + controllers: [AiController], }) export class AiModule {} diff --git a/BE/apps/api-server/src/modules/ai/ai.service.ts b/BE/apps/api-server/src/modules/ai/ai.service.ts index 1a64ad6e..37937eeb 100644 --- a/BE/apps/api-server/src/modules/ai/ai.service.ts +++ b/BE/apps/api-server/src/modules/ai/ai.service.ts @@ -26,59 +26,67 @@ export class AiService { ) {} async requestClovaX(data: RedisMessage['data']) { - if (BAD_WORDS_REGEX.test(data.aiContent)) { - this.publisherService.publish( - 'api-socket', - JSON.stringify({ event: 'textAi', data: { error: '욕설이 포함되어 있습니다.' } }), - ); - return; - } + try { + if (BAD_WORDS_REGEX.test(data.aiContent)) { + this.publisherService.publish( + 'api-socket', + JSON.stringify({ event: 'textAi', data: { error: '욕설이 포함되어 있습니다.' } }), + ); + return; + } - const URL = this.configService.get('CLOVA_URL'); - const headers = { - 'X-NCP-CLOVASTUDIO-API-KEY': this.configService.get('X_NCP_CLOVASTUDIO_API_KEY'), - 'X-NCP-APIGW-API-KEY': this.configService.get('X_NCP_APIGW_API_KEY'), - 'X-NCP-CLOVASTUDIO-REQUEST-ID': this.configService.get('X_NCP_CLOVASTUDIO_REQUEST_ID'), - 'Content-Type': 'application/json', - }; + const URL = this.configService.get('CLOVA_URL'); + const headers = { + 'X-NCP-CLOVASTUDIO-API-KEY': this.configService.get('X_NCP_CLOVASTUDIO_API_KEY'), + 'X-NCP-APIGW-API-KEY': this.configService.get('X_NCP_APIGW_API_KEY'), + 'X-NCP-CLOVASTUDIO-REQUEST-ID': this.configService.get('X_NCP_CLOVASTUDIO_REQUEST_ID'), + 'Content-Type': 'application/json', + }; - const messages = [ - { - role: 'system', - content: CLOVA_X_PROMPT, - }, - { - role: 'user', - content: data.aiContent, - }, - ]; + const messages = [ + { + role: 'system', + content: CLOVA_X_PROMPT, + }, + { + role: 'user', + content: data.aiContent, + }, + ]; - const requestData = { - messages, - topP: 0.8, - topK: 0, - maxTokens: 2272, - temperature: 0.06, - repeatPenalty: 5.0, - stopBefore: [], - includeAiFilters: false, - seed: 0, - }; + const requestData = { + messages, + topP: 0.8, + topK: 0, + maxTokens: 2272, + temperature: 0.06, + repeatPenalty: 5.0, + stopBefore: [], + includeAiFilters: false, + seed: 0, + }; - const response = await firstValueFrom(this.httpService.post(URL, requestData, { headers })); + const response = await firstValueFrom(this.httpService.post(URL, requestData, { headers })); - let result: string = response.data.result.message.content; + let result: string = response.data.result.message.content; - if (result[result.length - 1] !== '}') { - result = result + '}'; - } + if (result[result.length - 1] !== '}') { + result = result + '}'; + } - const resultJson = JSON.parse(result) as TextAiResponse; - const nodeData = await this.nodeService.aiCreateNode(resultJson, Number(data.mindmapId)); + const resultJson = JSON.parse(result) as TextAiResponse; + const nodeData = await this.nodeService.aiCreateNode(resultJson, Number(data.mindmapId)); - this.publisherService.publish( - 'api-socket', - JSON.stringify({ event: 'textAiSocket', data: { nodeData, connectionId: data.connectionId } }), - ); + this.publisherService.publish( + 'api-socket', + JSON.stringify({ event: 'textAiSocket', data: { nodeData, connectionId: data.connectionId } }), + ); + } catch (error) { + this.logger.error('텍스트 AI 요청 에러 : ' + error); + this.publisherService.publish( + 'api-socket', + JSON.stringify({ event: 'textAiSocket', data: { error: 'AI 요청에 실패했습니다.' } }), + ); + } } } diff --git a/BE/apps/api-server/src/pipes/file.validation.pipe.ts b/BE/apps/api-server/src/pipes/file.validation.pipe.ts new file mode 100644 index 00000000..444a1457 --- /dev/null +++ b/BE/apps/api-server/src/pipes/file.validation.pipe.ts @@ -0,0 +1,21 @@ +import { BadRequestException, Injectable, PipeTransform } from '@nestjs/common'; +import { extname } from 'path'; + +@Injectable() +export class FileValidationPipe implements PipeTransform { + constructor(private readonly allowExtensions: string[]) {} + + transform(file: Express.Multer.File) { + if (!file) { + throw new BadRequestException('No file uploaded'); + } + + const ext = extname(file.originalname).toLowerCase(); + + if (!this.allowExtensions.includes(ext)) { + throw new BadRequestException(`File type not allowed. Only ${this.allowExtensions.join(', ')} allowed`); + } + + return file; + } +} diff --git a/BE/apps/api-server/src/pipes/index.ts b/BE/apps/api-server/src/pipes/index.ts new file mode 100644 index 00000000..bda84f3d --- /dev/null +++ b/BE/apps/api-server/src/pipes/index.ts @@ -0,0 +1 @@ +export * from './file.validation.pipe'; diff --git a/BE/apps/socket-server/src/modules/map/map.gateway.ts b/BE/apps/socket-server/src/modules/map/map.gateway.ts index e536c01c..4f2e3341 100644 --- a/BE/apps/socket-server/src/modules/map/map.gateway.ts +++ b/BE/apps/socket-server/src/modules/map/map.gateway.ts @@ -134,6 +134,12 @@ export class MapGateway implements OnGatewayInit, OnGatewayConnection, OnGateway await this.mapService.textAiRequest(client, aiRequestDto.aiContent); } + @SubscribeMessage('audioAiRequest') + async handleAudioAiRequest(@ConnectedSocket() client: Socket) { + this.logging(client, '오디오 AI 요청'); + this.server.to(client.data.connectionId).emit('aiPending', { status: true }); + } + textAiResponse(data) { const room = this.server.sockets.adapter.rooms.get(data.connectionId); if (data.error) { @@ -145,7 +151,6 @@ export class MapGateway implements OnGatewayInit, OnGatewayConnection, OnGateway if (room && room.size > 0) { // 첫 번째 클라이언트 ID 가져오기 const socketId = room.values().next().value; - this.logger.log('소켓 ID : ' + socketId); const clientSocket = this.server.sockets.sockets.get(socketId); if (clientSocket) { diff --git a/BE/package-lock.json b/BE/package-lock.json index 35563af8..5a51da04 100644 --- a/BE/package-lock.json +++ b/BE/package-lock.json @@ -43,6 +43,7 @@ "@types/cookie-parser": "^1.4.7", "@types/express": "^5.0.0", "@types/jest": "^29.5.2", + "@types/multer": "^1.4.12", "@types/node": "^20.3.1", "@types/passport-jwt": "^4.0.1", "@types/supertest": "^6.0.0", @@ -2350,6 +2351,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/multer": { + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.12.tgz", + "integrity": "sha512-pQ2hoqvXiJt2FP9WQVLPRO+AmiIm/ZYkavPlIQnx282u4ZrVdztx0pkh3jjpQt0Kz+YI0YhSG264y08UJKoUQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/node": { "version": "20.17.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz", diff --git a/BE/package.json b/BE/package.json index b7e472b9..0b2c1100 100644 --- a/BE/package.json +++ b/BE/package.json @@ -54,6 +54,7 @@ "@types/cookie-parser": "^1.4.7", "@types/express": "^5.0.0", "@types/jest": "^29.5.2", + "@types/multer": "^1.4.12", "@types/node": "^20.3.1", "@types/passport-jwt": "^4.0.1", "@types/supertest": "^6.0.0", @@ -100,4 +101,4 @@ "^@app/publisher(|/.*)$": "/libs/publisher/src/$1" } } -} \ No newline at end of file +} diff --git a/nginx/default.conf b/nginx/default.conf index 4084f2cc..f3ecc770 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -1,7 +1,7 @@ server { listen 80; server_name boomap.site www.boomap.site; - + client_max_body_size 100M; location / { return 301 https://$host$request_uri; } @@ -16,10 +16,12 @@ server { server_name boomap.site www.boomap.site; - # SSL 인증서 경로 설정 + # SSL 인증서 경로 설정 ssl_certificate /etc/letsencrypt/live/boomap.site/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/boomap.site/privkey.pem; + client_max_body_size 100M; + location / { # 요청 파일이 없을 경우 /index.html로 리다이렉트 try_files $uri $uri/ /index.html; diff --git a/nginx/dev.conf b/nginx/dev.conf index 8e97eda2..ee6f21b3 100644 --- a/nginx/dev.conf +++ b/nginx/dev.conf @@ -2,7 +2,7 @@ server { listen 80; server_name localhost; - + client_max_body_size 100M; location / { # 요청 파일이 없을 경우 /index.html로 리다이렉트 proxy_pass http://fe:5173; From 3b235113b54c9bba7a91666ae4752308ab0e2bf1 Mon Sep 17 00:00:00 2001 From: adkm12 Date: Tue, 3 Dec 2024 00:27:13 +0900 Subject: [PATCH 017/110] =?UTF-8?q?fix=20:=20fix=20:=20HttpException=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/auth/auth.service.ts | 40 ++++++++----------- .../modules/connection/connection.service.ts | 4 +- .../src/modules/mindmap/mindmap.service.ts | 6 +-- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/BE/apps/api-server/src/modules/auth/auth.service.ts b/BE/apps/api-server/src/modules/auth/auth.service.ts index d14bb15d..f7a1b198 100644 --- a/BE/apps/api-server/src/modules/auth/auth.service.ts +++ b/BE/apps/api-server/src/modules/auth/auth.service.ts @@ -1,9 +1,8 @@ import { RedisService } from '@liaoliaots/nestjs-redis'; -import { Injectable, Logger } from '@nestjs/common'; +import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { User } from '@app/entity'; import Redis from 'ioredis'; -import { authException } from '../../exceptions'; interface tokenPayload { email: string; @@ -34,28 +33,23 @@ export class AuthService { } async verifiedRefreshToken(refreshToken: string) { - try { - const isBlacklisted = await this.GeneralRedis.get(refreshToken); - if (isBlacklisted === 'true') { - throw new Error('다시 로그인해주세요.'); - } - this.jwtService.verify(refreshToken); - const decoded = this.jwtService.decode(refreshToken); - if (!decoded || typeof decoded !== 'object') { - throw new Error('Invalid token format'); - } + const isBlacklisted = await this.GeneralRedis.get(refreshToken); + if (isBlacklisted === 'true') { + throw new UnauthorizedException('다시 로그인해주세요.'); + } + this.jwtService.verify(refreshToken); + const decoded = this.jwtService.decode(refreshToken); + if (!decoded || typeof decoded !== 'object') { + throw new UnauthorizedException('Invalid token format'); + } - const payload: tokenPayload = { - email: decoded.email, - id: decoded.id, - }; + const payload: tokenPayload = { + email: decoded.email, + id: decoded.id, + }; - const accessToken = this.jwtService.sign(payload, { expiresIn: 60 * 30 }); - return accessToken; - } catch (error) { - this.logger.error(error); - throw new authException('다시 로그인해주세요.'); - } + const accessToken = this.jwtService.sign(payload, { expiresIn: 60 * 30 }); + return accessToken; } async logout(refreshToken: string) { @@ -63,7 +57,7 @@ export class AuthService { await this.GeneralRedis.set(refreshToken, 'true', 'EX', 60 * 60 * 24 * 3); } catch (error) { this.logger.error(error); - throw new authException('로그아웃에 실패했습니다.'); + throw new UnauthorizedException('로그아웃에 실패했습니다.'); } } } diff --git a/BE/apps/api-server/src/modules/connection/connection.service.ts b/BE/apps/api-server/src/modules/connection/connection.service.ts index eb073b55..39b4b077 100644 --- a/BE/apps/api-server/src/modules/connection/connection.service.ts +++ b/BE/apps/api-server/src/modules/connection/connection.service.ts @@ -1,6 +1,6 @@ import { MindmapService } from './../mindmap/mindmap.service'; import { UserService } from './../user/user.service'; -import { Injectable, Logger, NotFoundException, UnauthorizedException } from '@nestjs/common'; +import { ForbiddenException, Injectable, Logger, NotFoundException, UnauthorizedException } from '@nestjs/common'; import { Redis } from 'ioredis'; import { RedisService } from '@liaoliaots/nestjs-redis'; import { v4 as uuidv4 } from 'uuid'; @@ -42,7 +42,7 @@ export class ConnectionService { try { const role = await this.userService.getRole(userId, mindmapId); if (!role) { - throw new UnauthorizedException('권한이 없습니다.'); + throw new ForbiddenException('권한이 없습니다.'); } const owner = await this.mindmapService.getOwner(mindmapId); diff --git a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts index 582ef887..533e439d 100644 --- a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts +++ b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts @@ -1,5 +1,5 @@ import { InjectRepository } from '@nestjs/typeorm'; -import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; +import { ForbiddenException, Injectable, Logger, NotFoundException } from '@nestjs/common'; import { In, Repository } from 'typeorm'; import { Mindmap, UserMindmapRole } from '@app/entity'; import { v4 as uuidv4 } from 'uuid'; @@ -80,7 +80,7 @@ export class MindmapService { }); if (role.role !== Role.OWNER) { - throw new UnauthorizedException('권한이 없습니다.'); + throw new ForbiddenException('권한이 없습니다.'); } await this.mindmapRepository.softRemove({ id: mindmapId }); @@ -91,7 +91,7 @@ export class MindmapService { const mindmap = await this.mindmapRepository.findOne({ where: { id: mindmapId } }); const nodes = await this.nodeService.tableToCanvas(mindmap.id); if (!mindmap) { - throw new MindmapException('마인드맵을 찾을 수 없습니다.'); + throw new NotFoundException('마인드맵을 찾을 수 없습니다.'); } return { From bcc3f2d898e774fe5d875dd402c7c9fca9e2b24e Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 00:35:26 +0900 Subject: [PATCH 018/110] =?UTF-8?q?feat=20:=20addNode=20=EC=A0=9C=EC=95=BD?= =?UTF-8?q?=20=EC=82=AC=ED=95=AD=20=EC=9C=84=EB=B0=98=20=EC=8B=9C=20toast?= =?UTF-8?q?=20UI=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/konva_mindmap/events/addNode.ts | 46 ++++++++++------------ 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/client/src/konva_mindmap/events/addNode.ts b/client/src/konva_mindmap/events/addNode.ts index 68853d93..4ef928cf 100644 --- a/client/src/konva_mindmap/events/addNode.ts +++ b/client/src/konva_mindmap/events/addNode.ts @@ -1,8 +1,8 @@ -import { calculateVector } from "@/konva_mindmap/utils/vector"; -import { Node, NodeData, SelectedNode } from "@/types/Node"; -import { findRootNodeKey } from "../utils/findRootNodeKey"; +import { NodeData, SelectedNode } from "@/types/Node"; import { NODE_DEPTH_LIMIT } from "@/constants/node"; import { useConnectionStore } from "@/store/useConnectionStore"; +import { getNewNodePosition } from "../utils/getNewNodePosition"; +import { checkAllNodeCount, checkNodeCount } from "../utils/checkNodeCount"; export function addNode( data: NodeData, @@ -11,6 +11,24 @@ export function addNode( onNodeCreated?: (id: number) => void, ) { const handleSocketEvent = useConnectionStore.getState().handleSocketEvent; + + if (selectedNode.nodeId === 0) { + useConnectionStore.getState().propagateError("노드가 선택되지 않았습니다.", "error"); + return; + } + + const isCheckNodeCount = checkNodeCount(data, selectedNode.nodeId); + const isCheckAllNodeCount = checkAllNodeCount(data); + + if (!isCheckNodeCount) { + useConnectionStore.getState().propagateError("한 노드당 최대 15개 생성 가능해요.", "error"); + return; + } + if (!isCheckAllNodeCount) { + useConnectionStore.getState().propagateError("노드는 최대 150개 생성 가능해요.", "error"); + return; + } + // 아무 노드도 없을 때는 임의로 id 생성해서 현재는 넣음 if (!Object.keys(data).length) { const newNode = { @@ -80,25 +98,3 @@ export function addNode( }); return newNodeId; } - -// 수직벡터 -> 벡터 구한 다음에 벡터의 y값이 x값으로 가고 x값의 반대 부호값이 y좌표 -// 단위벡터 * 내가 원하는 만큼 떼놓을 거리값을 마지막 요소의 x와 y좌표에 더한다, -function getNewNodePosition(children: number[], data: NodeData, parentNode: Node) { - const rootKey = findRootNodeKey(data); - - if (!children.length) { - if (parentNode.id === rootKey) - return { - x: parentNode.location.x + 300, - y: parentNode.location.y, - }; - const { x, y } = calculateVector(data[rootKey].location, parentNode.location, -80, 240); - return parentNode ? { x: parentNode.location.x + x, y: parentNode.location.y + y } : { x: 0, y: 0 }; - } - const lastChildren = data[children[children.length - 1]]; - const uv = calculateVector(parentNode.location, lastChildren.location, 110, 240); - return { - x: lastChildren.location.x + uv.x, - y: lastChildren.location.y + uv.y, - }; -} From 120fcd1b67e6eff96818a2229fcb5241a00dfedb Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 00:40:27 +0900 Subject: [PATCH 019/110] =?UTF-8?q?chore=20:=20addNode=20error=20=EB=AC=B8?= =?UTF-8?q?=EA=B5=AC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/konva_mindmap/events/addNode.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/konva_mindmap/events/addNode.ts b/client/src/konva_mindmap/events/addNode.ts index 4ef928cf..8628dfd8 100644 --- a/client/src/konva_mindmap/events/addNode.ts +++ b/client/src/konva_mindmap/events/addNode.ts @@ -25,7 +25,7 @@ export function addNode( return; } if (!isCheckAllNodeCount) { - useConnectionStore.getState().propagateError("노드는 최대 150개 생성 가능해요.", "error"); + useConnectionStore.getState().propagateError("노드는 최대 150개까지 생성 가능해요.", "error"); return; } From 6b2a7d9a6471741b83ca332cc9ad66341c50c0f1 Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 00:41:06 +0900 Subject: [PATCH 020/110] =?UTF-8?q?chore=20:=20=EB=85=B8=EB=93=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=20line=20=EC=9C=84=EC=B9=98=20const=20?= =?UTF-8?q?=EA=B0=92=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/konva_mindmap/utils/nodeAttrs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/konva_mindmap/utils/nodeAttrs.ts b/client/src/konva_mindmap/utils/nodeAttrs.ts index 0c0c984d..fee49b62 100644 --- a/client/src/konva_mindmap/utils/nodeAttrs.ts +++ b/client/src/konva_mindmap/utils/nodeAttrs.ts @@ -10,7 +10,7 @@ export const TEXT_WIDTH = (depth: number) => NODE_DEFAULT_SIZE * 2 - depth * 18; //CONNECTED_LINE export const CONNECTED_LINE_FROM = (depth: number) => NODE_DEFAULT_SIZE - depth * 7 + 10; -export const CONNECTED_LINE_TO = (depth: number) => NODE_DEFAULT_SIZE - depth * 7 - 20; +export const CONNECTED_LINE_TO = (depth: number) => NODE_DEFAULT_SIZE - depth * 7 + 5; //TEXT export const TEXT_FONT_SIZE = 20; From 971e53ab5c62a21c69ed4148606d94e8bba3ff6d Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 00:42:00 +0900 Subject: [PATCH 021/110] =?UTF-8?q?refactor=20:=20=EB=85=B8=EB=93=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=9C=84=EC=B9=98=20=EA=B3=84=EC=82=B0=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../konva_mindmap/utils/getNewNodePosition.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 client/src/konva_mindmap/utils/getNewNodePosition.ts diff --git a/client/src/konva_mindmap/utils/getNewNodePosition.ts b/client/src/konva_mindmap/utils/getNewNodePosition.ts new file mode 100644 index 00000000..3f665ab1 --- /dev/null +++ b/client/src/konva_mindmap/utils/getNewNodePosition.ts @@ -0,0 +1,23 @@ +import { Node, NodeData } from "@/types/Node"; +import { findRootNodeKey } from "./findRootNodeKey"; +import { calculateVector } from "./vector"; + +export function getNewNodePosition(children: number[], data: NodeData, parentNode: Node) { + const rootKey = findRootNodeKey(data); + + if (!children.length) { + if (parentNode.id === rootKey) + return { + x: parentNode.location.x + 300, + y: parentNode.location.y, + }; + const { x, y } = calculateVector(data[rootKey].location, parentNode.location, -80, 240); + return parentNode ? { x: parentNode.location.x + x, y: parentNode.location.y + y } : { x: 0, y: 0 }; + } + const lastChildren = data[children[children.length - 1]]; + const uv = calculateVector(parentNode.location, lastChildren.location, 110, 240); + return { + x: lastChildren.location.x + uv.x, + y: lastChildren.location.y + uv.y, + }; +} From f0fb08414d5c9ecef9f4a42c842c7109fa2a7052 Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 00:43:02 +0900 Subject: [PATCH 022/110] =?UTF-8?q?feat=20:=20deleteNode=20=EC=B5=9C?= =?UTF-8?q?=EC=83=81=EC=9C=84=20=EB=85=B8=EB=93=9C=20=ED=8F=AC=ED=95=A8?= =?UTF-8?q?=EC=8B=9C=20error=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/konva_mindmap/events/deleteNode.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/src/konva_mindmap/events/deleteNode.ts b/client/src/konva_mindmap/events/deleteNode.ts index 9685abcf..8338a150 100644 --- a/client/src/konva_mindmap/events/deleteNode.ts +++ b/client/src/konva_mindmap/events/deleteNode.ts @@ -7,9 +7,13 @@ export function deleteNodes(data: string, selectedNodeIds: number | number[], ov const rootKey = findRootNodeKey(newNodeData); if (Array.isArray(selectedNodeIds) && selectedNodeIds.includes(rootKey)) { + useConnectionStore.getState().propagateError("최상위 노드는 삭제되지 않습니다.", "error"); return deleteNodes(data, [...newNodeData[rootKey].children], overrideNodeData); } - if (!Array.isArray(selectedNodeIds) && selectedNodeIds === rootKey) return; + if (!Array.isArray(selectedNodeIds) && selectedNodeIds === rootKey) { + useConnectionStore.getState().propagateError("최상위 노드는 삭제되지 않습니다.", "error"); + return; + } const nodeIds = Array.isArray(selectedNodeIds) ? selectedNodeIds : [selectedNodeIds]; if (nodeIds.some((id) => !id || !newNodeData[id])) return; From 94bd5acee75e5a60781dbd1f77dd09592af4d696 Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 00:43:31 +0900 Subject: [PATCH 023/110] =?UTF-8?q?feat=20:=20=EB=85=B8=EB=93=9C=20?= =?UTF-8?q?=EA=B0=9C=EC=88=98=20=ED=99=95=EC=9D=B8=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/konva_mindmap/utils/checkNodeCount.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 client/src/konva_mindmap/utils/checkNodeCount.ts diff --git a/client/src/konva_mindmap/utils/checkNodeCount.ts b/client/src/konva_mindmap/utils/checkNodeCount.ts new file mode 100644 index 00000000..b8d00635 --- /dev/null +++ b/client/src/konva_mindmap/utils/checkNodeCount.ts @@ -0,0 +1,14 @@ +import { NodeData } from "@/types/Node"; + +export function checkNodeCount(data: NodeData, id: number) { + const nodeData = data[id]; + const childrenCount = nodeData.children.length; + if (childrenCount >= 15) return false; + return true; +} + +export function checkAllNodeCount(data: NodeData) { + const allNodeCount = Object.keys(data).length; + if (allNodeCount >= 150) return false; + return true; +} From b4ec50f0384b3a2cd84775e324ee6e1b04918bae Mon Sep 17 00:00:00 2001 From: adkm12 Date: Tue, 3 Dec 2024 00:18:40 +0900 Subject: [PATCH 024/110] =?UTF-8?q?Revert=20"fix=20:=20HttpException=20?= =?UTF-8?q?=EC=88=98=EC=A0=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit c05579c3d287be1985a5f758a2825daf2a690bd5. 수정함: BE/apps/api-server/src/modules/auth/auth.service.ts 수정함: BE/apps/api-server/src/modules/connection/connection.service.ts 수정함: BE/apps/api-server/src/modules/mindmap/mindmap.service.ts --- .../src/modules/auth/auth.service.ts | 40 +++++++++++-------- .../modules/connection/connection.service.ts | 4 +- .../src/modules/mindmap/mindmap.service.ts | 6 +-- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/BE/apps/api-server/src/modules/auth/auth.service.ts b/BE/apps/api-server/src/modules/auth/auth.service.ts index f7a1b198..d14bb15d 100644 --- a/BE/apps/api-server/src/modules/auth/auth.service.ts +++ b/BE/apps/api-server/src/modules/auth/auth.service.ts @@ -1,8 +1,9 @@ import { RedisService } from '@liaoliaots/nestjs-redis'; -import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { User } from '@app/entity'; import Redis from 'ioredis'; +import { authException } from '../../exceptions'; interface tokenPayload { email: string; @@ -33,23 +34,28 @@ export class AuthService { } async verifiedRefreshToken(refreshToken: string) { - const isBlacklisted = await this.GeneralRedis.get(refreshToken); - if (isBlacklisted === 'true') { - throw new UnauthorizedException('다시 로그인해주세요.'); - } - this.jwtService.verify(refreshToken); - const decoded = this.jwtService.decode(refreshToken); - if (!decoded || typeof decoded !== 'object') { - throw new UnauthorizedException('Invalid token format'); - } + try { + const isBlacklisted = await this.GeneralRedis.get(refreshToken); + if (isBlacklisted === 'true') { + throw new Error('다시 로그인해주세요.'); + } + this.jwtService.verify(refreshToken); + const decoded = this.jwtService.decode(refreshToken); + if (!decoded || typeof decoded !== 'object') { + throw new Error('Invalid token format'); + } - const payload: tokenPayload = { - email: decoded.email, - id: decoded.id, - }; + const payload: tokenPayload = { + email: decoded.email, + id: decoded.id, + }; - const accessToken = this.jwtService.sign(payload, { expiresIn: 60 * 30 }); - return accessToken; + const accessToken = this.jwtService.sign(payload, { expiresIn: 60 * 30 }); + return accessToken; + } catch (error) { + this.logger.error(error); + throw new authException('다시 로그인해주세요.'); + } } async logout(refreshToken: string) { @@ -57,7 +63,7 @@ export class AuthService { await this.GeneralRedis.set(refreshToken, 'true', 'EX', 60 * 60 * 24 * 3); } catch (error) { this.logger.error(error); - throw new UnauthorizedException('로그아웃에 실패했습니다.'); + throw new authException('로그아웃에 실패했습니다.'); } } } diff --git a/BE/apps/api-server/src/modules/connection/connection.service.ts b/BE/apps/api-server/src/modules/connection/connection.service.ts index 39b4b077..eb073b55 100644 --- a/BE/apps/api-server/src/modules/connection/connection.service.ts +++ b/BE/apps/api-server/src/modules/connection/connection.service.ts @@ -1,6 +1,6 @@ import { MindmapService } from './../mindmap/mindmap.service'; import { UserService } from './../user/user.service'; -import { ForbiddenException, Injectable, Logger, NotFoundException, UnauthorizedException } from '@nestjs/common'; +import { Injectable, Logger, NotFoundException, UnauthorizedException } from '@nestjs/common'; import { Redis } from 'ioredis'; import { RedisService } from '@liaoliaots/nestjs-redis'; import { v4 as uuidv4 } from 'uuid'; @@ -42,7 +42,7 @@ export class ConnectionService { try { const role = await this.userService.getRole(userId, mindmapId); if (!role) { - throw new ForbiddenException('권한이 없습니다.'); + throw new UnauthorizedException('권한이 없습니다.'); } const owner = await this.mindmapService.getOwner(mindmapId); diff --git a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts index 0e0643db..cb05ff0a 100644 --- a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts +++ b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts @@ -1,5 +1,5 @@ import { InjectRepository } from '@nestjs/typeorm'; -import { ForbiddenException, Injectable, Logger, NotFoundException } from '@nestjs/common'; +import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; import { In, Repository } from 'typeorm'; import { Mindmap, UserMindmapRole } from '@app/entity'; import { v4 as uuidv4 } from 'uuid'; @@ -80,7 +80,7 @@ export class MindmapService { }); if (role.role !== Role.OWNER) { - throw new ForbiddenException('권한이 없습니다.'); + throw new UnauthorizedException('권한이 없습니다.'); } const mindmap = await this.mindmapRepository.findOne({ @@ -97,7 +97,7 @@ export class MindmapService { const mindmap = await this.mindmapRepository.findOne({ where: { id: mindmapId } }); const nodes = await this.nodeService.tableToCanvas(mindmap.id); if (!mindmap) { - throw new NotFoundException('마인드맵을 찾을 수 없습니다.'); + throw new MindmapException('마인드맵을 찾을 수 없습니다.'); } return { From 3769b0e66d2ecd3ef3b102b22759b08ca486b6c7 Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 00:44:07 +0900 Subject: [PATCH 025/110] =?UTF-8?q?refactor=20:=20=EA=B3=A0=EC=9C=A0?= =?UTF-8?q?=ED=95=9C=20key=EA=B0=92=EB=93=A4=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Dashboard/MindMapInfoItem.tsx | 2 +- client/src/components/Dashboard/UserDashBoard.tsx | 2 +- client/src/components/MindMapCanvas/ShowShortCut.tsx | 4 ++-- client/src/components/MindMapCanvas/ToolMenu.tsx | 2 +- .../ControlSection/ListView/NodeList.tsx | 2 +- client/src/hooks/useToast.ts | 9 ++++----- client/src/konva_mindmap/components/DrawMindMap.tsx | 2 +- 7 files changed, 11 insertions(+), 12 deletions(-) diff --git a/client/src/components/Dashboard/MindMapInfoItem.tsx b/client/src/components/Dashboard/MindMapInfoItem.tsx index c941fc7b..81352a33 100644 --- a/client/src/components/Dashboard/MindMapInfoItem.tsx +++ b/client/src/components/Dashboard/MindMapInfoItem.tsx @@ -48,7 +48,7 @@ export default function MindMapInfoItem({ data, index }: MindMapInfoItemProps) {
{keywordData.map((keyword, i) => ( {keyword} diff --git a/client/src/components/Dashboard/UserDashBoard.tsx b/client/src/components/Dashboard/UserDashBoard.tsx index af4b9702..b384699b 100644 --- a/client/src/components/Dashboard/UserDashBoard.tsx +++ b/client/src/components/Dashboard/UserDashBoard.tsx @@ -40,7 +40,7 @@ export default function UserDashBoard() {
{filteredData.map((info, i) => ( - + ))}
diff --git a/client/src/components/MindMapCanvas/ShowShortCut.tsx b/client/src/components/MindMapCanvas/ShowShortCut.tsx index f103ae7c..6423f5e1 100644 --- a/client/src/components/MindMapCanvas/ShowShortCut.tsx +++ b/client/src/components/MindMapCanvas/ShowShortCut.tsx @@ -54,9 +54,9 @@ export default function ShowShortCut() { {isClicked || isVisible ? (
{shortcuts.map(({ keys, description }, index) => ( -

+

{keys.map((key, i) => ( - + {key} {i < keys.length - 1 && " + "} diff --git a/client/src/components/MindMapCanvas/ToolMenu.tsx b/client/src/components/MindMapCanvas/ToolMenu.tsx index df09ecf4..f6a764e5 100644 --- a/client/src/components/MindMapCanvas/ToolMenu.tsx +++ b/client/src/components/MindMapCanvas/ToolMenu.tsx @@ -19,7 +19,7 @@ type ToolMenuProps = { setDragmode: React.Dispatch>; }; export default function ToolMenu({ dimensions, zoomIn, zoomOut, dragmode, setDragmode }: ToolMenuProps) { - const { data, selectNode, selectedNode, saveHistory, overrideNodeData, deleteSelectedNodes } = useNodeListContext(); + const { data, selectNode, selectedNode, saveHistory, overrideNodeData } = useNodeListContext(); const intervalRef = useRef(null); const startZoom = (zoomFn) => { diff --git a/client/src/components/MindMapMainSection/ControlSection/ListView/NodeList.tsx b/client/src/components/MindMapMainSection/ControlSection/ListView/NodeList.tsx index 9a580f70..f2d9e438 100644 --- a/client/src/components/MindMapMainSection/ControlSection/ListView/NodeList.tsx +++ b/client/src/components/MindMapMainSection/ControlSection/ListView/NodeList.tsx @@ -22,7 +22,7 @@ export default function NodeList({ data, parentNodeId, root }: NodeListProps) { /> {open && root.children.map((childId) => { - return ; + return ; })}

); diff --git a/client/src/hooks/useToast.ts b/client/src/hooks/useToast.ts index 83d73a8a..313cf769 100644 --- a/client/src/hooks/useToast.ts +++ b/client/src/hooks/useToast.ts @@ -8,19 +8,18 @@ export default function useToast() { useEffect(() => { if (wsError.length > 0) { - setToasts((prevToasts) => [ - ...prevToasts, - { id: new Date().getTime(), message: wsError[wsError.length - 1], status: "fail" }, - ]); + const num = `${new Date().getTime()}-${Math.random().toString(36)}`; + setToasts((prevToasts) => [...prevToasts, { id: num, message: wsError[wsError.length - 1], status: "fail" }]); } }, [wsError]); useEffect(() => { if (nodeError.length > 0) { + const num = `${new Date().getTime()}-${Math.random().toString(36)}`; setToasts((prevToasts) => [ ...prevToasts, { - id: new Date().getTime(), + id: num, message: nodeError[nodeError.length - 1].message, status: nodeError[nodeError.length - 1].status, }, diff --git a/client/src/konva_mindmap/components/DrawMindMap.tsx b/client/src/konva_mindmap/components/DrawMindMap.tsx index ff4994d8..5c4a0f94 100644 --- a/client/src/konva_mindmap/components/DrawMindMap.tsx +++ b/client/src/konva_mindmap/components/DrawMindMap.tsx @@ -26,7 +26,7 @@ export default function DrawMindMap({ data, root, depth = 0, parentNode, dragmod )} {root.children?.map((childNode, index) => ( - + ))} From 51fcf2891122dc247f1095e52e8258f94e8007e6 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:45:27 +0900 Subject: [PATCH 026/110] =?UTF-8?q?feat=20:=20=EA=B6=8C=ED=95=9C=EC=9D=B4?= =?UTF-8?q?=20=EC=97=86=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20=EB=A7=89=EC=95=84?= =?UTF-8?q?=EC=A4=84UploadAvailabilityArrowBox=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UploadAvailabilityArrowBox.tsx | 17 +++++++++ .../ControlSection/VoiceFileUpload.tsx | 37 +++++++++++++++++- client/src/hooks/useUpload.ts | 38 ++++++++++--------- 3 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 client/src/components/MindMapMainSection/ControlSection/UploadAvailabilityArrowBox.tsx diff --git a/client/src/components/MindMapMainSection/ControlSection/UploadAvailabilityArrowBox.tsx b/client/src/components/MindMapMainSection/ControlSection/UploadAvailabilityArrowBox.tsx new file mode 100644 index 00000000..8dc82bf7 --- /dev/null +++ b/client/src/components/MindMapMainSection/ControlSection/UploadAvailabilityArrowBox.tsx @@ -0,0 +1,17 @@ +import ArrowBox from "@/components/common/ArrowBox"; + +export default function UploadAvailabilityArrowBox({ content }: { content: string }) { + return ( + <> + {content && ( + +

{content}

+
+ )} + + ); +} diff --git a/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx b/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx index 7d21a63a..41bb5373 100644 --- a/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx +++ b/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx @@ -2,13 +2,48 @@ import UploadBox from "@/components/MindMapMainSection/ControlSection/UploadBox" import { Button } from "@headlessui/react"; import { useState } from "react"; import clovaX from "@/assets/clovaX.png"; +import useUpload from "@/hooks/useUpload"; +import UploadAvailabilityArrowBox from "@/components/MindMapMainSection/ControlSection/UploadAvailabilityArrowBox"; +import { useNodeListContext } from "@/store/NodeListProvider"; +import { useConnectionStore } from "@/store/useConnectionStore"; +import { AudioAiConvert } from "@/api/ai"; export default function VoiceFileUpload() { const [file, setFile] = useState(null); + const { availabilityInform, handleMouseEnter, handleMouseLeave } = useUpload(); + const { aiCount } = useNodeListContext(); + const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); + + async function sendAudioFile() { + if (!file) { + alert("파일을 선택해주세요."); + return; + } + + handleSocketEvent({ actionType: "audioAiRequest" }); + const formData = new FormData(); + formData.append("aiAudio", file); + try { + const response = await AudioAiConvert(formData, "22"); + console.log("업로드 성공:", response); + } catch (error) { + console.error("업로드 에러:", error); + } + } + return (
- +

남은 AI 변환 : {aiCount}

+
clovaX
diff --git a/client/src/hooks/useUpload.ts b/client/src/hooks/useUpload.ts index 8b33f631..63672ecc 100644 --- a/client/src/hooks/useUpload.ts +++ b/client/src/hooks/useUpload.ts @@ -1,25 +1,19 @@ import { MIN_TEXT_UPLOAD_LIMIT } from "@/constants/textUploadLimit"; +import { useNodeListContext } from "@/store/NodeListProvider"; import { useConnectionStore } from "@/store/useConnectionStore"; -import { useEffect, useState } from "react"; +import { useState } from "react"; export default function useUpload() { const [content, setContent] = useState(""); - const [aiProcessing, setAiProcessing] = useState(false); const role = useConnectionStore((state) => state.currentRole); - const socket = useConnectionStore((state) => state.socket); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); - const [availabilityInformBox, setAvailabilityInformBox] = useState(false); + const { aiCount } = useNodeListContext(); + const [availabilityInform, setAvailabilityInform] = useState(""); - const buttonAvailability = role === "owner"; - - useEffect(() => { - socket?.on("aiPending", (response) => { - setAiProcessing(response.status); - }); - }, [socket]); + const ownerAvailability = role === "owner"; function handleAiProcessButton() { - if (content.length <= MIN_TEXT_UPLOAD_LIMIT || !buttonAvailability) return; + if (content.length <= MIN_TEXT_UPLOAD_LIMIT || !ownerAvailability) return; handleSocketEvent({ actionType: "aiRequest", payload: { aiContent: content } }); } @@ -28,20 +22,30 @@ export default function useUpload() { } function handleMouseEnter() { - if (!buttonAvailability) setAvailabilityInformBox(true); + checkAvailability(); } + function handleMouseLeave() { - setAvailabilityInformBox(false); + setAvailabilityInform(""); + } + + function checkAvailability() { + if (!ownerAvailability) { + setAvailabilityInform("마인드맵 소유자만 AI 변환을 할 수 있어요"); + return; + } + if (!aiCount) { + setAvailabilityInform("모든 AI 변환 요청을 다 사용했어요"); + return; + } } return { content, updateContent, - aiProcessing, - buttonAvailability, handleAiProcessButton, - availabilityInformBox, handleMouseEnter, handleMouseLeave, + availabilityInform, }; } From 80e463c477fe80c1d25afe6ab76260e39f117180 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:45:53 +0900 Subject: [PATCH 027/110] =?UTF-8?q?feat=20:=20ai=20=EC=9D=8C=EC=84=B1=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=9A=94=EC=B2=AD=20api=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/ai.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 client/src/api/ai.ts diff --git a/client/src/api/ai.ts b/client/src/api/ai.ts new file mode 100644 index 00000000..ca8859e9 --- /dev/null +++ b/client/src/api/ai.ts @@ -0,0 +1,15 @@ +import { instance } from "@/api"; + +export function AudioAiConvert(formData: FormData, mindmapId: string) { + return instance.post( + `ai/audio/${mindmapId}`, + { + formData, + }, + { + headers: { + "Content-Type": "multipart/form-data", + }, + }, + ); +} From 2c7e36af614a0076a46bc49f5502fc8408dbe0cc Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:46:03 +0900 Subject: [PATCH 028/110] =?UTF-8?q?feat=20:=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/auth.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/api/auth.ts b/client/src/api/auth.ts index 04543a0f..d6f96753 100644 --- a/client/src/api/auth.ts +++ b/client/src/api/auth.ts @@ -10,3 +10,7 @@ export const getUser = async (): Promise => { const { data } = await instance.get("/user/info"); return data; }; + +export const signOut = async () => { + return instance.post("/auth/logout"); +}; From adbbf163add3a9e9fd4f15fd06aeae3cd7a3ab96 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:46:40 +0900 Subject: [PATCH 029/110] =?UTF-8?q?feat=20:=20401=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=9E=AC=EB=B0=9C=EC=83=9D=EC=8B=9C=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EC=9A=94=EC=B2=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/api/index.ts b/client/src/api/index.ts index 957aff6c..1a93a32a 100644 --- a/client/src/api/index.ts +++ b/client/src/api/index.ts @@ -1,4 +1,4 @@ -import { tokenRefresh } from "@/api/auth"; +import { signOut, tokenRefresh } from "@/api/auth"; import { logOnDev } from "@/utils/logging"; import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from "axios"; import { useConnectionStore } from "@/store/useConnectionStore"; @@ -52,13 +52,13 @@ instance.interceptors.response.use( if (error.response.status === 401) { if (!originalRequest._retry) { originalRequest._retry = true; - const newAccessToken = await tokenRefresh(); useConnectionStore.getState().tokenRefresh(newAccessToken.accessToken); originalRequest.headers["Authorization"] = `Bearer ${newAccessToken.accessToken}`; return instance(originalRequest); } + await signOut(); useConnectionStore.getState().logout(); return Promise.reject(error); } From b4f66c001b4e1915b1a9d9684533f31612105fd3 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:47:25 +0900 Subject: [PATCH 030/110] =?UTF-8?q?feat=20:=20=EB=A1=9C=EB=94=A9=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EA=B4=80=EB=A6=AC=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=9B=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/MindMapCanvas/index.tsx | 5 ++-- .../MindMapMainSection/MindMapView.tsx | 7 +++-- client/src/hooks/useLoading.ts | 26 +++++++++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 client/src/hooks/useLoading.ts diff --git a/client/src/components/MindMapCanvas/index.tsx b/client/src/components/MindMapCanvas/index.tsx index 31689413..a6e25e6d 100644 --- a/client/src/components/MindMapCanvas/index.tsx +++ b/client/src/components/MindMapCanvas/index.tsx @@ -18,7 +18,6 @@ import { addNode } from "@/konva_mindmap/events/addNode"; import { useConnectionStore } from "@/store/useConnectionStore"; import { moveToNextNode, moveToPreviousNode } from "@/konva_mindmap/utils/moveToNode"; - export default function MindMapCanvas({ showMinutes, handleShowMinutes }) { const { data, @@ -27,7 +26,7 @@ export default function MindMapCanvas({ showMinutes, handleShowMinutes }) { updateNode, overrideNodeData, saveHistory, - loading, + loadingStatus, deleteSelectedNodes, selectedNode, selectNode, @@ -140,7 +139,7 @@ export default function MindMapCanvas({ showMinutes, handleShowMinutes }) { setDragmode={setDragMode} /> - {!Object.keys(data).length && !loading ? ( + {!Object.keys(data).length && !loadingStatus.socketLoading ? ( ) : ( - {loading && } + {loadingStatus.socketLoading && createPortal(, document.body)} + {loadingStatus.aiPending && createPortal(, document.body)} diff --git a/client/src/hooks/useLoading.ts b/client/src/hooks/useLoading.ts new file mode 100644 index 00000000..d42677fc --- /dev/null +++ b/client/src/hooks/useLoading.ts @@ -0,0 +1,26 @@ +import { useState } from "react"; + +export type MindMapLoadingHook = { + loadingStatus: MindMapLoading; + updateLoadingStatus: ({ type, status }: { type: "aiPending" | "socketLoading"; status: boolean }) => void; +}; + +type MindMapLoading = { + aiPending: boolean; + socketLoading: boolean; +}; +export default function useLoading(): MindMapLoadingHook { + const [loadingStatus, setLoadingStatus] = useState({ + aiPending: false, + socketLoading: false, + }); + + function updateLoadingStatus({ type, status }: { type: "aiPending" | "socketLoading"; status: boolean }) { + if (type === "aiPending") setLoadingStatus((prev) => ({ ...prev, aiPending: status })); + else setLoadingStatus((prev) => ({ ...prev, socketLoading: status })); + } + return { + loadingStatus, + updateLoadingStatus, + }; +} From e57948f0789da09d2e23f3bd45e4adfd71a1cf6b Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:47:45 +0900 Subject: [PATCH 031/110] =?UTF-8?q?feat=20:=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EB=B2=84=ED=8A=BC=20=EB=88=84=EB=A5=BC=20=EC=8B=9C?= =?UTF-8?q?=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/MindMapHeader/ProfileModal.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/components/MindMapHeader/ProfileModal.tsx b/client/src/components/MindMapHeader/ProfileModal.tsx index 4cdbc0b4..422893f7 100644 --- a/client/src/components/MindMapHeader/ProfileModal.tsx +++ b/client/src/components/MindMapHeader/ProfileModal.tsx @@ -1,3 +1,4 @@ +import { signOut } from "@/api/auth"; import profileIcon from "@/assets/profile.png"; import { useConnectionStore } from "@/store/useConnectionStore"; import { Button } from "@headlessui/react"; @@ -15,7 +16,8 @@ export default function ProfileModal({ open, close }: ProfileModalProps) { const modalRef = useRef(null); const navigate = useNavigate(); - const handleLogout = () => { + const handleLogout = async () => { + await signOut(); logout(); navigate("/"); close(); From 77aeb4b21434b36d3c4b3ab7c4012f129e5aab18 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:48:44 +0900 Subject: [PATCH 032/110] =?UTF-8?q?feat=20:=20ai=20=EC=B9=B4=EC=9A=B4?= =?UTF-8?q?=ED=8A=B8=20=ED=9A=9F=EC=88=98=20=ED=91=9C=EA=B8=B0=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B8=94=EB=9D=BD=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ControlSection/TextUpload.tsx | 38 ++++++------------- client/src/hooks/useAiCount.ts | 24 ++++++++++++ 2 files changed, 36 insertions(+), 26 deletions(-) create mode 100644 client/src/hooks/useAiCount.ts diff --git a/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx b/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx index 5deeeca1..61e683e7 100644 --- a/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx +++ b/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx @@ -2,22 +2,14 @@ import ArrowBox from "@/components/common/ArrowBox"; import { MAX_TEXT_UPLOAD_LIMIT } from "@/constants/textUploadLimit"; import useUpload from "@/hooks/useUpload"; import { Button, Textarea } from "@headlessui/react"; -import { createPortal } from "react-dom"; import clovaX from "@/assets/clovaX.png"; -import AiSpinner from "@/components/common/aiSpinner"; +import { useNodeListContext } from "@/store/NodeListProvider"; +import UploadAvailabilityArrowBox from "@/components/MindMapMainSection/ControlSection/UploadAvailabilityArrowBox"; export default function TextUpload() { - const { - content, - aiProcessing, - buttonAvailability, - updateContent, - handleAiProcessButton, - availabilityInformBox, - handleMouseEnter, - handleMouseLeave, - } = useUpload(); - + const { content, updateContent, handleAiProcessButton, availabilityInform, handleMouseEnter, handleMouseLeave } = + useUpload(); + const { aiCount } = useNodeListContext(); return (
@@ -29,9 +21,12 @@ export default function TextUpload() { onChange={(e) => updateContent(e.target.value)} maxLength={MAX_TEXT_UPLOAD_LIMIT} /> -

- {content.length}/{MAX_TEXT_UPLOAD_LIMIT} -

+
+

AI 변환 남은 횟수 : {aiCount}번

+

+ {content.length}/{MAX_TEXT_UPLOAD_LIMIT} +

+
- {aiProcessing && createPortal(, document.body)}
clovaX
diff --git a/client/src/hooks/useAiCount.ts b/client/src/hooks/useAiCount.ts new file mode 100644 index 00000000..de86a4b2 --- /dev/null +++ b/client/src/hooks/useAiCount.ts @@ -0,0 +1,24 @@ +import { useState } from "react"; + +export type AiCountHook = { + aiCount: number; + initializeAiCount: (initialData) => void; + decreaseAiCount: () => void; +}; + +export default function useAiCount(): AiCountHook { + const [aiCount, setAiCount] = useState(0); + + function initializeAiCount(initialData) { + setAiCount(parseInt(initialData.aiCount)); + } + + function decreaseAiCount() { + setAiCount((prev) => prev - 1); + } + return { + aiCount, + initializeAiCount, + decreaseAiCount, + }; +} From 43a988777d53a109e7921c06f88be407b60a3dda Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:49:43 +0900 Subject: [PATCH 033/110] =?UTF-8?q?refactor=20:=20HandleSocketEventProps?= =?UTF-8?q?=20payload=20type=20=EC=98=B5=EC=85=98=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/store/createSocketSlice.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/store/createSocketSlice.ts b/client/src/store/createSocketSlice.ts index 19863ebe..4d77f137 100644 --- a/client/src/store/createSocketSlice.ts +++ b/client/src/store/createSocketSlice.ts @@ -18,7 +18,7 @@ export type SocketSlice = { type HandleSocketEventProps = { actionType: actionType; - payload: HandleSocketEventPayloads; + payload?: HandleSocketEventPayloads; callback?: (response?: any) => void; }; From 476b18b79911927b8472b57c603bc5064f7043d9 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:50:09 +0900 Subject: [PATCH 034/110] =?UTF-8?q?feat=20:=20=EC=97=85=EB=A1=9C=EB=93=9C?= =?UTF-8?q?=20=EB=B0=95=EC=8A=A4=EC=97=90=EC=84=9C=20=ED=8A=B9=EC=A0=95=20?= =?UTF-8?q?=ED=99=95=EC=9E=A5=EC=9E=90=EB=A7=8C=20=EC=9D=B8=EC=8B=9D?= =?UTF-8?q?=ED=95=B4=EC=84=9C=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ControlSection/UploadBox.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/client/src/components/MindMapMainSection/ControlSection/UploadBox.tsx b/client/src/components/MindMapMainSection/ControlSection/UploadBox.tsx index 5c7620d9..cfc26f67 100644 --- a/client/src/components/MindMapMainSection/ControlSection/UploadBox.tsx +++ b/client/src/components/MindMapMainSection/ControlSection/UploadBox.tsx @@ -18,7 +18,12 @@ export default function UploadBox({ file, setFile }: UploadBoxProps) { function handleFileChange(e: React.ChangeEvent) { if (e.target.files !== null) { - setFile(e.target.files[0]); + const allowedExtensions = ["m4a", "ogg", "aac", "mp3"]; + + const fileExtension = e.target.files[0].name.split(".").pop()?.toLowerCase(); + if (fileExtension && allowedExtensions.includes(fileExtension)) { + setFile(e.target.files[0]); + } } } @@ -60,7 +65,14 @@ export default function UploadBox({ file, setFile }: UploadBoxProps) { > - {file ? file.name :

음성 파일을 업로드해주세요(머시기 확장자)

} + {file ? ( + file.name + ) : ( +
+

음성 파일을 업로드해주세요

+

(m4a, ogg, aac, mp3만 가능)

+
+ )}
); } From 1e0cbf59fd2ed31dee9439653031727ff9b663fe Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:50:55 +0900 Subject: [PATCH 035/110] =?UTF-8?q?feat=20:=20aipending=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=ED=9B=85=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/store/NodeListProvider.tsx | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/client/src/store/NodeListProvider.tsx b/client/src/store/NodeListProvider.tsx index 8350e89a..a3364835 100644 --- a/client/src/store/NodeListProvider.tsx +++ b/client/src/store/NodeListProvider.tsx @@ -8,6 +8,8 @@ import useMindMapTitle from "@/hooks/useMindMapTitle"; import useContent from "@/hooks/useContent"; import { useConnectionStore } from "@/store/useConnectionStore"; import initializeNodePosition from "@/konva_mindmap/utils/initializeNodePosition"; +import useAiCount, { AiCountHook } from "@/hooks/useAiCount"; +import useLoading, { MindMapLoadingHook } from "@/hooks/useLoading"; export type NodeListContextType = { data: NodeData | null; @@ -24,11 +26,11 @@ export type NodeListContextType = { groupSelect: (group: Konva.Group[]) => void; groupRelease: () => void; selectedGroup: string[]; - loading: boolean; deleteSelectedNodes: () => void; content: string; updateContent: (updatedContent: string) => void; -}; +} & Partial & + Partial; const NodeListContext = createContext(undefined); export function useNodeListContext() { @@ -42,28 +44,29 @@ export function useNodeListContext() { export default function NodeListProvider({ children }: { children: ReactNode }) { const [data, setData] = useState({}); const [selectedNode, setSelectedNode] = useState({ nodeId: 0, parentNodeId: 0 }); + const { aiCount, decreaseAiCount, initializeAiCount } = useAiCount(); const { saveHistory, overrideHistory, undo, redo, history } = useHistoryState(JSON.stringify(data)); const { title, initializeTitle, updateTitle } = useMindMapTitle(); const { content, updateContent, initializeContent } = useContent(); - const [loading, setLoading] = useState(true); + const { loadingStatus, updateLoadingStatus } = useLoading(); const { selectedGroup, groupRelease, groupSelect } = useGroupSelect(); const socket = useConnectionStore((state) => state.socket); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); useEffect(() => { socket?.on("joinRoom", (initialData) => { - setLoading(true); + updateLoadingStatus({ type: "socketLoading", status: true }); setTimeout(() => { setData({ ...initialData.nodeData }); overrideHistory(JSON.stringify(initialData)); initializeTitle(initialData); initializeContent(initialData); - setLoading(false); + initializeAiCount(initialData); + updateLoadingStatus({ type: "socketLoading", status: false }); }, 0); }); socket?.on("updateNode", (updatedNodeData) => { - console.log("updatedNodeData", updatedNodeData); overrideNodeData(updatedNodeData); }); @@ -80,7 +83,12 @@ export default function NodeListProvider({ children }: { children: ReactNode }) overrideHistory(JSON.stringify({})); }); + socket?.on("aiPending", (response) => { + updateLoadingStatus({ type: "aiPending", status: response.status }); + }); + socket?.on("aiResponse", (response) => { + decreaseAiCount(); const initializedNodes = initializeNodePosition(response); handleSocketEvent({ actionType: "updateNode", @@ -150,10 +158,12 @@ export default function NodeListProvider({ children }: { children: ReactNode }) groupSelect, groupRelease, selectedGroup, - loading, deleteSelectedNodes, content, updateContent, + aiCount, + initializeAiCount, + loadingStatus, }} > {children} From 98e9120efb2aac8504c9563baa709d0dbfee4132 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 00:51:27 +0900 Subject: [PATCH 036/110] =?UTF-8?q?feat=20:=20audioAiRequest=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=EC=9D=B4=EB=B2=A4=ED=8A=B8=20payload=20type=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/types/NodePayload.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/src/types/NodePayload.ts b/client/src/types/NodePayload.ts index 20a91091..437401be 100644 --- a/client/src/types/NodePayload.ts +++ b/client/src/types/NodePayload.ts @@ -1,6 +1,13 @@ import { NodeData } from "./Node"; -export type actionType = "createNode" | "deleteNode" | "updateNode" | "updateTitle" | "updateContent" | "aiRequest"; +export type actionType = + | "createNode" + | "deleteNode" + | "updateNode" + | "updateTitle" + | "updateContent" + | "aiRequest" + | "audioAiRequest"; export type HandleSocketEventPayloads = | createNodePayload From 33978410bbe6878b243f6607d3421dfcbd1cee7b Mon Sep 17 00:00:00 2001 From: Minhyung Cho <126141140+alsgud8311@users.noreply.github.com> Date: Tue, 3 Dec 2024 01:04:01 +0900 Subject: [PATCH 037/110] Update client/src/store/NodeListProvider.tsx Co-authored-by: Kim Nam Hee <103100783+kimnamheeee@users.noreply.github.com> --- client/src/store/NodeListProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/store/NodeListProvider.tsx b/client/src/store/NodeListProvider.tsx index 8350e89a..8c67426f 100644 --- a/client/src/store/NodeListProvider.tsx +++ b/client/src/store/NodeListProvider.tsx @@ -92,7 +92,7 @@ export default function NodeListProvider({ children }: { children: ReactNode }) }); return () => { - socket?.off; + socket?.offAny(); }; }, [socket]); From acf9def86dd0df69dbe46699adca8213b2014b46 Mon Sep 17 00:00:00 2001 From: adkm12 Date: Tue, 3 Dec 2024 01:08:58 +0900 Subject: [PATCH 038/110] =?UTF-8?q?fix=20:=20pipe=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/apps/api-server/common/constant.ts | 2 +- BE/apps/api-server/src/modules/ai/ai.module.ts | 4 ++-- ...alidation.pipe.ts => audio.file.validation.pipe.ts} | 10 +++++----- BE/apps/api-server/src/pipes/index.ts | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) rename BE/apps/api-server/src/pipes/{file.validation.pipe.ts => audio.file.validation.pipe.ts} (60%) diff --git a/BE/apps/api-server/common/constant.ts b/BE/apps/api-server/common/constant.ts index a6f99bb7..7657734a 100644 --- a/BE/apps/api-server/common/constant.ts +++ b/BE/apps/api-server/common/constant.ts @@ -1,2 +1,2 @@ export const MAX_FILE_SIZE = 1024 * 1024 * 100; // 100MB -export const ALLOW_AUDIO_FILE_FORMAT = ['m4a', 'ogg', 'aac', 'mp3']; +export const ALLOW_AUDIO_FILE_FORMAT = ['.m4a', '.ogg', '.ac3', '.aac', '.mp3']; diff --git a/BE/apps/api-server/src/modules/ai/ai.module.ts b/BE/apps/api-server/src/modules/ai/ai.module.ts index e2107071..a4e49ee7 100644 --- a/BE/apps/api-server/src/modules/ai/ai.module.ts +++ b/BE/apps/api-server/src/modules/ai/ai.module.ts @@ -3,11 +3,11 @@ import { AiService } from './ai.service'; import { HttpModule } from '@nestjs/axios'; import { NodeModule } from '../node/node.module'; import { AiController } from './ai.controller'; -import { FileValidationPipe } from '../../pipes'; +import { AudioFileValidationPipe } from '../../pipes'; @Module({ imports: [HttpModule, NodeModule], - providers: [AiService, FileValidationPipe], + providers: [AiService, AudioFileValidationPipe], exports: [AiService], controllers: [AiController], }) diff --git a/BE/apps/api-server/src/pipes/file.validation.pipe.ts b/BE/apps/api-server/src/pipes/audio.file.validation.pipe.ts similarity index 60% rename from BE/apps/api-server/src/pipes/file.validation.pipe.ts rename to BE/apps/api-server/src/pipes/audio.file.validation.pipe.ts index 444a1457..36a4889a 100644 --- a/BE/apps/api-server/src/pipes/file.validation.pipe.ts +++ b/BE/apps/api-server/src/pipes/audio.file.validation.pipe.ts @@ -1,19 +1,19 @@ import { BadRequestException, Injectable, PipeTransform } from '@nestjs/common'; +import { ALLOW_AUDIO_FILE_FORMAT } from 'apps/api-server/common/constant'; import { extname } from 'path'; @Injectable() -export class FileValidationPipe implements PipeTransform { - constructor(private readonly allowExtensions: string[]) {} - +export class AudioFileValidationPipe implements PipeTransform { transform(file: Express.Multer.File) { if (!file) { throw new BadRequestException('No file uploaded'); } const ext = extname(file.originalname).toLowerCase(); + console.log(ext); - if (!this.allowExtensions.includes(ext)) { - throw new BadRequestException(`File type not allowed. Only ${this.allowExtensions.join(', ')} allowed`); + if (!ALLOW_AUDIO_FILE_FORMAT.includes(ext)) { + throw new BadRequestException(`File type not allowed. Only ${ALLOW_AUDIO_FILE_FORMAT.join(', ')} allowed`); } return file; diff --git a/BE/apps/api-server/src/pipes/index.ts b/BE/apps/api-server/src/pipes/index.ts index bda84f3d..73ceb0ba 100644 --- a/BE/apps/api-server/src/pipes/index.ts +++ b/BE/apps/api-server/src/pipes/index.ts @@ -1 +1 @@ -export * from './file.validation.pipe'; +export * from './audio.file.validation.pipe'; From 736970f7f090a9bb0438be9da453ebed9f4fba7a Mon Sep 17 00:00:00 2001 From: adkm12 Date: Tue, 3 Dec 2024 01:21:30 +0900 Subject: [PATCH 039/110] =?UTF-8?q?fix=20:=20HttpException=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../middlewares/token.refresh.middleware.ts | 63 ------------------- .../modules/connection/connection.service.ts | 52 +++++++-------- .../src/modules/mindmap/mindmap.service.ts | 11 ++-- 3 files changed, 28 insertions(+), 98 deletions(-) delete mode 100644 BE/apps/api-server/src/middlewares/token.refresh.middleware.ts diff --git a/BE/apps/api-server/src/middlewares/token.refresh.middleware.ts b/BE/apps/api-server/src/middlewares/token.refresh.middleware.ts deleted file mode 100644 index 4e458379..00000000 --- a/BE/apps/api-server/src/middlewares/token.refresh.middleware.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Injectable, NestMiddleware, UnauthorizedException } from '@nestjs/common'; -import { JwtService } from '@nestjs/jwt'; -import { Request, Response, NextFunction } from 'express'; - -@Injectable() -export class TokenRefreshMiddleware implements NestMiddleware { - constructor(private readonly jwtService: JwtService) {} - - use(req: Request, res: Response, next: NextFunction) { - const authHeader = req.headers.authorization; - const refreshToken = req.cookies['refreshToken']; - - // 토큰이 전혀 없는 경우 통과 - if (!authHeader && !refreshToken) { - return next(); - } - - // access token이 있는 경우 검증 - if (authHeader) { - const accessToken = authHeader.split(' ')[1]; - try { - this.jwtService.verify(accessToken); - return next(); - } catch { - // access token이 만료되었고 refresh token이 있는 경우 - if (refreshToken) { - this.validateAndRefreshToken(refreshToken, req); - } - } - } - - // access token이 없고 refresh token만 있는 경우 - if (!authHeader && refreshToken) { - this.validateAndRefreshToken(refreshToken, req); - } - - next(); - } - - private validateAndRefreshToken(refreshToken: string, req: Request): void { - try { - this.jwtService.verify(refreshToken); - const decoded = this.jwtService.decode(refreshToken); - const payload = { email: decoded['email'], id: decoded['id'] }; - const newAccessToken = this.jwtService.sign(payload, { expiresIn: '30m' }); - req.headers.authorization = `Bearer ${newAccessToken}`; - } catch { - req.cookies['refreshToken'] = ''; - throw new UnauthorizedException('Refresh token is expired or invalid'); - } - } -} - -// error: Cannot read properties of undefined (reading 'map') {"context":"ConnectionService","error":{},"stack":[ -// "TypeError: Cannot read properties of undefined (reading 'map')\n -// at /app/dist/main.js:1020:37\n at Array.map ()\n -// at NodeService.tableToCanvas (/app/dist/main.js:1015:40)\n -// at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n -// at async MindmapService.getDataByMindmapId (/app/dist/main.js:922:23)\n -// at async ConnectionService.setConnection (/app/dist/main.js:782:33)\n -// at async ConnectionController.setConnection (/app/dist/main.js:601:16)\n -// at async /app/node_modules/@nestjs/core/router/router-execution-context.js:46:28\n -// at async /app/node_modules/@nestjs/core/router/router-proxy.js:9:17"]} diff --git a/BE/apps/api-server/src/modules/connection/connection.service.ts b/BE/apps/api-server/src/modules/connection/connection.service.ts index eb073b55..4fd2f100 100644 --- a/BE/apps/api-server/src/modules/connection/connection.service.ts +++ b/BE/apps/api-server/src/modules/connection/connection.service.ts @@ -1,10 +1,9 @@ import { MindmapService } from './../mindmap/mindmap.service'; import { UserService } from './../user/user.service'; -import { Injectable, Logger, NotFoundException, UnauthorizedException } from '@nestjs/common'; +import { ForbiddenException, Injectable, Logger, NotFoundException } from '@nestjs/common'; import { Redis } from 'ioredis'; import { RedisService } from '@liaoliaots/nestjs-redis'; import { v4 as uuidv4 } from 'uuid'; -import { ConnectionException } from '../../exceptions'; @Injectable() export class ConnectionService { @@ -39,37 +38,28 @@ export class ConnectionService { } async setConnection(mindmapId: number, userId: number) { - try { - const role = await this.userService.getRole(userId, mindmapId); - if (!role) { - throw new UnauthorizedException('권한이 없습니다.'); - } + const role = await this.userService.getRole(userId, mindmapId); + if (!role) { + throw new ForbiddenException('권한이 없습니다.'); + } - const owner = await this.mindmapService.getOwner(mindmapId); - const mindmapData = await this.mindmapService.getDataByMindmapId(mindmapId); - await this.GeneralRedis.hset(mindmapData.connectionId, { - type: 'user', - mindmapId: mindmapId, - aiCount: mindmapData.aiCount, - title: mindmapData.title, - ownerId: owner.pop().userId, - }); + const owner = await this.mindmapService.getOwner(mindmapId); + const mindmapData = await this.mindmapService.getDataByMindmapId(mindmapId); + await this.GeneralRedis.hset(mindmapData.connectionId, { + type: 'user', + mindmapId: mindmapId, + aiCount: mindmapData.aiCount, + title: mindmapData.title, + ownerId: owner.pop().userId, + }); - await this.GeneralRedis.set(`mindmapState:${mindmapData.connectionId}`, JSON.stringify(mindmapData.nodes)); - await this.GeneralRedis.set(`content:${mindmapData.connectionId}`, mindmapData.content); + await this.GeneralRedis.set(`mindmapState:${mindmapData.connectionId}`, JSON.stringify(mindmapData.nodes)); + await this.GeneralRedis.set(`content:${mindmapData.connectionId}`, mindmapData.content); - return { - mindmapId, - connectionId: mindmapData.connectionId, - role: role, - }; - } catch (error) { - this.logger.error(error); - if (error instanceof UnauthorizedException) { - throw error; - } else { - throw new ConnectionException(error.message); - } - } + return { + mindmapId, + connectionId: mindmapData.connectionId, + role: role, + }; } } diff --git a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts index cb05ff0a..b1ff9d27 100644 --- a/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts +++ b/BE/apps/api-server/src/modules/mindmap/mindmap.service.ts @@ -1,5 +1,5 @@ import { InjectRepository } from '@nestjs/typeorm'; -import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; +import { ForbiddenException, Injectable, Logger, NotFoundException } from '@nestjs/common'; import { In, Repository } from 'typeorm'; import { Mindmap, UserMindmapRole } from '@app/entity'; import { v4 as uuidv4 } from 'uuid'; @@ -80,24 +80,27 @@ export class MindmapService { }); if (role.role !== Role.OWNER) { - throw new UnauthorizedException('권한이 없습니다.'); + throw new ForbiddenException('권한이 없습니다.'); } const mindmap = await this.mindmapRepository.findOne({ where: { id: mindmapId }, relations: ['nodes', 'userMindmapRoles'], }); + if (!mindmap) { - throw new MindmapException('마인드맵을 찾을 수 없습니다.'); + throw new NotFoundException('마인드맵을 찾을 수 없습니다.'); } + await this.mindmapRepository.softRemove(mindmap); } async getDataByMindmapId(mindmapId: number) { const mindmap = await this.mindmapRepository.findOne({ where: { id: mindmapId } }); const nodes = await this.nodeService.tableToCanvas(mindmap.id); + if (!mindmap) { - throw new MindmapException('마인드맵을 찾을 수 없습니다.'); + throw new NotFoundException('마인드맵을 찾을 수 없습니다.'); } return { From 08f7061c0cfdae562b7d318f20d8dd1573860959 Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 01:26:06 +0900 Subject: [PATCH 040/110] =?UTF-8?q?refactor=20:=20toast=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=83=80=EC=9E=85=20=EC=A7=80?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/common/Toast/Toast.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/src/components/common/Toast/Toast.tsx b/client/src/components/common/Toast/Toast.tsx index c49dc409..a236f963 100644 --- a/client/src/components/common/Toast/Toast.tsx +++ b/client/src/components/common/Toast/Toast.tsx @@ -1,6 +1,12 @@ import { useEffect, useState } from "react"; -export default function Toast({ message, status, onClose }) { +type ToastProps = { + message: string; + status: "success" | "fail" | "error"; + onClose: () => void; +}; + +export default function Toast({ message, status, onClose }: ToastProps) { const [progress, setProgress] = useState(0); const duration = 3000; From 1f9ea0095b9501c9affebb2ea07156829e26471e Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 01:27:01 +0900 Subject: [PATCH 041/110] =?UTF-8?q?refactor=20:=20wsError,=20nodeError=20?= =?UTF-8?q?=EB=B3=91=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/hooks/useToast.ts | 8 -------- client/src/store/createSocketSlice.ts | 11 ++++++++--- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/client/src/hooks/useToast.ts b/client/src/hooks/useToast.ts index 313cf769..4fc5a423 100644 --- a/client/src/hooks/useToast.ts +++ b/client/src/hooks/useToast.ts @@ -2,17 +2,9 @@ import { useEffect, useState } from "react"; import { useConnectionStore } from "@/store/useConnectionStore"; export default function useToast() { - const wsError = useConnectionStore((state) => state.wsError); const nodeError = useConnectionStore((state) => state.nodeError); const [toasts, setToasts] = useState([]); - useEffect(() => { - if (wsError.length > 0) { - const num = `${new Date().getTime()}-${Math.random().toString(36)}`; - setToasts((prevToasts) => [...prevToasts, { id: num, message: wsError[wsError.length - 1], status: "fail" }]); - } - }, [wsError]); - useEffect(() => { if (nodeError.length > 0) { const num = `${new Date().getTime()}-${Math.random().toString(36)}`; diff --git a/client/src/store/createSocketSlice.ts b/client/src/store/createSocketSlice.ts index 216a8846..1dda80eb 100644 --- a/client/src/store/createSocketSlice.ts +++ b/client/src/store/createSocketSlice.ts @@ -4,6 +4,11 @@ import { actionType, HandleSocketEventPayloads } from "@/types/NodePayload"; import { createMindmap, getMindMap } from "@/api/mindmap.api"; import { ConnectionStore } from "@/types/store"; +type NodeError = { + message: string; + status: string; +}; + export type SocketSlice = { socket: Socket | null; connectSocket: (id: string, token: string) => void; @@ -11,7 +16,7 @@ export type SocketSlice = { handleSocketEvent: (props: HandleSocketEventProps) => void; handleConnection: () => Promise; getConnection: (mindMapId: number, connectionId: string) => void; - wsError: string[]; + nodeError: NodeError[]; currentJobStatus: string; connectionStatus: string; }; @@ -25,7 +30,7 @@ type HandleSocketEventProps = { export const createSocketSlice: StateCreator = (set, get) => ({ socket: null, role: null, - wsError: [], + nodeError: [], currentJobStatus: "", connectionStatus: "", @@ -46,7 +51,7 @@ export const createSocketSlice: StateCreator { - set({ wsError: [...get().wsError, "작업 중 에러가 발생했어요"] }); + set({ nodeError: [...get().nodeError, { message: "작업 중 에러가 발생했어요", status: "fail" }] }); set({ currentJobStatus: "error" }); }); From a01985fad95034d3c6bb719c6addd0c0674cf2d4 Mon Sep 17 00:00:00 2001 From: kimnamheeee Date: Mon, 2 Dec 2024 16:40:15 +0900 Subject: [PATCH 042/110] =?UTF-8?q?feat=20:=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20url=EB=A1=9C=20=EC=A0=91=EA=B7=BC=ED=95=A0=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20404=ED=8E=98=EC=9D=B4=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/main.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/main.tsx b/client/src/main.tsx index 854f295e..96289b21 100644 --- a/client/src/main.tsx +++ b/client/src/main.tsx @@ -4,12 +4,13 @@ import "./index.css"; import { createBrowserRouter, RouterProvider } from "react-router-dom"; import App from "./App"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import NotFound from "@/components/common/Error"; +import Error from "@/components/common/Error"; import AuthorizeCallback from "@/pages/auth"; import Layout from "@/pages/layout"; import MindMap from "@/pages/Mindmap"; import { ErrorBoundary } from "react-error-boundary"; import { useConnectionStore } from "@/store/useConnectionStore"; +import NotFound from "./components/common/NotFound"; const router = createBrowserRouter([ { @@ -57,7 +58,7 @@ queryClient.getQueryCache().subscribe((event) => { createRoot(document.getElementById("root")!).render( - }> + }> From fd006655033f4577f496e36d4f922d801706fc05 Mon Sep 17 00:00:00 2001 From: kimnamheeee Date: Mon, 2 Dec 2024 17:20:19 +0900 Subject: [PATCH 043/110] =?UTF-8?q?fix=20:=20connectSocket=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B5=9C=EC=8B=A0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 머지 과정에서 사라진 로직을 찾아... --- client/src/components/MindMapMainSection/index.tsx | 2 +- client/src/store/createSocketSlice.ts | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/client/src/components/MindMapMainSection/index.tsx b/client/src/components/MindMapMainSection/index.tsx index 86bd96b9..8a4f2d9c 100644 --- a/client/src/components/MindMapMainSection/index.tsx +++ b/client/src/components/MindMapMainSection/index.tsx @@ -24,7 +24,7 @@ export default function MindMapMainSection() { useEffect(() => { if (mindMapId) { - connectSocket(mindMapId, token); + connectSocket(mindMapId); } return () => { disconnectSocket(); diff --git a/client/src/store/createSocketSlice.ts b/client/src/store/createSocketSlice.ts index e0169c92..4319ceac 100644 --- a/client/src/store/createSocketSlice.ts +++ b/client/src/store/createSocketSlice.ts @@ -11,7 +11,7 @@ type NodeError = { export type SocketSlice = { socket: Socket | null; - connectSocket: (id: string, token: string) => void; + connectSocket: (id: string) => void; disconnectSocket: () => void; handleSocketEvent: (props: HandleSocketEventProps) => void; handleConnection: () => Promise; @@ -34,7 +34,7 @@ export const createSocketSlice: StateCreator { + connectSocket: (connectionId) => { if (get().socket) return; const options: any = { @@ -44,6 +44,7 @@ export const createSocketSlice: StateCreator { - set({ connectionStatus: "connected" }); - }); - set({ socket: socket, connectionStatus: "connected" }); }, @@ -93,7 +90,7 @@ export const createSocketSlice: StateCreator Date: Mon, 2 Dec 2024 17:33:41 +0900 Subject: [PATCH 044/110] =?UTF-8?q?feat=20:=20=EC=A1=B4=EC=9E=AC=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A7=88=EC=9D=B8=EB=93=9C?= =?UTF-8?q?=EB=A7=B5=EC=9D=98=20=EA=B2=BD=EC=9A=B0=20notFound=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=A0=84=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/layout/index.tsx | 2 ++ client/src/store/createSocketSlice.ts | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/client/src/pages/layout/index.tsx b/client/src/pages/layout/index.tsx index cf60bccf..ee84252c 100644 --- a/client/src/pages/layout/index.tsx +++ b/client/src/pages/layout/index.tsx @@ -7,6 +7,7 @@ import { useConnectionStore } from "@/store/useConnectionStore"; import OfflineModal from "@/components/OfflineModal"; import useWindowEventListener from "@/hooks/useWindowEventListener"; import { useState } from "react"; +import NotFound from "@/components/common/NotFound"; export default function Layout() { const sidebar = useSideBar(); @@ -18,6 +19,7 @@ export default function Layout() { }); if (connectionStatus === "error") return ; + if (connectionStatus === "notFound") return ; return ( }> diff --git a/client/src/store/createSocketSlice.ts b/client/src/store/createSocketSlice.ts index 4319ceac..bf2e0f5e 100644 --- a/client/src/store/createSocketSlice.ts +++ b/client/src/store/createSocketSlice.ts @@ -52,6 +52,15 @@ export const createSocketSlice: StateCreator { + try { + const response = await getMindMap(connectionId); + get().connectSocket(connectionId); + } catch (error) { + set({ connectionStatus: "notFound" }); + } + }); + socket.on("error", () => { set({ nodeError: [...get().nodeError, { message: "작업 중 에러가 발생했어요", status: "fail" }] }); set({ currentJobStatus: "error" }); From be2bf0d1b9d4747e7e9e55a68fca4082a460aff6 Mon Sep 17 00:00:00 2001 From: kimnamheeee Date: Tue, 3 Dec 2024 00:32:13 +0900 Subject: [PATCH 045/110] =?UTF-8?q?feat=20:=20forbidden=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/assets/lock.webp | Bin 0 -> 13524 bytes client/src/components/common/Forbidden.tsx | 22 +++++++++++++++++++++ client/src/store/createSocketSlice.ts | 2 ++ 3 files changed, 24 insertions(+) create mode 100644 client/src/assets/lock.webp create mode 100644 client/src/components/common/Forbidden.tsx diff --git a/client/src/assets/lock.webp b/client/src/assets/lock.webp new file mode 100644 index 0000000000000000000000000000000000000000..f17a619b247a848e77e1320c67db17197444427c GIT binary patch literal 13524 zcmYkj1z20b@;)4#;=!d92u^XA;sh_y;BLjW6lw9|?(SOL8ru4 z+F>med82>Su+`-!gzpwy-#F*>Fv00u?4dv)=;C&pcTMO<@-3_-0qch~r505|7tdqE z-0kClK;e+!Z6)-=Qc4l<(((El{XmtbJ+B>Mo|)Q5oK%Pi4WT6++58n_8I)^d|JvQ) zd7M7*bP*8m{dk$}xzkhi$KrB_!;&z`43P_vQh(o-ExHwry>DpXIj%11{U?eGfQbH^ z&JPSwb@M)x^HCuE>~y<|;&Ge6?fl|k&>;c{|NSlxPV0JhV07B(P}uC{NT5k|3XiDO z#f5U=7ZQ5sv1aDEFHN%rmi3!B5VWNr*t;18plgnU(HXVYqzk!FjMXWnN!6P&t3vc+ z!9zt>^cV%l#aYD7OwkV=Yd3Es`UdV22^x)|ywXi_flJjOigL|&0%G%bf<|@Yt8Cx% zWC=coG0Mq|ieq4o`x1ye=WM5f)ITr^)~y?L>gcntuiVOe5tdBS^cg(dGdtT=B49oF z&sfBg>O%w$>h+B=S*6Nv(1)P1k=%?oQ|Uh@mN34pfOcr&NL?VTUgRNm6+QCw^1@(i zc$&m`C4h-!cqiQLFjV$qM8U#QH`d$;#$CaTY5|>MSQ~4)-@>5ah=_tBh$j}JQyxxj zf_GGXzxJG`-zd?GQa}U2<4i0e z%Cpg-T8}p&EP0bA?{2Bz`!jHy(JVHty4WB&*G$G!nlU`BQ||f!vDw`0E(90+aUZ`h z(XGSFt3o`{D8(&mk7 zqXgHe)5b3sGptKh|1%_iCVXaFw#ggQMv;7#hQ4Gd4!;3xD<4$hVfHCLSZ|<92O`!g z$7+pBd)@nhiaB(SdA+%vXOR7)j=INtn1&~>fM4yixXGN|^kf9W&u4YH8B{0s7LTNa zWiC0wo`U2ao!E_|Lok7I*rI+96j?ZwS;{#xVj%?NN;otn%K_{7>i)2Ywc?X};^xt{ z(b1;q6vj+*6w3o#!f|ZUQ=2SE(VNN?^?4?oKF3J*S@BVj`%L281~(UgQI#Cdl!`B` za7*!ZLJ<&RPH4)_1)xaMGn1{H#?e*jJZ?z{2Z4*6uhTW)jR?;bB~gz5=IDKXGx9Jn zjEY&@Q#2dSl&q#SmHG(B-h-RrSMd%40h&yO8=cS_Rmdc0P#gW&f{HT+|2ikcOiOUh6C%`HQ(!OoDzs!)73Nq4u-qnNI>q4FAoJ!8@`Us zawTVR0r;p}<)TiWsq31eI>~?0?Y$~3B;f`e?1$MA0}U{E4XxZDHpuM-$u>oa1^*KH z6mo=8{qxdBKs`Wjk1D5Ha))Wlxz`ns-6Gcss5aMgM441yg^R8-<$`+Be~v~=xap2A zm_S|=Sr$_MU3JnaDp3^)QW*|Z`PR9F&6r%{$P-}hZ*`gQo3ieGIk!>2u$hXoL)d~f z$Q4f;en;?K5U>?o5>l?e6uE&apbme1)gO}Y7>cVP>kd~wE0sa5`6Ju8Ai@?0P}JPBRxRF{1c|Wc(}c}-uO|(|F*7bn zM1Rdc5~Gr}_c~33Ys+EStkujJ#2S;FV{m561^1OOA+{EKvzS%& zacadcG7veP$)o1u?J*Ht^h-lmHzf!wIOH24p|p)6zLi7e*WZ9MreqN+odOpicdz!z z@|zqdU^t)5+tiS?gj|EQV4hTgTY|h3>EfQ~*<`W#D%e#o+>&Cik7FNTPVg0n6oY-M z%8cejNFs>(x5^ZOCDauPAz=%QoX`z#Dx6$@;M5C_n(1I9h;m|YNPF{Ire6}c-bko+#5wFi~V zn^N<)dxIVl-Lpu9N-*^dG^AEP{~lWaeemJ;43M)`rzE0?*M_@_X=im2l^U-mUrl0; z`Uu3GO2m-(_dElLmI9ScrCshYi4R>+VE*Cmv;u^8tecuLoin7?vF&ArkhIfo?h|{1 z*eDM`+-WRCM0xr$N22mEN5op;Zx+^TIDg#)M=JH2w+$A8=N~8QQfDdDSg8)o@)6hF z3k$*KCxHtlzKiI?j^u)npz*<>!h|{_Z~!mYbrh$28^Q`I*j9#xrAY}am5$lKkobkh zHUP&lR!@(#;0Q-6zl+DLv7KKhNOP#k`PWPPTZyuJeMV7Y7Qp;aAFa&w0|tg2@4B-< za+Y3)*jvUPIC+|6{KQ&EEQ$QkJ9S2j2x1Hwo0>sd$;oR$V$zBY`a^Z2DcXEOc9%-` zSOs5v4=+4mMSTw+j5RX$L*UU$Q6KIrErjt%#*k{+*7*1iOmc5 z-!k-r^Ot=#j}!ZdfXpEt7=nwU%C>Uv8Q`0ASq~vB_hYwaUuW@2-p{%)aw@tSB(mt4 zaKfxoXWEK&p#w-6-QTViSa|;)m`BEl-0L$_X@9f14~J}2g#B_8u87$mVJHPVDe49$ja@&hEI0)$lwu zM-;s0_#_SW?Xo|4Uh^2Ka}zDxxavxPjJ?hJs>Dc3aU37S+WI$r91ehv+2yFl$QS&E zG6jsGw6!Wzxhe zxIb+te?;-C`+;4|ww22Rl%`BW!l;D4#?n9CGh+S}F@xa4q8V7UVQ09CP?bOb`yTs}D&SiTEEj`yHrwC)wymzy$kz^GoYBgIRa%H}N7@&g_)S0@khYN9Gle4h(+HYWc z3`T}}?B>upL5>U8%F)obmNg6l^nzJRa7NjQ=Y58X#+owYq;91kGc>YHv@D*qMy9%* z$jSub^BW2v80(eIdmA0C_i~tY%BeIwR&ge5h;KA#^K2-n6ZaX>ZaGM4F zqbDwpP8%X%wYnqBMAzCEDC=uwoX*5y0_`>ufUQa0>$OQBEYJq zY2W~J58rUH86@0=7pK2MIT8;vd-Nw{YYt@q?USNAU-K6x#Xj8u^iSIEaLs=iq__az z4pOL?4nix8OqJQuiS^FzDcT_4TXA-p?F0h8(4`nV2I{YQAAgLN%j;K!p}w`%3pFR! zJ3=ySJU4(54jMp@RdnaD#du>*yu6;c)_7hWc*NW3-^NmEG1Q^9PWVv?GG||W9_3JZP ztvW{pb^%5fjxOhK;^OEb1^p(a^D>jO*(AOzKAuH1O|ZSzf+8$JMV44WLa3hGm{%Ci zl8q%TD=}CLoXr4tX5Aji6dtF7c)a7~bwP7F>;N*K&FHufp9=b&hFu^PNC=zg%KFT- z<1{?=@!B3eOw7)mOBC(uar9v`#L7*ql7ViW?xNon<&|PdFNX^JjT6l}%aw)cU|YAy zXSFGHRCNOC^WBz$EYK{XoV84E80R_?pDb+8X1@PGSDqzk>sYz1U9dz2J4r^R+N(+0an=4Z&>6rFaS! zhim*yL%qI|MkO%0OLDIRPP!16i@+ic`GT||Hk_lL^N-ioblMHdGJ&o>ke@nlN>*@e zs5b>b>7m;XsO7vE*~zM-36-xB#hB}Kg-LNPawt8A z@Qw1JEZ{Z~LlR(m(}G%xGp~s{@#_1cH2FEhqC6(*vBa_ph_XY33J|VLv|yw^?h4c! z#@;F)TG4mS;jI28A;Y@7at)+`=vW7_F`i<9yC$yQ6irA+zg`eToyDnvO4VtYpP-Z> z_vBvOfaY~eH{Uz)Xg0U20fBprHGLUcz?2tFv%2|$GL=X;G8RHI#kr?N)I^-Wo`r;x z!gU5b&is(o&&7L`8h#r^PIV~-l17O*j#;?6idE5hWr*ubywvlP)jA=U3A0A2&QucQ zh|E4d`9lv1Vl3simg%47@@9dhlqR}F=@@+{!1u;%JJRu2AG8RF4VWCbD|<>eBAx2e zqBVMAo$AxhG<)Vr#~5eNxtf-2rwWTDdq^sRFWBD&_9O^)z$I`DmMs=A^I4CIkUw>5*}j z(#3vv!AX}zAxs%g3N1s;7BIw=n<7_9;bsH!k-K!KmPw5e9@y`C&(Kmn*3W0Tl0}*} zTn&Vk<)AHh5Axphv@!Zaz&u}u!J4Ed(tIshlefPXl4dO#oxZOM92`*t8SP34X+)#S zs_n1S6dja3o=lWIN=5G=C@I$UOuvhx&h#W}2#=%5?;$}P4TKJBflB|Q^}8VId7-0q z8O-2H<=HO2KV!E?>*$y=m1}cdGCQ{XuXr`ct8ALkkInB0EWfp6jM5!dah0yS*jaQ9 zqY|8#CjB!LL2KiIiY~QAC!9Pcy-hY+$bzITzg(4{dM7KS=Sy1&TKz}6J^y{WHs6og z)&gxJnn*{YrOUQ6M;_H^T3fk6lJjgh?~MW<|BR)g#=m1fIStA$_^sm4TXnLmht#ND zvhsQKtaSab9tsOJ(He_SKC~(!A!e{R@Xbu8Q!BXx=?53>i!;mCEu8Ao3%rcuvo?Yc z7wz@fDtxgFZ9Y_$_>J>s&1-f6FMeL$ps}~M{B5m5TP>b(eu1JH%zhKmg#)56@nu%2 zb+Jb738_~HE;vV(`ubvKsZHO53Ce3^n|3m^klruPx+=+JT=|yxXjt<)Wf~&gdHt4a zCN{nZZ)`o$Q$yJs{1bWfBzULZlY7M6J2ZYyEkHKLSWS8d`6G~vB?8jyxi=$kl^YBC zYD?ZKRkHI`jSR}7uFr6o73=I*F5B^}!_sh9Y1;5?NA@kbgc08k}eW(B1b9#B`%4Dxq-63_NM*!1rB_85x+;m26$58>mgB z%<%>~K(<6^Ta3GjaDaTs0&7_p!@+HFzi%QT6SQf<1;3mSpjTNyc=-^+jdKVxdZw4+#T#~k z2bEqj(bnNH*{Mj>4grpt5HhOSql$f%?4anOK0466 zS@Bc|OWcA)ad{ChxEzS6mp3COd*ed**AZCcWVmj&M8lXR{g(mhq3kmtk|JiBJLme|LYb&vgb>vHJr{S8 zL6-JFNK9%+sY5^278l>+fE;#0D#EN8PMH`_c#48vyy6Q>y~J1ifVBmvPvrUuwHj8= zi7~Yhwh^+={2dWW`~wfmRLYf6A_ zSZ9zbIx)y%p-e{yiBa*9)n#IDO*AN8;nv67t`q)n$+0+Nn}48dJ8swK8*L}3RA}?t zHR+ZtXA@1wVFi~jYfd*TktfF*Wrjbr9ry5Cq)`A?H-;$$(S8e+4HNhtcXibl?0^Oc zazAry)Y~Qo$HD3f=vm#*`T>4mHLuQ+Lms+MG+!^6<**I!>yoPwD7C~+WXiu4#qr<7 zfZ~N{4}OGqTy^unQEGMaTQ2D5@wdl-QkS8~XHDm-D3xL2P~R^#Jt#Y%0brPk(y6w8 z^osNHA2$OyfS-1!7Kvl2d+Zhxn6t%WZatsx`OqJwGQ7)@klhuTna_~b=>sL0lm09| zNaWkr-?Kj!EEqiDa9btDd_!Oj3h?fBR&kf}Em+ijFU!WLI29=Z8sty-8>~Ub7&o+1 zl8avXdJkk8+k#x>r-O{DHt$;=_#kO04!ePy)=9^#YB?3w=+Gmqb*$sO+l8 zdvGezZ|Gnt)&GsCP=>;Lf=-o#JFU<6%c`$wAI&c%hB(DjCCs+7hisqiopiR~+%9Hh z?oL!sS*O@K@vxCqkGY9pd%=zAs#SZepmc39Aq*g!yIz}=20UZj;tDiK#Qk@w;Roji zb@mUggz#ym!5?4CMZzzMG$=N%ct`s)i=GjmRbYiDJ$f*0M;n`r!@<5O)(io2enY{72>1RUJG zWAJIV?CYbqa#;*c-FdPwGGRk|x{qL^sQ*n$Y;VqyvqM@v1#FNTVszU44`19@2OU|j zCwymhO1%@7ga|s-aMOl9{!-&K0-s=x6n`rxNwoHT2z%{o=fgAyw=*FEsnb57_1sf# zhzlI`_J5SG5e)e3Bc+f37orw!;iR~QhIYJQa5CrL6lW$L9iC=o44bZ8*K@xqO^1xnoyCgVQhFRH2+nBqD3*&cH+al|@=+(2~ z(~&z>Xa5pZwg;c}W;)LxgO|*a_J-GAtM?7qFZ&N^&!yLuR~0W7UaAuah0~9_ zveBhJ1260^zTc#ttQuAte5^0Ig8Uf|q&lYlYCNLk?A@+ui`ToI$% zgw+3uKpE-E+YPT%`MZmCl=rHQK{1+u z$^3szJ}InT)In#gl4|5C-AKAKAr4PU#&3-h7mM!x7NH0wd@;d8-dQb>P4E$WlVoN3}{4rTZxX{zn%(LKQ|KM5m;E7BNy%^)nXF77Lkt5zou;$RS z10h|OSrw68NFxBhM*@LSp7jacr?YxiT^*8GV8J6Q;n*NLX8nU_d)I~*w?~Qj28D@2 z``})Zys~$j<4K+*%5GrJ1$6Y&x!(sTkrLJNe3oSH=R-T@ojQPY!pzz$^W#;DfBk#?BS(dpQ z>yg-WzR2D$V3t8vx9D0Ef^S_ORiFJgG_$WPDUnWB5T0UW3zbmP7isWRwTn2Kub@+I zd9G+hRMJ*owOqH~{nX4TQ=MUso13ekLrbUTPO157dH>2pZ@?Od=H}+$7TKPdb-A$*9YNg^gfn67&}RXI zDJw?Q&!BUQfF)%s&SD*90H(WdM10RTTW$gkXrOicsDxZK_C#-(2yU+94{rF_(Mn3mo*9i(D^2Q(J#8}7qUusyA0}hqhP_*`upKm7I`EG4 zoDw5R-dopJhIPE(c+LgCOTx*ld;O%6Q0UFwECvoK83JM(NwvAp51F^C=~IIGEQWqZ zvc>>Spyr1Ex2XN6Gy=TbA5fB#oj1H5pQYb?M9b|cQer@Y$n_IQ6HE~6JHef`NG=!j zKOyJ_>res!%9dET7c=iSdRRHvzd%$&kRKjh0@@*?Gk8|(=}uBS(6?UxLJzA2CZiP< zM|Y+|=6ySGN+iWvP0mGD&tmE7mk^|#Tmyrzj;bQm@E5n%Xh+>`T`H+GI(Vu~sR^5teSxYA^4pk}`zx-wQ8>cJ2_tC!F3P^v4dIXwBdJ}dFS?!19*x5a+i zx@oG3SZ#SzSgD*L=r(F{p73Fwf+;;&0 z2yG+%Az{2TK4MFEJ5$$9m+`0IN#zRBEtVG}*g_kjuSEMqgrCO=`DxjABD_P-Z!;vk-K{tX5<_QuA|KfY zbO{DYB3W;pNVCRK^;_;h zb>Y9RJjVW6zQSWHRr!PShqoi(Xjum|^D{QTT6 z4soHX2akUDSvN+V^d`$%FBaz~C0Rdt33@wSfIp6j82oCg!(1zOdp;=#QJGymJXfDGHUn zc`Hsi%w7EH@XJ9viy1`&Mo-F(WX&iDX}8lj_hxREloMQ!BtaY^YxDH$zgDgAL#-cU(nS&=~a8vwY6l#&Rqpq*lY$my9uQlChBL?1a%B$ zo+XMQz84xAYDNfIE94h*=}me7##5*v;j?&F(6{w00?(l`#H@FWv};>F zLsLHxwLb(eBc)RYFutyKKI&7Sr_G_zR50QqQk=D`+qa2B$o*)a_v(Kf#d=5BoRC@< z&t{+uKMtERE40}SOYc2g$_TVT@k`SOyO6NT0DxcTXEZ$Kv2r$Guuk#?Z5^+>ztD#3 z#dRg!VG75g{03)z?^@;grycW%b5;?xnO7;vYAW{}7lN<3KWV%~MV4CjKhAC3@Oq>M z5Rx9eOKf^2TDhu>M190nh#^cG*^nDAN@8}HRd_j+w_3S1=6d)OtfG(V=jYordH74c zV7}h_^L5A!fK`KfZGzf)GiLocR(@AHYH56|_iY)5bRtfw+qRwPZJ`ZqhTPxP&k9&x zZz^cZFl1e~2uV!%2pEO_)_Q={Nf$2RMzrU0rT6PpHLk-3_dR{g)M+=eK+)@*j>%tq zVUI^hV$bu!0p4W-Y8pEEu*WV-dUb!aM9wJrbKUu6TQv*e&6c@^b;SGsbbR@p$Kolw z;J|*90(bQFXgz0VwIA77-J7*U=^#%X zWK?W82Fsk~j6|X5xd_KednM(=jUU zBzPLKwb4BXUx~i+_jHN8%loJmTS=cC#F)#5qe%6WyU}F2Y{2Qa?dz;h)LJ8#ef*23 z<%Df>GH-p6)6Fvi>Q^qg5X2M|Zu@#MTt*Dw&4GNy>Y7CgTZ@0ndf43u!ru?FANHqR z>nPF+<@5ymcw;Av1xkv%R{=;PC^S@zl}kr&mA7KJr++|x*ozOfdqP|=eQKz-OgLR1 z#gm<^-EUrNcyIqMR6jW|W_e;=Yq~B^|Cx)_^FAc8WQa@eM9O%ew`|8c{YuRjT}Hxg zm`JCPj_N+9Y}qgN5{NIXrf_Qa^sAn_kI9fjGdt+X+;4vjpjc$ytwYMD3i zEuBU6HP;9qx9dxv)pCMn4)1s1N~oJ}7NkHr&hYqv_AK3AymuwI5$0My5y>)baWbDo zRNrwm+^EY`d9d$e^XLYsPZ?f*I-_;%GAq?TV1@GqI2McIBo*P9`ztfYjG%c{!-*TH zTSr&FRORgYOdj`*i2Ih5$O!9hh5wvTDik8M318yjWxo_8`vN7c{BrMQT))z7dQ-W7 z9NNm<^1}dud9d8JBfQ_$@XLa@3g=Qt>c>0R-3*yB9;F*^vt2zbzz;|i#>qIYr3H|u zR&?^a`rLdaXC&(%R3ayG&)?Y1`#7X+7d1H<3QBJ2Wj}o1n)xE)G(=5htSsREH8XH= zB2-bljSV&M0M;nxdnpI=jQD}p2=xKNj_t?w YOi>|U0MJ?PuUXj3*F75hyPD`BG z8qnIOht*oT4AWn2mwFM(>{WO_^7SABinZ4?du?+Y{yXK}3RaxMmOqJ&#yuAl8nQH$ zz+NqunGMHhGH?$nIqyy=jShCL|B!|+=_#~qu(Y=a0mimfqr{>HdFO~w1Lu_B{8(Ri zbDuBYM4dz@^b|xXDKz#ni7vZ&XKvS%d1b7uo9|v}>Sfn|u35Pfw2P2AgqIRtUyr+L znW+%n95gw_2K6IjVnJw(@YAnU=!21T8Ex>N|2S+`#@PS~$p`_0k;A7E-wbMVhI^tx zh!dlK4#JH)QChmWF`AO|b;h|`22@3m{Sk*K{hYT~nZ$ep@BN94>9jt6(L0}w5KrOO zv|P8aE%ho=dsZ~a2tgjxs>f$tw{si9G@~Nm_3h@i%daAv!m9M<$PW&>_cwW6kn|!1 zGSkU@3h*G%`Osm7M*YB56@K>f%=zPkfCn|vGb-8E+R>`Qg@ZDZcWkj70HGt01AeXf zt*@Zx@s=n_jkL-=HI^-?^ISAca6KR-6D02GS`5n_gqdloIT z(VS^{-xxJv{I2b`H#cQ++SQtMf7s2G;t)$hj-KyHSwT!pa%FW4D-7#-Cvu8Ab=E<) zkHVQYMx3zjc%bzdwEg{+yV~A1b3P^{KmFD&f$>?}lOTbErgh=!MUl&AbdKQkT;nY!mSAYlkN!&u>3xCW)aTeTc9Vql`us3CCVy;7(n>PtJbx zx<`PFs>9^&%s>wps$E5urP`O;v7*H4LK4hf?a#=;9rCN|%@>BOHkn7qBfWI#s*IUt zD(!29K$>bsZtOc?;4sVFulj6U-}Yom><@n#?e-gQDeufEiQhrASwnt%*)0A7ww1SU zoQ@+RN>LCKdl@66w|j;X0LI;h`h5_OoUE+I9*^D^PLs@iJ2a(#n7cs}irLZvE^?0% zDIhM^3m(mxunCQ_D&mOYqsRCy(^IQ1OY|(YYOMHPaMIYP|aJH zX`*s^uP(H>!z&tDur`$1^zBx@HZ>vJ(P3(Kpx(|2$;=af9qrrl{z8FrZt{h+BL=jU0GJ~=t(e~)iN zMrSkkp(^WpxpQQb^XdV#0Gj)(FHL~-iwIjwC?lO1E|fsJ4#U3I_?JUhMkHtir~c3bLa;jOQc4$FI~iH7b?fy6O*xW22N#e?NJeNka~y`uYIbM%K=^DC9@fP`!5 zF3u;``J_?;|MfWqRTedMuXlb3H~SI%y$+}&D`~k6P9|0_<#Y<)oVJfFeMJcvyEQzA zCI#kR1w#5(g%{Z3isDQbaiw~q-WJMkX}n3snh>w_WF?YlYQOV$4$eixH+50Lv&CT&)F2S^uge1q_bZOs=*0gknbx~xo*ABFz4xJcNi79h_(7qJX-Z+tT*iig1tZcQe=~Z7*I(3% zdGzAnm|a&cw>9;}kQH|5>6H*|50h*^>wjEkIrZ^JM-g{M`q?j)xCBk2OI39T_O$1mZ^_bDThR`@TDq1n4>`|WDwazzP;cUCb zFRT1MZBD6>N;h_JiB{kBzY+A#ypMjVtoSiWkA5LNp$|X(ygW5WGA`5o z>wRl?zFiC1D4kje6idi|e$f~>bxM(-$9Ihx72FXif|fq2y|+BfrHNvh(PpKq4+F}5 zk^gxvqWK(p^^Q6jq4=-HcR^V@^!VuOvuTOqr{eFPLOf2%yJSQjj59aEJ<~(8+&Cf) zN0;_r`92&3sQ$T^T%Eo1?o;5D|10K?sa_*;vIK#wauWQOR`1#^=EQv zy!bM^8LOR#T9$N0HYV-SJ0JtvLjO7SzTEAwAm(Fto=lPwg?G5iT;azQ<+@vNcB`%` zd~vWc_UV$tn_0qD{PIT3rPN@atf!%!Ba@!b?dg@iG?DZ zjN@+M@J6s?5Fs|kx{ZkZX(?S%LRy#da{CaNiAwyZ)GdZ9nwDLw?rlX0sBc16-Y z4PZLM|N6kgbUgU~ufJ6=;(z+X0RJPhu=jsB|5qXd05K>4L|6?wCkH!R?0~J~%MSOh)0N``}i`Wf=LHPga|KR^0PvzSN literal 0 HcmV?d00001 diff --git a/client/src/components/common/Forbidden.tsx b/client/src/components/common/Forbidden.tsx new file mode 100644 index 00000000..a89e65cd --- /dev/null +++ b/client/src/components/common/Forbidden.tsx @@ -0,0 +1,22 @@ +import { Button } from "@headlessui/react"; +import lockIcon from "@/assets/lock.webp"; + +export default function Forbidden() { + return ( +
+
+

403

+

접근이 거부되었습니다.

+

요청하신 페이지에 대한 접근이 거부되었습니다.

+

입력한 주소가 정확한지 다시 한 번 확인해 주세요.

+ +
+ forbidden +
+ ); +} diff --git a/client/src/store/createSocketSlice.ts b/client/src/store/createSocketSlice.ts index bf2e0f5e..0fcb7ced 100644 --- a/client/src/store/createSocketSlice.ts +++ b/client/src/store/createSocketSlice.ts @@ -54,6 +54,8 @@ export const createSocketSlice: StateCreator { try { + // TODO: connectionId를 기준으로 mindMapId를 가져오는 API 호출하기 + // 여기서 403이면 forbidden 페이지, 404면 notFound 페이지로 이동 const response = await getMindMap(connectionId); get().connectSocket(connectionId); } catch (error) { From a3e4853f69b78bf8859cb2ec48388c0aa7143bc6 Mon Sep 17 00:00:00 2001 From: kimnamheeee Date: Tue, 3 Dec 2024 00:51:22 +0900 Subject: [PATCH 046/110] =?UTF-8?q?feat=20:=20connectionId=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EB=A7=88=EC=9D=B8=EB=93=9C?= =?UTF-8?q?=EB=A7=B5=20id=EB=A5=BC=20=EB=B6=88=EB=9F=AC=EC=98=A4=EB=8A=94?= =?UTF-8?q?=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/mindmap.api.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/api/mindmap.api.ts b/client/src/api/mindmap.api.ts index f79e07f3..9fd09a53 100644 --- a/client/src/api/mindmap.api.ts +++ b/client/src/api/mindmap.api.ts @@ -12,3 +12,7 @@ export function getMindMap(mindMapId: string): Promise { export function deleteMindMap(mindMapId: string) { return instance.delete(`/mindmap/${mindMapId}`); } + +export function getMindMapByConnectionId(connectionId: string): Promise { + return instance.get(`/mindmap/${connectionId}`); +} From b22dfde40547fe4c5dd69e597716e0be5e95f49f Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 02:47:48 +0900 Subject: [PATCH 047/110] =?UTF-8?q?fix=20:=20=EB=A7=A8=20=EC=B2=98?= =?UTF-8?q?=EC=9D=8C=20=EC=8B=9C=EC=9E=91=EC=8B=9C=20=EB=85=B8=EB=93=9C?= =?UTF-8?q?=EA=B0=80=20=EC=84=A0=ED=83=9D=EB=90=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EC=95=98=EC=8A=B5=EB=8B=88=EB=8B=A4=EA=B0=80=20=EB=9C=A8?= =?UTF-8?q?=EB=8A=94=20=EC=97=90=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/konva_mindmap/events/addNode.ts | 35 +++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/client/src/konva_mindmap/events/addNode.ts b/client/src/konva_mindmap/events/addNode.ts index 8628dfd8..481c8c31 100644 --- a/client/src/konva_mindmap/events/addNode.ts +++ b/client/src/konva_mindmap/events/addNode.ts @@ -12,23 +12,6 @@ export function addNode( ) { const handleSocketEvent = useConnectionStore.getState().handleSocketEvent; - if (selectedNode.nodeId === 0) { - useConnectionStore.getState().propagateError("노드가 선택되지 않았습니다.", "error"); - return; - } - - const isCheckNodeCount = checkNodeCount(data, selectedNode.nodeId); - const isCheckAllNodeCount = checkAllNodeCount(data); - - if (!isCheckNodeCount) { - useConnectionStore.getState().propagateError("한 노드당 최대 15개 생성 가능해요.", "error"); - return; - } - if (!isCheckAllNodeCount) { - useConnectionStore.getState().propagateError("노드는 최대 150개까지 생성 가능해요.", "error"); - return; - } - // 아무 노드도 없을 때는 임의로 id 생성해서 현재는 넣음 if (!Object.keys(data).length) { const newNode = { @@ -62,6 +45,24 @@ export function addNode( }); return; } + + if (selectedNode.nodeId === 0) { + useConnectionStore.getState().propagateError("노드가 선택되지 않았습니다.", "error"); + return; + } + + const isCheckNodeCount = checkNodeCount(data, selectedNode.nodeId); + const isCheckAllNodeCount = checkAllNodeCount(data); + + if (!isCheckNodeCount) { + useConnectionStore.getState().propagateError("한 노드당 최대 15개 생성 가능해요.", "error"); + return; + } + if (!isCheckAllNodeCount) { + useConnectionStore.getState().propagateError("노드는 최대 150개까지 생성 가능해요.", "error"); + return; + } + if (!selectedNode.nodeId || data[selectedNode.nodeId].depth === NODE_DEPTH_LIMIT) return; const newNodeId = parseInt(Object.keys(data)[Object.keys(data).length - 1]) + 1; From 24d0597f8381da7752ecb11520118cc842fc84fe Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 02:56:04 +0900 Subject: [PATCH 048/110] =?UTF-8?q?feat=20:=20scale=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=A5=B8=20input=EC=B0=BD=20=ED=99=95=EB=8C=80=20=ED=98=B9?= =?UTF-8?q?=EC=9D=80=20=EC=B6=95=EC=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/MindMapCanvas/index.tsx | 2 +- .../src/konva_mindmap/components/DrawMindMap.tsx | 14 +++++++++++--- .../src/konva_mindmap/components/EditableText.tsx | 9 ++++++++- .../konva_mindmap/components/EditableTextInput.tsx | 6 +++++- .../src/konva_mindmap/components/MindMapNode.tsx | 3 ++- client/src/types/Node.ts | 2 +- 6 files changed, 28 insertions(+), 8 deletions(-) diff --git a/client/src/components/MindMapCanvas/index.tsx b/client/src/components/MindMapCanvas/index.tsx index a6e25e6d..f15cf74e 100644 --- a/client/src/components/MindMapCanvas/index.tsx +++ b/client/src/components/MindMapCanvas/index.tsx @@ -126,7 +126,7 @@ export default function MindMapCanvas({ showMinutes, handleShowMinutes }) { > {Object.keys(data).length >= 1 && ( - + )} diff --git a/client/src/konva_mindmap/components/DrawMindMap.tsx b/client/src/konva_mindmap/components/DrawMindMap.tsx index 5c4a0f94..b1bcc745 100644 --- a/client/src/konva_mindmap/components/DrawMindMap.tsx +++ b/client/src/konva_mindmap/components/DrawMindMap.tsx @@ -11,9 +11,10 @@ type MindMapProps = { parentNode?: any; update?: (id: number, node: Node) => void; dragmode: boolean; + scale: number; }; -export default function DrawMindMap({ data, root, depth = 0, parentNode, dragmode }: MindMapProps) { +export default function DrawMindMap({ data, root, depth = 0, parentNode, dragmode, scale }: MindMapProps) { return ( <> {parentNode && ( @@ -24,10 +25,17 @@ export default function DrawMindMap({ data, root, depth = 0, parentNode, dragmod toRadius={CONNECTED_LINE_TO(depth)} /> )} - + {root.children?.map((childNode, index) => ( - + ))} diff --git a/client/src/konva_mindmap/components/EditableText.tsx b/client/src/konva_mindmap/components/EditableText.tsx index 481ad957..72cde0d7 100644 --- a/client/src/konva_mindmap/components/EditableText.tsx +++ b/client/src/konva_mindmap/components/EditableText.tsx @@ -14,6 +14,7 @@ interface EditableTextProps { offsetX: number; offsetY: number; width: number; + scale: number; } export default function EditableText({ @@ -24,6 +25,7 @@ export default function EditableText({ offsetX, offsetY, width, + scale, }: EditableTextProps) { const originalContent = text; const [keyword, setKeyword] = useState(originalContent); @@ -65,6 +67,10 @@ export default function EditableText({ saveContent(); } + const fontSize = scale >= 1 ? TEXT_FONT_SIZE : TEXT_FONT_SIZE / scale; + offsetX = scale >= 1 ? offsetX : offsetX / scale; + width = scale >= 1 ? width : width / scale; + return ( <> {isEditing ? ( @@ -77,10 +83,11 @@ export default function EditableText({ offsetX={offsetX} offsetY={offsetY} width={width} + scale={scale} /> ) : ( ); diff --git a/client/src/konva_mindmap/components/MindMapNode.tsx b/client/src/konva_mindmap/components/MindMapNode.tsx index eb8f41f7..78794d57 100644 --- a/client/src/konva_mindmap/components/MindMapNode.tsx +++ b/client/src/konva_mindmap/components/MindMapNode.tsx @@ -22,7 +22,7 @@ import { useConnectionStore } from "@/store/useConnectionStore"; import { addNode } from "@/konva_mindmap/events/addNode"; import useWindowEventListener from "@/hooks/useWindowEventListener"; -export default function MindMapNode({ data, parentNode, node, depth, parentRef, dragmode }: NodeProps) { +export default function MindMapNode({ data, parentNode, node, depth, dragmode, scale }: NodeProps) { const nodeRef = useRef(null); const { saveHistory, updateNode, selectNode, selectedNode, selectedGroup, overrideNodeData, groupRelease } = useNodeListContext(); @@ -129,6 +129,7 @@ export default function MindMapNode({ data, parentNode, node, depth, parentRef, width={TEXT_WIDTH(depth)} isEditing={isEditing} setIsEditing={setIsEditing} + scale={scale} /> ; dragmode: boolean; + scale: number; }; From 09625bfbd4a50f9203c6c1afc9a71c84e2eecdfb Mon Sep 17 00:00:00 2001 From: kimnamheeee Date: Tue, 3 Dec 2024 11:27:51 +0900 Subject: [PATCH 049/110] =?UTF-8?q?chore=20:=20=EC=82=AC=EC=9A=A9=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EA=B0=92=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/MindMapMainSection/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/src/components/MindMapMainSection/index.tsx b/client/src/components/MindMapMainSection/index.tsx index 8a4f2d9c..b5a94a23 100644 --- a/client/src/components/MindMapMainSection/index.tsx +++ b/client/src/components/MindMapMainSection/index.tsx @@ -1,7 +1,6 @@ import MindMapHeader from "@/components/MindMapHeader"; import MindMapView from "@/components/MindMapMainSection/MindMapView"; import useSection from "@/hooks/useSection"; -import { useNodeListContext } from "@/store/NodeListProvider"; import { useEffect } from "react"; import { useParams } from "react-router-dom"; import ToastContainer from "../common/Toast/ToastContainer"; @@ -19,7 +18,6 @@ export default function MindMapMainSection() { const { mindMapId } = useParams<{ mindMapId: string }>(); const connectSocket = useConnectionStore((state) => state.connectSocket); const disconnectSocket = useConnectionStore((state) => state.disconnectSocket); - const token = useConnectionStore((state) => state.token); const { toasts, setToasts } = useToast(); useEffect(() => { From 201ff7809437bf7951f6751072b8b3540bfb4103 Mon Sep 17 00:00:00 2001 From: kimnamheeee Date: Tue, 3 Dec 2024 11:28:08 +0900 Subject: [PATCH 050/110] =?UTF-8?q?feat=20:=20api=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20url=20=EB=B6=84=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/mindmap.api.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/api/mindmap.api.ts b/client/src/api/mindmap.api.ts index 9fd09a53..be838c26 100644 --- a/client/src/api/mindmap.api.ts +++ b/client/src/api/mindmap.api.ts @@ -6,7 +6,7 @@ export function createMindmap() { } export function getMindMap(mindMapId: string): Promise { - return instance.get(`/connection/${mindMapId}`); + return instance.get(`/connection/m/${mindMapId}`); } export function deleteMindMap(mindMapId: string) { @@ -14,5 +14,5 @@ export function deleteMindMap(mindMapId: string) { } export function getMindMapByConnectionId(connectionId: string): Promise { - return instance.get(`/mindmap/${connectionId}`); + return instance.get(`/connection/c/${connectionId}`); } From 31ef0d505881bf91b1325d7afe43d503f54c1553 Mon Sep 17 00:00:00 2001 From: kimnamheeee Date: Tue, 3 Dec 2024 11:29:40 +0900 Subject: [PATCH 051/110] =?UTF-8?q?feat=20:=20redis=EC=97=90=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20connectionId=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EC=9E=AC=EC=97=B0=EA=B2=B0=20=EC=8B=9C=EB=8F=84=20=ED=9B=84=20?= =?UTF-8?q?=EC=B5=9C=EC=A2=85=20=EC=97=90=EB=9F=AC=20=EC=97=AC=EB=B6=80=20?= =?UTF-8?q?=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/store/createSocketSlice.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/client/src/store/createSocketSlice.ts b/client/src/store/createSocketSlice.ts index 0fcb7ced..0563485e 100644 --- a/client/src/store/createSocketSlice.ts +++ b/client/src/store/createSocketSlice.ts @@ -1,7 +1,7 @@ import { Socket, io } from "socket.io-client"; import { StateCreator } from "zustand"; import { actionType, HandleSocketEventPayloads } from "@/types/NodePayload"; -import { createMindmap, getMindMap } from "@/api/mindmap.api"; +import { createMindmap, getMindMap, getMindMapByConnectionId } from "@/api/mindmap.api"; import { ConnectionStore } from "@/types/store"; type NodeError = { @@ -54,12 +54,14 @@ export const createSocketSlice: StateCreator { try { - // TODO: connectionId를 기준으로 mindMapId를 가져오는 API 호출하기 - // 여기서 403이면 forbidden 페이지, 404면 notFound 페이지로 이동 - const response = await getMindMap(connectionId); - get().connectSocket(connectionId); + const response = await getMindMapByConnectionId(connectionId); + if (response) { + get().disconnectSocket(); + get().connectSocket(connectionId); + } } catch (error) { - set({ connectionStatus: "notFound" }); + if (error.status === 404) set({ connectionStatus: "notFound" }); + if (error.status === 403) set({ connectionStatus: "forbidden" }); } }); From 02f1180630d91bc3ca1a695660e620d0d9c08ac6 Mon Sep 17 00:00:00 2001 From: kimnamheeee Date: Tue, 3 Dec 2024 14:29:27 +0900 Subject: [PATCH 052/110] =?UTF-8?q?chore=20:=20mindmapId=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 요청 받아 복구합니다 --- client/src/components/MindMapMainSection/index.tsx | 3 +++ client/src/store/NodeListProvider.tsx | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/client/src/components/MindMapMainSection/index.tsx b/client/src/components/MindMapMainSection/index.tsx index b5a94a23..b7baa239 100644 --- a/client/src/components/MindMapMainSection/index.tsx +++ b/client/src/components/MindMapMainSection/index.tsx @@ -6,6 +6,7 @@ import { useParams } from "react-router-dom"; import ToastContainer from "../common/Toast/ToastContainer"; import { useConnectionStore } from "@/store/useConnectionStore"; import useToast from "@/hooks/useToast"; +import { useNodeListContext } from "@/store/NodeListProvider"; const modeView = { voiceupload: "음성 파일 업로드", @@ -19,10 +20,12 @@ export default function MindMapMainSection() { const connectSocket = useConnectionStore((state) => state.connectSocket); const disconnectSocket = useConnectionStore((state) => state.disconnectSocket); const { toasts, setToasts } = useToast(); + const { updateMindMapId } = useNodeListContext(); useEffect(() => { if (mindMapId) { connectSocket(mindMapId); + updateMindMapId(mindMapId); } return () => { disconnectSocket(); diff --git a/client/src/store/NodeListProvider.tsx b/client/src/store/NodeListProvider.tsx index db681fc0..7b799441 100644 --- a/client/src/store/NodeListProvider.tsx +++ b/client/src/store/NodeListProvider.tsx @@ -29,6 +29,7 @@ export type NodeListContextType = { deleteSelectedNodes: () => void; content: string; updateContent: (updatedContent: string) => void; + updateMindMapId: (mindMapId: string) => void; } & Partial & Partial; @@ -52,6 +53,7 @@ export default function NodeListProvider({ children }: { children: ReactNode }) const { selectedGroup, groupRelease, groupSelect } = useGroupSelect(); const socket = useConnectionStore((state) => state.socket); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); + const [mindMapId, setMindMapId] = useState(""); useEffect(() => { socket?.on("joinRoom", (initialData) => { @@ -141,6 +143,10 @@ export default function NodeListProvider({ children }: { children: ReactNode }) if (selectedNode.nodeId) deleteNodes(JSON.stringify(data), selectedNode.nodeId, overrideNodeData); } + function updateMindMapId(mindMapId: string) { + setMindMapId(mindMapId); + } + return ( {children} From ba88feffd9330648eb9c37beb4819f7514f6cd5c Mon Sep 17 00:00:00 2001 From: Minju9187 Date: Tue, 3 Dec 2024 14:35:56 +0900 Subject: [PATCH 053/110] =?UTF-8?q?refactor=20:=20input=20=EC=95=88=20font?= =?UTF-8?q?Size=EB=8F=84=201=EB=B0=B0=20=EC=9D=B4=EC=83=81=20=EB=8A=98?= =?UTF-8?q?=EC=96=B4=EB=82=A0=EC=8B=9C=20=EA=B8=B0=EB=B3=B8=20=ED=8F=B0?= =?UTF-8?q?=ED=8A=B8=20=EC=9C=A0=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/konva_mindmap/components/EditableTextInput.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/konva_mindmap/components/EditableTextInput.tsx b/client/src/konva_mindmap/components/EditableTextInput.tsx index 2097b6e8..2bb1f159 100644 --- a/client/src/konva_mindmap/components/EditableTextInput.tsx +++ b/client/src/konva_mindmap/components/EditableTextInput.tsx @@ -23,7 +23,7 @@ export default function EditableTextInput({ focus, scale, }: EditableTextInputProps) { - const fontSize = 16 / scale; + const fontSize = scale >= 1 ? 16 : 16 / scale; return ( From 1dff3777d15685247bd15a80e11cad3a3c1cf6d3 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 13:58:23 +0900 Subject: [PATCH 054/110] =?UTF-8?q?refactor=20:=20ai=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=20=EC=A0=84=EC=9A=A9=20=EC=9D=B8=EC=8A=A4=ED=84=B4=EC=8A=A4=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9D=B8=ED=84=B0=EC=85=89=ED=84=B0=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/ai.ts | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/client/src/api/ai.ts b/client/src/api/ai.ts index ca8859e9..5d0c660f 100644 --- a/client/src/api/ai.ts +++ b/client/src/api/ai.ts @@ -1,15 +1,30 @@ -import { instance } from "@/api"; +import { useConnectionStore } from "@/store/useConnectionStore"; +import { logOnDev } from "@/utils/logging"; +import axios from "axios"; +import { InternalAxiosRequestConfig } from "axios"; -export function AudioAiConvert(formData: FormData, mindmapId: string) { - return instance.post( - `ai/audio/${mindmapId}`, - { - formData, - }, - { - headers: { - "Content-Type": "multipart/form-data", - }, +export const instanceForAi = axios.create({ + baseURL: import.meta.env.VITE_APP_API_SERVER_BASE_URL, + timeout: 3000, + withCredentials: true, + headers: { + "Content-Type": "multipart/form-data", + }, +}); + +instanceForAi.interceptors.request.use((config: InternalAxiosRequestConfig) => { + const { method, baseURL, url } = config; + logOnDev(`🚀 [API Request] ${method?.toUpperCase()} ${baseURL} ${url}`); + const accessToken = useConnectionStore.getState().token; + + config.headers["Authorization"] = `Bearer ${accessToken}`; + return config; +}); + +export function AudioAiConvert(formData: FormData) { + return instanceForAi.post(`/ai/audio`, formData, { + headers: { + "Content-Type": "multipart/form-data", }, - ); + }); } From d5f7ccd6db605629341b059267b039143989e54e Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 13:59:48 +0900 Subject: [PATCH 055/110] =?UTF-8?q?refactor=20:=20tokenRefresh=20=EC=A0=84?= =?UTF-8?q?=EC=9A=A9=20=EB=A6=AC=ED=94=84=EB=A0=88=EC=8B=9C=20=EC=9D=B8?= =?UTF-8?q?=EC=8A=A4=ED=84=B4=EC=8A=A4=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/auth.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/src/api/auth.ts b/client/src/api/auth.ts index d6f96753..4e1ea97b 100644 --- a/client/src/api/auth.ts +++ b/client/src/api/auth.ts @@ -1,8 +1,18 @@ import { instance } from "@/api"; import { TokenRefresh, User } from "@/types/auth"; +import axios from "axios"; + +export const instanceForRefresh = axios.create({ + baseURL: import.meta.env.VITE_APP_API_SERVER_BASE_URL, + timeout: 3000, + withCredentials: true, + headers: { + "Content-Type": "application/json", + }, +}); export const tokenRefresh = async (): Promise => { - const { data } = await instance.post("/auth/refresh", {}, { withCredentials: true }); + const { data } = await instanceForRefresh.post("/auth/refresh", {}, { withCredentials: true }); return data; }; From 3add9e065cebe4c61d9ee87dea3a73da8c402f7d Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 14:01:01 +0900 Subject: [PATCH 056/110] =?UTF-8?q?fix=20:=20connectionId=EB=A5=BC=20?= =?UTF-8?q?=EC=9E=84=EC=9D=98=EB=A1=9C=20=EC=9E=85=EB=A0=A5=ED=95=A0=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20refresh=EA=B0=80=20=EA=B3=84=EC=86=8D=20?= =?UTF-8?q?=EA=B0=80=EB=8D=98=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/index.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/client/src/api/index.ts b/client/src/api/index.ts index 1a93a32a..eabddd32 100644 --- a/client/src/api/index.ts +++ b/client/src/api/index.ts @@ -51,12 +51,15 @@ instance.interceptors.response.use( if (error.response.status === 401) { if (!originalRequest._retry) { - originalRequest._retry = true; - const newAccessToken = await tokenRefresh(); - useConnectionStore.getState().tokenRefresh(newAccessToken.accessToken); - originalRequest.headers["Authorization"] = `Bearer ${newAccessToken.accessToken}`; - - return instance(originalRequest); + try { + originalRequest._retry = true; + const newAccessToken = await tokenRefresh(); + useConnectionStore.getState().tokenRefresh(newAccessToken.accessToken); + originalRequest.headers["Authorization"] = `Bearer ${newAccessToken.accessToken}`; + return instance(originalRequest); + } catch (error) { + return Promise.reject(error); + } } await signOut(); useConnectionStore.getState().logout(); From aff841883c5224f67b377e2194ee0761a603e165 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 14:01:24 +0900 Subject: [PATCH 057/110] =?UTF-8?q?refactor=20:=20=EC=A0=9C=EB=AA=A9=20?= =?UTF-8?q?=EB=82=99=EC=B2=9C=EC=A0=81=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/MindMapHeader/index.tsx | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/client/src/components/MindMapHeader/index.tsx b/client/src/components/MindMapHeader/index.tsx index d649935e..e6353bb2 100644 --- a/client/src/components/MindMapHeader/index.tsx +++ b/client/src/components/MindMapHeader/index.tsx @@ -1,36 +1,33 @@ -import Spinner from "@/components/common/Spinner"; import MindMapHeaderButtons from "@/components/MindMapHeader/MindMapHeaderButtons"; import Profile from "@/components/MindMapHeader/Profile"; -import useAuth from "@/hooks/useAuth"; import { useNodeListContext } from "@/store/NodeListProvider"; import { useConnectionStore } from "@/store/useConnectionStore"; import { Input } from "@headlessui/react"; import { useState } from "react"; -import { createPortal } from "react-dom"; import { FaPencilAlt } from "react-icons/fa"; export default function MindMapHeader() { const { title, updateTitle } = useNodeListContext(); + const originalContent = title; const [editMode, setEditMode] = useState(false); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); - const [editTitle, setEditTitle] = useState(title); const role = useConnectionStore((state) => state.currentRole); + const currentJobStatus = useConnectionStore((state) => state.currentJobStatus); function handleInputBlur() { - if (!editTitle.length) { - setEditTitle(title); + if (!title.length) { setEditMode(false); return; } handleSocketEvent({ actionType: "updateTitle", - payload: { title: editTitle }, + payload: { title: title }, callback: (response) => { updateTitle(response.title); - setEditTitle(response.title); }, }); + if (currentJobStatus === "error") updateTitle(originalContent); setEditMode(false); } @@ -52,8 +49,8 @@ export default function MindMapHeader() { {editMode ? ( setEditTitle(e.target.value)} + value={title} + onChange={(e) => updateTitle(e.target.value)} onBlur={handleInputBlur} onKeyDown={handleInputKeyDown} maxLength={32} From fef593cb9434d237278e4c40fec7b01636d38140 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 14:02:00 +0900 Subject: [PATCH 058/110] =?UTF-8?q?refactor=20:=20=EC=9D=8C=EC=84=B1?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20ai=20=EC=9A=94=EC=B2=AD=20api=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MindMapMainSection/ControlSection/VoiceFileUpload.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx b/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx index 41bb5373..82a07ca2 100644 --- a/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx +++ b/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx @@ -7,9 +7,11 @@ import UploadAvailabilityArrowBox from "@/components/MindMapMainSection/ControlS import { useNodeListContext } from "@/store/NodeListProvider"; import { useConnectionStore } from "@/store/useConnectionStore"; import { AudioAiConvert } from "@/api/ai"; +import { useParams } from "react-router-dom"; export default function VoiceFileUpload() { const [file, setFile] = useState(null); + const { mindMapId: connectionId } = useParams<{ mindMapId: string }>(); const { availabilityInform, handleMouseEnter, handleMouseLeave } = useUpload(); const { aiCount } = useNodeListContext(); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); @@ -23,9 +25,10 @@ export default function VoiceFileUpload() { handleSocketEvent({ actionType: "audioAiRequest" }); const formData = new FormData(); formData.append("aiAudio", file); + formData.append("mindmapId", "1"); + formData.append("connectionId", connectionId); try { - const response = await AudioAiConvert(formData, "22"); - console.log("업로드 성공:", response); + await AudioAiConvert(formData); } catch (error) { console.error("업로드 에러:", error); } From 2130d3fb72584be2a307e7b2f5fd2376ed2d2ef8 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 14:59:43 +0900 Subject: [PATCH 059/110] =?UTF-8?q?refactor=20:=20stage=20=EC=A0=84?= =?UTF-8?q?=EC=97=AD=20=EA=B4=80=EB=A6=AC=20=EC=83=81=ED=83=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EB=B0=8F=20nodelistConetxt=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/MindMapCanvas/index.tsx | 15 ++++----------- client/src/store/NodeListProvider.tsx | 5 ++++- client/src/store/useStageStore.ts | 15 --------------- 3 files changed, 8 insertions(+), 27 deletions(-) delete mode 100644 client/src/store/useStageStore.ts diff --git a/client/src/components/MindMapCanvas/index.tsx b/client/src/components/MindMapCanvas/index.tsx index f15cf74e..d08d25db 100644 --- a/client/src/components/MindMapCanvas/index.tsx +++ b/client/src/components/MindMapCanvas/index.tsx @@ -5,15 +5,13 @@ import initializeNodePosition from "@/konva_mindmap/utils/initializeNodePosition import { Layer, Stage } from "react-konva"; import { useNodeListContext } from "@/store/NodeListProvider"; import { useCollisionDetection } from "@/konva_mindmap/hooks/useCollisionDetection"; -import { useEffect, useRef, useState } from "react"; -import { useStageStore } from "@/store/useStageStore"; +import { useState } from "react"; import NoNodeInform from "@/components/MindMapCanvas/NoNodeInform"; import CanvasButtons from "@/components/MindMapCanvas/CanvasButtons"; import SelectionRect from "@/konva_mindmap/components/selectionRect"; import DrawMindMap from "@/konva_mindmap/components/DrawMindMap"; import ShowShortCut from "./ShowShortCut"; import { findRootNodeKey } from "@/konva_mindmap/utils/findRootNodeKey"; -import Konva from "konva"; import { addNode } from "@/konva_mindmap/events/addNode"; import { useConnectionStore } from "@/store/useConnectionStore"; import { moveToNextNode, moveToPreviousNode } from "@/konva_mindmap/utils/moveToNode"; @@ -31,20 +29,15 @@ export default function MindMapCanvas({ showMinutes, handleShowMinutes }) { selectedNode, selectNode, groupRelease, + stage, } = useNodeListContext(); const [isDragMode, setDragMode] = useState(false); const { dimensions, targetRef, handleWheel, zoomIn, zoomOut, reArrange } = useDimension(data); const registerLayer = useCollisionDetection(data, updateNode); - const stageRef = useRef(); - const { registerStageRef } = useStageStore(); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); const rootKey = findRootNodeKey(data); - useEffect(() => { - registerStageRef(stageRef); - }, [stageRef]); - function handleReArrange() { handleSocketEvent({ actionType: "updateNode", @@ -113,7 +106,7 @@ export default function MindMapCanvas({ showMinutes, handleShowMinutes }) {
= 1 && ( )} - + ; data: NodeData | null; selectedNode: SelectedNode | null; history: string[]; @@ -51,6 +52,7 @@ export default function NodeListProvider({ children }: { children: ReactNode }) const { content, updateContent, initializeContent } = useContent(); const { loadingStatus, updateLoadingStatus } = useLoading(); const { selectedGroup, groupRelease, groupSelect } = useGroupSelect(); + const stage = useRef(); const socket = useConnectionStore((state) => state.socket); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); const [mindMapId, setMindMapId] = useState(""); @@ -171,6 +173,7 @@ export default function NodeListProvider({ children }: { children: ReactNode }) initializeAiCount, loadingStatus, updateMindMapId, + stage, }} > {children} diff --git a/client/src/store/useStageStore.ts b/client/src/store/useStageStore.ts deleted file mode 100644 index 5cbc49ae..00000000 --- a/client/src/store/useStageStore.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Konva from "konva"; -import { RefObject } from "react"; -import { create } from "zustand"; - -interface StageStore { - stage: null | RefObject; - registerStageRef: (stage: RefObject) => void; -} -export const useStageStore = create((set) => ({ - stage: null, - registerStageRef: (stage) => - set({ - stage: stage, - }), -})); From 99f89fa4eed66c918bfaf47492b8eac4631ca98d Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 15:04:26 +0900 Subject: [PATCH 060/110] =?UTF-8?q?refactor=20:=20=EB=A7=88=EC=9D=B8?= =?UTF-8?q?=EB=93=9C=EB=A7=B5=20export=20=ED=99=94=EC=A7=88=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20=EB=B0=8F=20=EB=85=B8=EB=93=9C=EA=B0=80=20=EC=97=86?= =?UTF-8?q?=EC=9C=BC=EB=A9=B4=20=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B8=94=EB=9D=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MindMapHeader/MindMapHeaderButtons.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/src/components/MindMapHeader/MindMapHeaderButtons.tsx b/client/src/components/MindMapHeader/MindMapHeaderButtons.tsx index 617ebd31..379a133b 100644 --- a/client/src/components/MindMapHeader/MindMapHeaderButtons.tsx +++ b/client/src/components/MindMapHeader/MindMapHeaderButtons.tsx @@ -1,17 +1,19 @@ import { downloadURI } from "@/konva_mindmap/utils/download"; -import { useStageStore } from "@/store/useStageStore"; import { Button } from "@headlessui/react"; import useModal from "@/hooks/useModal"; import ShareModal from "../ShareModal"; import { LuShare, LuShare2 } from "react-icons/lu"; import { createPortal } from "react-dom"; +import { useNodeListContext } from "@/store/NodeListProvider"; export default function MindMapHeaderButtons() { - const stage = useStageStore((state) => state.stage); const { open, openModal, closeModal } = useModal(); + const { title, stage } = useNodeListContext(); function handleExport() { - downloadURI(stage.current.getStage().toDataURL({ mimeType: "image/png", quality: 1 }), "demo"); + const nodes = stage.current.children[0].children.length; + if (nodes > 1) + downloadURI(stage.current.getStage().toDataURL({ mimeType: "image/png", quality: 1, pixelRatio: 3 }), title); } return ( From b4fed9b2f2ad908110c21a7ff6011437135e2a13 Mon Sep 17 00:00:00 2001 From: adkm12 Date: Tue, 3 Dec 2024 16:40:20 +0900 Subject: [PATCH 061/110] =?UTF-8?q?chore=20:=20openai=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/package-lock.json | 141 +++++++++++++++++++++++++++++++++++++++++++ BE/package.json | 1 + 2 files changed, 142 insertions(+) diff --git a/BE/package-lock.json b/BE/package-lock.json index 5a51da04..2dec74f2 100644 --- a/BE/package-lock.json +++ b/BE/package-lock.json @@ -29,6 +29,7 @@ "ioredis": "^5.4.1", "mysql2": "^3.11.4", "nest-winston": "^1.9.7", + "openai": "^4.74.0", "passport-jwt": "^4.0.1", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", @@ -2370,6 +2371,16 @@ "undici-types": "~6.19.2" } }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, "node_modules/@types/oauth": { "version": "0.9.6", "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.6.tgz", @@ -2946,6 +2957,18 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2995,6 +3018,18 @@ "node": ">=0.4.0" } }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", @@ -4934,6 +4969,15 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -5422,6 +5466,25 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "license": "MIT" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "license": "MIT", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, "node_modules/formidable": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.2.tgz", @@ -5779,6 +5842,15 @@ "node": ">=10.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -7693,6 +7765,25 @@ "dev": true, "license": "MIT" }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-emoji": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", @@ -7843,6 +7934,47 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openai": { + "version": "4.74.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.74.0.tgz", + "integrity": "sha512-pQ8t1jchUymw5WB5jZPchuBtWvxul7RyVxa+9RWfiCQyzvzUyI2sKvUYfpEDI/ouaRLcik3K6psj15ByCefeNA==", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/openai/node_modules/@types/node": { + "version": "18.19.67", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.67.tgz", + "integrity": "sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/openai/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -10316,6 +10448,15 @@ "defaults": "^1.0.3" } }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/BE/package.json b/BE/package.json index 0b2c1100..65bba794 100644 --- a/BE/package.json +++ b/BE/package.json @@ -40,6 +40,7 @@ "ioredis": "^5.4.1", "mysql2": "^3.11.4", "nest-winston": "^1.9.7", + "openai": "^4.74.0", "passport-jwt": "^4.0.1", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1", From 51c07a9bf9ffd484dde51008dae370f7bdb1d1c6 Mon Sep 17 00:00:00 2001 From: adkm12 Date: Tue, 3 Dec 2024 16:41:07 +0900 Subject: [PATCH 062/110] =?UTF-8?q?refactor=20:=20publisher=20json=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=B3=80=ED=99=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/subscriber/subscriber.service.ts | 7 ++++++- .../src/modules/subscriber/subscriber.service.ts | 8 +------- BE/libs/publisher/src/publisher.service.ts | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/BE/apps/api-server/src/modules/subscriber/subscriber.service.ts b/BE/apps/api-server/src/modules/subscriber/subscriber.service.ts index 7f4e0f7f..b20cb1f4 100644 --- a/BE/apps/api-server/src/modules/subscriber/subscriber.service.ts +++ b/BE/apps/api-server/src/modules/subscriber/subscriber.service.ts @@ -7,6 +7,7 @@ import { MindmapService } from '../mindmap/mindmap.service'; import { plainToInstance } from 'class-transformer'; import { Role } from '@app/entity/enum/role.enum'; import { AiService } from '../ai/ai.service'; +import { AiDto } from '../ai/dto/ai.dto'; export interface RedisMessage { event: string; @@ -111,7 +112,11 @@ export class SubscriberService implements OnModuleInit { } private async handleTextAiEvent(data: RedisMessage['data']) { - await this.aiService.requestClovaX(data); + const mindmapId = Number(data.mindmapId); + const connectionId = data.connectionId; + const aiContent = data.aiContent; + const ClovaPromptDto = plainToInstance(AiDto, { mindmapId, connectionId, aiContent }); + await this.aiService.requestOpenAi(ClovaPromptDto); this.logger.log('AI 데이터 처리 완료'); } } diff --git a/BE/apps/socket-server/src/modules/subscriber/subscriber.service.ts b/BE/apps/socket-server/src/modules/subscriber/subscriber.service.ts index c2f86151..90fcff3a 100644 --- a/BE/apps/socket-server/src/modules/subscriber/subscriber.service.ts +++ b/BE/apps/socket-server/src/modules/subscriber/subscriber.service.ts @@ -49,12 +49,10 @@ export class SubscriberService implements OnModuleInit { const { event, data } = JSON.parse(message) as RedisMessage; if (event === 'textAiSocket') { this.textAiFinished(data); - } else if (event === 'audioAi') { - this.aiAudioFinish(data); } } } catch (error) { - this.logger.error('Redis handleMessage error:', error); + this.logger.error('Redis handlㄴeMessage error:', error); } } @@ -65,8 +63,4 @@ export class SubscriberService implements OnModuleInit { } this.mapGateway.textAiResponse(data); } - - aiAudioFinish(data) { - console.log('aiAudioFinish' + data); - } } diff --git a/BE/libs/publisher/src/publisher.service.ts b/BE/libs/publisher/src/publisher.service.ts index 33257fa5..7577a813 100644 --- a/BE/libs/publisher/src/publisher.service.ts +++ b/BE/libs/publisher/src/publisher.service.ts @@ -10,8 +10,8 @@ export class PublisherService { this.redis = redisService.getOrThrow('publisher'); } - async publish(channel: string, message: string) { + async publish(channel: string, message: any) { this.logger.log(`Publishing to ${channel}: ${message}`); - await this.redis.publish(channel, message); + await this.redis.publish(channel, JSON.stringify(message)); } } From f5fc440c31630e9336c2891ffa51b29801d871ae Mon Sep 17 00:00:00 2001 From: adkm12 Date: Tue, 3 Dec 2024 16:41:32 +0900 Subject: [PATCH 063/110] =?UTF-8?q?feat=20:=20ai=20=EC=9A=94=EC=B2=AD=20dt?= =?UTF-8?q?o=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BE/apps/api-server/src/main.ts | 6 +- .../api-server/src/modules/ai/dto/ai.dto.ts | 12 ++++ .../src/modules/ai/dto/audio.upload.dto.ts | 11 ++++ .../ai/dto/clova.speech.request.dtd.ts | 29 ++++++++++ .../src/modules/ai/dto/openai.request.dto.ts | 58 +++++++++++++++++++ 5 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 BE/apps/api-server/src/modules/ai/dto/ai.dto.ts create mode 100644 BE/apps/api-server/src/modules/ai/dto/audio.upload.dto.ts create mode 100644 BE/apps/api-server/src/modules/ai/dto/clova.speech.request.dtd.ts create mode 100644 BE/apps/api-server/src/modules/ai/dto/openai.request.dto.ts diff --git a/BE/apps/api-server/src/main.ts b/BE/apps/api-server/src/main.ts index 2ea55ab1..469f2c8b 100644 --- a/BE/apps/api-server/src/main.ts +++ b/BE/apps/api-server/src/main.ts @@ -13,12 +13,8 @@ async function bootstrap() { app.setGlobalPrefix('api'); app.useGlobalPipes( new ValidationPipe({ - transform: true, //dto를 수정 가능하게(dto 기본값 들어가도록) - transformOptions: { - enableImplicitConversion: true, //Class-Validator Type에 맞게 자동형변환 - }, + transform: true, whitelist: true, - forbidNonWhitelisted: true, }), ); diff --git a/BE/apps/api-server/src/modules/ai/dto/ai.dto.ts b/BE/apps/api-server/src/modules/ai/dto/ai.dto.ts new file mode 100644 index 00000000..18348645 --- /dev/null +++ b/BE/apps/api-server/src/modules/ai/dto/ai.dto.ts @@ -0,0 +1,12 @@ +import { IsNumber, IsString } from 'class-validator'; + +export class AiDto { + @IsNumber() + mindmapId: number; + + @IsString() + connectionId: string; + + @IsString() + aiContent: string; +} diff --git a/BE/apps/api-server/src/modules/ai/dto/audio.upload.dto.ts b/BE/apps/api-server/src/modules/ai/dto/audio.upload.dto.ts new file mode 100644 index 00000000..f622718b --- /dev/null +++ b/BE/apps/api-server/src/modules/ai/dto/audio.upload.dto.ts @@ -0,0 +1,11 @@ +import { Type } from 'class-transformer'; +import { IsNumber, IsString } from 'class-validator'; + +export class AudioUploadDto { + @IsNumber() + @Type(() => Number) + mindmapId: number; + + @IsString() + connectionId: string; +} diff --git a/BE/apps/api-server/src/modules/ai/dto/clova.speech.request.dtd.ts b/BE/apps/api-server/src/modules/ai/dto/clova.speech.request.dtd.ts new file mode 100644 index 00000000..67acdabb --- /dev/null +++ b/BE/apps/api-server/src/modules/ai/dto/clova.speech.request.dtd.ts @@ -0,0 +1,29 @@ +export class ClovaSpeechRequestDto { + private formData: FormData; + private headers = { + 'X-CLOVASPEECH-API-KEY': '', + 'Content-Type': 'multipart/form-data', + }; + private params = { + completion: 'sync', + diarization: { enable: false }, + language: 'ko-KR', + }; + + constructor(apiKey: string, audioFile: Express.Multer.File) { + this.headers['X-CLOVASPEECH-API-KEY'] = apiKey; + + const blob = new Blob([audioFile.buffer], { type: audioFile.mimetype }); + this.formData = new FormData(); + this.formData.append('media', blob); + this.formData.append('params', JSON.stringify(this.params)); + } + + getFormData() { + return this.formData; + } + + getHeaders() { + return this.headers; + } +} diff --git a/BE/apps/api-server/src/modules/ai/dto/openai.request.dto.ts b/BE/apps/api-server/src/modules/ai/dto/openai.request.dto.ts new file mode 100644 index 00000000..b4f38c4f --- /dev/null +++ b/BE/apps/api-server/src/modules/ai/dto/openai.request.dto.ts @@ -0,0 +1,58 @@ +import { ResponseFormatText } from 'openai/resources'; + +export class OpenAiRequestDto { + private model = 'gpt-4o-mini'; + private response_format: ResponseFormatText = { type: 'text' }; + private temperature = 1; + private max_tokens = 4096; + private top_p = 1; + private frequency_penalty = 0; + private presence_penalty = 0; + private messages: any[]; + private tools: any[]; + + setPrompt(prompt: string) { + this.messages = [ + { + role: 'system', + content: [ + { + text: prompt, + type: 'text', + }, + ], + }, + ]; + } + + setAiContent(aiContent: string) { + this.messages.push({ + role: 'user', + content: [ + { + text: aiContent, + type: 'text', + }, + ], + }); + } + + setTools(tool: any) { + this.tools = []; + this.tools.push(tool); + } + + toObject() { + return { + model: this.model, + response_format: this.response_format, + temperature: this.temperature, + max_tokens: this.max_tokens, + top_p: this.top_p, + frequency_penalty: this.frequency_penalty, + presence_penalty: this.presence_penalty, + messages: this.messages, + tools: this.tools, + }; + } +} From fbf244d6d7dfa7de631be2000ebc9cfd2af9a1e2 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:41:38 +0900 Subject: [PATCH 064/110] =?UTF-8?q?refactor=20:=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=99=80=20=EC=9D=8C=EC=84=B1=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?validation=20=ED=99=95=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ControlSection/TextUpload.tsx | 45 ++++++++++++---- .../ControlSection/VoiceFileUpload.tsx | 52 ++++++++++++------- 2 files changed, 67 insertions(+), 30 deletions(-) diff --git a/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx b/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx index 61e683e7..4d46a0c9 100644 --- a/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx +++ b/client/src/components/MindMapMainSection/ControlSection/TextUpload.tsx @@ -1,15 +1,35 @@ import ArrowBox from "@/components/common/ArrowBox"; -import { MAX_TEXT_UPLOAD_LIMIT } from "@/constants/textUploadLimit"; +import { MAX_TEXT_UPLOAD_LIMIT, MIN_TEXT_UPLOAD_LIMIT } from "@/constants/uploadLimit"; import useUpload from "@/hooks/useUpload"; import { Button, Textarea } from "@headlessui/react"; import clovaX from "@/assets/clovaX.png"; import { useNodeListContext } from "@/store/NodeListProvider"; import UploadAvailabilityArrowBox from "@/components/MindMapMainSection/ControlSection/UploadAvailabilityArrowBox"; +import { useConnectionStore } from "@/store/useConnectionStore"; export default function TextUpload() { - const { content, updateContent, handleAiProcessButton, availabilityInform, handleMouseEnter, handleMouseLeave } = + const { content, updateContent, availabilityInform, handleMouseEnter, handleMouseLeave, errorMsg, updateErrorMsg } = useUpload(); + const role = useConnectionStore((state) => state.currentRole); + const ownerAvailability = role === "owner"; + const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); + + function textUploadValidation() { + if (content.length < MIN_TEXT_UPLOAD_LIMIT) { + updateErrorMsg("텍스트는 500자를 넘어야 합니다."); + return false; + } + return true; + } + + function handleAiProcessButton() { + if (!textUploadValidation() || !ownerAvailability) return; + updateErrorMsg(""); + handleSocketEvent({ actionType: "aiRequest", payload: { aiContent: content } }); + } + const { aiCount } = useNodeListContext(); + return (
@@ -28,15 +48,18 @@ export default function TextUpload() {

- +
+ + {errorMsg &&

{errorMsg}

} +
clovaX
diff --git a/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx b/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx index 82a07ca2..f6c5f34a 100644 --- a/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx +++ b/client/src/components/MindMapMainSection/ControlSection/VoiceFileUpload.tsx @@ -8,26 +8,37 @@ import { useNodeListContext } from "@/store/NodeListProvider"; import { useConnectionStore } from "@/store/useConnectionStore"; import { AudioAiConvert } from "@/api/ai"; import { useParams } from "react-router-dom"; +import { getMindMapByConnectionId } from "@/api/mindmap.api"; +import { audioFormData } from "@/utils/formData"; +import { FILE_UPLOAD_LIMIT } from "@/constants/uploadLimit"; export default function VoiceFileUpload() { const [file, setFile] = useState(null); const { mindMapId: connectionId } = useParams<{ mindMapId: string }>(); - const { availabilityInform, handleMouseEnter, handleMouseLeave } = useUpload(); + const { availabilityInform, handleMouseEnter, handleMouseLeave, errorMsg, updateErrorMsg } = useUpload(); const { aiCount } = useNodeListContext(); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); - async function sendAudioFile() { + function fileValidation(file) { if (!file) { - alert("파일을 선택해주세요."); - return; + updateErrorMsg("파일을 선택해주세요."); + return false; + } + if (file.size < FILE_UPLOAD_LIMIT) { + updateErrorMsg("파일 크기는 50MB를 넘을 수 없습니다."); + return false; } + return true; + } + async function sendAudioFile() { + if (!fileValidation(file)) return; + updateErrorMsg(""); handleSocketEvent({ actionType: "audioAiRequest" }); - const formData = new FormData(); - formData.append("aiAudio", file); - formData.append("mindmapId", "1"); - formData.append("connectionId", connectionId); + try { + const mindMapId = await getMindMapByConnectionId(connectionId); + const formData = audioFormData(file, mindMapId, connectionId); await AudioAiConvert(formData); } catch (error) { console.error("업로드 에러:", error); @@ -35,18 +46,21 @@ export default function VoiceFileUpload() { } return ( -
+
-

남은 AI 변환 : {aiCount}

- +

AI 변환 남은 횟수 : {aiCount}번

+
+ + {errorMsg &&

{errorMsg}

} +
clovaX
From 58666b243e59967b3ca6f7951f27c30ba288ade1 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:43:48 +0900 Subject: [PATCH 065/110] =?UTF-8?q?remove=20:=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/assets/profile.png | Bin 7872 -> 0 bytes client/src/assets/search.png | Bin 1638 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 client/src/assets/profile.png delete mode 100644 client/src/assets/search.png diff --git a/client/src/assets/profile.png b/client/src/assets/profile.png deleted file mode 100644 index aafde320d8c9e6c64aa8be0cb564b40c93ac586a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7872 zcmX9@c|26__qWZMVT3UlLW3FmGWIQD3)hv@^M0RLypbLg12+Q|6%~^{4r@Y1MGgEnK$I(0 zw1V1I$^`bt-SwlQVr2U_sHyS_;FLvbKNCF+)vGa{uM~mKS?h)t71irx#!~`-ii+>H zK32>00rmGn>jYEBr~MZ%+PDBgg@O0Eoz3#LsgVgnfzs~vjJYLTgFvBF>W=$T9N*vG zP5dv`R$g}%x0)01pG+L5{aTz;F5@g+bTW3P8mE@ubsSdWv|1T*gL5gWxs@zn+*t~eMI1NpMk1@~80#k*8vGp8ZEXL+$ z$LK%#y)M^RcdI-~b5HD)eex^!c8KSkZ1wrr8%bXkL0PLhRFO-{vTo|UwZ~Ll3f2}J z%U;Ahb3+OH+2>c);uqR&VBfpNT~OCn{xvb*?Gx@h0vWd!C%J}jNu{hBA`l=geF~Sc zQU}U#ga*-gZ#@zF_(#uh*ILHv5mo7aBT!G`CnkZ^ZOalt8`yq3#Rx^iT%i$Ya9xKC z5YhLoL>`mJa8C^LGuiCuU{N5V;C+d~yzoJj06%|j69z2MD)R5$-=I>5Pm!d?Lp73QM>q_md%ooY<;0X z$rXkOArYX(5Tg!892P|-+6XPm2zM`rlXPvs*do_hPiG-k9*V+yo+z1bdim8YoWJ=* zE%ssXh*j0i7-C{EzPHQxErlCg~Eam=yX0~R7t^Nhf@KM?hAM_hs>e5W|1d2tn!p)#HT07#! zj;FpztRIBORDe+GSuB~@H>OiM_70bURxXb)@m;o}0cZCD(qlzYo>`Y*0O+;ZvPK2A zWw@!ysj4Bp9nBrxN9kx2UN?f~)8e*E8unxyMDT?{e4~$)q@6fqlr3htS2ZZcu|KTu z=08EXmG;%`SpL^+!0R%VSC?6`ap~~)BsYbm5{GIMVXL9Tr3_(7N`aSn)=#f08t~>P zP?r{4VQN{Rw^lyBj)_D=o;JPCHE3pmKKX00VXkhc+|Nj>LqxKy_H~&PmJ(?6<@?z4 z+-_Lg6UxxarT7Bl`<$3G!&ma(Yzvg(vzgunG!*NiKNF3fJpJH^bkVvHgo~E-w{o6$ zA_-zBxO^JS-W1`IU{5Xx$HQ=szACzahCu`5WfUeZN0yGg6>a;ScAx;aXDwM7|=WD&1!X@-b+~a5QW(Sr~#pMMT~jWZ*~Q@(d2M6dS-1at^2xxp~aOW>X6k32+^3XzMKSr8RY>AHO(YV0<`L4RN1~d+r zusi697iAH$)qgV5TjCCGy0rzh%os#4ucW)s>Eh6gH@Rhj1F`bam0{IsSNcuVq&P zJJfbC;&5E4gXtcqa@#{f{27-cjIr8{jcmsP-lK_EWsHdUB2LFeCJmr*(w*fVX;?`uAAnyWNVJqDW&H zxvA!4eUJVM7#y9-dUti>*SElbuSfhzof~dsO#VwRk(Q?r{QUauadG0h-ptFnpQ{%a z4Z}Q6j+UhR1E09#+9Ijv^hASM|GsQ@(KdT;ZUc%uU@`|qZXQsjb_)irWn?9RdYAjm z+PH90VUqO^H+ZU=pN`j9!dn)@L-)kaRyUjI#TeH6j41vpY6E+5YFKsr71l$1QS+9^ zD-k{W;%l$2oSXZoPZ@^@Iqf3&+u= zVWkhEQVtks>GR|xF41-Cb{0Eq-BB`+_5~AI)@Y=Ra8a6tv^NzZi6zfM!-v@sz=h;m z$U>T6^?X$?wZJm{2GepeX0Y8gGDTr7^WMTzz3alx<4w-DIwfvrhikDfrm!Y21O>Mq zhGbqn+Jo-X%4QX+U1IoP=yKAm|56mfAiw^yL&v_#NT`Cj>vtt#<>%cu zCe0H2d2b6{z5C5ih#goR&k`um@N>hhy^q-&yrrB&gTamp9TAFr@mTR2jZJw)rtlUi zjC94&Sq6(Y10gcOQ&YG%*)Pn#*zLVxjsBoTIrasM#}W7&ems8-)=#s!B<%N3)t`5& z(^-kGOL#xhDyRMQ9{VzsVsYuMUacR@pXqaMLqUZYL_+ZQ&o4y56@Wig+f?wERXKmW z$@Rq@qm$-XruVr@9~q z4>#A{0!XSziwpat_xWtDvx{@8>MgVa{FsjJvU-?G3Jbx2w{=@A+HcIKs%|upp?g9uzDO#Xsz zGFXM0g}yl+8yrsN65QeGzV(~&ho>U_;GP54s3cXD^P#)@-Dz|M+iM4lO9#%n+dX0l z(!!Ly;rKe?J$OpD1<)?p_ma(+>Gbj&_f=rFj=Wv65^e5&k@i4wx*?x#@sCdpvj(vF zcJf(gUwls5Ut^V?37;QTrxAYm8dn17LsWKr$a(l0Nc)@nVbZb*&DckD!SjiZC+WuB z#jc4){GT;bHc$`TJ(Her8TZEzs%R)(QgtauZ+y98X&}K~%Cz%wEfVQbyQ?7Hn)Uvd z!gWd>q1QcY{mCqL?>=W~VwKseSj#jP)ui&-o+%Gb^*FJY>8?q{UyP)(JmX&wrAUGU z$+HWa$JQd_3bn>Vb4*I8n@L@z=p3BM_$%aw&oevI<>zQ~#Rxq%ErBBWnNayG_v4|O zz0@QvwaMKaG0)aO)I*OpWSlj0(7aidEeTz*#HxLR$9-b7!Q~!XGqNW7$HT0M==UV8 zrZRvIp~WY{lOOUX$}=07K3S=j-HEWVwdJ~`WFW}cXCk0Y05M9}hUi;ZKiI840T{y~ z_v-ZGR3Zc+ikqC6)u%hxeGJp?aPnRBo+VwE5bS=29+sJTHozZy?YUBW=U{q6{D;`& zh4!LgCt+vgRiMNE6+O5_e3!lXgS*x-WGS$-1dmzi66(SAiEWcf(IBDWayq%Fl>3Jd z%I39_H}N^W%NM6!`xtRv?HpJ;bo~z^H+n##H{bNehv|d(ID5WI6UX%~V1z^Zec}FVFKoC=P6@{b97^>O6@J{1f^*}10 z2a_rFG^nI|#$kx}l2{`)UhQ6l+k?Gj)C#@7n9ZZzdxA{J{fp3p0k0D%fXcYoGKP;K zg1VY=5JQUCLTB{$%QycP{IQ+kx$137Nj&3+Tlc zuio>5UNAFgEHqx|uv738#tdLWEyp|UtlT)%{Qe*$~_JM-xGsyz?YrrtiQ*3$Re9R>Vf#ZmF2&npz4n56UTU+4zOFfv3C zmp*Z=cuUo8I>`fKK2By3|7O;nYW5Xa=?*Yc*G@* zN9!N3Qfg7R9_(l8%@EP>ENE0jJx!J9YQx7zvMk|&>h%dmUET-?ZMPpP!THClo_eqB zW~Q6hi3`y)DPAxrqqp|*68nyqw~W&Z9s36_PhQ_Pq7Uz-RgKCa-VvDBhCLg%AwzVM zp@0qWYXL8&!lvYXtJouI0(w?m6Vx^({md{%FzdG^1qEnt>%T}br#aj!fr4+*(Kz<} z%#3&FtL(HR!_5#7PNUh!S*T=&SVD^&cEDXSfPcAf+Qcu7l(99UVr~KPs1&LB8g!^%9`yC3at`Y=KU8J>Z}*uR4lyhO zQL<=)0u6E9-iqokXO8INi}#eP_=;ZA178fsmkZI*EEW8x68t06vlJD3W~V>mzE#7ZmyHQ z1d4FIS-^_HZHvOzf*x2(pxjk~m>Ar{rPt;LGXWYD;eKTkx4&1ae`fDFh!HdJ8Vw^qXSUC_lrd9QBP! z0tM2S%j8D83IliHH*l^)&7-eB4?lqiV67b!wLtpJfOh45bEgcngG3e^sSN7o->>{x z#sRJgP1BXN-#znbSNHXba){{QtF=D9wSSx`UFfk;`N2w6-F2I{S?xq4tyi}CXJotB zqRj4&K{@QKX^@-$HEn*o-G65DN1W23{Mmc>AMK{9ZYwMAIalZl3RT$W$O}IC|IP0F z-cT#QtG>r0&~3l9qE85S_bJu(*w=>vBf6^2TTcNhL4g%5Cw`&$Sn@i#DW+D}*nD_J z_I#cJ1XL`DY;QT7tC6h=h#DOpE1N^}WD4)_oxJra?>(kgo5QD2^Y0K9F%4->G8I4_0juf+iTn>v2g$)t8l`RLOqkb~ zyeS|+6sRB)k3G&&hbpsWvD(TKY*knhETo8&DTL_w<+tSAQ8|bV!Zj;o?RB#mzNg0 zVHVwF-)nmMtUHr0G3XE1h@_z%TvGg zw!||;!ZT0tpediR@cEa0g@gS$>$5_0;=glbAR?uSkyTE&hu}8W2?a%f4={XWcARCp#l48?Qx`zyqkw21 zO4vN!8O47c&qlf8ZT=Ow{LMM{J$lVu8ED~G9j}-a&5DZBJ8CaZ(WYAO)txg-+Xo_6ARulbrR`upjG$zGpNwIUZ07h+YZ5%0{&`RgbRqqR=Ac}k2 zHXnusSf8ik?Em0dW*;2#xEZP!SvI3HFu0w`ln2vcNj*1hPIB3bztZj69uMnOUe6i% z+e|l{*wKC|I!&Lfe)U&(+ed$?Z7}c1M@a~RDLtjG@v-Hh+jr%%S>6`vOLj$2a3M`< zX;+25Fz>*M0X&TlBVgNGl_`Y)F;{+hWbn;$Tod7+&806bIo|?UGN6P3%j_-HH!lt7 ztvUGs{P4Y#+2hH>Mkdn$3YMgR5rfirzjcl#8j&|C$SmwXJ^^ zTz{0;wI)7i&#jkM--ijrxftRRw8RO==qS_ueiwVqAB-&pmTvRh=e}^{!-cz%bs_^D z-t({eqJUMC*RX5?TXv@d#6{J1djNPUzqon}&+k*Pzrs;a%a+_btDp&M>S(+dPIA<4 z&_vige(1ckOIY~pXt2YnFR{PH5qEDpwWTepSdCfY@+eKG7V}L z9nJ(QA3r9ocp58Aa((^-!%?m1;FuESmR+pr%1tdsbO1!U;*9z=MggxQcEHk{Ojw$m=2Qy1HW|BWIDQC_eL?jN z#Hhb=6W>a^!SghfQ0StK5BSlHXIxC8CM%c&_HR$p=|3D*0U2*SJUxL$(h(OOrv=Zo z?W=2#hrYEJy1j$D&q`3U#@LJ4V@{x*byqZ+7lPD>Qew=mnuG|6I%f+6==k7 z{IXv0V)5nhnYzZ7wpa1mhN8tHm#p9REmJ@};O(6rCPBa~4|d61zqp&KfKm>8%}ycu zo)q2|iKkIx{#vqi=`6lyZdd{P@#Wy6dhOfCJPRx>=&(9N20BgiYv1V|7+{h9CLHuu zw4s`p*)GpT#ftG?l}xLQcwmtYCS#eWF|@#!r*Ab|srB9g ztT7oM1R#j&w3Q{|Go!@K=-q)9mN=LkWqvCis;RZ^~*_AxDL zA>9ATwQ>e40f^=v4&MX=fsR#y_V}Jonn0DsZoRf6S^o{X{ChE>N|LU}( z!$g@Ts=lnD5Vn)2qv9Fk(ntr{rw?3fY89VHr3pN#c_8f~3?q;&;!G@2DQ~*GIKw^k zO_#Taqcj- z-lg=Uul+-y8*ojQhqOs$hYW4ZqwF!3EV_S(F8}FRt@Vp~2;iMeOlPe`Q=u+helw^m#(jVk|dwYm?5;5UzAaRP>JVs@or)TmYTwk+V)?q>O?fEu@7jde4CY&xYrtk zq60&$3`fi!sRdNqOyflcb>}Zb`BNEa$#&xH=wpNHwVu?S*fs!EzUubK+_$A$lG7|Y z^mYOQoIteS(@&N+cupM{VSv(j&*b#~yqP|2cq15${SiXlAOcmA@=X2Xos*6>00|4> ziIwtx{E$gtQEhL|=SNSYSDXlyJ&Ag>z%9Tmj`n%~o3_YTotv!`(nooHo^j@Vxi9ww zDysL%Cq?Jq4u5zSU1UF*cDg%Z^J6-o=Hh9{FX`uu`~;bf<8MZX)i&;P zpWkkpjaQ$^FJ9TrnvgEO%U~$kjP z@Xq<(tfbfn>*u`$)4UN5RBT>Sr2S9HfW#Gxg|jMW!Fwl5Sus?Q#bMP7cX9k=sTzarI!AIOR}+ysBfvNCyG$tTpz4cPM?BW+{(0 z>R;33pjO)@l^sJPiT}*Or!;T*h<;u(1MFF z9e&iU@~yIfeKN3v^Oz-6s^#*5_>B5KWYV_w*gtGDa+azkTx`S@nbp4t!e;KzZ z5j6uqBTW!NfPaOpKBF#{7xh@-*sT6*_SfltNmBCxf@s>J%fj~(!y@NRtgx=veH z@kAr=>y36qMhQBBNRujSnpDhp+46IBK}tRzUipuW9*KD~wp>9frR(BOedjX9DiqO; zk0?nGe32NIMw1E=0R?CgD%e2St~AdqxJ+dD5(7hoVUAWWy|eOA)_10+o#%*_i0&m; z5Y}F6YG$QDWkA;vIoeppkw|henl9#+(>z`U+b=3tk7>{jDyFCO z>cqN-%Q2}Sm=pcq5;TcQr&|LS;Z3=NVC{O-6u1mS5wKW`HO8i$5;%!Dk{@GWIUZo4 zle*P#>un6@~0drDELIAGL9O(c600d`2O+f$vv5yP-CIAGg8axUzJL(b%VY7)IB{tJ%UJ46h%=KMNt$*Q4~c{6h)yW62R5f)yCS| z+Wykg()W|eWFH5=-r#fc#&pa_#_x^!y-PkW9v>es_xAQOT2Lwz2%@a7uOIP6KIEfA z#mM+Le|UKKWzobcU7*|B+k{U&2*c+M3JiN!%BSJh*4D4I0F)+>31g=$Oqa?bdwF^J zX?uJ7l4?vT0*ywa4}9uT1dp-7H^h*~sgt^fzNiAhYgSiR2mJDoswLy`>7b4xMH2{P z4d1;V`DH>v;E?w-hrBbY5eG;u(q(Kx-ix#?4l2<}0~bN--WBvDc|AePft%5w#*BkVi!d)u{)e!z(fud$#Q%M3O)X31sfnu8S=^r_8!o z9+9xL!F9s-B#@#W)N?Vym{W%5yaghmU`n6nRC8gw4-&n|Tc8}?lg3I2T!7c|#kYPw zyol?DMB)WNjsqV5-X3$(nvY`xns36(O(;2X-ti#yW7oR>iO zPq-{oV;zQsU@8Ww&5o0WA4w2i0-?df!7P=y1352#Nn+@NI7bFb!=rIeBSA9K0oNA4BO&;PxWw|l z&(4E{<0bH6yh5aLX@5ak}Z%62?-&JKv)PPB?wUja!DeD zlaUa7v$)J+l8{jNyNelLT!vn&W5PY+^xoI>)oTRzLH2mGHlWa+I zIA0ISYzERwCcv@CD{2nsI|f;M*rXL5L9^NH*lcXkp=^9TD0Q$o6t}k0XjqpLc#o+XfqJjh~d)Ua*m2O3Bp?-G`ZVsOe2O<=TA&r zy@x~Kkc3gFvy@Y5bZ>TSc2zd1n_Yg`4wG0+vsSCMN5UvHQFUy@z`#4;3zbj>VB<15 zR5tQ7-Iqz>-fUMdq6+qjVmBSydL2wfdJiaE>T&fVCgD)?u`Ex@Ar5-?#O`h=ERY#n zTz3XU7YSnyi!*c;2W`mV2)TRu2j>+l61xPA|;TeaJ5G0WSt2)4t{Y@EV) zlxN<93GXpad{ZjG)Z=BkloRP2ii2(56HOq1Ig;5Yno>pZn01CK0p>fdKO;$`Xd&(`Cd149G>`(| z=IC<@|GDa(H|$CXcclpgFkj(2`iL)5m*NSP8DVB_HL06Or3y5S@hEJg>`)lK@R+Yr zCy^=>=#|%pA@P#LJ2SU&*}Vtws4_euE9D99?|D~3>mpL+0?h(FbyLrW`}b^~m5l>S z1J)f1F4RFJkph*8bdmn|0s+Y)sXzv)BB?-ANEAs0dV@5PRG=A15=jO63Q|N;f#x7V zBo)X))gq}t4pb?U3gk#tBB?+*s6r$aC?{o$qyl+RrbsG~CuNBgwP|FLLDy2AMigd3 z9;gQu#Kn_}{4o&~C;;^19#4D)REu@~07*qoM6N<$f_=>GvH$=8 From b88c5c72a5186501e10254b756904d214c1389c1 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:44:50 +0900 Subject: [PATCH 066/110] =?UTF-8?q?refactor=20:=20connectionId=20=EB=B0=9B?= =?UTF-8?q?=EC=95=84=EC=98=A4=EB=8A=94=20api=20=EB=A6=AC=ED=84=B4=EA=B0=92?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/mindmap.api.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/api/mindmap.api.ts b/client/src/api/mindmap.api.ts index be838c26..3aa8d6fb 100644 --- a/client/src/api/mindmap.api.ts +++ b/client/src/api/mindmap.api.ts @@ -13,6 +13,7 @@ export function deleteMindMap(mindMapId: string) { return instance.delete(`/mindmap/${mindMapId}`); } -export function getMindMapByConnectionId(connectionId: string): Promise { - return instance.get(`/connection/c/${connectionId}`); +export async function getMindMapByConnectionId(connectionId: string): Promise { + const { data } = await instance.get(`/connection/c/${connectionId}`); + return data.mindmapId; } From fc2ce4a9dfd2c984dccc23ab5f334c69e4a2d26a Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:45:20 +0900 Subject: [PATCH 067/110] =?UTF-8?q?design=20:=20bm-blue=20=EC=83=89?= =?UTF-8?q?=EC=83=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/tailwind.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/tailwind.config.js b/client/tailwind.config.js index 7969577e..035b5878 100644 --- a/client/tailwind.config.js +++ b/client/tailwind.config.js @@ -5,7 +5,7 @@ export default { extend: { colors: { bm: { - blue: "#2F2FE9", + blue: "#2563EB", purple: "#98A4EE", }, grayscale: { From f052675f26dffb810eb8725336ebb8ab3e8a09ba Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:45:51 +0900 Subject: [PATCH 068/110] =?UTF-8?q?chore=20:=20=EC=95=84=EC=9D=B4=EC=BD=98?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Dashboard/MindMapInfoItem.tsx | 4 ++-- client/src/components/Dashboard/UserDashBoard.tsx | 8 +++----- client/src/components/MindMapHeader/ProfileModal.tsx | 1 - 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/client/src/components/Dashboard/MindMapInfoItem.tsx b/client/src/components/Dashboard/MindMapInfoItem.tsx index 81352a33..bd866161 100644 --- a/client/src/components/Dashboard/MindMapInfoItem.tsx +++ b/client/src/components/Dashboard/MindMapInfoItem.tsx @@ -4,7 +4,7 @@ import { Button } from "@headlessui/react"; import extractDate from "@/utils/extractDate"; import DeleteMindMapModal from "../DeleteMindMapModal"; import { createPortal } from "react-dom"; -import { FaRegTrashAlt } from "react-icons/fa"; +import { FaRegTrashAlt, FaUserCircle } from "react-icons/fa"; import { useNavigate } from "react-router-dom"; import { useDeleteMindMap } from "@/api/fetchHooks/useDeleteMindMap"; import { DashBoard } from "@/konva_mindmap/types/dashboard"; @@ -56,7 +56,7 @@ export default function MindMapInfoItem({ data, index }: MindMapInfoItemProps) { ))}
- 소유자 이미지 +
{data.ownerName}
diff --git a/client/src/components/Dashboard/UserDashBoard.tsx b/client/src/components/Dashboard/UserDashBoard.tsx index b384699b..141b2dfa 100644 --- a/client/src/components/Dashboard/UserDashBoard.tsx +++ b/client/src/components/Dashboard/UserDashBoard.tsx @@ -1,12 +1,12 @@ import MindMapInfoItem from "./MindMapInfoItem"; -import searchIcon from "@/assets/search.png"; import { Button, Input } from "@headlessui/react"; import { useEffect, useState } from "react"; -import { FaPlus } from "react-icons/fa"; +import { FaPlus, FaSearch } from "react-icons/fa"; import { useNavigate } from "react-router-dom"; import useDashBoard from "@/api/fetchHooks/useDashBoard"; import NoMindMap from "@/components/Dashboard/NoMindMap"; import { useConnectionStore } from "@/store/useConnectionStore"; +import { IoSearch } from "react-icons/io5"; export default function UserDashBoard() { const { data } = useDashBoard(); @@ -60,9 +60,7 @@ export default function UserDashBoard() { }} placeholder="키워드나 제목을 입력하세요" /> - +
); diff --git a/client/src/components/MindMapHeader/ProfileModal.tsx b/client/src/components/MindMapHeader/ProfileModal.tsx index 422893f7..f0c169f2 100644 --- a/client/src/components/MindMapHeader/ProfileModal.tsx +++ b/client/src/components/MindMapHeader/ProfileModal.tsx @@ -1,5 +1,4 @@ import { signOut } from "@/api/auth"; -import profileIcon from "@/assets/profile.png"; import { useConnectionStore } from "@/store/useConnectionStore"; import { Button } from "@headlessui/react"; import { useEffect, useRef } from "react"; From 96c658dfb149a9ef8116cfebab7891a5a0716ae2 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:46:09 +0900 Subject: [PATCH 069/110] =?UTF-8?q?remove=20:=20connectionId=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/store/NodeListProvider.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client/src/store/NodeListProvider.tsx b/client/src/store/NodeListProvider.tsx index e960d475..6df54d8e 100644 --- a/client/src/store/NodeListProvider.tsx +++ b/client/src/store/NodeListProvider.tsx @@ -30,7 +30,6 @@ export type NodeListContextType = { deleteSelectedNodes: () => void; content: string; updateContent: (updatedContent: string) => void; - updateMindMapId: (mindMapId: string) => void; } & Partial & Partial; @@ -55,7 +54,6 @@ export default function NodeListProvider({ children }: { children: ReactNode }) const stage = useRef(); const socket = useConnectionStore((state) => state.socket); const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); - const [mindMapId, setMindMapId] = useState(""); useEffect(() => { socket?.on("joinRoom", (initialData) => { @@ -145,10 +143,6 @@ export default function NodeListProvider({ children }: { children: ReactNode }) if (selectedNode.nodeId) deleteNodes(JSON.stringify(data), selectedNode.nodeId, overrideNodeData); } - function updateMindMapId(mindMapId: string) { - setMindMapId(mindMapId); - } - return ( From 3d81bb91c71a05a8ab33515c5329fa8696fd32bd Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:46:41 +0900 Subject: [PATCH 070/110] =?UTF-8?q?refactor=20:=20api=EB=A1=9C=20=EB=B3=B4?= =?UTF-8?q?=EB=82=BC=20formdata=20=ED=95=A8=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/utils/formData.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 client/src/utils/formData.ts diff --git a/client/src/utils/formData.ts b/client/src/utils/formData.ts new file mode 100644 index 00000000..530ee213 --- /dev/null +++ b/client/src/utils/formData.ts @@ -0,0 +1,7 @@ +export function audioFormData(file: File, mindmapId: string, connectionId: string) { + const formData = new FormData(); + formData.append("aiAudio", file); + formData.append("mindmapId", mindmapId); + formData.append("connectionId", connectionId); + return formData; +} From 0fb9710aeeaa62d508d4edaa791a2e99aaee5e0b Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:46:54 +0900 Subject: [PATCH 071/110] =?UTF-8?q?chore=20:=20=EB=85=B8=EB=93=9C=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=20=ED=81=AC=EA=B8=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/konva_mindmap/utils/nodeAttrs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/konva_mindmap/utils/nodeAttrs.ts b/client/src/konva_mindmap/utils/nodeAttrs.ts index fee49b62..c23bb2af 100644 --- a/client/src/konva_mindmap/utils/nodeAttrs.ts +++ b/client/src/konva_mindmap/utils/nodeAttrs.ts @@ -13,7 +13,7 @@ export const CONNECTED_LINE_FROM = (depth: number) => NODE_DEFAULT_SIZE - depth export const CONNECTED_LINE_TO = (depth: number) => NODE_DEFAULT_SIZE - depth * 7 + 5; //TEXT -export const TEXT_FONT_SIZE = 20; +export const TEXT_FONT_SIZE = 16; export const TOOL_OFFSET_X = NODE_DEFAULT_SIZE - 30; export const TOOL_OFFSET_Y = (radius: number) => NODE_DEFAULT_SIZE + radius - 20; From 2b1db73ebc6ab6ccc0ddba4693f118b5315d4290 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:47:28 +0900 Subject: [PATCH 072/110] =?UTF-8?q?chore=20:=20ai=20=EC=9A=94=EC=B2=AD=20c?= =?UTF-8?q?onstant=20=ED=8C=8C=EC=9D=BC=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=B0=8F=20=ED=8C=8C=EC=9D=BC=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EC=A0=9C=ED=95=9C=20=EC=83=81=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/constants/{textUploadLimit.ts => uploadLimit.ts} | 1 + 1 file changed, 1 insertion(+) rename client/src/constants/{textUploadLimit.ts => uploadLimit.ts} (62%) diff --git a/client/src/constants/textUploadLimit.ts b/client/src/constants/uploadLimit.ts similarity index 62% rename from client/src/constants/textUploadLimit.ts rename to client/src/constants/uploadLimit.ts index 574b633a..27b4a01c 100644 --- a/client/src/constants/textUploadLimit.ts +++ b/client/src/constants/uploadLimit.ts @@ -1,2 +1,3 @@ export const MAX_TEXT_UPLOAD_LIMIT = 2000; export const MIN_TEXT_UPLOAD_LIMIT = 500; +export const FILE_UPLOAD_LIMIT = 1024 * 1024 * 50; From fe7988355ee8495de843348d8d78da927c2f1c2a Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:47:51 +0900 Subject: [PATCH 073/110] =?UTF-8?q?remove=20:=20connectionId=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=EC=97=90=20=EB=94=B0=EB=A5=B8=20updateConnectionId=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EB=AC=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/MindMapMainSection/index.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/src/components/MindMapMainSection/index.tsx b/client/src/components/MindMapMainSection/index.tsx index b7baa239..b5a94a23 100644 --- a/client/src/components/MindMapMainSection/index.tsx +++ b/client/src/components/MindMapMainSection/index.tsx @@ -6,7 +6,6 @@ import { useParams } from "react-router-dom"; import ToastContainer from "../common/Toast/ToastContainer"; import { useConnectionStore } from "@/store/useConnectionStore"; import useToast from "@/hooks/useToast"; -import { useNodeListContext } from "@/store/NodeListProvider"; const modeView = { voiceupload: "음성 파일 업로드", @@ -20,12 +19,10 @@ export default function MindMapMainSection() { const connectSocket = useConnectionStore((state) => state.connectSocket); const disconnectSocket = useConnectionStore((state) => state.disconnectSocket); const { toasts, setToasts } = useToast(); - const { updateMindMapId } = useNodeListContext(); useEffect(() => { if (mindMapId) { connectSocket(mindMapId); - updateMindMapId(mindMapId); } return () => { disconnectSocket(); From 6e52df08f8181f8387e81fb1dcab037738557735 Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:48:14 +0900 Subject: [PATCH 074/110] =?UTF-8?q?refactor=20:=20useUpload=EA=B0=80=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=EC=99=80=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=AA=A8=EB=93=9C=20=EB=91=98=20=EB=8B=A4=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/hooks/useUpload.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/client/src/hooks/useUpload.ts b/client/src/hooks/useUpload.ts index 63672ecc..26437f82 100644 --- a/client/src/hooks/useUpload.ts +++ b/client/src/hooks/useUpload.ts @@ -1,4 +1,3 @@ -import { MIN_TEXT_UPLOAD_LIMIT } from "@/constants/textUploadLimit"; import { useNodeListContext } from "@/store/NodeListProvider"; import { useConnectionStore } from "@/store/useConnectionStore"; import { useState } from "react"; @@ -6,17 +5,12 @@ import { useState } from "react"; export default function useUpload() { const [content, setContent] = useState(""); const role = useConnectionStore((state) => state.currentRole); - const handleSocketEvent = useConnectionStore((state) => state.handleSocketEvent); const { aiCount } = useNodeListContext(); const [availabilityInform, setAvailabilityInform] = useState(""); + const [errorMsg, setErrorMsg] = useState(""); const ownerAvailability = role === "owner"; - function handleAiProcessButton() { - if (content.length <= MIN_TEXT_UPLOAD_LIMIT || !ownerAvailability) return; - handleSocketEvent({ actionType: "aiRequest", payload: { aiContent: content } }); - } - function updateContent(content: string) { setContent(content); } @@ -40,12 +34,17 @@ export default function useUpload() { } } + function updateErrorMsg(message: string) { + setErrorMsg(message); + } + return { content, updateContent, - handleAiProcessButton, handleMouseEnter, handleMouseLeave, availabilityInform, + errorMsg, + updateErrorMsg, }; } From cd15f7437861b0237edfbb9b6e6ac84cd17eecfc Mon Sep 17 00:00:00 2001 From: Minhyung Cho Date: Tue, 3 Dec 2024 16:48:30 +0900 Subject: [PATCH 075/110] =?UTF-8?q?design=20:=20=EC=82=AC=EC=9D=B4?= =?UTF-8?q?=EB=93=9C=EB=B0=94=20min-height=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/components/Sidebar/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/Sidebar/index.tsx b/client/src/components/Sidebar/index.tsx index f74228c5..2e2240d1 100644 --- a/client/src/components/Sidebar/index.tsx +++ b/client/src/components/Sidebar/index.tsx @@ -17,7 +17,7 @@ export default function Sidebar({ isSidebarOpen, toggleSidebar }: SidebarProps) return ( <>