diff --git a/package-lock.json b/package-lock.json
index 74aa09d8..38f02c20 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -108,16 +108,81 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz",
- "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==",
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
"dependencies": {
- "@babel/highlight": "^7.22.5"
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
},
"engines": {
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/code-frame/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/@babel/compat-data": {
"version": "7.22.9",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
@@ -156,11 +221,11 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.21.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz",
- "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
"dependencies": {
- "@babel/types": "^7.21.5",
+ "@babel/types": "^7.23.0",
"@jridgewell/gen-mapping": "^0.3.2",
"@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
@@ -188,20 +253,20 @@
}
},
"node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
- "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-function-name": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
- "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
"dependencies": {
- "@babel/template": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
},
"engines": {
"node": ">=6.9.0"
@@ -286,9 +351,9 @@
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
- "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"engines": {
"node": ">=6.9.0"
}
@@ -315,12 +380,12 @@
}
},
"node_modules/@babel/highlight": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz",
- "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.22.5",
- "chalk": "^2.0.0",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
"js-tokens": "^4.0.0"
},
"engines": {
@@ -392,9 +457,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.22.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz",
- "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -442,31 +507,31 @@
}
},
"node_modules/@babel/template": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz",
- "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"dependencies": {
- "@babel/code-frame": "^7.22.5",
- "@babel/parser": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.21.5",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz",
- "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==",
- "dependencies": {
- "@babel/code-frame": "^7.21.4",
- "@babel/generator": "^7.21.5",
- "@babel/helper-environment-visitor": "^7.21.5",
- "@babel/helper-function-name": "^7.21.0",
- "@babel/helper-hoist-variables": "^7.18.6",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.21.5",
- "@babel/types": "^7.21.5",
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -475,12 +540,12 @@
}
},
"node_modules/@babel/types": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz",
- "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
"dependencies": {
"@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
},
"engines": {
@@ -8062,11 +8127,63 @@
}
},
"@babel/code-frame": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz",
- "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==",
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
"requires": {
- "@babel/highlight": "^7.22.5"
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
}
},
"@babel/compat-data": {
@@ -8097,11 +8214,11 @@
}
},
"@babel/generator": {
- "version": "7.21.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.5.tgz",
- "integrity": "sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
"requires": {
- "@babel/types": "^7.21.5",
+ "@babel/types": "^7.23.0",
"@jridgewell/gen-mapping": "^0.3.2",
"@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
@@ -8120,17 +8237,17 @@
}
},
"@babel/helper-environment-visitor": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
- "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q=="
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA=="
},
"@babel/helper-function-name": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
- "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
"requires": {
- "@babel/template": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
}
},
"@babel/helper-hoist-variables": {
@@ -8188,9 +8305,9 @@
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw=="
},
"@babel/helper-validator-identifier": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
- "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ=="
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A=="
},
"@babel/helper-validator-option": {
"version": "7.22.5",
@@ -8208,12 +8325,12 @@
}
},
"@babel/highlight": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz",
- "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
"requires": {
- "@babel/helper-validator-identifier": "^7.22.5",
- "chalk": "^2.0.0",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
"js-tokens": "^4.0.0"
},
"dependencies": {
@@ -8269,9 +8386,9 @@
}
},
"@babel/parser": {
- "version": "7.22.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz",
- "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q=="
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw=="
},
"@babel/plugin-transform-react-jsx-self": {
"version": "7.21.0",
@@ -8298,39 +8415,39 @@
}
},
"@babel/template": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz",
- "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"requires": {
- "@babel/code-frame": "^7.22.5",
- "@babel/parser": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
}
},
"@babel/traverse": {
- "version": "7.21.5",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.5.tgz",
- "integrity": "sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==",
- "requires": {
- "@babel/code-frame": "^7.21.4",
- "@babel/generator": "^7.21.5",
- "@babel/helper-environment-visitor": "^7.21.5",
- "@babel/helper-function-name": "^7.21.0",
- "@babel/helper-hoist-variables": "^7.18.6",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.21.5",
- "@babel/types": "^7.21.5",
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "requires": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz",
- "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
"requires": {
"@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
}
},
diff --git a/src/components/InteractiveTutorial/InteractiveTutorial.jsx b/src/components/InteractiveTutorial/InteractiveTutorial.jsx
index 43e3bcd9..922a5db3 100644
--- a/src/components/InteractiveTutorial/InteractiveTutorial.jsx
+++ b/src/components/InteractiveTutorial/InteractiveTutorial.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import Box from '@mui/material/Box';
import { alpha } from '@mui/material';
@@ -9,10 +9,27 @@ import { mdxComponents } from './MdxComponents/MdxComponents';
import { useTutorial } from '../../context/tutorial-context';
import { TutorialFooter } from './TutorialFooter';
import { tutorialSubPages, tutorialIndexPage } from './TutorialSubpages';
+import { useLocation } from 'react-router-dom';
+import { Prism } from 'prism-react-renderer';
const InteractiveTutorial = ({ pageSlug }) => {
const theme = useTheme();
const { result } = useTutorial();
+ const location = useLocation();
+ const tutorialPanelRef = React.useRef(null);
+
+ useEffect(() => {
+ // we need this to use prismjs support for json highlighting
+ // which is not included in the prism-react-renderer package by default
+ window.Prism = Prism; // (or check for window is undefined for ssr and use global)
+ (async () => await import('prismjs/components/prism-json'))();
+ }, []);
+
+ useEffect(() => {
+ if (tutorialPanelRef.current) {
+ tutorialPanelRef.current.scrollTop = 0;
+ }
+ }, [location]);
let TagName;
try {
@@ -36,6 +53,7 @@ const InteractiveTutorial = ({ pageSlug }) => {
bottom: 0,
overflowY: 'scroll',
}}
+ ref={tutorialPanelRef}
>
diff --git a/src/components/InteractiveTutorial/MdxComponents/CodeBlock.jsx b/src/components/InteractiveTutorial/MdxComponents/CodeBlock.jsx
index 9181b32a..2f22927b 100644
--- a/src/components/InteractiveTutorial/MdxComponents/CodeBlock.jsx
+++ b/src/components/InteractiveTutorial/MdxComponents/CodeBlock.jsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from 'react';
+import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Highlight, Prism, themes } from 'prism-react-renderer';
import Editor from 'react-simple-code-editor';
@@ -30,6 +30,7 @@ const StyledEditor = styled((props) => {
const { setResult } = useTutorial();
const handleClick = () => {
+ setResult('{}');
requestFromCode(code, false)
.then((res) => {
setResult(() => JSON.stringify(res));
@@ -64,13 +65,6 @@ export const CodeBlock = ({ children }) => {
const prismTheme = theme.palette.mode === 'light' ? themes.nightOwlLight : themes.vsDark;
const backgroundColor = theme.palette.mode === 'light' ? LIGHT_BACKGROUND : DARK_BACKGROUND;
- useEffect(() => {
- // we need this to use prismjs support for json highlighting
- // which is not included in the prism-react-renderer package by default
- window.Prism = Prism; // (or check for window is undefined for ssr and use global)
- (async () => await import('prismjs/components/prism-json'))();
- }, []);
-
const handleChange = (code) => {
setCode(() => code);
};
diff --git a/src/components/InteractiveTutorial/MdxPages/Another.mdx b/src/components/InteractiveTutorial/MdxPages/Another.mdx
deleted file mode 100644
index 6b9f6061..00000000
--- a/src/components/InteractiveTutorial/MdxPages/Another.mdx
+++ /dev/null
@@ -1,15 +0,0 @@
-export const title = "Another Page"
-
-# {title}
-
-Rename this file and edit it to create another page.
-
-```json withRunButton=true
-PUT collections/test_collection2
-{
- "vectors": {
- "size": 4,
- "distance": "Dot"
- }
-}
-```
diff --git a/src/components/InteractiveTutorial/MdxPages/FilteringClauses.mdx b/src/components/InteractiveTutorial/MdxPages/FilteringClauses.mdx
new file mode 100644
index 00000000..0867b210
--- /dev/null
+++ b/src/components/InteractiveTutorial/MdxPages/FilteringClauses.mdx
@@ -0,0 +1,192 @@
+export const title = "Filtering Clauses"
+
+# {title}
+
+Click **RUN** button at code blocks to see a result of the query in the right part of the screen.
Click inside a code block to edit it.
+
+
+Qdrant support filtering of collections combining condition and clauses.
+In this tutorial you will learn how to filter collections using **filtering clauses**.
+
+Clauses are different logical operations, such as OR, AND, and NOT.
+Clauses can be recursively nested into each other so that you can reproduce an arbitrary boolean expression.
+
+Let's start with creating a new collection and populating it with points.
+
+## Set up for this tutorial
+
+Before we start to practice with filtering conditions, let's create some datapoints to work with.
+
+
+ Run these two steps:
+
+1. Create a collection:
+
+``` json withRunButton="true"
+PUT collections/demo
+{
+ "vectors": {
+ "size": 4,
+ "distance": "Dot"
+ }
+}
+```
+
+2. And add points to it:
+
+``` json withRunButton="true"
+PUT /collections/demo/points
+{
+ "points": [
+ {
+ "id": 1,
+ "vector": [0.1, 0.2, 0.3, 0.4],
+ "payload": { "city": "London", "color": "green" }
+ }, {
+ "id": 2,
+ "vector": [0.2, 0.3, 0.4, 0.5],
+ "payload": { "city": "London", "color": "red" }
+ }, {
+ "id": 3,
+ "vector": [0.3, 0.4, 0.5, 0.6],
+ "payload": { "city": "London", "color": "blue" }
+ }, {
+ "id": 4,
+ "vector": [0.4, 0.5, 0.6, 0.7],
+ "payload": { "city": "Berlin", "color": "red" }
+ }, {
+ "id": 5,
+ "vector": [0.5, 0.6, 0.7, 0.8],
+ "payload": { "city": "Moscow", "color": "green" }
+ }, {
+ "id": 6,
+ "vector": [0.6, 0.7, 0.8, 0.9],
+ "payload": { "city": "Moscow", "color": "blue" }
+ }
+ ]
+}
+```
+
+
+Take a note of what data we put into points' `payload` field.
+
+## Must
+
+When using `must`, the clause becomes `true` only if every condition listed inside `must` is satisfied.
+In this sense, `must` is equivalent to the operator `AND`.
+
+Run the next example:
+
+``` json withRunButton="true"
+POST /collections/demo/points/scroll
+{
+ "filter": {
+ "must": [
+ {
+ "key": "city",
+ "match": { "value": "London" }
+ }, {
+ "key": "color",
+ "match": { "value": "red" }
+ }
+ ]
+ }
+}
+```
+
+## Should
+
+When using `should`, the clause becomes `true` if at least one condition listed inside `should` is satisfied.
+In this sense, `should` is equivalent to the operator `OR`.
+
+Example:
+
+``` json withRunButton="true"
+POST /collections/demo/points/scroll
+{
+ "filter": {
+ "should": [
+ {
+ "key": "city",
+ "match": { "value": "London" }
+ }, {
+ "key": "color",
+ "match": { "value": "red" }
+ }
+ ]
+ }
+}
+```
+
+## Must Not
+
+When using `must_not`, the clause becomes `true` if none if the conditions listed inside `should` is satisfied.
+In this sense, `must_not` is equivalent to the expression `(NOT A) AND (NOT B) AND (NOT C)`.
+
+Example:
+
+``` json withRunButton="true"
+POST /collections/demo/points/scroll
+{
+ "filter": {
+ "must_not": [
+ {
+ "key": "city",
+ "match": { "value": "London" }
+ }, {
+ "key": "color",
+ "match": { "value": "red" }
+ }
+ ]
+ }
+}
+```
+
+## Clauses combination
+
+It is also possible to use several clauses simultaneously:
+
+``` json withRunButton="true"
+POST /collections/demo/points/scroll
+{
+ "filter": {
+ "must": [
+ {
+ "key": "city",
+ "match": { "value": "London" }
+ }
+ ],
+ "must_not": [
+ {
+ "key": "color",
+ "match": { "value": "red" }
+ }
+ ]
+ }
+}
+```
+
+In this case, the conditions are combined by `AND`.
+
+Also, the conditions could be recursively nested. Example:
+
+``` json withRunButton="true"
+POST /collections/demo/points/scroll
+{
+ "filter": {
+ "must_not": [
+ {
+ "must": [
+ {
+ "key": "city",
+ "match": { "value": "London" }
+ }, {
+ "key": "color",
+ "match": { "value": "red" }
+ }
+ ]
+ }
+ ]
+ }
+}
+```
diff --git a/src/components/InteractiveTutorial/MdxPages/Index.mdx b/src/components/InteractiveTutorial/MdxPages/Index.mdx
index 714a4593..62ef35cf 100644
--- a/src/components/InteractiveTutorial/MdxPages/Index.mdx
+++ b/src/components/InteractiveTutorial/MdxPages/Index.mdx
@@ -1,115 +1,26 @@
-
- **Table of Contents**
-- [Introduction](#/tutorial/another-page)
-- [Installation](#/tutorial/other)
-
-
-
# Interactive Tutorial
-In this short example, you will create a Collection, load data into it and run a basic search query.
-
-Click RUN button at code blocks to see a result of the query in the right part of the screen.
-
-## Create a collection
-
-You will be storing all of your vector data in a Qdrant collection. Let's call it `test_collection`. This collection will be using a dot product distance metric to compare vectors.
-
-```json withRunButton=true
-PUT collections/test_collection
-{
- "vectors": {
- "size": 4,
- "distance": "Dot"
- }
-}
-```
-
-## Add vectors
+## How to run Qdrant?
-Let's now add a few vectors with a payload. Payloads are other data you want to associate with the vector:
+If you are reading this, you probably already have Qdrant running!
+All the examples in this tutorial do not require any additional setup from your side.
-```json withRunButton=true
-PUT collections/test_collection/points
-{
- "points": [
- {
- "id": 1,
- "vector": [0.05, 0.61, 0.76, 0.74],
- "payload": {"city": "Berlin"}
- },
- {
- "id": 2,
- "vector": [0.19, 0.81, 0.75, 0.11],
- "payload": {"city": "London"}
- },
- {
- "id": 3,
- "vector": [0.36, 0.55, 0.47, 0.94],
- "payload": {"city": "Moscow"}
- },
- {
- "id": 4,
- "vector": [0.18, 0.01, 0.85, 0.80],
- "payload": {"city": "New York"}
- },
- {
- "id": 5,
- "vector": [0.24, 0.18, 0.22, 0.44],
- "payload": {"city": "Beijing"}
- },
- {
- "id": 6,
- "vector": [0.35, 0.08, 0.11, 0.44],
- "payload": {"city": "Mumbai"}
- }
- ]
-}
-```
+This tutorial will demonstrate principles of Qdrant API, which you would be able to reproduce in
+Qdrant UI or in Qdrant client for your [favorite programming language](https://qdrant.tech/documentation/interfaces/).
-## Run a query
+## What is a interactive tutorial?
-Let's ask a basic question - Which of our stored vectors are most similar to the query vector `[0.2, 0.1, 0.9, 0.7]`?
+In this tutorial, we will guide you through Qdrant API step by step.
+You will explore the main features and learn core concepts of Qdrant on an interactive examples.
-```json withRunButton=true
-POST collections/test_collection/points/search
-{
- "vector": [0.2, 0.1, 0.9, 0.7],
- "limit": 3
-}
-```
+You will be able to run the code blocks in this tutorial and see the results in real-time.
+You also can edit the code blocks and see how the results change.
-The results are returned in decreasing similarity order. Note that payload and vector data is missing in these results by default.
-See [payload and vector in the result](https://qdrant.tech/documentation/concepts/search#payload-and-vector-in-the-result) on how to enable it.
-## Add a filter
-
-We can narrow down the results further by filtering by payload. Let's find the closest results that include "London".
-
-```json withRunButton=true
-POST collections/test_collection/points/search
-{
- "vector": [0.2, 0.1, 0.9, 0.7],
- "filter": {
- "must": [
- {
- "key": "city",
- "match": {
- "value": "London"
- }
- }
- ]
- },
- "limit": 3
-}
-```
-
-You have just conducted vector search. You loaded vectors into a database and queried the database with a vector of your own. Qdrant found the closest results and presented you with a similarity score.
-
-## Next steps
-
-Now you know how Qdrant works. Getting started with [Qdrant Cloud](https://qdrant.tech/documentation/cloud/quickstart-cloud/) is just as easy. [Create an account](https://qdrant.to/cloud) and use our SaaS completely free. We will take care of infrastructure maintenance and software updates.
-
-To move onto some more complex examples of vector search, read our [Tutorials](https://qdrant.tech/documentation/tutorials/) and create your own app with the help of our [Examples](https://qdrant.tech/documentation/examples/).
+
+ **Table of Contents**
+ - [Quickstart](#/tutorial/quickstart)
+ - [Filtering Clauses](#/tutorial/filtering-clauses)
+
+
-**Note:** There is another way of running Qdrant locally. If you are a Python developer, we recommend that you try Local Mode in [Qdrant Client](https://github.com/qdrant/qdrant-client), as it only takes a few moments to get setup.
diff --git a/src/components/InteractiveTutorial/MdxPages/Other.mdx b/src/components/InteractiveTutorial/MdxPages/Other.mdx
deleted file mode 100644
index 7218714d..00000000
--- a/src/components/InteractiveTutorial/MdxPages/Other.mdx
+++ /dev/null
@@ -1,7 +0,0 @@
-export const title = "Something Other"
-
-# {title}
-
-Rename this file and edit it to create another page.
-
-This is success, you read everything!
diff --git a/src/components/InteractiveTutorial/MdxPages/Quickstart.mdx b/src/components/InteractiveTutorial/MdxPages/Quickstart.mdx
new file mode 100644
index 00000000..2e62b136
--- /dev/null
+++ b/src/components/InteractiveTutorial/MdxPages/Quickstart.mdx
@@ -0,0 +1,106 @@
+export const title = 'Quickstart';
+
+# {title}
+
+In this short example, you will create a Collection, load data into it and run a basic search query.
+
+Click **RUN** button at code blocks to see a result of the query in the right part of the screen.
Click inside a code block to edit it.
+
+## Create a collection
+
+You will be storing all of your vector data in a Qdrant collection. Let's call it `test_collection`. This collection will be using a dot product distance metric to compare vectors.
+
+```json withRunButton=true
+PUT collections/test_collection
+{
+ "vectors": {
+ "size": 4,
+ "distance": "Dot"
+ }
+}
+```
+
+## Add vectors
+
+Let's now add a few vectors with a payload. Payloads are other data you want to associate with the vector:
+
+```json withRunButton=true
+PUT collections/test_collection/points
+{
+ "points": [
+ {
+ "id": 1,
+ "vector": [0.05, 0.61, 0.76, 0.74],
+ "payload": {"city": "Berlin"}
+ },
+ {
+ "id": 2,
+ "vector": [0.19, 0.81, 0.75, 0.11],
+ "payload": {"city": "London"}
+ },
+ {
+ "id": 3,
+ "vector": [0.36, 0.55, 0.47, 0.94],
+ "payload": {"city": "Moscow"}
+ },
+ {
+ "id": 4,
+ "vector": [0.18, 0.01, 0.85, 0.80],
+ "payload": {"city": "New York"}
+ },
+ {
+ "id": 5,
+ "vector": [0.24, 0.18, 0.22, 0.44],
+ "payload": {"city": "Beijing"}
+ },
+ {
+ "id": 6,
+ "vector": [0.35, 0.08, 0.11, 0.44],
+ "payload": {"city": "Mumbai"}
+ }
+ ]
+}
+```
+
+## Run a query
+
+Let's ask a basic question - Which of our stored vectors are most similar to the query vector `[0.2, 0.1, 0.9, 0.7]`?
+
+```json withRunButton=true
+POST collections/test_collection/points/search
+{
+ "vector": [0.2, 0.1, 0.9, 0.7],
+ "limit": 3,
+ "with_payload": true
+}
+```
+
+The results are returned in decreasing similarity order. Note that payload and vector data is missing in these results by default.
+See [payload and vector in the result](https://qdrant.tech/documentation/concepts/search#payload-and-vector-in-the-result) on how to enable it.
+
+## Add a filter
+
+We can narrow down the results further by filtering by payload. Let's find the closest results that include "London".
+
+```json withRunButton=true
+POST collections/test_collection/points/search
+{
+ "vector": [0.2, 0.1, 0.9, 0.7],
+ "filter": {
+ "must": [
+ {
+ "key": "city",
+ "match": { "value": "London" }
+ }
+ ]
+ },
+ "limit": 3,
+ "with_payload": true
+}
+```
+
+You have just conducted vector search. You loaded vectors into a database and queried the database with a vector of your own. Qdrant found the closest results and presented you with a similarity score.
+
+## Next steps
+
+In the next section, you will learn how to create complex filter conditions and how to use them in your queries.
\ No newline at end of file
diff --git a/src/components/InteractiveTutorial/TutorialSubpages.jsx b/src/components/InteractiveTutorial/TutorialSubpages.jsx
index bd3e7003..4f60466c 100644
--- a/src/components/InteractiveTutorial/TutorialSubpages.jsx
+++ b/src/components/InteractiveTutorial/TutorialSubpages.jsx
@@ -1,6 +1,6 @@
-import * as Another from './MdxPages/Another.mdx';
-import * as Other from './MdxPages/Other.mdx';
import * as Index from './MdxPages/Index.mdx';
+import * as Quickstart from './MdxPages/Quickstart.mdx';
+import * as FilteringClauses from './MdxPages/FilteringClauses.mdx';
/**
* MDX page object (Index etc.) contains:
@@ -11,8 +11,9 @@ import * as Index from './MdxPages/Index.mdx';
export const tutorialIndexPage = Index;
const tutorialSubPages = [
- ['another-page', Another],
- ['other', Other],
+ ['quickstart', Quickstart],
+ ['filtering-clauses', FilteringClauses],
+ // add more pages here
];
export { tutorialSubPages };
diff --git a/src/components/Sidebar/Sidebar.jsx b/src/components/Sidebar/Sidebar.jsx
index 6f6f59cd..8a0024be 100644
--- a/src/components/Sidebar/Sidebar.jsx
+++ b/src/components/Sidebar/Sidebar.jsx
@@ -6,7 +6,7 @@ import { List, Typography, Divider, ListItem, ListItemButton, ListItemIcon, List
import { Link } from 'react-router-dom';
import { LibraryBooks, Terminal } from '@mui/icons-material';
import Tooltip from '@mui/material/Tooltip';
-// import SidebarTutorialSection from './SidebarTutorialSection';
+import SidebarTutorialSection from './SidebarTutorialSection';
const drawerWidth = 240;
@@ -111,10 +111,9 @@ export default function Sidebar({ open, version }) {
- {/* todo: uncomment when tutorial is ready*/}
- {/* */}
- {/* */}
- {/* */}
+
+
+
diff --git a/src/components/Sidebar/SidebarTutorialSection.jsx b/src/components/Sidebar/SidebarTutorialSection.jsx
index 9a0a6336..47da55b1 100644
--- a/src/components/Sidebar/SidebarTutorialSection.jsx
+++ b/src/components/Sidebar/SidebarTutorialSection.jsx
@@ -10,7 +10,7 @@ const TutorialsList = tutorialSubPages.map((page) => {
const [slug, pageObject] = page;
return (
-
+