25 Commits

Author SHA1 Message Date
agoodday
50737455ac Add files via upload 2026-03-14 19:24:00 +08:00
agoodday
723a4380fb Add files via upload 2026-03-11 01:15:49 +08:00
agoodday
57ac14a553 Add files via upload 2026-03-09 21:09:01 +08:00
agoodday
2dfbf4b3cf Add files via upload 2026-03-09 21:08:25 +08:00
agoodday
5ccca02e00 Remove China mirror repository section and disclaimer
Removed information about faster mirror repository for users in China and important disclaimer.
2026-03-09 09:37:53 +08:00
agoodday
62bb7e66a7 Update README_CN.md 2026-03-09 09:36:59 +08:00
agoodday
6f5f58ba5f Update README_CN.md 2026-03-09 09:27:57 +08:00
agoodday
41de48a71f Update README.md 2026-03-09 09:26:53 +08:00
agoodday
6493f2c17e Update README_CN.md 2026-03-09 05:31:10 +08:00
agoodday
b374b20690 Update README_CN.md 2026-03-09 05:28:28 +08:00
agoodday
f594f82e6f Update README.md 2026-03-09 05:27:12 +08:00
hotbob011
5cbd5d4af2 Create generator-generic-ossf-slsa3-publish.yml 2026-03-09 02:50:11 +08:00
hotbob011
2f0c4080bc Update README.md 2026-03-09 02:17:13 +08:00
hotbob011
437e0b1686 Update README_CN.md 2026-03-09 02:16:25 +08:00
hotbob011
0017ff79e3 Update README.md 2026-03-09 02:14:12 +08:00
hotbob011
79698c2130 Update README_CN.md 2026-03-09 02:13:35 +08:00
hotbob011
5ff108ad4e Update README_CN.md 2026-03-09 02:09:34 +08:00
hotbob011
8e23673f1d Update README.md 2026-03-09 02:08:42 +08:00
hotbob011
fd30f08223 Update README.md 2026-03-09 02:06:44 +08:00
hotbob011
8f8421d30f Update README.md 2026-03-09 02:05:15 +08:00
hotbob011
fa503cc073 Add files via upload 2026-03-09 02:04:03 +08:00
hotbob011
7eda584a76 Add files via upload 2026-03-09 02:03:45 +08:00
hotbob011
13b03c6371 Update README.md 2026-03-09 02:01:32 +08:00
hotbob011
08321080cb Update README_CN.md 2026-03-09 02:00:17 +08:00
hotbob011
3aac36dd06 Add files via upload 2026-03-09 01:59:39 +08:00
9 changed files with 471 additions and 26 deletions

View File

@@ -0,0 +1,66 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow lets you generate SLSA provenance file for your project.
# The generation satisfies level 3 for the provenance requirements - see https://slsa.dev/spec/v0.1/requirements
# The project is an initiative of the OpenSSF (openssf.org) and is developed at
# https://github.com/slsa-framework/slsa-github-generator.
# The provenance file can be verified using https://github.com/slsa-framework/slsa-verifier.
# For more information about SLSA and how it improves the supply-chain, visit slsa.dev.
name: SLSA generic generator
on:
workflow_dispatch:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
outputs:
digests: ${{ steps.hash.outputs.digests }}
steps:
- uses: actions/checkout@v4
# ========================================================
#
# Step 1: Build your artifacts.
#
# ========================================================
- name: Build artifacts
run: |
# These are some amazing artifacts.
echo "artifact1" > artifact1
echo "artifact2" > artifact2
# ========================================================
#
# Step 2: Add a step to generate the provenance subjects
# as shown below. Update the sha256 sum arguments
# to include all binaries that you generate
# provenance for.
#
# ========================================================
- name: Generate subject for provenance
id: hash
run: |
set -euo pipefail
# List the artifacts the provenance will refer to.
files=$(ls artifact*)
# Generate the subjects (base64 encoded).
echo "hashes=$(sha256sum $files | base64 -w0)" >> "${GITHUB_OUTPUT}"
provenance:
needs: [build]
permissions:
actions: read # To read the workflow path.
id-token: write # To sign the provenance.
contents: write # To add assets to a release.
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0
with:
base64-subjects: "${{ needs.build.outputs.digests }}"
upload-assets: true # Optional: Upload to a new release

BIN
ERC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

174
README.md
View File

@@ -197,6 +197,146 @@ console.log(csv);
console.log(json); console.log(json);
``` ```
### Offline Local-Only Usage (Run Everything on Your Own Machine)
If, like me, you prefer to **keep all data and logic on your own computer only**, without relying on any external server, you can treat MockAddress Core as a pure static site and run it via a simple local HTTP server:
- My development environment is a Windows PC with:
- A modern browser (Chrome / Edge, etc.)
- Python / PHP / Node.js (at least one of them; in my case I have all three installed)
- Clone this repository to a local directory, e.g. `D:\mockaddress-core\`.
- In the project root, create a `start-local-server.bat` with the following content to start a local server and automatically open `http://localhost:8000`:
```bat
@echo off
echo Starting local server...
echo.
REM Check if Python 3 is available
python --version >nul 2>&1
if %errorlevel% equ 0 (
python -c "import sys; sys.exit(0 if sys.version_info >= (3, 0) else 1)" >nul 2>&1
if %errorlevel% equ 0 (
echo Found Python 3
echo Starting server on http://localhost:8000
echo Press Ctrl+C to stop
echo.
timeout /t 2 /nobreak >nul
start http://localhost:8000
python -m http.server 8000
exit /b 0
)
)
REM Check if Python 2 is available
python --version >nul 2>&1
if %errorlevel% equ 0 (
python -c "import sys; sys.exit(0 if sys.version_info < (3, 0) else 1)" >nul 2>&1
if %errorlevel% equ 0 (
echo Found Python 2
echo Starting server on http://localhost:8000
echo Press Ctrl+C to stop
echo.
timeout /t 2 /nobreak >nul
start http://localhost:8000
python -m SimpleHTTPServer 8000
exit /b 0
)
)
REM Check if PHP is available
php --version >nul 2>&1
if %errorlevel% equ 0 (
echo Found PHP
echo Starting server on http://localhost:8000
echo Press Ctrl+C to stop
echo.
timeout /t 2 /nobreak >nul
start http://localhost:8000
php -S localhost:8000
exit /b 0
)
REM Check if Node.js is available
where npx >nul 2>&1
if %errorlevel% equ 0 (
echo Found Node.js
echo Starting server on http://localhost:8000
echo Press Ctrl+C to stop
echo.
timeout /t 2 /nobreak >nul
start http://localhost:8000
npx --yes http-server -p 8000
exit /b 0
)
echo Error: No server found
echo Please install Python, PHP, or Node.js
pause
exit /b 1
```
How to use:
- Double-click `start-local-server.bat`. The script will try Python 3 → Python 2 → PHP → Node.js in order, start the first available local server, and open `http://localhost:8000` in your browser.
- From that point on, **all address generation logic— including the US address generator and the Hong Kong English/Chinese address generator—runs entirely on your own machine, with no Internet connection required**.
- This setup is ideal for **intranet environments** or teams with strict privacy/compliance requirements.
For detailed usage instructions, see [`使用说明.md`](./使用说明.md) (Usage Guide in Chinese). For detailed usage instructions, see [`使用说明.md`](./使用说明.md) (Usage Guide in Chinese).
You can also refer to our production site <https://mockaddress.com/> to see real-world usage scenarios and UI design, then customize as needed in your own project. You can also refer to our production site <https://mockaddress.com/> to see real-world usage scenarios and UI design, then customize as needed in your own project.
@@ -362,3 +502,37 @@ address-generator, random-address, fake-address, tax-free-state, real-address, r
## License ## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
---
## 💰 Support & Technical Services
### Cryptocurrency Donations
You can also support us via cryptocurrency:
**Ethereum / USDT (ERC-20):**
```
0x6Df562A8B669bf90EAe5ccB0E0440eb9DF237E4e
```
![dashangerc](ERC.png)
**USDT (TRC-20):**
```
TYz2SP7GtL84t14CeL7tnhHLgeako3haHW
```
![dashangTRC](TRC.png)
> **Note**: Cryptocurrency donations are non-refundable. Please double-check the address before sending.
### 📊 Technical Services Support
Need technical support for your project? Feel free to contact us for paid services and technical assistance.
📧 Email: [jietoushiren01@gmail.com](mailto:jietoushiren01@gmail.com)

View File

@@ -10,8 +10,10 @@
> 本仓库包含 MockAddress 的**开源前端核心引擎**,用于生成跨多个国家/地区的真实格式测试地址和 MAC 地址数据。 > 本仓库包含 MockAddress 的**开源前端核心引擎**,用于生成跨多个国家/地区的真实格式测试地址和 MAC 地址数据。
> 完整生产环境网站:<https://mockaddress.com/> > 完整生产环境网站:<https://mockaddress.com/>
>
> 🇬🇧 **English users please see: [README_EN.md](./README_EN.md) (English Documentation)**
![mockaddress 美国免税州地址生成器首页示例图片](en.png) ![mockaddress 美国免税州地址生成器首页示例图片](cn.png)
## 项目简介 ## 项目简介
@@ -195,6 +197,146 @@ console.log(csv);
console.log(json); console.log(json);
``` ```
### 在本机离线运行(仅自己使用,无需联网)
如果你和我一样,希望**只在自己的电脑上独享数据,不依赖任何外网服务器**,可以把整个 MockAddress Core 当成一个纯静态站点,在本机用一个简单的 HTTP 服务跑起来:
- 我的开发环境是 Windows 电脑,安装了:
- 一个现代浏览器Chrome / Edge 等)
- Python / PHP / Node.js至少其一实际我三者都装了
- 仓库代码放在本地某个目录,比如:`D:\mockaddress-core\`
- 在项目根目录新建一个 `start-local-server.bat`,内容如下,一键启动本地服务器并自动打开浏览器访问 `http://localhost:8000`
```bat
@echo off
echo Starting local server...
echo.
REM Check if Python 3 is available
python --version >nul 2>&1
if %errorlevel% equ 0 (
python -c "import sys; sys.exit(0 if sys.version_info >= (3, 0) else 1)" >nul 2>&1
if %errorlevel% equ 0 (
echo Found Python 3
echo Starting server on http://localhost:8000
echo Press Ctrl+C to stop
echo.
timeout /t 2 /nobreak >nul
start http://localhost:8000
python -m http.server 8000
exit /b 0
)
)
REM Check if Python 2 is available
python --version >nul 2>&1
if %errorlevel% equ 0 (
python -c "import sys; sys.exit(0 if sys.version_info < (3, 0) else 1)" >nul 2>&1
if %errorlevel% equ 0 (
echo Found Python 2
echo Starting server on http://localhost:8000
echo Press Ctrl+C to stop
echo.
timeout /t 2 /nobreak >nul
start http://localhost:8000
python -m SimpleHTTPServer 8000
exit /b 0
)
)
REM Check if PHP is available
php --version >nul 2>&1
if %errorlevel% equ 0 (
echo Found PHP
echo Starting server on http://localhost:8000
echo Press Ctrl+C to stop
echo.
timeout /t 2 /nobreak >nul
start http://localhost:8000
php -S localhost:8000
exit /b 0
)
REM Check if Node.js is available
where npx >nul 2>&1
if %errorlevel% equ 0 (
echo Found Node.js
echo Starting server on http://localhost:8000
echo Press Ctrl+C to stop
echo.
timeout /t 2 /nobreak >nul
start http://localhost:8000
npx --yes http-server -p 8000
exit /b 0
)
echo Error: No server found
echo Please install Python, PHP, or Node.js
pause
exit /b 1
```
运行方式:
- 双击 `start-local-server.bat`,脚本会依次尝试 Python 3 → Python 2 → PHP → Node.js找到可用环境后自动启动本地服务器。
- 浏览器会自动打开 `http://localhost:8000`,此时**所有地址生成逻辑、包括美国地址生成器、香港中英文地址生成器等,全部只在你自己电脑本地运行,不依赖互联网**。
- 这种方式非常适合**内网环境**或对隐私/合规要求较高的团队。
详细使用说明请参考 [`使用说明.md`](./使用说明.md)。 详细使用说明请参考 [`使用说明.md`](./使用说明.md)。
你也可以参考我们的生产站点 <https://mockaddress.com/> 查看真实使用场景和 UI 设计,然后在自己的项目中按需定制。 你也可以参考我们的生产站点 <https://mockaddress.com/> 查看真实使用场景和 UI 设计,然后在自己的项目中按需定制。
@@ -360,3 +502,41 @@ address-generator, random-address, fake-address, tax-free-state, real-address, r
## License ## License
本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件。 本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件。
---
## 💰 支持与技术服务
### 加密货币打赏
你也可以通过加密货币支持我们:
**Ethereum / USDT (ERC-20):**
```
0x6Df562A8B669bf90EAe5ccB0E0440eb9DF237E4e
```
![dashangerc](ERC.png)
**USDT (TRC-20):**
```
TYz2SP7GtL84t14CeL7tnhHLgeako3haHW
```
![dashangTRC](TRC.png)
> **注意**:加密货币打赏不可退款,请确认地址无误后再发送。
### 📊 技术服务支持
需要建站的技术和内容支持?欢迎随时联系我们,提供付费服务与技术协助。
📧 邮箱:[jietoushiren01@gmail.com](mailto:jietoushiren01@gmail.com)

BIN
TRC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
cn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@@ -236,7 +236,7 @@ export async function generateUSAddress(selectedState = 'RANDOM') {
stateCode, stateCode,
zip, zip,
fullAddress, fullAddress,
country: '美国' country: 'US'
}; };
} catch (error) { } catch (error) {
console.error('Error generating US address:', error); console.error('Error generating US address:', error);
@@ -391,7 +391,7 @@ export async function generateHKAddress(selectedRegion = 'RANDOM', isEnglish = f
area: city, // 保留原字段以兼容 area: city, // 保留原字段以兼容
fullAddress, fullAddress,
zip, zip,
country: isEnglish ? '香港 Hong Kong' : '香港' country: 'HK'
}; };
} catch (error) { } catch (error) {
console.error('Error generating HK address:', error); console.error('Error generating HK address:', error);
@@ -500,7 +500,7 @@ export async function generateUKAddress(selectedRegion = 'RANDOM') {
postcode, postcode,
region: regionNameEn, // 显示英文地区名 region: regionNameEn, // 显示英文地区名
fullAddress, fullAddress,
country: '英国' country: 'UK'
}; };
} catch (error) { } catch (error) {
console.error('Error generating UK address:', error); console.error('Error generating UK address:', error);
@@ -610,7 +610,7 @@ export async function generateCAAddress(selectedProvince = 'RANDOM') {
postcode, postcode,
province: provinceNameEn, // 显示英文省份名 province: provinceNameEn, // 显示英文省份名
fullAddress, fullAddress,
country: '加拿大' country: 'CA'
}; };
} catch (error) { } catch (error) {
console.error('Error generating CA address:', error); console.error('Error generating CA address:', error);
@@ -778,7 +778,7 @@ export async function generateJPAddress(selectedPrefecture = 'RANDOM') {
prefecture: prefectureName, prefecture: prefectureName,
postcode, postcode,
fullAddress, fullAddress,
country: '日本' country: 'JP'
}; };
} catch (error) { } catch (error) {
console.error('Error generating JP address:', error); console.error('Error generating JP address:', error);
@@ -897,7 +897,7 @@ export async function generateINAddress(selectedState = 'RANDOM') {
state: stateNameEn, // 显示英文邦名 state: stateNameEn, // 显示英文邦名
pin, pin,
fullAddress, fullAddress,
country: '印度' country: 'IN'
}; };
} catch (error) { } catch (error) {
console.error('Error generating IN address:', error); console.error('Error generating IN address:', error);
@@ -1022,7 +1022,7 @@ export async function generateTWAddress(selectedCounty = 'RANDOM') {
district, district,
postcode, postcode,
fullAddress, fullAddress,
country: '台灣' country: 'TW'
}; };
} catch (error) { } catch (error) {
console.error('Error generating TW address:', error); console.error('Error generating TW address:', error);
@@ -1051,12 +1051,13 @@ export async function generateIdentityInfo(address) {
} }
// Use the same name group as the address based on country // Use the same name group as the address based on country
const c = address.country || '';
let nameGroup; let nameGroup;
if (address.country === '香港' || address.country === '台灣') { if (c === '香港' || c === '台灣' || c === 'HK' || c === 'TW') {
nameGroup = namesData.nameGroups.chinese; nameGroup = namesData.nameGroups.chinese;
} else if (address.country === '印度') { } else if (c === '印度' || c === 'IN') {
nameGroup = namesData.nameGroups.indian; nameGroup = namesData.nameGroups.indian;
} else if (address.country === '日本') { } else if (c === '日本' || c === 'JP') {
nameGroup = namesData.nameGroups.asian || namesData.nameGroups.western; nameGroup = namesData.nameGroups.asian || namesData.nameGroups.western;
} else { } else {
// Default to western names for US, UK, Canada, etc. // Default to western names for US, UK, Canada, etc.
@@ -1125,14 +1126,14 @@ export async function generateIdentityInfo(address) {
let ssn; let ssn;
const country = address.country || ''; const country = address.country || '';
if (country.includes('德国') || country.includes('Germany')) { if (country.includes('德国') || country.includes('Germany') || country === 'DE') {
// Generate German Steuer-ID (Tax ID): 11 digits, format: XX XXX XXX XXX // Generate German Steuer-ID (Tax ID): 11 digits, format: XX XXX XXX XXX
const part1 = randomInt(10, 99); const part1 = randomInt(10, 99);
const part2 = randomInt(100, 999); const part2 = randomInt(100, 999);
const part3 = randomInt(100, 999); const part3 = randomInt(100, 999);
const part4 = randomInt(100, 999); const part4 = randomInt(100, 999);
ssn = `${part1} ${part2} ${part3} ${part4}`; ssn = `${part1} ${part2} ${part3} ${part4}`;
} else if (country.includes('英国') || country.includes('UK') || country.includes('United Kingdom')) { } else if (country.includes('英国') || country.includes('UK') || country.includes('United Kingdom') || country === 'UK') {
// Generate UK NINO: Format: AA 12 34 56 A // Generate UK NINO: Format: AA 12 34 56 A
const letters1 = 'ABCDEFGHJKLMNOPRSTUVWXYZ'; const letters1 = 'ABCDEFGHJKLMNOPRSTUVWXYZ';
const letters2 = 'ABCDEFGHJKLMNOPRSTUVWXYZ'; const letters2 = 'ABCDEFGHJKLMNOPRSTUVWXYZ';
@@ -1141,25 +1142,25 @@ export async function generateIdentityInfo(address) {
const digits = randomInt(100000, 999999); const digits = randomInt(100000, 999999);
const letter3 = randomElement(letters2.split('')); const letter3 = randomElement(letters2.split(''));
ssn = `${letter1}${letter2} ${digits.toString().slice(0, 2)} ${digits.toString().slice(2, 4)} ${digits.toString().slice(4, 6)} ${letter3}`; ssn = `${letter1}${letter2} ${digits.toString().slice(0, 2)} ${digits.toString().slice(2, 4)} ${digits.toString().slice(4, 6)} ${letter3}`;
} else if (country.includes('加拿大') || country.includes('Canada')) { } else if (country.includes('加拿大') || country.includes('Canada') || country === 'CA') {
// Generate Canadian SIN: Format: XXX XXX XXX // Generate Canadian SIN: Format: XXX XXX XXX
const sin1 = randomInt(100, 999); const sin1 = randomInt(100, 999);
const sin2 = randomInt(100, 999); const sin2 = randomInt(100, 999);
const sin3 = randomInt(100, 999); const sin3 = randomInt(100, 999);
ssn = `${sin1} ${sin2} ${sin3}`; ssn = `${sin1} ${sin2} ${sin3}`;
} else if (country.includes('日本') || country.includes('Japan')) { } else if (country.includes('日本') || country.includes('Japan') || country === 'JP') {
// Generate Japanese My Number: Format: XXXX-XXXX-XXXX // Generate Japanese My Number: Format: XXXX-XXXX-XXXX
const myNum1 = randomInt(1000, 9999); const myNum1 = randomInt(1000, 9999);
const myNum2 = randomInt(1000, 9999); const myNum2 = randomInt(1000, 9999);
const myNum3 = randomInt(1000, 9999); const myNum3 = randomInt(1000, 9999);
ssn = `${myNum1}-${myNum2}-${myNum3}`; ssn = `${myNum1}-${myNum2}-${myNum3}`;
} else if (country.includes('印度') || country.includes('India')) { } else if (country.includes('印度') || country.includes('India') || country === 'IN') {
// Generate Indian Aadhaar: Format: XXXX XXXX XXXX // Generate Indian Aadhaar: Format: XXXX XXXX XXXX
const aadhaar1 = randomInt(1000, 9999); const aadhaar1 = randomInt(1000, 9999);
const aadhaar2 = randomInt(1000, 9999); const aadhaar2 = randomInt(1000, 9999);
const aadhaar3 = randomInt(1000, 9999); const aadhaar3 = randomInt(1000, 9999);
ssn = `${aadhaar1} ${aadhaar2} ${aadhaar3}`; ssn = `${aadhaar1} ${aadhaar2} ${aadhaar3}`;
} else if (country.includes('香港') || country.includes('Hong Kong')) { } else if (country.includes('香港') || country.includes('Hong Kong') || country === 'HK') {
// Generate Hong Kong ID Card: Format: A123456(7) or AB123456(7) // Generate Hong Kong ID Card: Format: A123456(7) or AB123456(7)
// 70%概率单字母30%概率双字母 // 70%概率单字母30%概率双字母
const letters = 'ABCDEFGHJKLMNPQRSTUVWXYZ'; const letters = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
@@ -1175,7 +1176,7 @@ export async function generateIdentityInfo(address) {
const digits = randomInt(100000, 999999).toString(); const digits = randomInt(100000, 999999).toString();
const checkDigit = randomInt(0, 9); const checkDigit = randomInt(0, 9);
ssn = `${prefix}${digits}(${checkDigit})`; ssn = `${prefix}${digits}(${checkDigit})`;
} else if (country.includes('台灣') || country.includes('台湾') || country.includes('Taiwan')) { } else if (country.includes('台灣') || country.includes('台湾') || country.includes('Taiwan') || country === 'TW') {
// Generate Taiwan ID Card: Format: A123456789 // Generate Taiwan ID Card: Format: A123456789
// 1st: letter (birthplace), 2nd: gender (1=Male, 2=Female), 3rd-9th: sequence // 1st: letter (birthplace), 2nd: gender (1=Male, 2=Female), 3rd-9th: sequence
const letters = 'ABCDEFGHJKLMNPQRSTUVXY'; const letters = 'ABCDEFGHJKLMNPQRSTUVXY';
@@ -1183,7 +1184,7 @@ export async function generateIdentityInfo(address) {
const genderDigit = isMaleForIdentity ? '1' : '2'; // 1=男, 2=女 const genderDigit = isMaleForIdentity ? '1' : '2'; // 1=男, 2=女
const sequenceDigits = randomInt(10000000, 99999999).toString(); const sequenceDigits = randomInt(10000000, 99999999).toString();
ssn = `${firstLetter}${genderDigit}${sequenceDigits}`; ssn = `${firstLetter}${genderDigit}${sequenceDigits}`;
} else if (country.includes('新加坡') || country.includes('Singapore')) { } else if (country.includes('新加坡') || country.includes('Singapore') || country === 'SG') {
// Generate Singapore NRIC: Format: S1234567D (prefix + 7 digits + check letter) // Generate Singapore NRIC: Format: S1234567D (prefix + 7 digits + check letter)
// S=citizen pre-2000, T=citizen 2000+, G/F=PR. Prefix should match birth year // S=citizen pre-2000, T=citizen 2000+, G/F=PR. Prefix should match birth year
let prefix; let prefix;
@@ -1204,7 +1205,7 @@ export async function generateIdentityInfo(address) {
// Default: US SSN format (XXX-XX-XXXX) // Default: US SSN format (XXX-XX-XXXX)
// SSN Area Number (first 3 digits) should match the state if available // SSN Area Number (first 3 digits) should match the state if available
let ssnAreaNumber; let ssnAreaNumber;
if (address.stateCode && address.country === '美国') { if (address.stateCode && (address.country === '美国' || address.country === 'US')) {
try { try {
const usData = await loadData('data/usData.json'); const usData = await loadData('data/usData.json');
const state = usData.states[address.stateCode]; const state = usData.states[address.stateCode];
@@ -1418,7 +1419,7 @@ export async function generateSGAddress(selectedState = 'RANDOM') {
state: stateNameEn, state: stateNameEn,
stateCode: stateKey, stateCode: stateKey,
fullAddress, fullAddress,
country: '新加坡' country: 'SG'
}; };
} catch (error) { } catch (error) {
console.error('Error generating SG address:', error); console.error('Error generating SG address:', error);
@@ -1530,7 +1531,7 @@ export async function generateDEAddress(selectedState = 'RANDOM') {
state: stateNameEn, state: stateNameEn,
stateCode: stateKey, stateCode: stateKey,
fullAddress, fullAddress,
country: '德国' country: 'DE'
}; };
} catch (error) { } catch (error) {
console.error('Error generating DE address:', error); console.error('Error generating DE address:', error);

View File

@@ -197,6 +197,13 @@ export function initLanguageSwitcher() {
// 获取当前语言 // 获取当前语言
const currentLang = getCurrentLanguage(); const currentLang = getCurrentLanguage();
const currentLangData = languages[currentLang]; const currentLangData = languages[currentLang];
const isMobileViewport = () => window.matchMedia && window.matchMedia('(max-width: 768px)').matches;
const formatCurrentLangLabel = () => {
// 模板工程:保持与正式站一致的移动端缩写策略
if (currentLang === 'zh' && isMobileViewport()) return 'CN';
if (currentLang === 'pt' && isMobileViewport()) return 'PT';
return `${currentLangData.flag} ${currentLangData.nativeName}`;
};
// 添加全局点击事件监听器(只添加一次) // 添加全局点击事件监听器(只添加一次)
if (!globalClickHandlerAdded) { if (!globalClickHandlerAdded) {
@@ -239,7 +246,7 @@ export function initLanguageSwitcher() {
// 更新按钮显示 // 更新按钮显示
if (langButtonText) { if (langButtonText) {
langButtonText.textContent = `${currentLangData.flag} ${currentLangData.nativeName}`; langButtonText.textContent = formatCurrentLangLabel();
} }
// 生成语言选项(不使用 inline onclick避免被其他脚本/策略影响) // 生成语言选项(不使用 inline onclick避免被其他脚本/策略影响)
@@ -296,6 +303,23 @@ export function initLanguageSwitcher() {
} }
}); });
}); });
// 处理横竖屏/窗口尺寸变化:与正式站保持一致
if (!window.__langBtnResizeBound) {
window.__langBtnResizeBound = true;
const onResize = () => {
document.querySelectorAll('.language-switcher').forEach((wrapper) => {
const langButtonText =
wrapper.querySelector('#language-switcher-text') ||
wrapper.querySelector('.language-switcher-text');
if (langButtonText) {
langButtonText.textContent = formatCurrentLangLabel();
}
});
};
window.addEventListener('resize', onResize, { passive: true });
window.addEventListener('orientationchange', onResize, { passive: true });
}
} }
// 自动初始化 - 只在 DOM 加载完成后执行 // 自动初始化 - 只在 DOM 加载完成后执行

View File

@@ -114,7 +114,7 @@ export function exportToCSV() {
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const link = document.createElement('a'); const link = document.createElement('a');
link.href = url; link.href = url;
link.download = `地址列表_${new Date().toISOString().split('T')[0]}.csv`; link.download = `CSV-${new Date().toISOString().split('T')[0]}.csv`;
link.click(); link.click();
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
@@ -139,7 +139,7 @@ export function exportToJSON() {
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const link = document.createElement('a'); const link = document.createElement('a');
link.href = url; link.href = url;
link.download = `地址列表_${new Date().toISOString().split('T')[0]}.json`; link.download = `JSON-${new Date().toISOString().split('T')[0]}.json`;
link.click(); link.click();
URL.revokeObjectURL(url); URL.revokeObjectURL(url);