🎯 MapView v2.0 - Global Deployment Ready

 MAJOR FEATURES:
• Auto-zoom intelligence với smart bounds fitting
• Enhanced 3D GPS markers với pulsing effects
• Professional route display với 6-layer rendering
• Status-based parking icons với availability indicators
• Production-ready build optimizations

🗺️ AUTO-ZOOM FEATURES:
• Smart bounds fitting cho GPS + selected parking
• Adaptive padding (50px) cho visual balance
• Max zoom control (level 16) để tránh quá gần
• Dynamic centering khi không có selection

🎨 ENHANCED VISUALS:
• 3D GPS marker với multi-layer pulse effects
• Advanced parking icons với status colors
• Selection highlighting với animation
• Dimming system cho non-selected items

🛣️ ROUTE SYSTEM:
• OpenRouteService API integration
• Multi-layer route rendering (glow, shadow, main, animated)
• Real-time distance & duration calculation
• Visual route info trong popup

📱 PRODUCTION READY:
• SSR safe với dynamic imports
• Build errors resolved
• Global deployment via Vercel
• Optimized performance

🌍 DEPLOYMENT:
• Vercel: https://whatever-ctk2auuxr-phong12hexdockworks-projects.vercel.app
• Bundle size: 22.8 kB optimized
• Global CDN distribution
• HTTPS enabled

💾 VERSION CONTROL:
• MapView-v2.0.tsx backup created
• MAPVIEW_VERSIONS.md documentation
• Full version history tracking
This commit is contained in:
2025-07-20 19:52:16 +07:00
parent 3203463a6a
commit c65cc97a33
64624 changed files with 7199453 additions and 6462 deletions

View File

@@ -0,0 +1,82 @@
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.3.2](https://github.com/nuxt-contrib/opencollective/compare/v0.3.1...v0.3.2) (2020-10-13)
### Bug Fixes
* **pkg:** update main entry name ([e70d401](https://github.com/nuxt-contrib/opencollective/commit/e70d4016f883398629cacc671c7f5d61e18d5180))
### [0.3.1](https://github.com/nuxt-contrib/opencollective/compare/v0.3.0...v0.3.1) (2020-10-13)
<a name="0.3.0"></a>
# [0.3.0](https://github.com/nuxt-contrib/opencollective/compare/v0.2.2...v0.3.0) (2019-08-26)
### Bug Fixes
* build step ([af95080](https://github.com/nuxt-contrib/opencollective/commit/af95080))
### Features
* add opt out compatibility with `opencollective-postinstall` (closes [#7](https://github.com/nuxt-contrib/opencollective/issues/7)) ([#8](https://github.com/nuxt-contrib/opencollective/issues/8)) ([aed4a80](https://github.com/nuxt-contrib/opencollective/commit/aed4a80))
<a name="0.2.2"></a>
## [0.2.2](https://github.com/nuxt-contrib/opencollective/compare/v0.2.1...v0.2.2) (2019-04-02)
### Bug Fixes
* properly hide message ([#6](https://github.com/nuxt-contrib/opencollective/issues/6)) ([ed2efb0](https://github.com/nuxt-contrib/opencollective/commit/ed2efb0))
<a name="0.2.1"></a>
## [0.2.1](https://github.com/nuxt-contrib/opencollective/compare/v0.2.0...v0.2.1) (2018-12-12)
### Bug Fixes
* **bin:** force exit process ([#4](https://github.com/nuxt-contrib/opencollective/issues/4)) ([b5b0a81](https://github.com/nuxt-contrib/opencollective/commit/b5b0a81))
* gracefully handle network errors ([#3](https://github.com/nuxt-contrib/opencollective/issues/3)) ([04df30a](https://github.com/nuxt-contrib/opencollective/commit/04df30a))
<a name="0.2.0"></a>
# [0.2.0](https://github.com/nuxt-contrib/opencollective/compare/v0.1.0...v0.2.0) (2018-11-25)
### Bug Fixes
* **ci:** add build step ([d8e7314](https://github.com/nuxt-contrib/opencollective/commit/d8e7314))
### Features
* update consola and esm dependencies ([714ca65](https://github.com/nuxt-contrib/opencollective/commit/714ca65))
### Performance Improvements
* **pkg:** use CJS dist for smaller package and faster startup ([2ade457](https://github.com/nuxt-contrib/opencollective/commit/2ade457))
<a name="0.1.0"></a>
# 0.1.0 (2018-09-02)
### Bug Fixes
* legacy logo query ([c1b5b91](https://github.com/nuxt-contrib/opencollective/commit/c1b5b91))
* print donation text and url ([1d54f60](https://github.com/nuxt-contrib/opencollective/commit/1d54f60))
### Features
* make it work ([8d1cb6e](https://github.com/nuxt-contrib/opencollective/commit/8d1cb6e))

21
backend/node_modules/@nuxtjs/opencollective/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Nuxt Community
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

121
backend/node_modules/@nuxtjs/opencollective/README.md generated vendored Normal file
View File

@@ -0,0 +1,121 @@
# @nuxt/opencollective 🤝 Pretty opencollective stats on postinstall!
[![npm version][npm-v-src]][npm-v-href]
[![npm downloads][npm-d-src]][npm-d-href]
[![status][github-actions-src]][github-actions-href]
![Showcase](https://i.imgur.com/PZqyT3x.jpg)
>
[📖 **Release Notes**](./CHANGELOG.md)
## Features
Displaying **opencollective** statistics and a donation URL after users install a package
is important for many creators. After problems with current packages that offer similar
features, we decided to spin off our one own. Our key goals are:
* No interference/problems when installing packages. Never break installation because of the package
* Pretty output for all information
* Decent configurability
* Seamless drop-in for [common](https://github.com/opencollective/opencollective-cli) [solutions](https://github.com/opencollective/opencollective-postinstall)
## Setup
- Add `@nuxt/opencollective` dependency using yarn or npm to your project
- Add the script to `postinstall` in your package.json
```js
{
// ...
"scripts": {
"postinstall": "opencollective || exit 0"
},
"collective": {
"url": "https://opencollective.com/nuxtjs"
}
// ...
}
```
- Configure it
## Configuration
Configuration is applied through your project's `package.json`.
A full configuration looks like:
```json
{
"collective": {
"url": "https://opencollective.com/nuxtjs",
"logoUrl": "https://opencollective.com/nuxtjs/logo.txt?reverse=true&variant=variant2",
"donation": {
"slug": "/order/591",
"amount": "50",
"text": "Please donate:"
}
}
}
```
---
| Attribute | Optional | Default | Comment |
| --- | --- | --- | --- |
| url | ❌ | - | The URL to your opencollective page
| logo | ✅ | - | **LEGACY**: The URL to the logo that should be displayed. Please use `logoUrl` instead.
| logoUrl | ✅ | - | The URL to the ASCII-logo that should be displayed.
| donation.slug | ✅ | '/donate' | The slug that should be appended to `url`. Can be used to setup a specific order.
| donation.amount | ✅ | - | The default amount that should be selected on the opencollective page.
| donation.text | ✅ | 'Donate:' | The text that will be displayed before your donation url.
## Disable message
We know the postinstall messages can be annoying when deploying in
production or running a CI pipeline. That's why the message is
**disabled** in those environments by default.
**Enabled** when one the following environment variables is set:
* `NODE_ENV=dev`
* `NODE_ENV=development`
* `OPENCOLLECTIVE_FORCE`
**Strictly Disabled** when one the following environment variables is set:
- `OC_POSTINSTALL_TEST`
- `OPENCOLLECTIVE_HIDE`
- `CI`
- `CONTINUOUS_INTEGRATION`
- `NODE_ENV` (set and **not** `dev` or `development`)
- `DISABLE_OPENCOLLECTIVE` (set to any string value that is not `'false'` or `'0'`,
for compatability with
[opencollective-postinatall](https://github.com/opencollective/opencollective-postinstall))
## Development
- Clone this repository
- Install dependencies using `yarn install` or `npm install`
- Run it manually `path/to/project/root/src/index.js path/to/package/you/want/to/try`
- Run tests with `npm t` or `yarn test`
## Inspiration
This project is heavily inspired by [opencollective-cli](https://github.com/opencollective/opencollective-cli).
## License
[MIT License](./LICENSE)
MIT. Made with 💖
<!-- Refs -->
[npm-v-src]: https://img.shields.io/npm/v/@nuxt/opencollective?style=flat-square
[npm-v-href]: https://npmjs.com/package/@nuxt/opencollective
[npm-d-src]: https://img.shields.io/npm/dm/@nuxt/opencollective?style=flat-square
[npm-d-href]: https://npmjs.com/package/@nuxt/opencollective
[github-actions-src]: https://img.shields.io/github/workflow/status/nuxt-contrib/opencollective/ci/master?style=flat-square
[github-actions-href]: https://github.com/nuxt-contrib/opencollective/actions?query=workflow%3Aci

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env node
require('../dist/index.js')
.init(process.argv.length > 2 ? process.argv[2] : '.')
.then(() => process.exit(0))
.catch(() => process.exit(1))

View File

@@ -0,0 +1,448 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var fetch = require('node-fetch');
var child_process = require('child_process');
var chalk = require('chalk');
var consola = require('consola');
var path = require('path');
var fs = require('fs');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
var chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk);
var consola__default = /*#__PURE__*/_interopDefaultLegacy(consola);
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var reportAndThrowError = function reportAndThrowError(msg) {
report(msg);
throw new Error(msg);
};
var report = function report(message) {
consola__default['default'].debug({
message: String(message),
tag: 'opencollective'
});
};
var hideMessage = function hideMessage() {
var env = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : process.env;
// Show message if it is forced
if (env.OPENCOLLECTIVE_FORCE) {
return false;
} // Don't show after oracle postinstall
if (env.OC_POSTINSTALL_TEST) {
return true;
} // Don't show if opted-out
if (env.OPENCOLLECTIVE_HIDE) {
return true;
} // Compatability with opencollective-postinstall
if (!!env.DISABLE_OPENCOLLECTIVE && env.DISABLE_OPENCOLLECTIVE !== '0' && env.DISABLE_OPENCOLLECTIVE !== 'false') {
return true;
} // Don't show if on CI
if (env.CI || env.CONTINUOUS_INTEGRATION) {
return true;
} // Only show in dev environment
return Boolean(env.NODE_ENV) && !['dev', 'development'].includes(env.NODE_ENV);
};
var formatMoney = function formatMoney(currency) {
return function (amount) {
amount = amount / 100; // converting cents
var precision = 0;
return amount.toLocaleString(currency, {
style: 'currency',
currency: currency,
minimumFractionDigits: precision,
maximumFractionDigits: precision
});
};
};
var isWin32 = process.platform === 'win32';
var stripLeadingSlash = function stripLeadingSlash(s) {
return s.startsWith('/') ? s.substring(1) : s;
};
var stripTrailingSlash = function stripTrailingSlash(s) {
return s.endsWith('/') ? s.slice(0, -1) : s;
};
/* eslint-disable no-console */
var print = function print() {
var color = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
return function () {
var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var terminalCols = retrieveCols();
var strLength = str.replace(/\u001B\[[0-9]{2}m/g, '').length;
var leftPaddingLength = Math.floor((terminalCols - strLength) / 2);
var leftPadding = ' '.repeat(Math.max(leftPaddingLength, 0));
if (color) {
str = chalk__default['default'][color](str);
}
console.log(leftPadding, str);
};
};
var retrieveCols = function () {
var result = false;
return function () {
if (result) {
return result;
}
var defaultCols = 80;
try {
var terminalCols = child_process.execSync('tput cols', {
stdio: ['pipe', 'pipe', 'ignore']
});
result = parseInt(terminalCols.toString()) || defaultCols;
} catch (e) {
result = defaultCols;
}
return result;
};
}();
var printStats = function printStats(stats, color) {
if (!stats) {
return;
}
var colored = print(color);
var bold = print('bold');
var formatWithCurrency = formatMoney(stats.currency);
colored("Number of contributors: ".concat(stats.contributorsCount));
colored("Number of backers: ".concat(stats.backersCount));
colored("Annual budget: ".concat(formatWithCurrency(stats.yearlyIncome)));
bold("Current balance: ".concat(formatWithCurrency(stats.balance)), 'bold');
};
var printLogo = function printLogo(logoText) {
if (!logoText) {
return;
}
logoText.split('\n').forEach(print('blue'));
};
/**
* Only show emoji on OSx (Windows shell doesn't like them that much ¯\_(ツ)_/¯ )
* @param {*} emoji
*/
var emoji = function emoji(_emoji) {
return process.stdout.isTTY && !isWin32 ? _emoji : '';
};
function printFooter(collective) {
var dim = print('dim');
var yellow = print('yellow');
var emptyLine = print();
yellow("Thanks for installing ".concat(collective.slug, " ").concat(emoji('🙏')));
dim('Please consider donating to our open collective');
dim('to help us maintain this package.');
emptyLine();
printStats(collective.stats);
emptyLine();
print()("".concat(chalk__default['default'].bold("".concat(emoji('👉 '), " ").concat(collective.donationText)), " ").concat(chalk__default['default'].underline(collective.donationUrl)));
emptyLine();
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArrayLimit(arr, i) {
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _await(value, then, direct) {
if (direct) {
return then ? then(value) : value;
}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
var FETCH_TIMEOUT = 3000;
function _catch(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
var fetchJson = _async(function (url) {
return _catch(function () {
return _await(global.fetch("".concat(url, ".json"), {
timeout: FETCH_TIMEOUT
}), function (_global$fetch) {
return _global$fetch.json();
});
}, function (e) {
report(e);
reportAndThrowError("Could not fetch ".concat(url, ".json"));
});
});
function _async(f) {
return function () {
for (var args = [], i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
try {
return Promise.resolve(f.apply(this, args));
} catch (e) {
return Promise.reject(e);
}
};
}
var fetchStats = _async(function (collectiveUrl) {
return _catch(function () {
return _await(fetchJson(collectiveUrl));
}, function (e) {
report(e);
report("Could not load the stats for ".concat(collectiveSlugFromUrl(collectiveUrl)));
});
});
var fetchLogo = _async(function (logoUrl) {
if (!logoUrl) {
// Silent return if no logo has been provided
return;
}
if (!logoUrl.match(/^https?:\/\//)) {
reportAndThrowError("Your logo URL isn't well-formatted - ".concat(logoUrl));
}
return _catch(function () {
return _await(global.fetch(logoUrl, {
timeout: FETCH_TIMEOUT
}), function (res) {
if (isLogoResponseWellFormatted(res)) {
return res.text();
}
report("Error while fetching logo from ".concat(logoUrl, ". The response wasn't well-formatted"));
});
}, function () {
report("Error while fetching logo from ".concat(logoUrl));
});
});
var isLogoResponseWellFormatted = function isLogoResponseWellFormatted(res) {
return res.status === 200 && res.headers.get('content-type').match(/^text\/plain/);
};
var fetchPkg = function fetchPkg(pathToPkg) {
var fullPathToPkg = path__default['default'].resolve("".concat(pathToPkg, "/package.json"));
try {
return JSON.parse(fs__default['default'].readFileSync(fullPathToPkg, 'utf8'));
} catch (e) {
reportAndThrowError("Could not find package.json at ".concat(fullPathToPkg));
}
};
function _await$1(value, then, direct) {
if (direct) {
return then ? then(value) : value;
}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
function _async$1(f) {
return function () {
for (var args = [], i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
try {
return Promise.resolve(f.apply(this, args));
} catch (e) {
return Promise.reject(e);
}
};
}
var collectiveSlugFromUrl = function collectiveSlugFromUrl(url) {
return url.substr(url.lastIndexOf('/') + 1).toLowerCase().replace(/\.json/g, '');
};
var collectiveUrl = function collectiveUrl(pkg) {
var url = pkg.collective && pkg.collective.url;
if (!url) {
reportAndThrowError('No collective URL set!');
}
return stripTrailingSlash(url);
}; // use pkg.collective.logo for "legacy"/compatibility reasons
var collectiveLogoUrl = function collectiveLogoUrl(pkg) {
return pkg.collective.logo || pkg.collective.logoUrl || false;
};
var collectiveDonationText = function collectiveDonationText(pkg) {
return pkg.collective.donation && pkg.collective.donation.text || 'Donate:';
};
var getCollective = _async$1(function (pkgPath) {
var pkg = fetchPkg(pkgPath);
var url = collectiveUrl(pkg);
var baseCollective = {
url: url,
slug: collectiveSlugFromUrl(url),
logoUrl: collectiveLogoUrl(pkg),
donationUrl: collectiveDonationUrl(pkg),
donationText: collectiveDonationText(pkg)
};
var logoUrl = baseCollective.logoUrl;
var promises = [fetchStats(url)].concat(logoUrl ? fetchLogo(logoUrl) : []);
return _await$1(Promise.all(promises), function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
stats = _ref2[0],
logo = _ref2[1];
return Object.assign(baseCollective, {
stats: stats,
logo: logo
});
});
});
var collectiveDonationUrl = function collectiveDonationUrl(pkg) {
var defaultDonationAmount = pkg.collective.donation && pkg.collective.donation.amount;
var donateUrl = "".concat(collectiveUrl(pkg), "/").concat(retrieveDonationSlug(pkg));
if (defaultDonationAmount) {
return "".concat(donateUrl, "/").concat(defaultDonationAmount);
}
return donateUrl;
};
var retrieveDonationSlug = function retrieveDonationSlug(pkg) {
var rawDonationSlug = pkg.collective.donation && pkg.collective.donation.slug;
if (!rawDonationSlug) {
return 'donate';
}
return stripLeadingSlash(rawDonationSlug);
};
function _await$2(value, then, direct) {
if (direct) {
return then ? then(value) : value;
}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
function _async$2(f) {
return function () {
for (var args = [], i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
try {
return Promise.resolve(f.apply(this, args));
} catch (e) {
return Promise.reject(e);
}
};
}
var init = _async$2(function (path, hide) {
if (hide === undefined) hide = hideMessage();
if (hide) {
return;
}
global.fetch = global.fetch || fetch__default['default'];
return _await$2(getCollective(path), function (collective) {
printLogo(collective.logo);
printFooter(collective);
});
});
exports.init = init;

View File

@@ -0,0 +1,48 @@
{
"name": "@nuxtjs/opencollective",
"version": "0.3.2",
"repository": "nuxt-contrib/opencollective",
"license": "MIT",
"main": "dist/index.js",
"bin": "bin/opencollective.js",
"files": [
"bin",
"dist"
],
"scripts": {
"build": "bili -t node --format cjs src/index.js",
"lint": "eslint src test",
"prepublish": "yarn build",
"release": "standard-version && git push --follow-tags && npm publish",
"test": "yarn lint && yarn test:coverage",
"test:ava": "nyc ava --verbose",
"test:coverage": "nyc --reporter=lcov --reporter=html ava"
},
"ava": {
"require": [
"esm"
]
},
"dependencies": {
"chalk": "^4.1.0",
"consola": "^2.15.0",
"node-fetch": "^2.6.1"
},
"devDependencies": {
"@commitlint/cli": "latest",
"@commitlint/config-conventional": "latest",
"@nuxtjs/eslint-config": "latest",
"ava": "latest",
"bili": "latest",
"eslint": "latest",
"esm": "latest",
"fetch-mock": "latest",
"nyc": "latest",
"sinon": "latest",
"standard-version": "latest"
},
"engines": {
"node": ">=8.0.0",
"npm": ">=5.0.0"
}
}