Merge pull request #15 from bitnine-oss/develop

Merge: Develop
diff --git a/backend/.babelrc b/backend/.babelrc
index b739808..5a2a1d8 100644
--- a/backend/.babelrc
+++ b/backend/.babelrc
@@ -5,6 +5,7 @@
   "plugins": [
     [
       "@babel/transform-runtime"
-    ]
+    ],
+    "@babel/plugin-proposal-class-properties"
   ]
-}
\ No newline at end of file
+}
diff --git a/backend/package-lock.json b/backend/package-lock.json
index 10e749e..03debcf 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -8,10 +8,12 @@
             "name": "ag-viewer-backend",
             "version": "0.4.0",
             "dependencies": {
-                "agensgraph": "git+https://github.com/bitnine-oss/agensgraph-nodejs.git",
+                "@bitnine-oss/ag-driver": "^0.1.0",
+                "antlr4": "^4.9.2",
                 "cookie-parser": "~1.4.5",
                 "cors": "^2.8.5",
                 "debug": "~4.3.1",
+                "ejs": "^3.1.6",
                 "express": "~4.17.1",
                 "express-session": "^1.17.1",
                 "http-status": "^1.5.0",
@@ -28,9 +30,13 @@
                 "@babel/cli": "^7.12.13",
                 "@babel/core": "^7.12.13",
                 "@babel/node": "^7.12.13",
+                "@babel/plugin-proposal-class-properties": "^7.13.0",
                 "@babel/plugin-transform-runtime": "^7.12.15",
                 "@babel/preset-env": "^7.12.13",
                 "@babel/register": "^7.12.13",
+                "babel-plugin-polyfill-corejs2": "^0.2.0",
+                "babel-plugin-polyfill-corejs3": "^0.2.0",
+                "babel-plugin-polyfill-regenerator": "^0.2.0",
                 "mocha": "^8.2.1",
                 "nodemon": "^2.0.7",
                 "supertest": "^6.0.1",
@@ -71,9 +77,9 @@
             }
         },
         "node_modules/@babel/compat-data": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.13.tgz",
-            "integrity": "sha512-U/hshG5R+SIoW7HVWIdmy1cB7s3ki+r3FpyEZiCgpi4tFgPnX/vynY80ZGSASOIrUM6O7VxOgCZgdt7h97bUGg==",
+            "version": "7.14.0",
+            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz",
+            "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==",
             "dev": true
         },
         "node_modules/@babel/core": {
@@ -103,12 +109,12 @@
             }
         },
         "node_modules/@babel/generator": {
-            "version": "7.12.15",
-            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz",
-            "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==",
+            "version": "7.14.1",
+            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz",
+            "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==",
             "dev": true,
             "dependencies": {
-                "@babel/types": "^7.12.13",
+                "@babel/types": "^7.14.1",
                 "jsesc": "^2.5.1",
                 "source-map": "^0.5.0"
             }
@@ -133,28 +139,44 @@
             }
         },
         "node_modules/@babel/helper-compilation-targets": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.13.tgz",
-            "integrity": "sha512-dXof20y/6wB5HnLOGyLh/gobsMvDNoekcC+8MCV2iaTd5JemhFkPD73QB+tK3iFC9P0xJC73B6MvKkyUfS9cCw==",
+            "version": "7.13.16",
+            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz",
+            "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==",
             "dev": true,
             "dependencies": {
-                "@babel/compat-data": "^7.12.13",
-                "@babel/helper-validator-option": "^7.12.11",
+                "@babel/compat-data": "^7.13.15",
+                "@babel/helper-validator-option": "^7.12.17",
                 "browserslist": "^4.14.5",
-                "semver": "^5.5.0"
+                "semver": "^6.3.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+            "version": "6.3.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "dev": true,
+            "bin": {
+                "semver": "bin/semver.js"
             }
         },
         "node_modules/@babel/helper-create-class-features-plugin": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.13.tgz",
-            "integrity": "sha512-Vs/e9wv7rakKYeywsmEBSRC9KtmE7Px+YBlESekLeJOF0zbGUicGfXSNi3o+tfXSNS48U/7K9mIOOCR79Cl3+Q==",
+            "version": "7.14.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz",
+            "integrity": "sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg==",
             "dev": true,
             "dependencies": {
+                "@babel/helper-annotate-as-pure": "^7.12.13",
                 "@babel/helper-function-name": "^7.12.13",
-                "@babel/helper-member-expression-to-functions": "^7.12.13",
+                "@babel/helper-member-expression-to-functions": "^7.13.12",
                 "@babel/helper-optimise-call-expression": "^7.12.13",
-                "@babel/helper-replace-supers": "^7.12.13",
+                "@babel/helper-replace-supers": "^7.13.12",
                 "@babel/helper-split-export-declaration": "^7.12.13"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
             }
         },
         "node_modules/@babel/helper-create-regexp-features-plugin": {
@@ -167,6 +189,34 @@
                 "regexpu-core": "^4.7.1"
             }
         },
+        "node_modules/@babel/helper-define-polyfill-provider": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz",
+            "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==",
+            "dev": true,
+            "dependencies": {
+                "@babel/helper-compilation-targets": "^7.13.0",
+                "@babel/helper-module-imports": "^7.12.13",
+                "@babel/helper-plugin-utils": "^7.13.0",
+                "@babel/traverse": "^7.13.0",
+                "debug": "^4.1.1",
+                "lodash.debounce": "^4.0.8",
+                "resolve": "^1.14.2",
+                "semver": "^6.1.2"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.4.0-0"
+            }
+        },
+        "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": {
+            "version": "6.3.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "dev": true,
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
         "node_modules/@babel/helper-explode-assignable-expression": {
             "version": "7.12.13",
             "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.13.tgz",
@@ -206,12 +256,12 @@
             }
         },
         "node_modules/@babel/helper-member-expression-to-functions": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz",
-            "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==",
+            "version": "7.13.12",
+            "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz",
+            "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==",
             "dev": true,
             "dependencies": {
-                "@babel/types": "^7.12.13"
+                "@babel/types": "^7.13.12"
             }
         },
         "node_modules/@babel/helper-module-imports": {
@@ -250,9 +300,9 @@
             }
         },
         "node_modules/@babel/helper-plugin-utils": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz",
-            "integrity": "sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA==",
+            "version": "7.13.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz",
+            "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==",
             "dev": true
         },
         "node_modules/@babel/helper-remap-async-to-generator": {
@@ -267,15 +317,15 @@
             }
         },
         "node_modules/@babel/helper-replace-supers": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz",
-            "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==",
+            "version": "7.13.12",
+            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz",
+            "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==",
             "dev": true,
             "dependencies": {
-                "@babel/helper-member-expression-to-functions": "^7.12.13",
+                "@babel/helper-member-expression-to-functions": "^7.13.12",
                 "@babel/helper-optimise-call-expression": "^7.12.13",
-                "@babel/traverse": "^7.12.13",
-                "@babel/types": "^7.12.13"
+                "@babel/traverse": "^7.13.0",
+                "@babel/types": "^7.13.12"
             }
         },
         "node_modules/@babel/helper-simple-access": {
@@ -306,15 +356,15 @@
             }
         },
         "node_modules/@babel/helper-validator-identifier": {
-            "version": "7.12.11",
-            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
-            "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
+            "version": "7.14.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
+            "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
             "dev": true
         },
         "node_modules/@babel/helper-validator-option": {
-            "version": "7.12.11",
-            "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz",
-            "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==",
+            "version": "7.12.17",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz",
+            "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==",
             "dev": true
         },
         "node_modules/@babel/helper-wrap-function": {
@@ -370,9 +420,9 @@
             }
         },
         "node_modules/@babel/parser": {
-            "version": "7.12.15",
-            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz",
-            "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==",
+            "version": "7.14.1",
+            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz",
+            "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==",
             "dev": true,
             "bin": {
                 "parser": "bin/babel-parser.js"
@@ -393,13 +443,16 @@
             }
         },
         "node_modules/@babel/plugin-proposal-class-properties": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz",
-            "integrity": "sha512-8SCJ0Ddrpwv4T7Gwb33EmW1V9PY5lggTO+A8WjyIwxrSHDUyBw4MtF96ifn1n8H806YlxbVCoKXbbmzD6RD+cA==",
+            "version": "7.13.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz",
+            "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==",
             "dev": true,
             "dependencies": {
-                "@babel/helper-create-class-features-plugin": "^7.12.13",
-                "@babel/helper-plugin-utils": "^7.12.13"
+                "@babel/helper-create-class-features-plugin": "^7.13.0",
+                "@babel/helper-plugin-utils": "^7.13.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
             }
         },
         "node_modules/@babel/plugin-proposal-dynamic-import": {
@@ -1069,33 +1122,40 @@
             }
         },
         "node_modules/@babel/traverse": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz",
-            "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==",
+            "version": "7.14.0",
+            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz",
+            "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==",
             "dev": true,
             "dependencies": {
                 "@babel/code-frame": "^7.12.13",
-                "@babel/generator": "^7.12.13",
+                "@babel/generator": "^7.14.0",
                 "@babel/helper-function-name": "^7.12.13",
                 "@babel/helper-split-export-declaration": "^7.12.13",
-                "@babel/parser": "^7.12.13",
-                "@babel/types": "^7.12.13",
+                "@babel/parser": "^7.14.0",
+                "@babel/types": "^7.14.0",
                 "debug": "^4.1.0",
-                "globals": "^11.1.0",
-                "lodash": "^4.17.19"
+                "globals": "^11.1.0"
             }
         },
         "node_modules/@babel/types": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz",
-            "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==",
+            "version": "7.14.1",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz",
+            "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==",
             "dev": true,
             "dependencies": {
-                "@babel/helper-validator-identifier": "^7.12.11",
-                "lodash": "^4.17.19",
+                "@babel/helper-validator-identifier": "^7.14.0",
                 "to-fast-properties": "^2.0.0"
             }
         },
+        "node_modules/@bitnine-oss/ag-driver": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/@bitnine-oss/ag-driver/-/ag-driver-0.1.0.tgz",
+            "integrity": "sha512-ih9BCSDHNZdUQ//yFP+rXqiUPhvvpoZ0n4j1sgNFyhXJ4Z3J6km87dIDXVD3sRv9ABhDZ5zz21YuUGZH5S+Adw==",
+            "dependencies": {
+                "lodash": "^4.17.20",
+                "pg": ">= 6.1.2"
+            }
+        },
         "node_modules/@dabh/diagnostics": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz",
@@ -1171,13 +1231,6 @@
                 "node": ">= 0.6"
             }
         },
-        "node_modules/agensgraph": {
-            "resolved": "git+ssh://git@github.com/bitnine-oss/agensgraph-nodejs.git#b43b2c35b676ea174e0b7a13477aa3a683ec1782",
-            "dependencies": {
-                "lodash": "^4.17.20",
-                "pg": ">= 6.1.2"
-            }
-        },
         "node_modules/ansi-align": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
@@ -1251,6 +1304,14 @@
                 "node": ">=4"
             }
         },
+        "node_modules/antlr4": {
+            "version": "4.9.2",
+            "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.9.2.tgz",
+            "integrity": "sha512-UjMSlenUORL+a+6g4RNZxRh5LcFWybRi2g0ASDBpgXBY6nlavg0BRVAVEQF0dz8jH6SyX3lV7uP5y/krJzc+Hw==",
+            "engines": {
+                "node": ">=14"
+            }
+        },
         "node_modules/anymatch": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
@@ -1379,6 +1440,54 @@
                 "object.assign": "^4.1.0"
             }
         },
+        "node_modules/babel-plugin-polyfill-corejs2": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz",
+            "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==",
+            "dev": true,
+            "dependencies": {
+                "@babel/compat-data": "^7.13.11",
+                "@babel/helper-define-polyfill-provider": "^0.2.0",
+                "semver": "^6.1.1"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
+            "version": "6.3.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "dev": true,
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
+        "node_modules/babel-plugin-polyfill-corejs3": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz",
+            "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==",
+            "dev": true,
+            "dependencies": {
+                "@babel/helper-define-polyfill-provider": "^0.2.0",
+                "core-js-compat": "^3.9.1"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
+        "node_modules/babel-plugin-polyfill-regenerator": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz",
+            "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==",
+            "dev": true,
+            "dependencies": {
+                "@babel/helper-define-polyfill-provider": "^0.2.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0-0"
+            }
+        },
         "node_modules/balanced-match": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -1700,22 +1809,26 @@
             "dev": true
         },
         "node_modules/browserslist": {
-            "version": "4.16.3",
-            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz",
-            "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==",
+            "version": "4.16.6",
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
+            "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
             "dev": true,
             "dependencies": {
-                "caniuse-lite": "^1.0.30001181",
-                "colorette": "^1.2.1",
-                "electron-to-chromium": "^1.3.649",
+                "caniuse-lite": "^1.0.30001219",
+                "colorette": "^1.2.2",
+                "electron-to-chromium": "^1.3.723",
                 "escalade": "^3.1.1",
-                "node-releases": "^1.1.70"
+                "node-releases": "^1.1.71"
             },
             "bin": {
                 "browserslist": "cli.js"
             },
             "engines": {
                 "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/browserslist"
             }
         },
         "node_modules/buffer-from": {
@@ -1819,9 +1932,9 @@
             }
         },
         "node_modules/caniuse-lite": {
-            "version": "1.0.30001185",
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz",
-            "integrity": "sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg==",
+            "version": "1.0.30001222",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001222.tgz",
+            "integrity": "sha512-rPmwUK0YMjfMlZVmH6nVB5U3YJ5Wnx3vmT5lnRO3nIKO8bJ+TRWMbGuuiSugDJqESy/lz+1hSrlQEagCtoOAWQ==",
             "dev": true
         },
         "node_modules/chalk": {
@@ -2106,9 +2219,9 @@
             }
         },
         "node_modules/colorette": {
-            "version": "1.2.1",
-            "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz",
-            "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==",
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
+            "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
             "dev": true
         },
         "node_modules/colors": {
@@ -2292,13 +2405,17 @@
             "hasInstallScript": true
         },
         "node_modules/core-js-compat": {
-            "version": "3.8.3",
-            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz",
-            "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==",
+            "version": "3.11.3",
+            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.11.3.tgz",
+            "integrity": "sha512-oNjHN/qUHOA0dPv+v5prqHfeSvIEJrk3hYVoaUK4MNzL9U433uu0MN+pImcdntV8o9pDq0r1v+9lTfKPjjbX/A==",
             "dev": true,
             "dependencies": {
-                "browserslist": "^4.16.1",
+                "browserslist": "^4.16.6",
                 "semver": "7.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/core-js"
             }
         },
         "node_modules/core-js-compat/node_modules/semver": {
@@ -2528,10 +2645,24 @@
             "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
             "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
         },
+        "node_modules/ejs": {
+            "version": "3.1.6",
+            "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
+            "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
+            "dependencies": {
+                "jake": "^10.6.1"
+            },
+            "bin": {
+                "ejs": "bin/cli.js"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
         "node_modules/electron-to-chromium": {
-            "version": "1.3.661",
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.661.tgz",
-            "integrity": "sha512-INNzKoL9ceOpPCpF5J+Fp9AOHY1RegwKViohAyTzV3XbkuRUx04r4v8edsDbevsog8UuL0GvD/Qerr2HwVTlSA==",
+            "version": "1.3.727",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz",
+            "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==",
             "dev": true
         },
         "node_modules/emoji-regex": {
@@ -2964,6 +3095,14 @@
                 "moment": "^2.11.2"
             }
         },
+        "node_modules/filelist": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
+            "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
+            "dependencies": {
+                "minimatch": "^3.0.4"
+            }
+        },
         "node_modules/fill-range": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
@@ -3849,6 +3988,28 @@
                 "node": ">=0.10.0"
             }
         },
+        "node_modules/jake": {
+            "version": "10.8.2",
+            "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
+            "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
+            "dependencies": {
+                "async": "0.9.x",
+                "chalk": "^2.4.2",
+                "filelist": "^1.0.1",
+                "minimatch": "^3.0.4"
+            },
+            "bin": {
+                "jake": "bin/cli.js"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/jake/node_modules/async": {
+            "version": "0.9.2",
+            "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+            "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
+        },
         "node_modules/js-tokens": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -3974,6 +4135,12 @@
             "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
             "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
         },
+        "node_modules/lodash.debounce": {
+            "version": "4.0.8",
+            "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+            "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
+            "dev": true
+        },
         "node_modules/log-symbols": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
@@ -4674,9 +4841,9 @@
             }
         },
         "node_modules/node-releases": {
-            "version": "1.1.70",
-            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz",
-            "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==",
+            "version": "1.1.71",
+            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz",
+            "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==",
             "dev": true
         },
         "node_modules/node-uuid": {
@@ -7229,9 +7396,9 @@
             }
         },
         "@babel/compat-data": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.13.tgz",
-            "integrity": "sha512-U/hshG5R+SIoW7HVWIdmy1cB7s3ki+r3FpyEZiCgpi4tFgPnX/vynY80ZGSASOIrUM6O7VxOgCZgdt7h97bUGg==",
+            "version": "7.14.0",
+            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz",
+            "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==",
             "dev": true
         },
         "@babel/core": {
@@ -7258,12 +7425,12 @@
             }
         },
         "@babel/generator": {
-            "version": "7.12.15",
-            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz",
-            "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==",
+            "version": "7.14.1",
+            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz",
+            "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==",
             "dev": true,
             "requires": {
-                "@babel/types": "^7.12.13",
+                "@babel/types": "^7.14.1",
                 "jsesc": "^2.5.1",
                 "source-map": "^0.5.0"
             }
@@ -7288,27 +7455,36 @@
             }
         },
         "@babel/helper-compilation-targets": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.13.tgz",
-            "integrity": "sha512-dXof20y/6wB5HnLOGyLh/gobsMvDNoekcC+8MCV2iaTd5JemhFkPD73QB+tK3iFC9P0xJC73B6MvKkyUfS9cCw==",
+            "version": "7.13.16",
+            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz",
+            "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==",
             "dev": true,
             "requires": {
-                "@babel/compat-data": "^7.12.13",
-                "@babel/helper-validator-option": "^7.12.11",
+                "@babel/compat-data": "^7.13.15",
+                "@babel/helper-validator-option": "^7.12.17",
                 "browserslist": "^4.14.5",
-                "semver": "^5.5.0"
+                "semver": "^6.3.0"
+            },
+            "dependencies": {
+                "semver": {
+                    "version": "6.3.0",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+                    "dev": true
+                }
             }
         },
         "@babel/helper-create-class-features-plugin": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.13.tgz",
-            "integrity": "sha512-Vs/e9wv7rakKYeywsmEBSRC9KtmE7Px+YBlESekLeJOF0zbGUicGfXSNi3o+tfXSNS48U/7K9mIOOCR79Cl3+Q==",
+            "version": "7.14.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz",
+            "integrity": "sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg==",
             "dev": true,
             "requires": {
+                "@babel/helper-annotate-as-pure": "^7.12.13",
                 "@babel/helper-function-name": "^7.12.13",
-                "@babel/helper-member-expression-to-functions": "^7.12.13",
+                "@babel/helper-member-expression-to-functions": "^7.13.12",
                 "@babel/helper-optimise-call-expression": "^7.12.13",
-                "@babel/helper-replace-supers": "^7.12.13",
+                "@babel/helper-replace-supers": "^7.13.12",
                 "@babel/helper-split-export-declaration": "^7.12.13"
             }
         },
@@ -7322,6 +7498,30 @@
                 "regexpu-core": "^4.7.1"
             }
         },
+        "@babel/helper-define-polyfill-provider": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz",
+            "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-compilation-targets": "^7.13.0",
+                "@babel/helper-module-imports": "^7.12.13",
+                "@babel/helper-plugin-utils": "^7.13.0",
+                "@babel/traverse": "^7.13.0",
+                "debug": "^4.1.1",
+                "lodash.debounce": "^4.0.8",
+                "resolve": "^1.14.2",
+                "semver": "^6.1.2"
+            },
+            "dependencies": {
+                "semver": {
+                    "version": "6.3.0",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+                    "dev": true
+                }
+            }
+        },
         "@babel/helper-explode-assignable-expression": {
             "version": "7.12.13",
             "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.13.tgz",
@@ -7361,12 +7561,12 @@
             }
         },
         "@babel/helper-member-expression-to-functions": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz",
-            "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==",
+            "version": "7.13.12",
+            "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz",
+            "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==",
             "dev": true,
             "requires": {
-                "@babel/types": "^7.12.13"
+                "@babel/types": "^7.13.12"
             }
         },
         "@babel/helper-module-imports": {
@@ -7405,9 +7605,9 @@
             }
         },
         "@babel/helper-plugin-utils": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz",
-            "integrity": "sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA==",
+            "version": "7.13.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz",
+            "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==",
             "dev": true
         },
         "@babel/helper-remap-async-to-generator": {
@@ -7422,15 +7622,15 @@
             }
         },
         "@babel/helper-replace-supers": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz",
-            "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==",
+            "version": "7.13.12",
+            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz",
+            "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==",
             "dev": true,
             "requires": {
-                "@babel/helper-member-expression-to-functions": "^7.12.13",
+                "@babel/helper-member-expression-to-functions": "^7.13.12",
                 "@babel/helper-optimise-call-expression": "^7.12.13",
-                "@babel/traverse": "^7.12.13",
-                "@babel/types": "^7.12.13"
+                "@babel/traverse": "^7.13.0",
+                "@babel/types": "^7.13.12"
             }
         },
         "@babel/helper-simple-access": {
@@ -7461,15 +7661,15 @@
             }
         },
         "@babel/helper-validator-identifier": {
-            "version": "7.12.11",
-            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
-            "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
+            "version": "7.14.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
+            "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
             "dev": true
         },
         "@babel/helper-validator-option": {
-            "version": "7.12.11",
-            "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz",
-            "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==",
+            "version": "7.12.17",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz",
+            "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==",
             "dev": true
         },
         "@babel/helper-wrap-function": {
@@ -7522,9 +7722,9 @@
             }
         },
         "@babel/parser": {
-            "version": "7.12.15",
-            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz",
-            "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==",
+            "version": "7.14.1",
+            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz",
+            "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==",
             "dev": true
         },
         "@babel/plugin-proposal-async-generator-functions": {
@@ -7539,13 +7739,13 @@
             }
         },
         "@babel/plugin-proposal-class-properties": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz",
-            "integrity": "sha512-8SCJ0Ddrpwv4T7Gwb33EmW1V9PY5lggTO+A8WjyIwxrSHDUyBw4MtF96ifn1n8H806YlxbVCoKXbbmzD6RD+cA==",
+            "version": "7.13.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz",
+            "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==",
             "dev": true,
             "requires": {
-                "@babel/helper-create-class-features-plugin": "^7.12.13",
-                "@babel/helper-plugin-utils": "^7.12.13"
+                "@babel/helper-create-class-features-plugin": "^7.13.0",
+                "@babel/helper-plugin-utils": "^7.13.0"
             }
         },
         "@babel/plugin-proposal-dynamic-import": {
@@ -8212,33 +8412,40 @@
             }
         },
         "@babel/traverse": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz",
-            "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==",
+            "version": "7.14.0",
+            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz",
+            "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==",
             "dev": true,
             "requires": {
                 "@babel/code-frame": "^7.12.13",
-                "@babel/generator": "^7.12.13",
+                "@babel/generator": "^7.14.0",
                 "@babel/helper-function-name": "^7.12.13",
                 "@babel/helper-split-export-declaration": "^7.12.13",
-                "@babel/parser": "^7.12.13",
-                "@babel/types": "^7.12.13",
+                "@babel/parser": "^7.14.0",
+                "@babel/types": "^7.14.0",
                 "debug": "^4.1.0",
-                "globals": "^11.1.0",
-                "lodash": "^4.17.19"
+                "globals": "^11.1.0"
             }
         },
         "@babel/types": {
-            "version": "7.12.13",
-            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz",
-            "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==",
+            "version": "7.14.1",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz",
+            "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==",
             "dev": true,
             "requires": {
-                "@babel/helper-validator-identifier": "^7.12.11",
-                "lodash": "^4.17.19",
+                "@babel/helper-validator-identifier": "^7.14.0",
                 "to-fast-properties": "^2.0.0"
             }
         },
+        "@bitnine-oss/ag-driver": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/@bitnine-oss/ag-driver/-/ag-driver-0.1.0.tgz",
+            "integrity": "sha512-ih9BCSDHNZdUQ//yFP+rXqiUPhvvpoZ0n4j1sgNFyhXJ4Z3J6km87dIDXVD3sRv9ABhDZ5zz21YuUGZH5S+Adw==",
+            "requires": {
+                "lodash": "^4.17.20",
+                "pg": ">= 6.1.2"
+            }
+        },
         "@dabh/diagnostics": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz",
@@ -8305,14 +8512,6 @@
                 "negotiator": "0.6.2"
             }
         },
-        "agensgraph": {
-            "version": "git+ssh://git@github.com/bitnine-oss/agensgraph-nodejs.git#b43b2c35b676ea174e0b7a13477aa3a683ec1782",
-            "from": "agensgraph@git+https://github.com/bitnine-oss/agensgraph-nodejs.git",
-            "requires": {
-                "lodash": "^4.17.20",
-                "pg": ">= 6.1.2"
-            }
-        },
         "ansi-align": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
@@ -8370,6 +8569,11 @@
                 "color-convert": "^1.9.0"
             }
         },
+        "antlr4": {
+            "version": "4.9.2",
+            "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.9.2.tgz",
+            "integrity": "sha512-UjMSlenUORL+a+6g4RNZxRh5LcFWybRi2g0ASDBpgXBY6nlavg0BRVAVEQF0dz8jH6SyX3lV7uP5y/krJzc+Hw=="
+        },
         "anymatch": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
@@ -8476,6 +8680,44 @@
                 "object.assign": "^4.1.0"
             }
         },
+        "babel-plugin-polyfill-corejs2": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz",
+            "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==",
+            "dev": true,
+            "requires": {
+                "@babel/compat-data": "^7.13.11",
+                "@babel/helper-define-polyfill-provider": "^0.2.0",
+                "semver": "^6.1.1"
+            },
+            "dependencies": {
+                "semver": {
+                    "version": "6.3.0",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+                    "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+                    "dev": true
+                }
+            }
+        },
+        "babel-plugin-polyfill-corejs3": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz",
+            "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-define-polyfill-provider": "^0.2.0",
+                "core-js-compat": "^3.9.1"
+            }
+        },
+        "babel-plugin-polyfill-regenerator": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz",
+            "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==",
+            "dev": true,
+            "requires": {
+                "@babel/helper-define-polyfill-provider": "^0.2.0"
+            }
+        },
         "balanced-match": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -8747,16 +8989,16 @@
             "dev": true
         },
         "browserslist": {
-            "version": "4.16.3",
-            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz",
-            "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==",
+            "version": "4.16.6",
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
+            "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
             "dev": true,
             "requires": {
-                "caniuse-lite": "^1.0.30001181",
-                "colorette": "^1.2.1",
-                "electron-to-chromium": "^1.3.649",
+                "caniuse-lite": "^1.0.30001219",
+                "colorette": "^1.2.2",
+                "electron-to-chromium": "^1.3.723",
                 "escalade": "^3.1.1",
-                "node-releases": "^1.1.70"
+                "node-releases": "^1.1.71"
             }
         },
         "buffer-from": {
@@ -8841,9 +9083,9 @@
             "dev": true
         },
         "caniuse-lite": {
-            "version": "1.0.30001185",
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz",
-            "integrity": "sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg==",
+            "version": "1.0.30001222",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001222.tgz",
+            "integrity": "sha512-rPmwUK0YMjfMlZVmH6nVB5U3YJ5Wnx3vmT5lnRO3nIKO8bJ+TRWMbGuuiSugDJqESy/lz+1hSrlQEagCtoOAWQ==",
             "dev": true
         },
         "chalk": {
@@ -9078,9 +9320,9 @@
             }
         },
         "colorette": {
-            "version": "1.2.1",
-            "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz",
-            "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==",
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
+            "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
             "dev": true
         },
         "colors": {
@@ -9236,12 +9478,12 @@
             "dev": true
         },
         "core-js-compat": {
-            "version": "3.8.3",
-            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz",
-            "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==",
+            "version": "3.11.3",
+            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.11.3.tgz",
+            "integrity": "sha512-oNjHN/qUHOA0dPv+v5prqHfeSvIEJrk3hYVoaUK4MNzL9U433uu0MN+pImcdntV8o9pDq0r1v+9lTfKPjjbX/A==",
             "dev": true,
             "requires": {
-                "browserslist": "^4.16.1",
+                "browserslist": "^4.16.6",
                 "semver": "7.0.0"
             },
             "dependencies": {
@@ -9422,10 +9664,18 @@
             "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
             "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
         },
+        "ejs": {
+            "version": "3.1.6",
+            "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
+            "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
+            "requires": {
+                "jake": "^10.6.1"
+            }
+        },
         "electron-to-chromium": {
-            "version": "1.3.661",
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.661.tgz",
-            "integrity": "sha512-INNzKoL9ceOpPCpF5J+Fp9AOHY1RegwKViohAyTzV3XbkuRUx04r4v8edsDbevsog8UuL0GvD/Qerr2HwVTlSA==",
+            "version": "1.3.727",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz",
+            "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==",
             "dev": true
         },
         "emoji-regex": {
@@ -9795,6 +10045,14 @@
                 "moment": "^2.11.2"
             }
         },
+        "filelist": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
+            "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
+            "requires": {
+                "minimatch": "^3.0.4"
+            }
+        },
         "fill-range": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
@@ -10500,6 +10758,24 @@
             "dev": true,
             "optional": true
         },
+        "jake": {
+            "version": "10.8.2",
+            "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
+            "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
+            "requires": {
+                "async": "0.9.x",
+                "chalk": "^2.4.2",
+                "filelist": "^1.0.1",
+                "minimatch": "^3.0.4"
+            },
+            "dependencies": {
+                "async": {
+                    "version": "0.9.2",
+                    "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+                    "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
+                }
+            }
+        },
         "js-tokens": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -10598,6 +10874,12 @@
             "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
             "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
         },
+        "lodash.debounce": {
+            "version": "4.0.8",
+            "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+            "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
+            "dev": true
+        },
         "log-symbols": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
@@ -11134,9 +11416,9 @@
             "dev": true
         },
         "node-releases": {
-            "version": "1.1.70",
-            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz",
-            "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==",
+            "version": "1.1.71",
+            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz",
+            "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==",
             "dev": true
         },
         "node-uuid": {
diff --git a/backend/package.json b/backend/package.json
index 3bc429d..7ad4147 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -1,47 +1,52 @@
 {
-  "name": "ag-viewer-backend",
-  "version": "0.4.0",
-  "private": true,
-  "scripts": {
-    "test": "mocha -r @babel/register --exit --timeout 100000",
-    "test:connector": "mocha -r @babel/register --exit --timeout 10000 ./test/connector.api.test.js",
-    "test:metachart": "mocha -r @babel/register --exit --timeout 10000 ./test/meta.api.test.js",
-    "test:cypher": "mocha -r @babel/register --exit --timeout 10000 ./test/cypher.api.test.js",
-    "test:session": "mocha -r @babel/register --exit --timeout 10000 ./test/session.api.test.js",
-    "test:query": "mocha -r @babel/register --exit --timeout 10000 ./test/cypher.service.test.js",
-    "start": "babel-node src/bin/www",
-    "start:dev": "nodemon --watch src/app.js --watch src/ --exec 'babel-node' src/bin/www",
-    "build": "babel -d ./build ./src -s",
-    "start:production": "node ./build/bin/www.js"
-  },
-  "dependencies": {
-    "@bitnine-oss/ag-driver": "^0.1.0",
-    "cookie-parser": "~1.4.5",
-    "cors": "^2.8.5",
-    "debug": "~4.3.1",
-    "ejs": "^3.1.6",
-    "express": "~4.17.1",
-    "express-session": "^1.17.1",
-    "http-status": "^1.5.0",
-    "morgan": "~1.10.0",
-    "node-uuid": "^1.4.8",
-    "npm-run-all": "^4.1.5",
-    "pegjs": "^0.10.0",
-    "pg": "^8.5.1",
-    "pg-types": "^2.2.0",
-    "winston": "^3.3.3",
-    "winston-daily-rotate-file": "^4.5.0"
-  },
-  "devDependencies": {
-    "@babel/cli": "^7.12.13",
-    "@babel/core": "^7.12.13",
-    "@babel/node": "^7.12.13",
-    "@babel/plugin-transform-runtime": "^7.12.15",
-    "@babel/preset-env": "^7.12.13",
-    "@babel/register": "^7.12.13",
-    "mocha": "^8.2.1",
-    "nodemon": "^2.0.7",
-    "supertest": "^6.0.1",
-    "supertest-session": "^4.1.0"
-  }
+    "name": "ag-viewer-backend",
+    "version": "0.4.0",
+    "private": true,
+    "scripts": {
+        "test": "mocha -r @babel/register --exit --timeout 100000",
+        "test:connector": "mocha -r @babel/register --exit --timeout 10000 ./test/connector.api.test.js",
+        "test:metachart": "mocha -r @babel/register --exit --timeout 10000 ./test/meta.api.test.js",
+        "test:cypher": "mocha -r @babel/register --exit --timeout 10000 ./test/cypher.api.test.js",
+        "test:session": "mocha -r @babel/register --exit --timeout 10000 ./test/session.api.test.js",
+        "test:query": "mocha -r @babel/register --exit --timeout 10000 ./test/cypher.service.test.js",
+        "start": "babel-node src/bin/www",
+        "start:dev": "nodemon --watch src/app.js --watch src/ --exec 'babel-node' src/bin/www",
+        "build": "babel -d ./build ./src -s",
+        "start:production": "node ./build/bin/www.js"
+    },
+    "dependencies": {
+        "@bitnine-oss/ag-driver": "^0.1.0",
+        "antlr4": "^4.9.2",
+        "cookie-parser": "~1.4.5",
+        "cors": "^2.8.5",
+        "debug": "~4.3.1",
+        "ejs": "^3.1.6",
+        "express": "~4.17.1",
+        "express-session": "^1.17.1",
+        "http-status": "^1.5.0",
+        "morgan": "~1.10.0",
+        "node-uuid": "^1.4.8",
+        "npm-run-all": "^4.1.5",
+        "pegjs": "^0.10.0",
+        "pg": "^8.5.1",
+        "pg-types": "^2.2.0",
+        "winston": "^3.3.3",
+        "winston-daily-rotate-file": "^4.5.0"
+    },
+    "devDependencies": {
+        "@babel/cli": "^7.12.13",
+        "@babel/core": "^7.12.13",
+        "@babel/node": "^7.12.13",
+        "@babel/plugin-proposal-class-properties": "^7.13.0",
+        "@babel/plugin-transform-runtime": "^7.12.15",
+        "@babel/preset-env": "^7.12.13",
+        "@babel/register": "^7.12.13",
+        "babel-plugin-polyfill-corejs2": "^0.2.0",
+        "babel-plugin-polyfill-corejs3": "^0.2.0",
+        "babel-plugin-polyfill-regenerator": "^0.2.0",
+        "mocha": "^8.2.1",
+        "nodemon": "^2.0.7",
+        "supertest": "^6.0.1",
+        "supertest-session": "^4.1.0"
+    }
 }
diff --git a/backend/sql/meta_edges/AGE.sql b/backend/sql/meta_edges/AGE.sql
index 30c22a9..5db9aba 100644
--- a/backend/sql/meta_edges/AGE.sql
+++ b/backend/sql/meta_edges/AGE.sql
@@ -1,6 +1,11 @@
-SELECT name as label, 0 as cnt
-FROM ag_catalog.ag_label
-WHERE graph = (SELECT oid FROM ag_catalog.ag_graph where name = '%s')
-  AND kind = 'e';
+SELECT label, count(label) as cnt
+FROM (
+         SELECT ag_catalog._label_name(oid, v)::text as label
+         from cypher('%s', $$
+             MATCH ()-[V]-()
+             RETURN id(V)
+             $$) as (V agtype), (SELECT oid FROM ag_catalog.ag_graph where name = '%s') as oid
+     ) b
+GROUP BY b.label;
 
 -- TODO: COUNT needs AGE supporting or Client-side processing.
diff --git a/backend/sql/meta_edges/AGENS.sql b/backend/sql/meta_edges/AGENS.sql
index 7afe289..36a39b2 100644
--- a/backend/sql/meta_edges/AGENS.sql
+++ b/backend/sql/meta_edges/AGENS.sql
@@ -3,4 +3,4 @@
 MATCH (v)-[e]-(v2) RETURN DISTINCT label(e) AS label, count(e) AS cnt
 ORDER BY label
 
--- %s
+-- %s %s
diff --git a/backend/sql/meta_nodes/AGE.sql b/backend/sql/meta_nodes/AGE.sql
index 471debd..8a173b5 100644
--- a/backend/sql/meta_nodes/AGE.sql
+++ b/backend/sql/meta_nodes/AGE.sql
@@ -1,6 +1,11 @@
-SELECT name as label, 0 as cnt
-FROM ag_catalog.ag_label
-WHERE graph = (SELECT oid FROM ag_catalog.ag_graph where name = '%s')
-  AND kind = 'v';
+SELECT label, count(label) as cnt
+FROM (
+         SELECT ag_catalog._label_name(oid, v)::text as label
+         from cypher('%s', $$
+             MATCH (V:_ag_label_vertex)
+             RETURN id(V)
+             $$) as (V agtype), (SELECT oid FROM ag_catalog.ag_graph where name = '%s') as oid
+     ) b
+GROUP BY b.label;
 
 -- TODO: COUNT needs AGE supporting or Client-side processing.
diff --git a/backend/sql/meta_nodes/AGENS.sql b/backend/sql/meta_nodes/AGENS.sql
index a953d93..25f54d5 100644
--- a/backend/sql/meta_nodes/AGENS.sql
+++ b/backend/sql/meta_nodes/AGENS.sql
@@ -2,4 +2,4 @@
 UNION ALL
 MATCH (v) RETURN DISTINCT label(v) AS label, count(v) AS cnt
 ORDER BY label
--- %s
+-- %s %s
diff --git a/backend/src/services/databaseService.js b/backend/src/services/databaseService.js
index 9f75e19..77fdf71 100644
--- a/backend/src/services/databaseService.js
+++ b/backend/src/services/databaseService.js
@@ -69,13 +69,13 @@
 
     async getNodes() {
         let agensDatabaseHelper = this._agensDatabaseHelper;
-        let queryResult = await agensDatabaseHelper.execute(util.format(getQuery(agensDatabaseHelper.flavor, 'meta_nodes'), agensDatabaseHelper._graph));
+        let queryResult = await agensDatabaseHelper.execute(util.format(getQuery(agensDatabaseHelper.flavor, 'meta_nodes'), agensDatabaseHelper._graph, agensDatabaseHelper._graph));
         return queryResult.rows;
     }
 
     async getEdges() {
         let agensDatabaseHelper = this._agensDatabaseHelper;
-        let queryResult = await agensDatabaseHelper.execute(util.format(getQuery(agensDatabaseHelper.flavor, 'meta_edges'), agensDatabaseHelper._graph));
+        let queryResult = await agensDatabaseHelper.execute(util.format(getQuery(agensDatabaseHelper.flavor, 'meta_edges'), agensDatabaseHelper._graph, agensDatabaseHelper._graph));
         return queryResult.rows;
     }
 
diff --git a/backend/src/tools/AGEParser.js b/backend/src/tools/AGEParser.js
index 5865e7d..bc4ba59 100644
--- a/backend/src/tools/AGEParser.js
+++ b/backend/src/tools/AGEParser.js
@@ -1,15 +1,18 @@
-function AGTypeParse(input) {
-    // todo: need to work with antlr4
+import antlr4 from 'antlr4';
+import AgtypeLexer from './AgtypeLexer';
+import AgtypeParser from './AgtypeParser';
+import CustomAgTypeListener from './CustomAgTypeListener';
 
-    const inputLength = input.length;
-    let splitJson;
-    if (input.endsWith("::edge")) {
-        splitJson = input.substring(0, inputLength - 6)
-    } else {
-        // ::vertex
-        splitJson = input.substring(0, inputLength - 8);
-    }
-    return JSON.parse(splitJson);
+function AGTypeParse(input) {
+    const chars = new antlr4.InputStream(input);
+    const lexer = new AgtypeLexer(chars);
+    const tokens = new antlr4.CommonTokenStream(lexer);
+    const parser = new AgtypeParser(tokens);
+    parser.buildParseTrees = true;
+    const tree = parser.agType();
+    const printer = new CustomAgTypeListener();
+    antlr4.tree.ParseTreeWalker.DEFAULT.walk(printer, tree);
+    return printer.getResult();
 }
 
 async function setAGETypes(client, types) {
diff --git a/backend/src/tools/Agtype.g4 b/backend/src/tools/Agtype.g4
new file mode 100644
index 0000000..7ad184e
--- /dev/null
+++ b/backend/src/tools/Agtype.g4
@@ -0,0 +1,97 @@
+grammar Agtype;
+
+agType
+  : agValue EOF
+  ;
+
+agValue
+  : value typeAnnotation?
+  ;
+
+value
+  : STRING #StringValue
+  | INTEGER #IntegerValue
+  | floatLiteral #FloatValue
+  | 'true' #TrueBoolean
+  | 'false' #FalseBoolean
+  | 'null' #NullValue
+  | obj #ObjectValue
+  | array #ArrayValue
+  ;
+
+obj
+  : '{' pair (',' pair)* '}'
+  | '{' '}'
+  ;
+
+pair
+  : STRING ':' agValue
+  ;
+
+array
+  : '[' agValue (',' agValue)* ']'
+  | '[' ']'
+  ;
+
+typeAnnotation
+  : '::' IDENT
+  ;
+
+IDENT
+  : [A-Z_a-z][$0-9A-Z_a-z]*
+  ;
+
+STRING
+  : '"' (ESC | SAFECODEPOINT)* '"'
+  ;
+
+fragment ESC
+  : '\\' (["\\/bfnrt] | UNICODE)
+  ;
+
+fragment UNICODE
+  : 'u' HEX HEX HEX HEX
+  ;
+
+fragment HEX
+  : [0-9a-fA-F]
+  ;
+
+fragment SAFECODEPOINT
+  : ~ ["\\\u0000-\u001F]
+  ;
+
+INTEGER
+  : '-'? INT
+  ;
+
+fragment INT
+  : '0' | [1-9] [0-9]*
+  ;
+
+floatLiteral
+  : RegularFloat
+  | ExponentFloat
+  | '-'? 'Infinity'
+  | 'NaN'
+  ;
+
+RegularFloat
+  : '-'? INT DECIMAL
+  ;
+
+ExponentFloat
+  : '-'? INT DECIMAL? SCIENTIFIC
+  ;
+
+fragment DECIMAL
+  : '.' [0-9]+
+  ;
+
+fragment SCIENTIFIC
+  : [Ee][+-]? [0-9]+
+  ;
+
+WS
+  : [ \t\n\r] + -> skip
+  ;
diff --git a/backend/src/tools/Agtype.interp b/backend/src/tools/Agtype.interp
new file mode 100644
index 0000000..c012d8f
--- /dev/null
+++ b/backend/src/tools/Agtype.interp
@@ -0,0 +1,57 @@
+token literal names:
+null
+'true'
+'false'
+'null'
+'{'
+','
+'}'
+':'
+'['
+']'
+'::'
+'-'
+'Infinity'
+'NaN'
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+IDENT
+STRING
+INTEGER
+RegularFloat
+ExponentFloat
+WS
+
+rule names:
+agType
+agValue
+value
+obj
+pair
+array
+typeAnnotation
+floatLiteral
+
+
+atn:
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 21, 82, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 5, 3, 24, 10, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 34, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 7, 5, 40, 10, 5, 12, 5, 14, 5, 43, 11, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 49, 10, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 7, 7, 59, 10, 7, 12, 7, 14, 7, 62, 11, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 68, 10, 7, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 5, 9, 76, 10, 9, 3, 9, 3, 9, 5, 9, 80, 10, 9, 3, 9, 2, 2, 10, 2, 4, 6, 8, 10, 12, 14, 16, 2, 2, 2, 89, 2, 18, 3, 2, 2, 2, 4, 21, 3, 2, 2, 2, 6, 33, 3, 2, 2, 2, 8, 48, 3, 2, 2, 2, 10, 50, 3, 2, 2, 2, 12, 67, 3, 2, 2, 2, 14, 69, 3, 2, 2, 2, 16, 79, 3, 2, 2, 2, 18, 19, 5, 4, 3, 2, 19, 20, 7, 2, 2, 3, 20, 3, 3, 2, 2, 2, 21, 23, 5, 6, 4, 2, 22, 24, 5, 14, 8, 2, 23, 22, 3, 2, 2, 2, 23, 24, 3, 2, 2, 2, 24, 5, 3, 2, 2, 2, 25, 34, 7, 17, 2, 2, 26, 34, 7, 18, 2, 2, 27, 34, 5, 16, 9, 2, 28, 34, 7, 3, 2, 2, 29, 34, 7, 4, 2, 2, 30, 34, 7, 5, 2, 2, 31, 34, 5, 8, 5, 2, 32, 34, 5, 12, 7, 2, 33, 25, 3, 2, 2, 2, 33, 26, 3, 2, 2, 2, 33, 27, 3, 2, 2, 2, 33, 28, 3, 2, 2, 2, 33, 29, 3, 2, 2, 2, 33, 30, 3, 2, 2, 2, 33, 31, 3, 2, 2, 2, 33, 32, 3, 2, 2, 2, 34, 7, 3, 2, 2, 2, 35, 36, 7, 6, 2, 2, 36, 41, 5, 10, 6, 2, 37, 38, 7, 7, 2, 2, 38, 40, 5, 10, 6, 2, 39, 37, 3, 2, 2, 2, 40, 43, 3, 2, 2, 2, 41, 39, 3, 2, 2, 2, 41, 42, 3, 2, 2, 2, 42, 44, 3, 2, 2, 2, 43, 41, 3, 2, 2, 2, 44, 45, 7, 8, 2, 2, 45, 49, 3, 2, 2, 2, 46, 47, 7, 6, 2, 2, 47, 49, 7, 8, 2, 2, 48, 35, 3, 2, 2, 2, 48, 46, 3, 2, 2, 2, 49, 9, 3, 2, 2, 2, 50, 51, 7, 17, 2, 2, 51, 52, 7, 9, 2, 2, 52, 53, 5, 4, 3, 2, 53, 11, 3, 2, 2, 2, 54, 55, 7, 10, 2, 2, 55, 60, 5, 4, 3, 2, 56, 57, 7, 7, 2, 2, 57, 59, 5, 4, 3, 2, 58, 56, 3, 2, 2, 2, 59, 62, 3, 2, 2, 2, 60, 58, 3, 2, 2, 2, 60, 61, 3, 2, 2, 2, 61, 63, 3, 2, 2, 2, 62, 60, 3, 2, 2, 2, 63, 64, 7, 11, 2, 2, 64, 68, 3, 2, 2, 2, 65, 66, 7, 10, 2, 2, 66, 68, 7, 11, 2, 2, 67, 54, 3, 2, 2, 2, 67, 65, 3, 2, 2, 2, 68, 13, 3, 2, 2, 2, 69, 70, 7, 12, 2, 2, 70, 71, 7, 16, 2, 2, 71, 15, 3, 2, 2, 2, 72, 80, 7, 19, 2, 2, 73, 80, 7, 20, 2, 2, 74, 76, 7, 13, 2, 2, 75, 74, 3, 2, 2, 2, 75, 76, 3, 2, 2, 2, 76, 77, 3, 2, 2, 2, 77, 80, 7, 14, 2, 2, 78, 80, 7, 15, 2, 2, 79, 72, 3, 2, 2, 2, 79, 73, 3, 2, 2, 2, 79, 75, 3, 2, 2, 2, 79, 78, 3, 2, 2, 2, 80, 17, 3, 2, 2, 2, 10, 23, 33, 41, 48, 60, 67, 75, 79]
\ No newline at end of file
diff --git a/backend/src/tools/Agtype.tokens b/backend/src/tools/Agtype.tokens
new file mode 100644
index 0000000..193f8c9
--- /dev/null
+++ b/backend/src/tools/Agtype.tokens
@@ -0,0 +1,32 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+T__7=8
+T__8=9
+T__9=10
+T__10=11
+T__11=12
+T__12=13
+IDENT=14
+STRING=15
+INTEGER=16
+RegularFloat=17
+ExponentFloat=18
+WS=19
+'true'=1
+'false'=2
+'null'=3
+'{'=4
+','=5
+'}'=6
+':'=7
+'['=8
+']'=9
+'::'=10
+'-'=11
+'Infinity'=12
+'NaN'=13
diff --git a/backend/src/tools/AgtypeLexer.interp b/backend/src/tools/AgtypeLexer.interp
new file mode 100644
index 0000000..19422db
--- /dev/null
+++ b/backend/src/tools/AgtypeLexer.interp
@@ -0,0 +1,81 @@
+token literal names:
+null
+'true'
+'false'
+'null'
+'{'
+','
+'}'
+':'
+'['
+']'
+'::'
+'-'
+'Infinity'
+'NaN'
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+IDENT
+STRING
+INTEGER
+RegularFloat
+ExponentFloat
+WS
+
+rule names:
+T__0
+T__1
+T__2
+T__3
+T__4
+T__5
+T__6
+T__7
+T__8
+T__9
+T__10
+T__11
+T__12
+IDENT
+STRING
+ESC
+UNICODE
+HEX
+SAFECODEPOINT
+INTEGER
+INT
+RegularFloat
+ExponentFloat
+DECIMAL
+SCIENTIFIC
+WS
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 21, 185, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 7, 15, 104, 10, 15, 12, 15, 14, 15, 107, 11, 15, 3, 16, 3, 16, 3, 16, 7, 16, 112, 10, 16, 12, 16, 14, 16, 115, 11, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 5, 17, 122, 10, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 5, 21, 135, 10, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 7, 22, 142, 10, 22, 12, 22, 14, 22, 145, 11, 22, 5, 22, 147, 10, 22, 3, 23, 5, 23, 150, 10, 23, 3, 23, 3, 23, 3, 23, 3, 24, 5, 24, 156, 10, 24, 3, 24, 3, 24, 5, 24, 160, 10, 24, 3, 24, 3, 24, 3, 25, 3, 25, 6, 25, 166, 10, 25, 13, 25, 14, 25, 167, 3, 26, 3, 26, 5, 26, 172, 10, 26, 3, 26, 6, 26, 175, 10, 26, 13, 26, 14, 26, 176, 3, 27, 6, 27, 180, 10, 27, 13, 27, 14, 27, 181, 3, 27, 3, 27, 2, 2, 28, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 2, 35, 2, 37, 2, 39, 2, 41, 18, 43, 2, 45, 19, 47, 20, 49, 2, 51, 2, 53, 21, 3, 2, 12, 5, 2, 67, 92, 97, 97, 99, 124, 7, 2, 38, 38, 50, 59, 67, 92, 97, 97, 99, 124, 10, 2, 36, 36, 49, 49, 94, 94, 100, 100, 104, 104, 112, 112, 116, 116, 118, 118, 5, 2, 50, 59, 67, 72, 99, 104, 5, 2, 2, 33, 36, 36, 94, 94, 3, 2, 51, 59, 3, 2, 50, 59, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 5, 2, 11, 12, 15, 15, 34, 34, 2, 191, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 3, 55, 3, 2, 2, 2, 5, 60, 3, 2, 2, 2, 7, 66, 3, 2, 2, 2, 9, 71, 3, 2, 2, 2, 11, 73, 3, 2, 2, 2, 13, 75, 3, 2, 2, 2, 15, 77, 3, 2, 2, 2, 17, 79, 3, 2, 2, 2, 19, 81, 3, 2, 2, 2, 21, 83, 3, 2, 2, 2, 23, 86, 3, 2, 2, 2, 25, 88, 3, 2, 2, 2, 27, 97, 3, 2, 2, 2, 29, 101, 3, 2, 2, 2, 31, 108, 3, 2, 2, 2, 33, 118, 3, 2, 2, 2, 35, 123, 3, 2, 2, 2, 37, 129, 3, 2, 2, 2, 39, 131, 3, 2, 2, 2, 41, 134, 3, 2, 2, 2, 43, 146, 3, 2, 2, 2, 45, 149, 3, 2, 2, 2, 47, 155, 3, 2, 2, 2, 49, 163, 3, 2, 2, 2, 51, 169, 3, 2, 2, 2, 53, 179, 3, 2, 2, 2, 55, 56, 7, 118, 2, 2, 56, 57, 7, 116, 2, 2, 57, 58, 7, 119, 2, 2, 58, 59, 7, 103, 2, 2, 59, 4, 3, 2, 2, 2, 60, 61, 7, 104, 2, 2, 61, 62, 7, 99, 2, 2, 62, 63, 7, 110, 2, 2, 63, 64, 7, 117, 2, 2, 64, 65, 7, 103, 2, 2, 65, 6, 3, 2, 2, 2, 66, 67, 7, 112, 2, 2, 67, 68, 7, 119, 2, 2, 68, 69, 7, 110, 2, 2, 69, 70, 7, 110, 2, 2, 70, 8, 3, 2, 2, 2, 71, 72, 7, 125, 2, 2, 72, 10, 3, 2, 2, 2, 73, 74, 7, 46, 2, 2, 74, 12, 3, 2, 2, 2, 75, 76, 7, 127, 2, 2, 76, 14, 3, 2, 2, 2, 77, 78, 7, 60, 2, 2, 78, 16, 3, 2, 2, 2, 79, 80, 7, 93, 2, 2, 80, 18, 3, 2, 2, 2, 81, 82, 7, 95, 2, 2, 82, 20, 3, 2, 2, 2, 83, 84, 7, 60, 2, 2, 84, 85, 7, 60, 2, 2, 85, 22, 3, 2, 2, 2, 86, 87, 7, 47, 2, 2, 87, 24, 3, 2, 2, 2, 88, 89, 7, 75, 2, 2, 89, 90, 7, 112, 2, 2, 90, 91, 7, 104, 2, 2, 91, 92, 7, 107, 2, 2, 92, 93, 7, 112, 2, 2, 93, 94, 7, 107, 2, 2, 94, 95, 7, 118, 2, 2, 95, 96, 7, 123, 2, 2, 96, 26, 3, 2, 2, 2, 97, 98, 7, 80, 2, 2, 98, 99, 7, 99, 2, 2, 99, 100, 7, 80, 2, 2, 100, 28, 3, 2, 2, 2, 101, 105, 9, 2, 2, 2, 102, 104, 9, 3, 2, 2, 103, 102, 3, 2, 2, 2, 104, 107, 3, 2, 2, 2, 105, 103, 3, 2, 2, 2, 105, 106, 3, 2, 2, 2, 106, 30, 3, 2, 2, 2, 107, 105, 3, 2, 2, 2, 108, 113, 7, 36, 2, 2, 109, 112, 5, 33, 17, 2, 110, 112, 5, 39, 20, 2, 111, 109, 3, 2, 2, 2, 111, 110, 3, 2, 2, 2, 112, 115, 3, 2, 2, 2, 113, 111, 3, 2, 2, 2, 113, 114, 3, 2, 2, 2, 114, 116, 3, 2, 2, 2, 115, 113, 3, 2, 2, 2, 116, 117, 7, 36, 2, 2, 117, 32, 3, 2, 2, 2, 118, 121, 7, 94, 2, 2, 119, 122, 9, 4, 2, 2, 120, 122, 5, 35, 18, 2, 121, 119, 3, 2, 2, 2, 121, 120, 3, 2, 2, 2, 122, 34, 3, 2, 2, 2, 123, 124, 7, 119, 2, 2, 124, 125, 5, 37, 19, 2, 125, 126, 5, 37, 19, 2, 126, 127, 5, 37, 19, 2, 127, 128, 5, 37, 19, 2, 128, 36, 3, 2, 2, 2, 129, 130, 9, 5, 2, 2, 130, 38, 3, 2, 2, 2, 131, 132, 10, 6, 2, 2, 132, 40, 3, 2, 2, 2, 133, 135, 7, 47, 2, 2, 134, 133, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, 135, 136, 3, 2, 2, 2, 136, 137, 5, 43, 22, 2, 137, 42, 3, 2, 2, 2, 138, 147, 7, 50, 2, 2, 139, 143, 9, 7, 2, 2, 140, 142, 9, 8, 2, 2, 141, 140, 3, 2, 2, 2, 142, 145, 3, 2, 2, 2, 143, 141, 3, 2, 2, 2, 143, 144, 3, 2, 2, 2, 144, 147, 3, 2, 2, 2, 145, 143, 3, 2, 2, 2, 146, 138, 3, 2, 2, 2, 146, 139, 3, 2, 2, 2, 147, 44, 3, 2, 2, 2, 148, 150, 7, 47, 2, 2, 149, 148, 3, 2, 2, 2, 149, 150, 3, 2, 2, 2, 150, 151, 3, 2, 2, 2, 151, 152, 5, 43, 22, 2, 152, 153, 5, 49, 25, 2, 153, 46, 3, 2, 2, 2, 154, 156, 7, 47, 2, 2, 155, 154, 3, 2, 2, 2, 155, 156, 3, 2, 2, 2, 156, 157, 3, 2, 2, 2, 157, 159, 5, 43, 22, 2, 158, 160, 5, 49, 25, 2, 159, 158, 3, 2, 2, 2, 159, 160, 3, 2, 2, 2, 160, 161, 3, 2, 2, 2, 161, 162, 5, 51, 26, 2, 162, 48, 3, 2, 2, 2, 163, 165, 7, 48, 2, 2, 164, 166, 9, 8, 2, 2, 165, 164, 3, 2, 2, 2, 166, 167, 3, 2, 2, 2, 167, 165, 3, 2, 2, 2, 167, 168, 3, 2, 2, 2, 168, 50, 3, 2, 2, 2, 169, 171, 9, 9, 2, 2, 170, 172, 9, 10, 2, 2, 171, 170, 3, 2, 2, 2, 171, 172, 3, 2, 2, 2, 172, 174, 3, 2, 2, 2, 173, 175, 9, 8, 2, 2, 174, 173, 3, 2, 2, 2, 175, 176, 3, 2, 2, 2, 176, 174, 3, 2, 2, 2, 176, 177, 3, 2, 2, 2, 177, 52, 3, 2, 2, 2, 178, 180, 9, 11, 2, 2, 179, 178, 3, 2, 2, 2, 180, 181, 3, 2, 2, 2, 181, 179, 3, 2, 2, 2, 181, 182, 3, 2, 2, 2, 182, 183, 3, 2, 2, 2, 183, 184, 8, 27, 2, 2, 184, 54, 3, 2, 2, 2, 17, 2, 105, 111, 113, 121, 134, 143, 146, 149, 155, 159, 167, 171, 176, 181, 3, 8, 2, 2]
\ No newline at end of file
diff --git a/backend/src/tools/AgtypeLexer.js b/backend/src/tools/AgtypeLexer.js
new file mode 100644
index 0000000..42f8c8a
--- /dev/null
+++ b/backend/src/tools/AgtypeLexer.js
@@ -0,0 +1,179 @@
+// Generated from src/tools/Agtype.g4 by ANTLR 4.9.2
+// jshint ignore: start
+import antlr4 from 'antlr4';
+
+
+const serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786",
+    "\u5964\u0002\u0015\u00b9\b\u0001\u0004\u0002\t\u0002\u0004\u0003\t\u0003",
+    "\u0004\u0004\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007",
+    "\t\u0007\u0004\b\t\b\u0004\t\t\t\u0004\n\t\n\u0004\u000b\t\u000b\u0004",
+    "\f\t\f\u0004\r\t\r\u0004\u000e\t\u000e\u0004\u000f\t\u000f\u0004\u0010",
+    "\t\u0010\u0004\u0011\t\u0011\u0004\u0012\t\u0012\u0004\u0013\t\u0013",
+    "\u0004\u0014\t\u0014\u0004\u0015\t\u0015\u0004\u0016\t\u0016\u0004\u0017",
+    "\t\u0017\u0004\u0018\t\u0018\u0004\u0019\t\u0019\u0004\u001a\t\u001a",
+    "\u0004\u001b\t\u001b\u0003\u0002\u0003\u0002\u0003\u0002\u0003\u0002",
+    "\u0003\u0002\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003",
+    "\u0003\u0003\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004",
+    "\u0003\u0005\u0003\u0005\u0003\u0006\u0003\u0006\u0003\u0007\u0003\u0007",
+    "\u0003\b\u0003\b\u0003\t\u0003\t\u0003\n\u0003\n\u0003\u000b\u0003\u000b",
+    "\u0003\u000b\u0003\f\u0003\f\u0003\r\u0003\r\u0003\r\u0003\r\u0003\r",
+    "\u0003\r\u0003\r\u0003\r\u0003\r\u0003\u000e\u0003\u000e\u0003\u000e",
+    "\u0003\u000e\u0003\u000f\u0003\u000f\u0007\u000fh\n\u000f\f\u000f\u000e",
+    "\u000fk\u000b\u000f\u0003\u0010\u0003\u0010\u0003\u0010\u0007\u0010",
+    "p\n\u0010\f\u0010\u000e\u0010s\u000b\u0010\u0003\u0010\u0003\u0010\u0003",
+    "\u0011\u0003\u0011\u0003\u0011\u0005\u0011z\n\u0011\u0003\u0012\u0003",
+    "\u0012\u0003\u0012\u0003\u0012\u0003\u0012\u0003\u0012\u0003\u0013\u0003",
+    "\u0013\u0003\u0014\u0003\u0014\u0003\u0015\u0005\u0015\u0087\n\u0015",
+    "\u0003\u0015\u0003\u0015\u0003\u0016\u0003\u0016\u0003\u0016\u0007\u0016",
+    "\u008e\n\u0016\f\u0016\u000e\u0016\u0091\u000b\u0016\u0005\u0016\u0093",
+    "\n\u0016\u0003\u0017\u0005\u0017\u0096\n\u0017\u0003\u0017\u0003\u0017",
+    "\u0003\u0017\u0003\u0018\u0005\u0018\u009c\n\u0018\u0003\u0018\u0003",
+    "\u0018\u0005\u0018\u00a0\n\u0018\u0003\u0018\u0003\u0018\u0003\u0019",
+    "\u0003\u0019\u0006\u0019\u00a6\n\u0019\r\u0019\u000e\u0019\u00a7\u0003",
+    "\u001a\u0003\u001a\u0005\u001a\u00ac\n\u001a\u0003\u001a\u0006\u001a",
+    "\u00af\n\u001a\r\u001a\u000e\u001a\u00b0\u0003\u001b\u0006\u001b\u00b4",
+    "\n\u001b\r\u001b\u000e\u001b\u00b5\u0003\u001b\u0003\u001b\u0002\u0002",
+    "\u001c\u0003\u0003\u0005\u0004\u0007\u0005\t\u0006\u000b\u0007\r\b\u000f",
+    "\t\u0011\n\u0013\u000b\u0015\f\u0017\r\u0019\u000e\u001b\u000f\u001d",
+    "\u0010\u001f\u0011!\u0002#\u0002%\u0002\'\u0002)\u0012+\u0002-\u0013",
+    "/\u00141\u00023\u00025\u0015\u0003\u0002\f\u0005\u0002C\\aac|\u0007",
+    "\u0002&&2;C\\aac|\n\u0002$$11^^ddhhppttvv\u0005\u00022;CHch\u0005\u0002",
+    "\u0002!$$^^\u0003\u00023;\u0003\u00022;\u0004\u0002GGgg\u0004\u0002",
+    "--//\u0005\u0002\u000b\f\u000f\u000f\"\"\u0002\u00bf\u0002\u0003\u0003",
+    "\u0002\u0002\u0002\u0002\u0005\u0003\u0002\u0002\u0002\u0002\u0007\u0003",
+    "\u0002\u0002\u0002\u0002\t\u0003\u0002\u0002\u0002\u0002\u000b\u0003",
+    "\u0002\u0002\u0002\u0002\r\u0003\u0002\u0002\u0002\u0002\u000f\u0003",
+    "\u0002\u0002\u0002\u0002\u0011\u0003\u0002\u0002\u0002\u0002\u0013\u0003",
+    "\u0002\u0002\u0002\u0002\u0015\u0003\u0002\u0002\u0002\u0002\u0017\u0003",
+    "\u0002\u0002\u0002\u0002\u0019\u0003\u0002\u0002\u0002\u0002\u001b\u0003",
+    "\u0002\u0002\u0002\u0002\u001d\u0003\u0002\u0002\u0002\u0002\u001f\u0003",
+    "\u0002\u0002\u0002\u0002)\u0003\u0002\u0002\u0002\u0002-\u0003\u0002",
+    "\u0002\u0002\u0002/\u0003\u0002\u0002\u0002\u00025\u0003\u0002\u0002",
+    "\u0002\u00037\u0003\u0002\u0002\u0002\u0005<\u0003\u0002\u0002\u0002",
+    "\u0007B\u0003\u0002\u0002\u0002\tG\u0003\u0002\u0002\u0002\u000bI\u0003",
+    "\u0002\u0002\u0002\rK\u0003\u0002\u0002\u0002\u000fM\u0003\u0002\u0002",
+    "\u0002\u0011O\u0003\u0002\u0002\u0002\u0013Q\u0003\u0002\u0002\u0002",
+    "\u0015S\u0003\u0002\u0002\u0002\u0017V\u0003\u0002\u0002\u0002\u0019",
+    "X\u0003\u0002\u0002\u0002\u001ba\u0003\u0002\u0002\u0002\u001de\u0003",
+    "\u0002\u0002\u0002\u001fl\u0003\u0002\u0002\u0002!v\u0003\u0002\u0002",
+    "\u0002#{\u0003\u0002\u0002\u0002%\u0081\u0003\u0002\u0002\u0002\'\u0083",
+    "\u0003\u0002\u0002\u0002)\u0086\u0003\u0002\u0002\u0002+\u0092\u0003",
+    "\u0002\u0002\u0002-\u0095\u0003\u0002\u0002\u0002/\u009b\u0003\u0002",
+    "\u0002\u00021\u00a3\u0003\u0002\u0002\u00023\u00a9\u0003\u0002\u0002",
+    "\u00025\u00b3\u0003\u0002\u0002\u000278\u0007v\u0002\u000289\u0007t",
+    "\u0002\u00029:\u0007w\u0002\u0002:;\u0007g\u0002\u0002;\u0004\u0003",
+    "\u0002\u0002\u0002<=\u0007h\u0002\u0002=>\u0007c\u0002\u0002>?\u0007",
+    "n\u0002\u0002?@\u0007u\u0002\u0002@A\u0007g\u0002\u0002A\u0006\u0003",
+    "\u0002\u0002\u0002BC\u0007p\u0002\u0002CD\u0007w\u0002\u0002DE\u0007",
+    "n\u0002\u0002EF\u0007n\u0002\u0002F\b\u0003\u0002\u0002\u0002GH\u0007",
+    "}\u0002\u0002H\n\u0003\u0002\u0002\u0002IJ\u0007.\u0002\u0002J\f\u0003",
+    "\u0002\u0002\u0002KL\u0007\u007f\u0002\u0002L\u000e\u0003\u0002\u0002",
+    "\u0002MN\u0007<\u0002\u0002N\u0010\u0003\u0002\u0002\u0002OP\u0007]",
+    "\u0002\u0002P\u0012\u0003\u0002\u0002\u0002QR\u0007_\u0002\u0002R\u0014",
+    "\u0003\u0002\u0002\u0002ST\u0007<\u0002\u0002TU\u0007<\u0002\u0002U",
+    "\u0016\u0003\u0002\u0002\u0002VW\u0007/\u0002\u0002W\u0018\u0003\u0002",
+    "\u0002\u0002XY\u0007K\u0002\u0002YZ\u0007p\u0002\u0002Z[\u0007h\u0002",
+    "\u0002[\\\u0007k\u0002\u0002\\]\u0007p\u0002\u0002]^\u0007k\u0002\u0002",
+    "^_\u0007v\u0002\u0002_`\u0007{\u0002\u0002`\u001a\u0003\u0002\u0002",
+    "\u0002ab\u0007P\u0002\u0002bc\u0007c\u0002\u0002cd\u0007P\u0002\u0002",
+    "d\u001c\u0003\u0002\u0002\u0002ei\t\u0002\u0002\u0002fh\t\u0003\u0002",
+    "\u0002gf\u0003\u0002\u0002\u0002hk\u0003\u0002\u0002\u0002ig\u0003\u0002",
+    "\u0002\u0002ij\u0003\u0002\u0002\u0002j\u001e\u0003\u0002\u0002\u0002",
+    "ki\u0003\u0002\u0002\u0002lq\u0007$\u0002\u0002mp\u0005!\u0011\u0002",
+    "np\u0005\'\u0014\u0002om\u0003\u0002\u0002\u0002on\u0003\u0002\u0002",
+    "\u0002ps\u0003\u0002\u0002\u0002qo\u0003\u0002\u0002\u0002qr\u0003\u0002",
+    "\u0002\u0002rt\u0003\u0002\u0002\u0002sq\u0003\u0002\u0002\u0002tu\u0007",
+    "$\u0002\u0002u \u0003\u0002\u0002\u0002vy\u0007^\u0002\u0002wz\t\u0004",
+    "\u0002\u0002xz\u0005#\u0012\u0002yw\u0003\u0002\u0002\u0002yx\u0003",
+    "\u0002\u0002\u0002z\"\u0003\u0002\u0002\u0002{|\u0007w\u0002\u0002|",
+    "}\u0005%\u0013\u0002}~\u0005%\u0013\u0002~\u007f\u0005%\u0013\u0002",
+    "\u007f\u0080\u0005%\u0013\u0002\u0080$\u0003\u0002\u0002\u0002\u0081",
+    "\u0082\t\u0005\u0002\u0002\u0082&\u0003\u0002\u0002\u0002\u0083\u0084",
+    "\n\u0006\u0002\u0002\u0084(\u0003\u0002\u0002\u0002\u0085\u0087\u0007",
+    "/\u0002\u0002\u0086\u0085\u0003\u0002\u0002\u0002\u0086\u0087\u0003",
+    "\u0002\u0002\u0002\u0087\u0088\u0003\u0002\u0002\u0002\u0088\u0089\u0005",
+    "+\u0016\u0002\u0089*\u0003\u0002\u0002\u0002\u008a\u0093\u00072\u0002",
+    "\u0002\u008b\u008f\t\u0007\u0002\u0002\u008c\u008e\t\b\u0002\u0002\u008d",
+    "\u008c\u0003\u0002\u0002\u0002\u008e\u0091\u0003\u0002\u0002\u0002\u008f",
+    "\u008d\u0003\u0002\u0002\u0002\u008f\u0090\u0003\u0002\u0002\u0002\u0090",
+    "\u0093\u0003\u0002\u0002\u0002\u0091\u008f\u0003\u0002\u0002\u0002\u0092",
+    "\u008a\u0003\u0002\u0002\u0002\u0092\u008b\u0003\u0002\u0002\u0002\u0093",
+    ",\u0003\u0002\u0002\u0002\u0094\u0096\u0007/\u0002\u0002\u0095\u0094",
+    "\u0003\u0002\u0002\u0002\u0095\u0096\u0003\u0002\u0002\u0002\u0096\u0097",
+    "\u0003\u0002\u0002\u0002\u0097\u0098\u0005+\u0016\u0002\u0098\u0099",
+    "\u00051\u0019\u0002\u0099.\u0003\u0002\u0002\u0002\u009a\u009c\u0007",
+    "/\u0002\u0002\u009b\u009a\u0003\u0002\u0002\u0002\u009b\u009c\u0003",
+    "\u0002\u0002\u0002\u009c\u009d\u0003\u0002\u0002\u0002\u009d\u009f\u0005",
+    "+\u0016\u0002\u009e\u00a0\u00051\u0019\u0002\u009f\u009e\u0003\u0002",
+    "\u0002\u0002\u009f\u00a0\u0003\u0002\u0002\u0002\u00a0\u00a1\u0003\u0002",
+    "\u0002\u0002\u00a1\u00a2\u00053\u001a\u0002\u00a20\u0003\u0002\u0002",
+    "\u0002\u00a3\u00a5\u00070\u0002\u0002\u00a4\u00a6\t\b\u0002\u0002\u00a5",
+    "\u00a4\u0003\u0002\u0002\u0002\u00a6\u00a7\u0003\u0002\u0002\u0002\u00a7",
+    "\u00a5\u0003\u0002\u0002\u0002\u00a7\u00a8\u0003\u0002\u0002\u0002\u00a8",
+    "2\u0003\u0002\u0002\u0002\u00a9\u00ab\t\t\u0002\u0002\u00aa\u00ac\t",
+    "\n\u0002\u0002\u00ab\u00aa\u0003\u0002\u0002\u0002\u00ab\u00ac\u0003",
+    "\u0002\u0002\u0002\u00ac\u00ae\u0003\u0002\u0002\u0002\u00ad\u00af\t",
+    "\b\u0002\u0002\u00ae\u00ad\u0003\u0002\u0002\u0002\u00af\u00b0\u0003",
+    "\u0002\u0002\u0002\u00b0\u00ae\u0003\u0002\u0002\u0002\u00b0\u00b1\u0003",
+    "\u0002\u0002\u0002\u00b14\u0003\u0002\u0002\u0002\u00b2\u00b4\t\u000b",
+    "\u0002\u0002\u00b3\u00b2\u0003\u0002\u0002\u0002\u00b4\u00b5\u0003\u0002",
+    "\u0002\u0002\u00b5\u00b3\u0003\u0002\u0002\u0002\u00b5\u00b6\u0003\u0002",
+    "\u0002\u0002\u00b6\u00b7\u0003\u0002\u0002\u0002\u00b7\u00b8\b\u001b",
+    "\u0002\u0002\u00b86\u0003\u0002\u0002\u0002\u0011\u0002ioqy\u0086\u008f",
+    "\u0092\u0095\u009b\u009f\u00a7\u00ab\u00b0\u00b5\u0003\b\u0002\u0002"].join("");
+
+
+const atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN);
+
+const decisionsToDFA = atn.decisionToState.map((ds, index) => new antlr4.dfa.DFA(ds, index));
+
+export default class AgtypeLexer extends antlr4.Lexer {
+
+    static grammarFileName = "Agtype.g4";
+    static channelNames = ["DEFAULT_TOKEN_CHANNEL", "HIDDEN"];
+    static modeNames = ["DEFAULT_MODE"];
+    static literalNames = [null, "'true'", "'false'", "'null'", "'{'", "','",
+        "'}'", "':'", "'['", "']'", "'::'", "'-'", "'Infinity'",
+        "'NaN'"];
+    static symbolicNames = [null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, "IDENT", "STRING",
+        "INTEGER", "RegularFloat", "ExponentFloat", "WS"];
+    static ruleNames = ["T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6",
+        "T__7", "T__8", "T__9", "T__10", "T__11", "T__12",
+        "IDENT", "STRING", "ESC", "UNICODE", "HEX", "SAFECODEPOINT",
+        "INTEGER", "INT", "RegularFloat", "ExponentFloat",
+        "DECIMAL", "SCIENTIFIC", "WS"];
+
+    constructor(input) {
+        super(input)
+        this._interp = new antlr4.atn.LexerATNSimulator(this, atn, decisionsToDFA, new antlr4.PredictionContextCache());
+    }
+
+    get atn() {
+        return atn;
+    }
+}
+
+AgtypeLexer.EOF = antlr4.Token.EOF;
+AgtypeLexer.T__0 = 1;
+AgtypeLexer.T__1 = 2;
+AgtypeLexer.T__2 = 3;
+AgtypeLexer.T__3 = 4;
+AgtypeLexer.T__4 = 5;
+AgtypeLexer.T__5 = 6;
+AgtypeLexer.T__6 = 7;
+AgtypeLexer.T__7 = 8;
+AgtypeLexer.T__8 = 9;
+AgtypeLexer.T__9 = 10;
+AgtypeLexer.T__10 = 11;
+AgtypeLexer.T__11 = 12;
+AgtypeLexer.T__12 = 13;
+AgtypeLexer.IDENT = 14;
+AgtypeLexer.STRING = 15;
+AgtypeLexer.INTEGER = 16;
+AgtypeLexer.RegularFloat = 17;
+AgtypeLexer.ExponentFloat = 18;
+AgtypeLexer.WS = 19;
+
+
+
diff --git a/backend/src/tools/AgtypeLexer.tokens b/backend/src/tools/AgtypeLexer.tokens
new file mode 100644
index 0000000..193f8c9
--- /dev/null
+++ b/backend/src/tools/AgtypeLexer.tokens
@@ -0,0 +1,32 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+T__7=8
+T__8=9
+T__9=10
+T__10=11
+T__11=12
+T__12=13
+IDENT=14
+STRING=15
+INTEGER=16
+RegularFloat=17
+ExponentFloat=18
+WS=19
+'true'=1
+'false'=2
+'null'=3
+'{'=4
+','=5
+'}'=6
+':'=7
+'['=8
+']'=9
+'::'=10
+'-'=11
+'Infinity'=12
+'NaN'=13
diff --git a/backend/src/tools/AgtypeListener.js b/backend/src/tools/AgtypeListener.js
new file mode 100644
index 0000000..d3a6b01
--- /dev/null
+++ b/backend/src/tools/AgtypeListener.js
@@ -0,0 +1,142 @@
+// Generated from src/tools/Agtype.g4 by ANTLR 4.9.2
+// jshint ignore: start
+import antlr4 from 'antlr4';
+
+// This class defines a complete listener for a parse tree produced by AgtypeParser.
+export default class AgtypeListener extends antlr4.tree.ParseTreeListener {
+
+    // Enter a parse tree produced by AgtypeParser#agType.
+    enterAgType(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#agType.
+    exitAgType(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#agValue.
+    enterAgValue(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#agValue.
+    exitAgValue(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#StringValue.
+    enterStringValue(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#StringValue.
+    exitStringValue(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#IntegerValue.
+    enterIntegerValue(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#IntegerValue.
+    exitIntegerValue(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#FloatValue.
+    enterFloatValue(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#FloatValue.
+    exitFloatValue(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#TrueBoolean.
+    enterTrueBoolean(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#TrueBoolean.
+    exitTrueBoolean(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#FalseBoolean.
+    enterFalseBoolean(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#FalseBoolean.
+    exitFalseBoolean(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#NullValue.
+    enterNullValue(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#NullValue.
+    exitNullValue(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#ObjectValue.
+    enterObjectValue(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#ObjectValue.
+    exitObjectValue(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#ArrayValue.
+    enterArrayValue(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#ArrayValue.
+    exitArrayValue(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#obj.
+    enterObj(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#obj.
+    exitObj(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#pair.
+    enterPair(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#pair.
+    exitPair(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#array.
+    enterArray(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#array.
+    exitArray(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#typeAnnotation.
+    enterTypeAnnotation(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#typeAnnotation.
+    exitTypeAnnotation(ctx) {
+    }
+
+
+    // Enter a parse tree produced by AgtypeParser#floatLiteral.
+    enterFloatLiteral(ctx) {
+    }
+
+    // Exit a parse tree produced by AgtypeParser#floatLiteral.
+    exitFloatLiteral(ctx) {
+    }
+
+}
diff --git a/backend/src/tools/AgtypeParser.js b/backend/src/tools/AgtypeParser.js
new file mode 100644
index 0000000..3ea29df
--- /dev/null
+++ b/backend/src/tools/AgtypeParser.js
@@ -0,0 +1,981 @@
+// Generated from src/tools/Agtype.g4 by ANTLR 4.9.2
+// jshint ignore: start
+import antlr4 from 'antlr4';
+import AgtypeListener from './AgtypeListener.js';
+
+const serializedATN = ["\u0003\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786",
+    "\u5964\u0003\u0015R\u0004\u0002\t\u0002\u0004\u0003\t\u0003\u0004\u0004",
+    "\t\u0004\u0004\u0005\t\u0005\u0004\u0006\t\u0006\u0004\u0007\t\u0007",
+    "\u0004\b\t\b\u0004\t\t\t\u0003\u0002\u0003\u0002\u0003\u0002\u0003\u0003",
+    "\u0003\u0003\u0005\u0003\u0018\n\u0003\u0003\u0004\u0003\u0004\u0003",
+    "\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0003\u0004\u0005",
+    "\u0004\"\n\u0004\u0003\u0005\u0003\u0005\u0003\u0005\u0003\u0005\u0007",
+    "\u0005(\n\u0005\f\u0005\u000e\u0005+\u000b\u0005\u0003\u0005\u0003\u0005",
+    "\u0003\u0005\u0003\u0005\u0005\u00051\n\u0005\u0003\u0006\u0003\u0006",
+    "\u0003\u0006\u0003\u0006\u0003\u0007\u0003\u0007\u0003\u0007\u0003\u0007",
+    "\u0007\u0007;\n\u0007\f\u0007\u000e\u0007>\u000b\u0007\u0003\u0007\u0003",
+    "\u0007\u0003\u0007\u0003\u0007\u0005\u0007D\n\u0007\u0003\b\u0003\b",
+    "\u0003\b\u0003\t\u0003\t\u0003\t\u0005\tL\n\t\u0003\t\u0003\t\u0005",
+    "\tP\n\t\u0003\t\u0002\u0002\n\u0002\u0004\u0006\b\n\f\u000e\u0010\u0002",
+    "\u0002\u0002Y\u0002\u0012\u0003\u0002\u0002\u0002\u0004\u0015\u0003",
+    "\u0002\u0002\u0002\u0006!\u0003\u0002\u0002\u0002\b0\u0003\u0002\u0002",
+    "\u0002\n2\u0003\u0002\u0002\u0002\fC\u0003\u0002\u0002\u0002\u000eE",
+    "\u0003\u0002\u0002\u0002\u0010O\u0003\u0002\u0002\u0002\u0012\u0013",
+    "\u0005\u0004\u0003\u0002\u0013\u0014\u0007\u0002\u0002\u0003\u0014\u0003",
+    "\u0003\u0002\u0002\u0002\u0015\u0017\u0005\u0006\u0004\u0002\u0016\u0018",
+    "\u0005\u000e\b\u0002\u0017\u0016\u0003\u0002\u0002\u0002\u0017\u0018",
+    "\u0003\u0002\u0002\u0002\u0018\u0005\u0003\u0002\u0002\u0002\u0019\"",
+    "\u0007\u0011\u0002\u0002\u001a\"\u0007\u0012\u0002\u0002\u001b\"\u0005",
+    "\u0010\t\u0002\u001c\"\u0007\u0003\u0002\u0002\u001d\"\u0007\u0004\u0002",
+    "\u0002\u001e\"\u0007\u0005\u0002\u0002\u001f\"\u0005\b\u0005\u0002 ",
+    "\"\u0005\f\u0007\u0002!\u0019\u0003\u0002\u0002\u0002!\u001a\u0003\u0002",
+    "\u0002\u0002!\u001b\u0003\u0002\u0002\u0002!\u001c\u0003\u0002\u0002",
+    "\u0002!\u001d\u0003\u0002\u0002\u0002!\u001e\u0003\u0002\u0002\u0002",
+    "!\u001f\u0003\u0002\u0002\u0002! \u0003\u0002\u0002\u0002\"\u0007\u0003",
+    "\u0002\u0002\u0002#$\u0007\u0006\u0002\u0002$)\u0005\n\u0006\u0002%",
+    "&\u0007\u0007\u0002\u0002&(\u0005\n\u0006\u0002\'%\u0003\u0002\u0002",
+    "\u0002(+\u0003\u0002\u0002\u0002)\'\u0003\u0002\u0002\u0002)*\u0003",
+    "\u0002\u0002\u0002*,\u0003\u0002\u0002\u0002+)\u0003\u0002\u0002\u0002",
+    ",-\u0007\b\u0002\u0002-1\u0003\u0002\u0002\u0002./\u0007\u0006\u0002",
+    "\u0002/1\u0007\b\u0002\u00020#\u0003\u0002\u0002\u00020.\u0003\u0002",
+    "\u0002\u00021\t\u0003\u0002\u0002\u000223\u0007\u0011\u0002\u000234",
+    "\u0007\t\u0002\u000245\u0005\u0004\u0003\u00025\u000b\u0003\u0002\u0002",
+    "\u000267\u0007\n\u0002\u00027<\u0005\u0004\u0003\u000289\u0007\u0007",
+    "\u0002\u00029;\u0005\u0004\u0003\u0002:8\u0003\u0002\u0002\u0002;>\u0003",
+    "\u0002\u0002\u0002<:\u0003\u0002\u0002\u0002<=\u0003\u0002\u0002\u0002",
+    "=?\u0003\u0002\u0002\u0002><\u0003\u0002\u0002\u0002?@\u0007\u000b\u0002",
+    "\u0002@D\u0003\u0002\u0002\u0002AB\u0007\n\u0002\u0002BD\u0007\u000b",
+    "\u0002\u0002C6\u0003\u0002\u0002\u0002CA\u0003\u0002\u0002\u0002D\r",
+    "\u0003\u0002\u0002\u0002EF\u0007\f\u0002\u0002FG\u0007\u0010\u0002\u0002",
+    "G\u000f\u0003\u0002\u0002\u0002HP\u0007\u0013\u0002\u0002IP\u0007\u0014",
+    "\u0002\u0002JL\u0007\r\u0002\u0002KJ\u0003\u0002\u0002\u0002KL\u0003",
+    "\u0002\u0002\u0002LM\u0003\u0002\u0002\u0002MP\u0007\u000e\u0002\u0002",
+    "NP\u0007\u000f\u0002\u0002OH\u0003\u0002\u0002\u0002OI\u0003\u0002\u0002",
+    "\u0002OK\u0003\u0002\u0002\u0002ON\u0003\u0002\u0002\u0002P\u0011\u0003",
+    "\u0002\u0002\u0002\n\u0017!)0<CKO"].join("");
+
+
+const atn = new antlr4.atn.ATNDeserializer().deserialize(serializedATN);
+
+const decisionsToDFA = atn.decisionToState.map((ds, index) => new antlr4.dfa.DFA(ds, index));
+
+const sharedContextCache = new antlr4.PredictionContextCache();
+
+export default class AgtypeParser extends antlr4.Parser {
+
+    static grammarFileName = "Agtype.g4";
+    static literalNames = [null, "'true'", "'false'", "'null'", "'{'",
+        "','", "'}'", "':'", "'['", "']'", "'::'", "'-'",
+        "'Infinity'", "'NaN'"];
+    static symbolicNames = [null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, "IDENT",
+        "STRING", "INTEGER", "RegularFloat", "ExponentFloat",
+        "WS"];
+    static ruleNames = ["agType", "agValue", "value", "obj", "pair", "array",
+        "typeAnnotation", "floatLiteral"];
+
+    constructor(input) {
+        super(input);
+        this._interp = new antlr4.atn.ParserATNSimulator(this, atn, decisionsToDFA, sharedContextCache);
+        this.ruleNames = AgtypeParser.ruleNames;
+        this.literalNames = AgtypeParser.literalNames;
+        this.symbolicNames = AgtypeParser.symbolicNames;
+    }
+
+    get atn() {
+        return atn;
+    }
+
+
+    agType() {
+        let localctx = new AgTypeContext(this, this._ctx, this.state);
+        this.enterRule(localctx, 0, AgtypeParser.RULE_agType);
+        try {
+            this.enterOuterAlt(localctx, 1);
+            this.state = 16;
+            this.agValue();
+            this.state = 17;
+            this.match(AgtypeParser.EOF);
+        } catch (re) {
+            if (re instanceof antlr4.error.RecognitionException) {
+                localctx.exception = re;
+                this._errHandler.reportError(this, re);
+                this._errHandler.recover(this, re);
+            } else {
+                throw re;
+            }
+        } finally {
+            this.exitRule();
+        }
+        return localctx;
+    }
+
+
+    agValue() {
+        let localctx = new AgValueContext(this, this._ctx, this.state);
+        this.enterRule(localctx, 2, AgtypeParser.RULE_agValue);
+        var _la = 0; // Token type
+        try {
+            this.enterOuterAlt(localctx, 1);
+            this.state = 19;
+            this.value();
+            this.state = 21;
+            this._errHandler.sync(this);
+            _la = this._input.LA(1);
+            if (_la === AgtypeParser.T__9) {
+                this.state = 20;
+                this.typeAnnotation();
+            }
+
+        } catch (re) {
+            if (re instanceof antlr4.error.RecognitionException) {
+                localctx.exception = re;
+                this._errHandler.reportError(this, re);
+                this._errHandler.recover(this, re);
+            } else {
+                throw re;
+            }
+        } finally {
+            this.exitRule();
+        }
+        return localctx;
+    }
+
+
+    value() {
+        let localctx = new ValueContext(this, this._ctx, this.state);
+        this.enterRule(localctx, 4, AgtypeParser.RULE_value);
+        try {
+            this.state = 31;
+            this._errHandler.sync(this);
+            switch (this._input.LA(1)) {
+                case AgtypeParser.STRING:
+                    localctx = new StringValueContext(this, localctx);
+                    this.enterOuterAlt(localctx, 1);
+                    this.state = 23;
+                    this.match(AgtypeParser.STRING);
+                    break;
+                case AgtypeParser.INTEGER:
+                    localctx = new IntegerValueContext(this, localctx);
+                    this.enterOuterAlt(localctx, 2);
+                    this.state = 24;
+                    this.match(AgtypeParser.INTEGER);
+                    break;
+                case AgtypeParser.T__10:
+                case AgtypeParser.T__11:
+                case AgtypeParser.T__12:
+                case AgtypeParser.RegularFloat:
+                case AgtypeParser.ExponentFloat:
+                    localctx = new FloatValueContext(this, localctx);
+                    this.enterOuterAlt(localctx, 3);
+                    this.state = 25;
+                    this.floatLiteral();
+                    break;
+                case AgtypeParser.T__0:
+                    localctx = new TrueBooleanContext(this, localctx);
+                    this.enterOuterAlt(localctx, 4);
+                    this.state = 26;
+                    this.match(AgtypeParser.T__0);
+                    break;
+                case AgtypeParser.T__1:
+                    localctx = new FalseBooleanContext(this, localctx);
+                    this.enterOuterAlt(localctx, 5);
+                    this.state = 27;
+                    this.match(AgtypeParser.T__1);
+                    break;
+                case AgtypeParser.T__2:
+                    localctx = new NullValueContext(this, localctx);
+                    this.enterOuterAlt(localctx, 6);
+                    this.state = 28;
+                    this.match(AgtypeParser.T__2);
+                    break;
+                case AgtypeParser.T__3:
+                    localctx = new ObjectValueContext(this, localctx);
+                    this.enterOuterAlt(localctx, 7);
+                    this.state = 29;
+                    this.obj();
+                    break;
+                case AgtypeParser.T__7:
+                    localctx = new ArrayValueContext(this, localctx);
+                    this.enterOuterAlt(localctx, 8);
+                    this.state = 30;
+                    this.array();
+                    break;
+                default:
+                    throw new antlr4.error.NoViableAltException(this);
+            }
+        } catch (re) {
+            if (re instanceof antlr4.error.RecognitionException) {
+                localctx.exception = re;
+                this._errHandler.reportError(this, re);
+                this._errHandler.recover(this, re);
+            } else {
+                throw re;
+            }
+        } finally {
+            this.exitRule();
+        }
+        return localctx;
+    }
+
+
+    obj() {
+        let localctx = new ObjContext(this, this._ctx, this.state);
+        this.enterRule(localctx, 6, AgtypeParser.RULE_obj);
+        var _la = 0; // Token type
+        try {
+            this.state = 46;
+            this._errHandler.sync(this);
+            var la_ = this._interp.adaptivePredict(this._input, 3, this._ctx);
+            switch (la_) {
+                case 1:
+                    this.enterOuterAlt(localctx, 1);
+                    this.state = 33;
+                    this.match(AgtypeParser.T__3);
+                    this.state = 34;
+                    this.pair();
+                    this.state = 39;
+                    this._errHandler.sync(this);
+                    _la = this._input.LA(1);
+                    while (_la === AgtypeParser.T__4) {
+                        this.state = 35;
+                        this.match(AgtypeParser.T__4);
+                        this.state = 36;
+                        this.pair();
+                        this.state = 41;
+                        this._errHandler.sync(this);
+                        _la = this._input.LA(1);
+                    }
+                    this.state = 42;
+                    this.match(AgtypeParser.T__5);
+                    break;
+
+                case 2:
+                    this.enterOuterAlt(localctx, 2);
+                    this.state = 44;
+                    this.match(AgtypeParser.T__3);
+                    this.state = 45;
+                    this.match(AgtypeParser.T__5);
+                    break;
+
+            }
+        } catch (re) {
+            if (re instanceof antlr4.error.RecognitionException) {
+                localctx.exception = re;
+                this._errHandler.reportError(this, re);
+                this._errHandler.recover(this, re);
+            } else {
+                throw re;
+            }
+        } finally {
+            this.exitRule();
+        }
+        return localctx;
+    }
+
+
+    pair() {
+        let localctx = new PairContext(this, this._ctx, this.state);
+        this.enterRule(localctx, 8, AgtypeParser.RULE_pair);
+        try {
+            this.enterOuterAlt(localctx, 1);
+            this.state = 48;
+            this.match(AgtypeParser.STRING);
+            this.state = 49;
+            this.match(AgtypeParser.T__6);
+            this.state = 50;
+            this.agValue();
+        } catch (re) {
+            if (re instanceof antlr4.error.RecognitionException) {
+                localctx.exception = re;
+                this._errHandler.reportError(this, re);
+                this._errHandler.recover(this, re);
+            } else {
+                throw re;
+            }
+        } finally {
+            this.exitRule();
+        }
+        return localctx;
+    }
+
+
+    array() {
+        let localctx = new ArrayContext(this, this._ctx, this.state);
+        this.enterRule(localctx, 10, AgtypeParser.RULE_array);
+        var _la = 0; // Token type
+        try {
+            this.state = 65;
+            this._errHandler.sync(this);
+            var la_ = this._interp.adaptivePredict(this._input, 5, this._ctx);
+            switch (la_) {
+                case 1:
+                    this.enterOuterAlt(localctx, 1);
+                    this.state = 52;
+                    this.match(AgtypeParser.T__7);
+                    this.state = 53;
+                    this.agValue();
+                    this.state = 58;
+                    this._errHandler.sync(this);
+                    _la = this._input.LA(1);
+                    while (_la === AgtypeParser.T__4) {
+                        this.state = 54;
+                        this.match(AgtypeParser.T__4);
+                        this.state = 55;
+                        this.agValue();
+                        this.state = 60;
+                        this._errHandler.sync(this);
+                        _la = this._input.LA(1);
+                    }
+                    this.state = 61;
+                    this.match(AgtypeParser.T__8);
+                    break;
+
+                case 2:
+                    this.enterOuterAlt(localctx, 2);
+                    this.state = 63;
+                    this.match(AgtypeParser.T__7);
+                    this.state = 64;
+                    this.match(AgtypeParser.T__8);
+                    break;
+
+            }
+        } catch (re) {
+            if (re instanceof antlr4.error.RecognitionException) {
+                localctx.exception = re;
+                this._errHandler.reportError(this, re);
+                this._errHandler.recover(this, re);
+            } else {
+                throw re;
+            }
+        } finally {
+            this.exitRule();
+        }
+        return localctx;
+    }
+
+
+    typeAnnotation() {
+        let localctx = new TypeAnnotationContext(this, this._ctx, this.state);
+        this.enterRule(localctx, 12, AgtypeParser.RULE_typeAnnotation);
+        try {
+            this.enterOuterAlt(localctx, 1);
+            this.state = 67;
+            this.match(AgtypeParser.T__9);
+            this.state = 68;
+            this.match(AgtypeParser.IDENT);
+        } catch (re) {
+            if (re instanceof antlr4.error.RecognitionException) {
+                localctx.exception = re;
+                this._errHandler.reportError(this, re);
+                this._errHandler.recover(this, re);
+            } else {
+                throw re;
+            }
+        } finally {
+            this.exitRule();
+        }
+        return localctx;
+    }
+
+
+    floatLiteral() {
+        let localctx = new FloatLiteralContext(this, this._ctx, this.state);
+        this.enterRule(localctx, 14, AgtypeParser.RULE_floatLiteral);
+        var _la = 0; // Token type
+        try {
+            this.state = 77;
+            this._errHandler.sync(this);
+            switch (this._input.LA(1)) {
+                case AgtypeParser.RegularFloat:
+                    this.enterOuterAlt(localctx, 1);
+                    this.state = 70;
+                    this.match(AgtypeParser.RegularFloat);
+                    break;
+                case AgtypeParser.ExponentFloat:
+                    this.enterOuterAlt(localctx, 2);
+                    this.state = 71;
+                    this.match(AgtypeParser.ExponentFloat);
+                    break;
+                case AgtypeParser.T__10:
+                case AgtypeParser.T__11:
+                    this.enterOuterAlt(localctx, 3);
+                    this.state = 73;
+                    this._errHandler.sync(this);
+                    _la = this._input.LA(1);
+                    if (_la === AgtypeParser.T__10) {
+                        this.state = 72;
+                        this.match(AgtypeParser.T__10);
+                    }
+
+                    this.state = 75;
+                    this.match(AgtypeParser.T__11);
+                    break;
+                case AgtypeParser.T__12:
+                    this.enterOuterAlt(localctx, 4);
+                    this.state = 76;
+                    this.match(AgtypeParser.T__12);
+                    break;
+                default:
+                    throw new antlr4.error.NoViableAltException(this);
+            }
+        } catch (re) {
+            if (re instanceof antlr4.error.RecognitionException) {
+                localctx.exception = re;
+                this._errHandler.reportError(this, re);
+                this._errHandler.recover(this, re);
+            } else {
+                throw re;
+            }
+        } finally {
+            this.exitRule();
+        }
+        return localctx;
+    }
+
+
+}
+
+AgtypeParser.EOF = antlr4.Token.EOF;
+AgtypeParser.T__0 = 1;
+AgtypeParser.T__1 = 2;
+AgtypeParser.T__2 = 3;
+AgtypeParser.T__3 = 4;
+AgtypeParser.T__4 = 5;
+AgtypeParser.T__5 = 6;
+AgtypeParser.T__6 = 7;
+AgtypeParser.T__7 = 8;
+AgtypeParser.T__8 = 9;
+AgtypeParser.T__9 = 10;
+AgtypeParser.T__10 = 11;
+AgtypeParser.T__11 = 12;
+AgtypeParser.T__12 = 13;
+AgtypeParser.IDENT = 14;
+AgtypeParser.STRING = 15;
+AgtypeParser.INTEGER = 16;
+AgtypeParser.RegularFloat = 17;
+AgtypeParser.ExponentFloat = 18;
+AgtypeParser.WS = 19;
+
+AgtypeParser.RULE_agType = 0;
+AgtypeParser.RULE_agValue = 1;
+AgtypeParser.RULE_value = 2;
+AgtypeParser.RULE_obj = 3;
+AgtypeParser.RULE_pair = 4;
+AgtypeParser.RULE_array = 5;
+AgtypeParser.RULE_typeAnnotation = 6;
+AgtypeParser.RULE_floatLiteral = 7;
+
+class AgTypeContext extends antlr4.ParserRuleContext {
+
+    constructor(parser, parent, invokingState) {
+        if (parent === undefined) {
+            parent = null;
+        }
+        if (invokingState === undefined || invokingState === null) {
+            invokingState = -1;
+        }
+        super(parent, invokingState);
+        this.parser = parser;
+        this.ruleIndex = AgtypeParser.RULE_agType;
+    }
+
+    agValue() {
+        return this.getTypedRuleContext(AgValueContext, 0);
+    };
+
+    EOF() {
+        return this.getToken(AgtypeParser.EOF, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterAgType(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitAgType(this);
+        }
+    }
+
+
+}
+
+
+class AgValueContext extends antlr4.ParserRuleContext {
+
+    constructor(parser, parent, invokingState) {
+        if (parent === undefined) {
+            parent = null;
+        }
+        if (invokingState === undefined || invokingState === null) {
+            invokingState = -1;
+        }
+        super(parent, invokingState);
+        this.parser = parser;
+        this.ruleIndex = AgtypeParser.RULE_agValue;
+    }
+
+    value() {
+        return this.getTypedRuleContext(ValueContext, 0);
+    };
+
+    typeAnnotation() {
+        return this.getTypedRuleContext(TypeAnnotationContext, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterAgValue(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitAgValue(this);
+        }
+    }
+
+
+}
+
+
+class ValueContext extends antlr4.ParserRuleContext {
+
+    constructor(parser, parent, invokingState) {
+        if (parent === undefined) {
+            parent = null;
+        }
+        if (invokingState === undefined || invokingState === null) {
+            invokingState = -1;
+        }
+        super(parent, invokingState);
+        this.parser = parser;
+        this.ruleIndex = AgtypeParser.RULE_value;
+    }
+
+
+    copyFrom(ctx) {
+        super.copyFrom(ctx);
+    }
+
+}
+
+
+class NullValueContext extends ValueContext {
+
+    constructor(parser, ctx) {
+        super(parser);
+        super.copyFrom(ctx);
+    }
+
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterNullValue(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitNullValue(this);
+        }
+    }
+
+
+}
+
+AgtypeParser.NullValueContext = NullValueContext;
+
+class ObjectValueContext extends ValueContext {
+
+    constructor(parser, ctx) {
+        super(parser);
+        super.copyFrom(ctx);
+    }
+
+    obj() {
+        return this.getTypedRuleContext(ObjContext, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterObjectValue(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitObjectValue(this);
+        }
+    }
+
+
+}
+
+AgtypeParser.ObjectValueContext = ObjectValueContext;
+
+class IntegerValueContext extends ValueContext {
+
+    constructor(parser, ctx) {
+        super(parser);
+        super.copyFrom(ctx);
+    }
+
+    INTEGER() {
+        return this.getToken(AgtypeParser.INTEGER, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterIntegerValue(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitIntegerValue(this);
+        }
+    }
+
+
+}
+
+AgtypeParser.IntegerValueContext = IntegerValueContext;
+
+class TrueBooleanContext extends ValueContext {
+
+    constructor(parser, ctx) {
+        super(parser);
+        super.copyFrom(ctx);
+    }
+
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterTrueBoolean(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitTrueBoolean(this);
+        }
+    }
+
+
+}
+
+AgtypeParser.TrueBooleanContext = TrueBooleanContext;
+
+class FalseBooleanContext extends ValueContext {
+
+    constructor(parser, ctx) {
+        super(parser);
+        super.copyFrom(ctx);
+    }
+
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterFalseBoolean(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitFalseBoolean(this);
+        }
+    }
+
+
+}
+
+AgtypeParser.FalseBooleanContext = FalseBooleanContext;
+
+class FloatValueContext extends ValueContext {
+
+    constructor(parser, ctx) {
+        super(parser);
+        super.copyFrom(ctx);
+    }
+
+    floatLiteral() {
+        return this.getTypedRuleContext(FloatLiteralContext, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterFloatValue(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitFloatValue(this);
+        }
+    }
+
+
+}
+
+AgtypeParser.FloatValueContext = FloatValueContext;
+
+class StringValueContext extends ValueContext {
+
+    constructor(parser, ctx) {
+        super(parser);
+        super.copyFrom(ctx);
+    }
+
+    STRING() {
+        return this.getToken(AgtypeParser.STRING, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterStringValue(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitStringValue(this);
+        }
+    }
+
+
+}
+
+AgtypeParser.StringValueContext = StringValueContext;
+
+class ArrayValueContext extends ValueContext {
+
+    constructor(parser, ctx) {
+        super(parser);
+        super.copyFrom(ctx);
+    }
+
+    array() {
+        return this.getTypedRuleContext(ArrayContext, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterArrayValue(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitArrayValue(this);
+        }
+    }
+
+
+}
+
+AgtypeParser.ArrayValueContext = ArrayValueContext;
+
+class ObjContext extends antlr4.ParserRuleContext {
+
+    constructor(parser, parent, invokingState) {
+        if (parent === undefined) {
+            parent = null;
+        }
+        if (invokingState === undefined || invokingState === null) {
+            invokingState = -1;
+        }
+        super(parent, invokingState);
+        this.parser = parser;
+        this.ruleIndex = AgtypeParser.RULE_obj;
+    }
+
+    pair = function (i) {
+        if (i === undefined) {
+            i = null;
+        }
+        if (i === null) {
+            return this.getTypedRuleContexts(PairContext);
+        } else {
+            return this.getTypedRuleContext(PairContext, i);
+        }
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterObj(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitObj(this);
+        }
+    }
+
+
+}
+
+
+class PairContext extends antlr4.ParserRuleContext {
+
+    constructor(parser, parent, invokingState) {
+        if (parent === undefined) {
+            parent = null;
+        }
+        if (invokingState === undefined || invokingState === null) {
+            invokingState = -1;
+        }
+        super(parent, invokingState);
+        this.parser = parser;
+        this.ruleIndex = AgtypeParser.RULE_pair;
+    }
+
+    STRING() {
+        return this.getToken(AgtypeParser.STRING, 0);
+    };
+
+    agValue() {
+        return this.getTypedRuleContext(AgValueContext, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterPair(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitPair(this);
+        }
+    }
+
+
+}
+
+
+class ArrayContext extends antlr4.ParserRuleContext {
+
+    constructor(parser, parent, invokingState) {
+        if (parent === undefined) {
+            parent = null;
+        }
+        if (invokingState === undefined || invokingState === null) {
+            invokingState = -1;
+        }
+        super(parent, invokingState);
+        this.parser = parser;
+        this.ruleIndex = AgtypeParser.RULE_array;
+    }
+
+    agValue = function (i) {
+        if (i === undefined) {
+            i = null;
+        }
+        if (i === null) {
+            return this.getTypedRuleContexts(AgValueContext);
+        } else {
+            return this.getTypedRuleContext(AgValueContext, i);
+        }
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterArray(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitArray(this);
+        }
+    }
+
+
+}
+
+
+class TypeAnnotationContext extends antlr4.ParserRuleContext {
+
+    constructor(parser, parent, invokingState) {
+        if (parent === undefined) {
+            parent = null;
+        }
+        if (invokingState === undefined || invokingState === null) {
+            invokingState = -1;
+        }
+        super(parent, invokingState);
+        this.parser = parser;
+        this.ruleIndex = AgtypeParser.RULE_typeAnnotation;
+    }
+
+    IDENT() {
+        return this.getToken(AgtypeParser.IDENT, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterTypeAnnotation(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitTypeAnnotation(this);
+        }
+    }
+
+
+}
+
+
+class FloatLiteralContext extends antlr4.ParserRuleContext {
+
+    constructor(parser, parent, invokingState) {
+        if (parent === undefined) {
+            parent = null;
+        }
+        if (invokingState === undefined || invokingState === null) {
+            invokingState = -1;
+        }
+        super(parent, invokingState);
+        this.parser = parser;
+        this.ruleIndex = AgtypeParser.RULE_floatLiteral;
+    }
+
+    RegularFloat() {
+        return this.getToken(AgtypeParser.RegularFloat, 0);
+    };
+
+    ExponentFloat() {
+        return this.getToken(AgtypeParser.ExponentFloat, 0);
+    };
+
+    enterRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.enterFloatLiteral(this);
+        }
+    }
+
+    exitRule(listener) {
+        if (listener instanceof AgtypeListener) {
+            listener.exitFloatLiteral(this);
+        }
+    }
+
+
+}
+
+
+AgtypeParser.AgTypeContext = AgTypeContext;
+AgtypeParser.AgValueContext = AgValueContext;
+AgtypeParser.ValueContext = ValueContext;
+AgtypeParser.ObjContext = ObjContext;
+AgtypeParser.PairContext = PairContext;
+AgtypeParser.ArrayContext = ArrayContext;
+AgtypeParser.TypeAnnotationContext = TypeAnnotationContext;
+AgtypeParser.FloatLiteralContext = FloatLiteralContext;
diff --git a/backend/src/tools/CustomAgTypeListener.js b/backend/src/tools/CustomAgTypeListener.js
new file mode 100644
index 0000000..0dc38eb
--- /dev/null
+++ b/backend/src/tools/CustomAgTypeListener.js
@@ -0,0 +1,91 @@
+import AgtypeListener from "./AgtypeListener";
+
+class CustomAgTypeListener extends AgtypeListener {
+    rootObject = null;
+    objectInsider = [];
+    lastValue = null;
+
+    exitStringValue(ctx) {
+        this.lastValue = this.stripQuotes(ctx.getText());
+    }
+
+    exitIntegerValue(ctx) {
+        this.lastValue = parseInt(ctx.getText());
+    }
+
+    exitFloatValue(ctx) {
+        this.lastValue = parseFloat(ctx.getText());
+    }
+
+    exitTrueBoolean(ctx) {
+        this.lastValue = true;
+    }
+
+    exitFalseBoolean(ctx) {
+        this.lastValue = false;
+    }
+
+    exitNullValue(ctx) {
+        this.lastValue = null;
+    }
+
+    enterObjectValue(ctx) {
+        this.objectInsider.unshift({});
+        this.lastValue = this.objectInsider[0];
+    }
+
+    exitObjectValue(ctx) {
+        if (this.objectInsider.length >= 2 && this.objectInsider[1] instanceof Array) {
+            const currentObject = this.objectInsider.shift();
+            this.objectInsider[0].push(currentObject);
+        }
+    }
+
+    enterArrayValue(ctx) {
+        this.objectInsider.unshift([]);
+        this.lastValue = this.objectInsider[0];
+    }
+
+    exitArrayValue(ctx) {
+        if (this.objectInsider.length >= 2 && this.objectInsider[1] instanceof Array) {
+            // if objectInsider == Object then is pair or root
+            const currentObject = this.objectInsider.shift();
+            this.objectInsider[0].push(currentObject);
+        }
+    }
+
+
+    exitPair(ctx) {
+        const name = this.stripQuotes(ctx.STRING().getText());
+
+        if (this.lastValue !== undefined) {
+            this.objectInsider[0][name] = this.lastValue;
+            this.lastValue = undefined;
+        } else {
+            const lastValue = this.objectInsider.shift();
+            if (this.objectInsider[0] instanceof Array) {
+                this.objectInsider[0].push(lastValue);
+            } else {
+                this.objectInsider[0][name] = lastValue;
+            }
+        }
+    }
+
+    exitFloatLiteral(ctx) {
+        this.lastValue = ctx.getText();
+    }
+
+    exitAgType(ctx) {
+        this.rootObject = this.objectInsider.shift();
+    }
+
+    stripQuotes(quotesString) {
+        return JSON.parse(quotesString);
+    }
+
+    getResult() {
+        return this.rootObject;
+    }
+}
+
+export default CustomAgTypeListener;
diff --git a/backend/src/tools/SQLFlavorManager.js b/backend/src/tools/SQLFlavorManager.js
index 5a18747..a9131eb 100644
--- a/backend/src/tools/SQLFlavorManager.js
+++ b/backend/src/tools/SQLFlavorManager.js
@@ -5,6 +5,7 @@
 
 const sqlBasePath = path.join(__dirname, '../../sql');
 
+// todo: util.format -> ejs
 function getQuery(flavor = Flavors.AGENS, name) {
     const defaultSqlPath = path.join(sqlBasePath, `./${name}/default.sql`);
     let sqlPath = path.join(sqlBasePath, `./${name}/${flavor}.sql`);
diff --git a/frontend/src/components/cytoscape/CypherResultCytoscapeLegend.jsx b/frontend/src/components/cytoscape/CypherResultCytoscapeLegend.jsx
index fe095e7..2186cd9 100644
--- a/frontend/src/components/cytoscape/CypherResultCytoscapeLegend.jsx
+++ b/frontend/src/components/cytoscape/CypherResultCytoscapeLegend.jsx
@@ -171,7 +171,7 @@
       <div className="legend-area" style={{ width: '80%' }}>
         <div className="d-flex nodeLegend">
           <div className={`mr-auto legends legend ${nodeLegendExpanded ? 'expandedLegend' : ''}`}>
-            <sapn>Node: </sapn>
+            <span>Node: </span>
             {nodeLedgend}
           </div>
           <button
@@ -186,7 +186,7 @@
         </div>
         <div className="d-flex edgeLegend">
           <div className={`mr-auto legends legend ${edgeLegendExpanded ? 'expandedLegend' : ''}`}>
-            <sapn>Edge: </sapn>
+            <span>Edge: </span>
             {edgeLedgend}
           </div>
           <button
diff --git a/frontend/src/components/frame/Frame.module.scss b/frontend/src/components/frame/Frame.module.scss
index bc0483c..929c1c9 100644
--- a/frontend/src/components/frame/Frame.module.scss
+++ b/frontend/src/components/frame/Frame.module.scss
@@ -9,6 +9,7 @@
   border: 1px solid rgba(0, 0, 0, .125);
   border-radius: .25rem;
   margin-top: 1rem;
+  overflow-y: auto;
 }
 
 .Frame.FullScreen {