diff --git a/package-lock.json b/package-lock.json index c5fe3122..1bcc36ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@abi-software/map-side-bar", - "version": "2.13.0", + "version": "2.13.0-acupoint.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@abi-software/map-side-bar", - "version": "2.13.0", + "version": "2.13.0-acupoint.7", "license": "Apache-2.0", "dependencies": { "@abi-software/gallery": "1.3.0", - "@abi-software/map-utilities": "1.7.7", + "@abi-software/map-utilities": "1.7.8-beta.3", "@abi-software/svg-sprite": "^1.0.2", "@element-plus/icons-vue": "^2.3.1", "algoliasearch": "^4.10.5", @@ -66,9 +66,9 @@ } }, "node_modules/@abi-software/map-utilities": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/@abi-software/map-utilities/-/map-utilities-1.7.7.tgz", - "integrity": "sha512-Sj7XGEakU0FC5XUKLxg4xX5D6FjCbiAWFSDxF8aET0PRhXpfJPTXcBNmJ2YQTJxLtYAkRnM5CAj+2EklFxzH7Q==", + "version": "1.7.8-beta.3", + "resolved": "https://registry.npmjs.org/@abi-software/map-utilities/-/map-utilities-1.7.8-beta.3.tgz", + "integrity": "sha512-kERUeci0eJwcHI3Z1xyE3ewsqr24AwUXPTVgH/z8pMO5nznG2G7Ct8XCEb1SdtJjUxbFEbOahYDe05j24Tm6Lw==", "dependencies": { "@abi-software/svg-sprite": "^1.0.1", "@element-plus/icons-vue": "^2.3.1", @@ -779,15 +779,19 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, - "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } @@ -823,9 +827,10 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, - "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -850,11 +855,13 @@ "license": "MIT" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -876,8 +883,10 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.3", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true }, "node_modules/@iconify-json/simple-icons": { "version": "1.2.26", @@ -1011,30 +1020,331 @@ } } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.5", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ] }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.5", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@shikijs/core": { "version": "2.5.0", "dev": true, @@ -1107,8 +1417,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.6", - "license": "MIT" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" }, "node_modules/@types/hast": { "version": "3.0.4", @@ -1539,9 +1850,10 @@ } }, "node_modules/ajv": { - "version": "6.12.6", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2177,7 +2489,9 @@ } }, "node_modules/ci-info": { - "version": "3.9.0", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -2185,7 +2499,6 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], - "license": "MIT", "engines": { "node": ">=8" } @@ -2414,12 +2727,13 @@ "license": "MIT" }, "node_modules/cypress": { - "version": "13.13.0", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.17.0.tgz", + "integrity": "sha512-5xWkaPurwkIljojFidhw8lFScyxhtiFHl/i/3zov+1Z5CmY4t9tjIdvSXfu82Y3w7wt0uR9KkucbhkVvJZLQSA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "dependencies": { - "@cypress/request": "^3.0.0", + "@cypress/request": "^3.0.6", "@cypress/xvfb": "^1.2.4", "@types/sinonjs__fake-timers": "8.1.1", "@types/sizzle": "^2.3.2", @@ -2430,6 +2744,7 @@ "cachedir": "^2.3.0", "chalk": "^4.1.0", "check-more-types": "^2.24.0", + "ci-info": "^4.0.0", "cli-cursor": "^3.1.0", "cli-table3": "~0.6.1", "commander": "^6.2.1", @@ -2444,7 +2759,6 @@ "figures": "^3.2.0", "fs-extra": "^9.1.0", "getos": "^3.2.1", - "is-ci": "^3.0.1", "is-installed-globally": "~0.4.0", "lazy-ass": "^1.6.0", "listr2": "^3.8.3", @@ -2459,6 +2773,7 @@ "semver": "^7.5.3", "supports-color": "^8.1.1", "tmp": "~0.2.3", + "tree-kill": "1.2.2", "untildify": "^4.0.0", "yauzl": "^2.10.0" }, @@ -2885,15 +3200,17 @@ } }, "node_modules/eslint": { - "version": "8.57.0", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -2939,24 +3256,25 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "9.24.0", + "version": "9.33.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.33.0.tgz", + "integrity": "sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "globals": "^13.24.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.15", - "semver": "^7.6.0", - "vue-eslint-parser": "^9.4.2", + "semver": "^7.6.3", + "vue-eslint-parser": "^9.4.3", "xml-name-validator": "^4.0.0" }, "engines": { "node": "^14.17.0 || >=16.0.0" }, "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/eslint-scope": { @@ -3266,9 +3584,10 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "dev": true, - "license": "ISC" + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", + "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "dev": true }, "node_modules/focus-trap": { "version": "7.6.4", @@ -3721,9 +4040,10 @@ } }, "node_modules/immutable": { - "version": "4.3.5", - "dev": true, - "license": "MIT" + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.8.tgz", + "integrity": "sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw==", + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -3788,17 +4108,6 @@ "node": ">=8" } }, - "node_modules/is-ci": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/is-core-module": { "version": "2.13.1", "license": "MIT", @@ -4280,17 +4589,6 @@ "loose-envify": "cli.js" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/magic-string": { "version": "0.30.17", "license": "MIT", @@ -4479,9 +4777,10 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4582,9 +4881,10 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dev": true, - "license": "ISC", "peer": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -5422,11 +5722,12 @@ } }, "node_modules/rollup": { - "version": "4.22.5", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "devOptional": true, - "license": "MIT", "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -5436,22 +5737,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.5", - "@rollup/rollup-android-arm64": "4.22.5", - "@rollup/rollup-darwin-arm64": "4.22.5", - "@rollup/rollup-darwin-x64": "4.22.5", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.5", - "@rollup/rollup-linux-arm-musleabihf": "4.22.5", - "@rollup/rollup-linux-arm64-gnu": "4.22.5", - "@rollup/rollup-linux-arm64-musl": "4.22.5", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.5", - "@rollup/rollup-linux-riscv64-gnu": "4.22.5", - "@rollup/rollup-linux-s390x-gnu": "4.22.5", - "@rollup/rollup-linux-x64-gnu": "4.22.5", - "@rollup/rollup-linux-x64-musl": "4.22.5", - "@rollup/rollup-win32-arm64-msvc": "4.22.5", - "@rollup/rollup-win32-ia32-msvc": "4.22.5", - "@rollup/rollup-win32-x64-msvc": "4.22.5", + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" } }, @@ -5532,12 +5842,10 @@ "peer": true }, "node_modules/semver": { - "version": "7.6.0", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -6228,10 +6536,11 @@ } }, "node_modules/unplugin-vue-components/node_modules/minimatch": { - "version": "9.0.4", - "license": "ISC", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -6564,9 +6873,10 @@ } }, "node_modules/vue-eslint-parser": { - "version": "9.4.2", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.4", "eslint-scope": "^7.1.1", @@ -6713,11 +7023,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, "node_modules/yargs": { "version": "17.7.2", "dev": true, diff --git a/package.json b/package.json index 307f953f..b1fcb86a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@abi-software/map-side-bar", - "version": "2.13.0", + "version": "2.13.0-acupoint.7", "license": "Apache-2.0", "repository": { "type": "git", @@ -44,7 +44,7 @@ }, "dependencies": { "@abi-software/gallery": "1.3.0", - "@abi-software/map-utilities": "1.7.7", + "@abi-software/map-utilities": "1.7.8-beta.3", "@abi-software/svg-sprite": "^1.0.2", "@element-plus/icons-vue": "^2.3.1", "algoliasearch": "^4.10.5", diff --git a/src/App.vue b/src/App.vue index 3299be0d..c82fe1cb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -18,6 +18,7 @@ keyword search Get facets Create Data/Annotation + Search Acupoints Connectivity Search @@ -42,6 +48,7 @@ + + diff --git a/src/components/AcupointsInfoSearch.vue b/src/components/AcupointsInfoSearch.vue new file mode 100644 index 00000000..8d7d1663 --- /dev/null +++ b/src/components/AcupointsInfoSearch.vue @@ -0,0 +1,620 @@ + + + + + + + Search + + + + + + + + + + No results found - Please change your search / filter criteria. + + + + + + + + + diff --git a/src/components/SearchFilters.vue b/src/components/SearchFilters.vue index ec21d8b5..5a3a447e 100644 --- a/src/components/SearchFilters.vue +++ b/src/components/SearchFilters.vue @@ -105,10 +105,10 @@ trigger="hover" popper-class="filter-help-popover" > - + - + Within categories: OR example: {{ entry.helper.within }} @@ -362,7 +362,7 @@ export default { }) // trigger reactivity only once - Object.assign(this.options, processedOptions); + Object.assign(this.options, processedOptions) }, populateCascader: function () { if (this.entry.options) { @@ -542,6 +542,13 @@ export default { }) return count } + const found = facet.children.find((item) => { + return item.label === "Show all" + }) + if (found) { + return facet.children.length - 1 + } + return facet.children.length }, /** diff --git a/src/components/SideBar.vue b/src/components/SideBar.vue index 377bd0bc..7676052e 100644 --- a/src/components/SideBar.vue +++ b/src/components/SideBar.vue @@ -64,6 +64,15 @@ @connectivity-item-close="onConnectivityItemClose" /> + + + { + console.log("broken") + const acupointTabRef = this.getTabRef(undefined, 'acupoints', true); + acupointTabRef.openSearch(facets, query) + }) + }, openConnectivitySearch: function (facets, query) { this.drawerOpen = true; // Because refs are in v-for, nextTick is needed here @@ -294,9 +330,6 @@ export default { datasetExplorerTabRef.openSearch(facets, query); }) }, - /** - * Get the ref id of the tab by id and type. - */ getTabRef: function (id, type, switchTab = false) { const matchedTab = this.tabEntries.filter((tabEntry) => { return (id === undefined || tabEntry.id === id) && @@ -502,6 +535,11 @@ export default { // This should respect the information provided by the property tabEntries: function () { return this.tabs.filter((tab) => + (tab.type === "acupoints" && + ( + this.acupointsInfoList && + Object.keys(this.acupointsInfoList).length > 0 + )) || tab.type === "datasetExplorer" || tab.type === "connectivityExplorer" || ( @@ -564,6 +602,16 @@ export default { this.$emit('connectivity-source-change', payLoad); }) + // Emit acupoints clicked event + EventBus.on('acupoints-clicked', (payLoad) => { + this.$emit('acupoints-clicked', payLoad); + }) + + // Emit acupoints hovered event + EventBus.on('acupoints-hovered', (payLoad) => { + this.$emit('acupoints-hovered', payLoad); + }) + // Get available anatomy facets for the connectivity info EventBus.on('available-facets', (payLoad) => { this.availableAnatomyFacets = payLoad.find((facet) => facet.label === 'Anatomical Structure').children diff --git a/src/services/flatmapKnowledge.js b/src/services/flatmapKnowledge.js new file mode 100644 index 00000000..e5116292 --- /dev/null +++ b/src/services/flatmapKnowledge.js @@ -0,0 +1,94 @@ +async function getReferenceConnectivitiesFromStorage(resource) { + const flatmapKnowledgeRaw = sessionStorage.getItem('flatmap-knowledge'); + + if (flatmapKnowledgeRaw) { + const flatmapKnowledge = JSON.parse(flatmapKnowledgeRaw); + const dataWithRefs = flatmapKnowledge.filter((x) => x.references && x.references.length); + const foundData = dataWithRefs.filter((x) => x.references.includes(resource)); + + if (foundData.length) { + const featureIds = foundData.map((x) => x.id); + return featureIds; + } + } + return []; +} + +async function getReferenceConnectivitiesByAPI(mapImp, resource, flatmapQueries) { + const knowledgeSource = getKnowledgeSource(mapImp); + const sql = `select knowledge from knowledge + where source="${knowledgeSource}" and + knowledge like "%${resource}%" order by source desc`; + console.log(sql) + const response = await flatmapQueries.flatmapQuery(sql); + const mappedData = response.values.map((x) => x[0]); + const parsedData = mappedData.map((x) => JSON.parse(x)); + const featureIds = parsedData.map((x) => x.id); + return featureIds; +} + +function getKnowledgeSource(mapImp) { + let mapKnowledgeSource = ''; + if (mapImp.provenance?.connectivity) { + const sckanProvenance = mapImp.provenance.connectivity; + if ('knowledge-source' in sckanProvenance) { + mapKnowledgeSource = sckanProvenance['knowledge-source']; + } else if ('npo' in sckanProvenance) { + mapKnowledgeSource = `${sckanProvenance.npo.release}-npo`; + } + } + + return mapKnowledgeSource; +} + +function loadAndStoreKnowledge(mapImp, flatmapQueries) { + const knowledgeSource = getKnowledgeSource(mapImp); + const sql = `select knowledge from knowledge + where source="${knowledgeSource}" + order by source desc`; + const flatmapKnowledge = sessionStorage.getItem('flatmap-knowledge'); + + if (!flatmapKnowledge) { + flatmapQueries.flatmapQuery(sql).then((response) => { + const mappedData = response.values.map(x => x[0]); + const parsedData = mappedData.map(x => JSON.parse(x)); + sessionStorage.setItem('flatmap-knowledge', JSON.stringify(parsedData)); + updateFlatmapKnowledgeCache(); + }); + } +} + +function updateFlatmapKnowledgeCache() { + const CACHE_LIFETIME = 24 * 60 * 60 * 1000; // One day + const now = new Date(); + const expiry = now.getTime() + CACHE_LIFETIME; + + sessionStorage.setItem('flatmap-knowledge-expiry', expiry); +} + +function removeFlatmapKnowledgeCache() { + const keys = [ + 'flatmap-knowledge', + 'flatmap-knowledge-expiry', + ]; + keys.forEach((key) => { + sessionStorage.removeItem(key); + }); +} + +function refreshFlatmapKnowledgeCache() { + const expiry = sessionStorage.getItem('flatmap-knowledge-expiry'); + const now = new Date(); + + if (now.getTime() > expiry) { + removeFlatmapKnowledgeCache(); + } +} + +export { + getReferenceConnectivitiesFromStorage, + getReferenceConnectivitiesByAPI, + loadAndStoreKnowledge, + getKnowledgeSource, + refreshFlatmapKnowledgeCache, +} diff --git a/src/services/flatmapQueries.js b/src/services/flatmapQueries.js new file mode 100644 index 00000000..b343a043 --- /dev/null +++ b/src/services/flatmapQueries.js @@ -0,0 +1,498 @@ +/* eslint-disable no-alert, no-console */ +// remove duplicates by stringifying the objects +const removeDuplicates = function (arrayOfAnything) { + if (!arrayOfAnything) return [] + return [...new Set(arrayOfAnything.map((e) => JSON.stringify(e)))].map((e) => + JSON.parse(e) + ) +} + +const cachedLabels = {} +const cachedTaxonLabels = []; + +const findTaxonomyLabel = async function (flatmapAPI, taxonomy) { + if (cachedLabels && cachedLabels.hasOwnProperty(taxonomy)) { + return cachedLabels[taxonomy] + } + + return new Promise((resolve) => { + fetch(`${flatmapAPI}knowledge/label/${taxonomy}`, { + method: 'GET', + }) + .then((response) => response.json()) + .then((data) => { + let label = data.label + if (label === 'Mammalia') { + label = 'Mammalia not otherwise specified' + } + cachedLabels[taxonomy] = label + resolve(label) + }) + .catch((error) => { + console.error('Error:', error) + cachedLabels[taxonomy] = taxonomy + resolve(taxonomy) + }) + }) +} + +const findTaxonomyLabels = async function (mapImp, taxonomies) { + const intersectionTaxonomies = taxonomies.filter((taxonomy) => + cachedTaxonLabels.some((obj) => obj.taxon === taxonomy) + ); + + const foundCachedTaxonLabels = cachedTaxonLabels.filter((obj) => + intersectionTaxonomies.includes(obj.taxon) + ); + + const leftoverTaxonomies = taxonomies.filter((taxonomy) => + !intersectionTaxonomies.includes(taxonomy) + ); + + if (!leftoverTaxonomies.length) { + return foundCachedTaxonLabels; + } else { + const entityLabels = await mapImp.queryLabels(leftoverTaxonomies); + if (entityLabels.length) { + entityLabels.forEach((entityLabel) => { + let { entity: taxon, label } = entityLabel; + if (label === 'Mammalia') { + label = 'Mammalia not otherwise specified' + } + const item = { taxon, label }; + foundCachedTaxonLabels.push(item); + cachedTaxonLabels.push(item); + }); + return foundCachedTaxonLabels; + } + } +} + +const inArray = function (ar1, ar2) { + if (!ar1 || !ar2) return false + let as1 = JSON.stringify(ar1) + let as2 = JSON.stringify(ar2) + return as1.indexOf(as2) !== -1 +} + +let FlatmapQueries = function () { + this.initialise = function (flatmapApi) { + this.flatmapApi = flatmapApi + this.destinations = [] + this.origins = [] + this.components = [] + this.rawURLs = [] + this.controller = undefined + this.uberons = [] + this.lookUp = [] + } + + this.createTooltipData = async function (mapImp, eventData) { + let hyperlinks = [] + if ( + eventData.feature.hyperlinks && + eventData.feature.hyperlinks.length > 0 + ) { + hyperlinks = eventData.feature.hyperlinks + } else { + hyperlinks = this.rawURLs; + } + let taxonomyLabel = undefined + if (eventData.provenanceTaxonomy) { + taxonomyLabel = [] + const entityLabels = await findTaxonomyLabels(mapImp, eventData.provenanceTaxonomy); + if (entityLabels.length) { + entityLabels.forEach((entityLabel) => { + const { label } = entityLabel; + taxonomyLabel.push(label); + }); + } + } + + let tooltipData = { + destinations: this.destinations, + origins: this.origins, + components: this.components, + destinationsWithDatasets: this.destinationsWithDatasets, + originsWithDatasets: this.originsWithDatasets, + componentsWithDatasets: this.componentsWithDatasets, + title: eventData.label, + featureId: eventData.resource, + hyperlinks: hyperlinks, + provenanceTaxonomy: eventData.provenanceTaxonomy, + provenanceTaxonomyLabel: taxonomyLabel, + } + return tooltipData + } + + this.createComponentsLabelList = function (components, lookUp) { + let labelList = [] + components.forEach((n) => { + labelList.push(this.createLabelFromNeuralNode(n[0]), lookUp) + if (n.length === 2) { + labelList.push(this.createLabelFromNeuralNode(n[1]), lookUp) + } + }) + return labelList + } + + this.createLabelLookup = function (mapImp, uberons) { + return new Promise(async (resolve) => { + let uberonMap = {} + this.uberons = [] + const entityLabels = await findTaxonomyLabels(mapImp, uberons); + if (entityLabels.length) { + entityLabels.forEach((entityLabel) => { + const { taxon: entity, label } = entityLabel; + uberonMap[entity] = label; + this.uberons.push({ + id: entity, + name: label, + }) + }); + resolve(uberonMap) + } + }) + } + + this.buildConnectivitySqlStatement = function (keastIds) { + let sql = 'select knowledge from knowledge where entity in (' + if (keastIds.length === 1) { + sql += `'${keastIds[0]}')` + } else if (keastIds.length > 1) { + for (let i in keastIds) { + sql += `'${keastIds[i]}'${i >= keastIds.length - 1 ? ')' : ','} ` + } + } + return sql + } + + this.buildLabelSqlStatement = function (uberons) { + let sql = 'select entity, label from labels where entity in (' + if (uberons.length === 1) { + sql += `'${uberons[0]}')` + } else if (uberons.length > 1) { + for (let i in uberons) { + sql += `'${uberons[i]}'${i >= uberons.length - 1 ? ')' : ','} ` + } + } + return sql + } + + this.findAllIdsFromConnectivity = function (connectivity) { + let dnodes = connectivity.connectivity.flat() // get nodes from edgelist + let nodes = [...new Set(dnodes)] // remove duplicates + let found = [] + nodes.forEach((n) => { + if (Array.isArray(n)) { + found.push(n.flat()) + } else { + found.push(n) + } + }) + return [...new Set(found.flat())] + } + + this.flattenConntectivity = function (connectivity) { + let dnodes = connectivity.flat() // get nodes from edgelist + let nodes = [...new Set(dnodes)] // remove duplicates + let found = [] + nodes.forEach((n) => { + if (Array.isArray(n)) { + found.push(n.flat()) + } else { + found.push(n) + } + }) + return found.flat() + } + + this.findComponents = function (connectivity) { + let dnodes = connectivity.connectivity.flat() // get nodes from edgelist + let nodes = removeDuplicates(dnodes) + + let found = [] + let terminal = false + nodes.forEach((node) => { + terminal = false + // Check if the node is an destination or origin (note that they are labelled dendrite and axon as opposed to origin and destination) + if (inArray(connectivity.axons, node)) { + terminal = true + } + if (connectivity.somas && inArray(connectivity.somas, node)) { + terminal = true + } + if (inArray(connectivity.dendrites, node)) { + terminal = true + } + if (!terminal) { + found.push(node) + } + }) + + return found + } + + this.retrieveFlatmapKnowledgeForEvent = async function (mapImp, eventData) { + // check if there is an existing query + if (this.controller) this.controller.abort() + + // set up the abort controller + this.controller = new AbortController() + const signal = this.controller.signal + + const keastIds = eventData.resource + this.destinations = [] + this.origins = [] + this.components = [] + this.rawURLs = [] + if (!keastIds || keastIds.length == 0 || !keastIds[0]) return + + let prom1 = this.queryForConnectivityNew(mapImp, keastIds, signal) // This on returns a promise so dont need 'await' + let results = await Promise.all([prom1]) + return results + } + + this.queryForConnectivityNew = function (mapImp, keastIds, signal, processConnectivity=true) { + return new Promise((resolve) => { + mapImp.queryKnowledge(keastIds[0]) + .then((response) => { + if (this.checkConnectivityExists(response)) { + let connectivity = response; + if (processConnectivity) { + this.processConnectivity(mapImp, connectivity).then((processedConnectivity) => { + // response.references is publication urls + if (response.references) { + // with publications from both PubMed and Others + this.rawURLs = [...response.references]; + resolve(processedConnectivity) + } else { + // without publications + resolve(processedConnectivity) + } + }) + } + else resolve(connectivity) + } else { + resolve(false) + } + }) + .catch((error) => { + if (error.name === 'AbortError') { + // This error is from AbortController's abort method. + } else { + // console.error('Error:', error) + // TODO: to update after queryKnowledge method update + console.warn(`Unable to get the knowledge for the entity ${keastIds[0]}.`) + } + resolve(false) + }) + }) + } + + this.queryForConnectivity = function (mapImp, keastIds, signal, processConnectivity=true) { + const data = { sql: this.buildConnectivitySqlStatement(keastIds) } + const headers = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + ...(signal ? { signal: signal } : {}), // add signal to header if it exists + } + return new Promise((resolve) => { + fetch(`${this.flatmapApi}knowledge/query/`, headers) + .then((response) => response.json()) + .then((data) => { + if (this.connectivityExists(data)) { + let connectivity = JSON.parse(data.values[0][0]) + if (processConnectivity) { + this.processConnectivity(mapImp, connectivity).then((processedConnectivity) => { + resolve(processedConnectivity) + }) + } + else resolve(connectivity) + } else { + resolve(false) + } + }) + .catch((error) => { + if (error.name === 'AbortError') { + // This error is from AbortController's abort method. + } else { + console.error('Error:', error) + } + resolve(false) + }) + }) + } + + this.checkConnectivityExists = function (data) { + return data && data.connectivity?.length; + }; + + this.connectivityExists = function (data) { + if ( + data.values && + data.values.length > 0 && + JSON.parse(data.values[0][0]).connectivity && + JSON.parse(data.values[0][0]).connectivity.length > 0 + ) { + return true + } else { + return false + } + } + + // This function is used to determine if a node is a single node or a node with multiple children + // Returns the id of the node if it is a single node, otherwise returns false + this.findIfNodeIsSingle = function (node) { + if (node.length === 1) { // If the node is in the form [id] + console.error("Server returns a single node", node) + return node[0] + } else { + if (node.length === 2 && node[1].length === 0) { // If the node is in the form [id, []] + return node[0] + } else { + return false // If the node is in the form [id, [id1, id2]] + } + } + } + + this.createLabelFromNeuralNode = function (node, lookUp) { + + // Check if the node is a single node or a node with multiple children + let nodeIsSingle = this.findIfNodeIsSingle(node) + + // Case where node is in the form [id] + if (nodeIsSingle) { + return lookUp[nodeIsSingle] + } + + // Case where node is in the form [id, [id1 (,id2)]] + let label = lookUp[node[0]] + if (node.length === 2 && node[1].length > 0) { + node[1].forEach((n) => { + if (lookUp[n] == undefined) { + label += `, ${n}` + } else { + label += `, ${lookUp[n]}` + } + }) + } + return label + } + + this.flattenAndFindDatasets = function (components, axons, dendrites) { + // process the nodes for finding datasets (Note this is not critical to the tooltip, only for the 'search on components' button) + let componentsFlat = this.flattenConntectivity(components) + let axonsFlat = this.flattenConntectivity(axons) + let dendritesFlat = this.flattenConntectivity(dendrites) + + // Filter for the anatomy which is annotated on datasets + this.destinationsWithDatasets = this.uberons.filter( + (ub) => axonsFlat.indexOf(ub.id) !== -1 + ) + this.originsWithDatasets = this.uberons.filter( + (ub) => dendritesFlat.indexOf(ub.id) !== -1 + ) + this.componentsWithDatasets = this.uberons.filter( + (ub) => componentsFlat.indexOf(ub.id) !== -1 + ) + } + + this.processConnectivity = function (mapImp, connectivity) { + return new Promise((resolve) => { + // Filter the origin and destinations from components + let components = this.findComponents(connectivity) + + // Remove duplicates + let axons = removeDuplicates(connectivity.axons) + //Somas will become part of origins, support this for future proof + let dendrites = [] + if (connectivity.somas && connectivity.somas.length > 0) { + dendrites.push(...connectivity.somas) + } + if (connectivity.dendrites && connectivity.dendrites.length > 0) { + dendrites.push(...connectivity.dendrites) + } + dendrites = removeDuplicates(dendrites) + + // Create list of ids to get labels for + let conIds = this.findAllIdsFromConnectivity(connectivity) + + // Create readable labels from the nodes. Setting this to 'this.origins' updates the display + this.createLabelLookup(mapImp, conIds).then((lookUp) => { + this.destinations = axons.map((a) => + this.createLabelFromNeuralNode(a, lookUp) + ) + this.origins = dendrites.map((d) => + this.createLabelFromNeuralNode(d, lookUp) + ) + this.components = components.map((c) => + this.createLabelFromNeuralNode(c, lookUp) + ) + this.flattenAndFindDatasets(components, axons, dendrites) + resolve({ + ids: { + axons: axons, + dendrites: dendrites, + components: components, + }, + labels: { + destinations: this.destinations, + origins: this.origins, + components: this.components, + } + }) + }) + }) + } + + this.flattenConntectivity = function (connectivity) { + let dnodes = connectivity.flat() // get nodes from edgelist + let nodes = [...new Set(dnodes)] // remove duplicates + let found = [] + nodes.forEach((n) => { + if (Array.isArray(n)) { + found.push(n.flat()) + } else { + found.push(n) + } + }) + return found.flat() + } + + this.buildPubmedSqlStatement = function (keastIds) { + let sql = 'select distinct publication from publications where entity in (' + if (keastIds.length === 1) { + sql += `'${keastIds[0]}')` + } else if (keastIds.length > 1) { + for (let i in keastIds) { + sql += `'${keastIds[i]}'${i >= keastIds.length - 1 ? ')' : ','} ` + } + } + return sql + } + + this.buildPubmedSqlStatementForModels = function (model) { + return `select distinct publication from publications where entity = '${model}'` + } + + this.flatmapQuery = function (sql) { + const data = { sql: sql } + return fetch(`${this.flatmapApi}knowledge/query/`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }) + .then((response) => response.json()) + .catch((error) => { + console.error('Error:', error) + }) + } +} + +export { FlatmapQueries, findTaxonomyLabel, findTaxonomyLabels }