diff --git a/package.json b/package.json index 850e805a..103b7723 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,13 @@ "@iconify/vue": "^5.0.0", "@shikijs/langs": "^4.0.2", "@shikijs/themes": "^4.0.2", + "@types/three": "^0.183.1", "@unhead/vue": "^2.1.12", "@vueuse/core": "^14.2.1", "html-to-image": "^1.11.13", "pinia": "^3.0.4", "shiki": "^4.0.2", + "three": "^0.183.2", "vue": "^3.5.30", "vue-router": "^5.0.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a1f49aa..942204dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: '@shikijs/themes': specifier: ^4.0.2 version: 4.0.2 + '@types/three': + specifier: ^0.183.1 + version: 0.183.1 '@unhead/vue': specifier: ^2.1.12 version: 2.1.12(vue@3.5.30(typescript@5.9.3)) @@ -32,6 +35,9 @@ importers: shiki: specifier: ^4.0.2 version: 4.0.2 + three: + specifier: ^0.183.2 + version: 0.183.2 vue: specifier: ^3.5.30 version: 3.5.30(typescript@5.9.3) @@ -401,6 +407,9 @@ packages: resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} engines: {node: '>=20.19.0'} + '@dimforge/rapier3d-compat@0.12.0': + resolution: {integrity: sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==} + '@emnapi/runtime@1.8.1': resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} @@ -1342,6 +1351,9 @@ packages: '@tsconfig/node24@24.0.4': resolution: {integrity: sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA==} + '@tweenjs/tween.js@23.1.3': + resolution: {integrity: sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==} + '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -1369,6 +1381,12 @@ packages: '@types/node@24.11.0': resolution: {integrity: sha512-fPxQqz4VTgPI/IQ+lj9r0h+fDR66bzoeMGHp8ASee+32OSGIkeASsoZuJixsQoVef1QJbeubcPBxKk22QVoWdw==} + '@types/stats.js@0.17.4': + resolution: {integrity: sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==} + + '@types/three@0.183.1': + resolution: {integrity: sha512-f2Pu5Hrepfgavttdye3PsH5RWyY/AvdZQwIVhrc4uNtvF7nOWJacQKcoVJn0S4f0yYbmAE6AR+ve7xDcuYtMGw==} + '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} @@ -1378,6 +1396,9 @@ packages: '@types/web-bluetooth@0.0.21': resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + '@types/webxr@0.5.24': + resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==} + '@typescript-eslint/eslint-plugin@8.56.1': resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1642,6 +1663,9 @@ packages: peerDependencies: vue: ^3.5.0 + '@webgpu/types@0.1.69': + resolution: {integrity: sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==} + abbrev@2.0.0: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -2103,6 +2127,9 @@ packages: picomatch: optional: true + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -2512,6 +2539,9 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + meshoptimizer@1.0.1: + resolution: {integrity: sha512-Vix+QlA1YYT3FwmBBZ+49cE5y/b+pRrcXKqGpS5ouh33d3lSp2PoTpCw19E0cKDFWalembrHnIaZetf27a+W2g==} + micromark-util-character@2.1.1: resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} @@ -2943,6 +2973,9 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + three@0.183.2: + resolution: {integrity: sha512-di3BsL2FEQ1PA7Hcvn4fyJOlxRRgFYBpMTcyOgkwJIaDOdJMebEFPA+t98EvjuljDx4hNulAGwF6KIjtwI5jgQ==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -3686,6 +3719,8 @@ snapshots: '@csstools/css-tokenizer@4.0.0': {} + '@dimforge/rapier3d-compat@0.12.0': {} + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 @@ -4271,6 +4306,8 @@ snapshots: '@tsconfig/node24@24.0.4': {} + '@tweenjs/tween.js@23.1.3': {} + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 @@ -4303,12 +4340,26 @@ snapshots: dependencies: undici-types: 7.16.0 + '@types/stats.js@0.17.4': {} + + '@types/three@0.183.1': + dependencies: + '@dimforge/rapier3d-compat': 0.12.0 + '@tweenjs/tween.js': 23.1.3 + '@types/stats.js': 0.17.4 + '@types/webxr': 0.5.24 + '@webgpu/types': 0.1.69 + fflate: 0.8.2 + meshoptimizer: 1.0.1 + '@types/tough-cookie@4.0.5': {} '@types/unist@3.0.3': {} '@types/web-bluetooth@0.0.21': {} + '@types/webxr@0.5.24': {} + '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -4695,6 +4746,8 @@ snapshots: dependencies: vue: 3.5.30(typescript@5.9.3) + '@webgpu/types@0.1.69': {} + abbrev@2.0.0: {} acorn-jsx@5.3.2(acorn@8.16.0): @@ -5150,6 +5203,8 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fflate@0.8.2: {} + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -5533,6 +5588,8 @@ snapshots: merge2@1.4.1: {} + meshoptimizer@1.0.1: {} + micromark-util-character@2.1.1: dependencies: micromark-util-symbol: 2.0.1 @@ -6018,6 +6075,8 @@ snapshots: tapable@2.3.0: {} + three@0.183.2: {} + tinybench@2.9.0: {} tinyexec@1.0.2: {} diff --git a/src/views/geo-guess/index.vue b/src/views/geo-guess/index.vue new file mode 100644 index 00000000..014531c7 --- /dev/null +++ b/src/views/geo-guess/index.vue @@ -0,0 +1,1019 @@ + + + + + diff --git a/src/views/geo-guess/meta.ts b/src/views/geo-guess/meta.ts new file mode 100644 index 00000000..147aedc5 --- /dev/null +++ b/src/views/geo-guess/meta.ts @@ -0,0 +1,11 @@ +import type { PageMeta } from '@/types/page' + +const meta: PageMeta = { + name: 'GeoGuess VN - Đoán địa điểm Việt Nam', + description: + 'Đoán địa điểm Việt Nam qua ảnh 360° từ NDAMaps.vn — phiên bản GeoGuessr made in Vietnam!', + author: 'iBinh', + category: 'game', +} + +export default meta