add apple app store for ios
This commit is contained in:
2
.github/workflows/gh-pages.yml
vendored
2
.github/workflows/gh-pages.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 23
|
||||
node-version: 24
|
||||
- run: |
|
||||
npm install
|
||||
|
||||
|
||||
11
public/.well-known/apple-app-site-association
Normal file
11
public/.well-known/apple-app-site-association
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"applinks": {
|
||||
"apps": [],
|
||||
"details": [
|
||||
{
|
||||
"appID": "6DQ24D2652.ai.syui.card",
|
||||
"paths": ["/oauth/callback"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
267
public/app.html
Normal file
267
public/app.html
Normal file
@@ -0,0 +1,267 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Aicard - App Store</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background: #f5f5f7;
|
||||
color: #1d1d1f;
|
||||
line-height: 1.8;
|
||||
}
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
.app-header {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
padding-bottom: 30px;
|
||||
border-bottom: 1px solid #d2d2d7;
|
||||
}
|
||||
.app-icon {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 24px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
margin: 0 auto 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 48px;
|
||||
color: #fff;
|
||||
box-shadow: 0 10px 40px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
.app-title {
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
color: #1d1d1f;
|
||||
}
|
||||
.app-subtitle {
|
||||
font-size: 18px;
|
||||
color: #86868b;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.download-btn {
|
||||
display: inline-block;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #fff;
|
||||
padding: 14px 32px;
|
||||
border-radius: 12px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.download-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
.section {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.section-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 16px;
|
||||
color: #1d1d1f;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid #667eea;
|
||||
display: inline-block;
|
||||
}
|
||||
.section p {
|
||||
color: #424245;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.feature-list {
|
||||
list-style: none;
|
||||
}
|
||||
.feature-list li {
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #d2d2d7;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.feature-list li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.feature-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
.feature-text h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 4px;
|
||||
color: #1d1d1f;
|
||||
}
|
||||
.feature-text p {
|
||||
font-size: 14px;
|
||||
color: #424245;
|
||||
margin: 0;
|
||||
}
|
||||
.screenshots {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
overflow-x: auto;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.screenshot {
|
||||
min-width: 200px;
|
||||
height: 360px;
|
||||
background: #f0f0f5;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #86868b;
|
||||
font-size: 14px;
|
||||
border: 1px solid #d2d2d7;
|
||||
}
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.info-item {
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
background: #f0f0f5;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.info-item .label {
|
||||
font-size: 12px;
|
||||
color: #86868b;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.info-item .value {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-top: 4px;
|
||||
color: #1d1d1f;
|
||||
}
|
||||
footer {
|
||||
text-align: center;
|
||||
padding: 30px 20px;
|
||||
color: #86868b;
|
||||
font-size: 14px;
|
||||
}
|
||||
footer a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.info-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.app-title {
|
||||
font-size: 28px;
|
||||
}
|
||||
.section {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="app-header">
|
||||
<div class="app-icon">ai</div>
|
||||
<h1 class="app-title">Aicard</h1>
|
||||
<p class="app-subtitle">ai.syui.card</p>
|
||||
<a href="#" class="download-btn">App Store</a>
|
||||
</header>
|
||||
|
||||
<section class="section">
|
||||
<h2 class="section-title">App</h2>
|
||||
<p>
|
||||
Aicard (iOS) is a card collecting game. You can save your data to your Atproto account. Saved data is linked to Airse (Windows, Mac), an open-world action game.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2 class="section-title">Function</h2>
|
||||
<ul class="feature-list">
|
||||
<li>
|
||||
<div class="feature-icon">✨</div>
|
||||
<div class="feature-text">
|
||||
<h4>Holographic Effect</h4>
|
||||
<p>Special cards change color depending on the angle of light.</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="feature-icon">🃏</div>
|
||||
<div class="feature-text">
|
||||
<h4>Card Collection</h4>
|
||||
<p>The initial set includes 13 types of cards.</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="feature-icon">🌐</div>
|
||||
<div class="feature-text">
|
||||
<h4>Bluesky Integration</h4>
|
||||
<p>Proof of card ownership linked with a decentralized social network.</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2 class="section-title">App Information</h2>
|
||||
<div class="info-grid">
|
||||
<div class="info-item">
|
||||
<div class="label">Version</div>
|
||||
<div class="value">1.0.1</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="label">Category</div>
|
||||
<div class="value">Entertainment</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="label">Supported OS</div>
|
||||
<div class="value">iOS 26.0+</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="label">Price</div>
|
||||
<div class="value">Free (Offers in-app purchases)</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<p style="margin-top: 8px;">
|
||||
<a href="/privacy.html">Privacy Policy</a>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<p>© syui</p>
|
||||
<p style="margin-top: 8px;">
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -21,6 +21,7 @@
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 20px;
|
||||
backdrop-filter: blur(10px);
|
||||
max-width: 400px;
|
||||
}
|
||||
.spinner {
|
||||
border: 4px solid rgba(255, 255, 255, 0.3);
|
||||
@@ -35,6 +36,28 @@
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
.message {
|
||||
font-size: 18px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 15px 30px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: 2px solid white;
|
||||
border-radius: 10px;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.button:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
.error {
|
||||
color: #ff6b6b;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
@@ -45,8 +68,10 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="content">
|
||||
<div class="spinner"></div>
|
||||
<p id="status">認証中...</p>
|
||||
<p class="message">認証中...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -62,61 +87,45 @@
|
||||
console.log('OAuth callback page loaded');
|
||||
console.log('Params:', { code: code ? 'present' : 'missing', state: state ? 'present' : 'missing' });
|
||||
|
||||
const content = document.getElementById('content');
|
||||
|
||||
// エラーチェック
|
||||
if (error) {
|
||||
document.getElementById('status').innerHTML =
|
||||
`<div class="error">認証エラー: ${errorDescription || error}</div>`;
|
||||
content.innerHTML = `<div class="error">認証エラー: ${errorDescription || error}</div>`;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!code || !state) {
|
||||
document.getElementById('status').innerHTML =
|
||||
'<div class="error">認証パラメータが不足しています</div>';
|
||||
content.innerHTML = '<div class="error">認証パラメータが不足しています</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// React Nativeアプリに戻す (deep link)
|
||||
// カスタムスキームのDeep Linkを生成
|
||||
const deepLink = `aicard://oauth/callback?code=${encodeURIComponent(code)}&state=${encodeURIComponent(state)}`;
|
||||
|
||||
console.log('Deep link:', deepLink);
|
||||
document.getElementById('status').innerHTML = 'アプリに戻っています...<br><small>' + deepLink + '</small>';
|
||||
console.log('OAuth callback received, attempting app launch...');
|
||||
console.log('Universal Link should trigger automatically if configured correctly');
|
||||
|
||||
// Method 1: iframe approach
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.style.display = 'none';
|
||||
iframe.src = deepLink;
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
// Method 2: Direct window.location
|
||||
// 即座にカスタムスキームへのリダイレクトを試行(フォールバック)
|
||||
// Universal Linksが動作すればこのコードに到達する前にアプリが開く
|
||||
// 動作しない場合はカスタムスキームで開く
|
||||
setTimeout(() => {
|
||||
console.log('Attempting window.location redirect');
|
||||
console.log('Attempting fallback custom scheme redirect');
|
||||
window.location.href = deepLink;
|
||||
}, 500);
|
||||
|
||||
// Method 3: Link click simulation
|
||||
// 2秒後に手動ボタンを表示(念のため)
|
||||
setTimeout(() => {
|
||||
console.log('Attempting link click');
|
||||
const link = document.createElement('a');
|
||||
link.href = deepLink;
|
||||
link.click();
|
||||
}, 1000);
|
||||
|
||||
// Method 4: Window.open
|
||||
setTimeout(() => {
|
||||
console.log('Attempting window.open');
|
||||
window.open(deepLink, '_self');
|
||||
}, 1500);
|
||||
|
||||
// フォールバック: 5秒後にメッセージ表示
|
||||
setTimeout(() => {
|
||||
document.getElementById('status').innerHTML =
|
||||
'<div class="error">アプリが開かない場合は、下のリンクをタップしてください<br><br>' +
|
||||
'<a href="' + deepLink + '" style="color: white; text-decoration: underline; font-size: 18px;">Aicardアプリを開く</a></div>';
|
||||
}, 5000);
|
||||
content.innerHTML = `
|
||||
<div class="message">認証が完了しました</div>
|
||||
<p style="font-size: 14px; opacity: 0.9;">アプリが自動的に開かない場合は、<br>下のボタンをタップしてください</p>
|
||||
<a href="${deepLink}" class="button">アプリを開く</a>
|
||||
`;
|
||||
}, 2000);
|
||||
|
||||
} catch (err) {
|
||||
console.error('Callback error:', err);
|
||||
document.getElementById('status').innerHTML =
|
||||
document.getElementById('content').innerHTML =
|
||||
`<div class="error">エラーが発生しました: ${err.message}</div>`;
|
||||
}
|
||||
})();
|
||||
|
||||
251
public/privacy.html
Normal file
251
public/privacy.html
Normal file
@@ -0,0 +1,251 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Privacy Policy - Aicard</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background: #f5f5f7;
|
||||
color: #1d1d1f;
|
||||
line-height: 1.8;
|
||||
}
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
header {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
padding-bottom: 30px;
|
||||
border-bottom: 1px solid #d2d2d7;
|
||||
}
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
color: #1d1d1f;
|
||||
}
|
||||
.app-name {
|
||||
font-size: 16px;
|
||||
color: #86868b;
|
||||
}
|
||||
.last-updated {
|
||||
font-size: 14px;
|
||||
color: #86868b;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.section {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 16px;
|
||||
color: #1d1d1f;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid #667eea;
|
||||
display: inline-block;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
color: #424245;
|
||||
}
|
||||
ul {
|
||||
margin: 16px 0;
|
||||
padding-left: 24px;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 8px;
|
||||
color: #424245;
|
||||
}
|
||||
.highlight {
|
||||
background: #f0f0f5;
|
||||
padding: 16px 20px;
|
||||
border-radius: 8px;
|
||||
margin: 16px 0;
|
||||
border-left: 4px solid #667eea;
|
||||
}
|
||||
.contact-info {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #fff;
|
||||
padding: 24px;
|
||||
border-radius: 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.contact-info a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
footer {
|
||||
text-align: center;
|
||||
padding: 30px 20px;
|
||||
color: #86868b;
|
||||
font-size: 14px;
|
||||
}
|
||||
footer a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
}
|
||||
.section {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Privacy Policy</h1>
|
||||
<p class="app-name">Aicard</p>
|
||||
<p class="last-updated">update 2025.11.23</p>
|
||||
</header>
|
||||
|
||||
<section class="section">
|
||||
<h2>Introduction</h2>
|
||||
<p>
|
||||
This Privacy Policy explains how Aicard (hereinafter referred to as “the App”) handles personal information.
|
||||
Please read this policy carefully before using the App.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>Information We Collect</h2>
|
||||
<p>The App may collect and use the following information:</p>
|
||||
|
||||
<h3 style="font-size: 16px; margin: 16px 0 8px; color: #1d1d1f;">1. Information Collected Automatically</h3>
|
||||
<ul>
|
||||
<li>Device information (model, OS version)</li>
|
||||
<li>App usage data (launch count, viewed cards, etc.)</li>
|
||||
<li>Crash logs and performance data</li>
|
||||
</ul>
|
||||
|
||||
<h3 style="font-size: 16px; margin: 16px 0 8px; color: #1d1d1f;">2. Information Provided by Users</h3>
|
||||
<ul>
|
||||
<li>DID (Decentralized Identifier) when linking a Bluesky account</li>
|
||||
<li>Favorite card settings</li>
|
||||
</ul>
|
||||
|
||||
<div class="highlight">
|
||||
<strong>Important:</strong> The App does not collect information that directly identifies an individual, such as name, email address, or phone number.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>Purpose of Use</h2>
|
||||
<p>The collected information is used for the following purposes:</p>
|
||||
<ul>
|
||||
<li>Providing app functionality and improving services</li>
|
||||
<li>Offering the card collection feature</li>
|
||||
<li>Enhancing user experience</li>
|
||||
<li>Diagnosing and resolving technical issues</li>
|
||||
<li>Preventing fraudulent activities</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>Information Sharing</h2>
|
||||
<p>
|
||||
The App does not share collected information with third parties except in the following cases:
|
||||
</p>
|
||||
<ul>
|
||||
<li>When user consent is obtained</li>
|
||||
<li>When disclosure is required by law</li>
|
||||
<li>When sharing with service providers necessary for operation (under appropriate agreements)</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>Data Storage</h2>
|
||||
<p>
|
||||
User data such as favorite settings is primarily stored on your device.
|
||||
Data related to Bluesky integration is managed on Bluesky's servers.
|
||||
</p>
|
||||
<p>
|
||||
Any data stored on the App’s servers is protected with appropriate security measures.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>External Services</h2>
|
||||
<p>The App may integrate with the following external services:</p>
|
||||
<ul>
|
||||
<li><strong>Bluesky (AT Protocol)</strong> – Card ownership verification and user authentication</li>
|
||||
<li><strong>api.syui.ai</strong> – Retrieving card data</li>
|
||||
</ul>
|
||||
<p>
|
||||
Each external service has its own privacy policy.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>User Rights</h2>
|
||||
<p>Users have the following rights:</p>
|
||||
<ul>
|
||||
<li>Right to access their data</li>
|
||||
<li>Right to request correction or deletion</li>
|
||||
<li>Right to withdraw consent to data processing</li>
|
||||
</ul>
|
||||
<p>
|
||||
To exercise these rights, please contact us using the information below.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>Children’s Privacy</h2>
|
||||
<p>
|
||||
The App does not intentionally collect personal information from children under the age of 13.
|
||||
Children under 13 should use the App only with parental consent.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>Changes to This Policy</h2>
|
||||
<p>
|
||||
This policy may be updated as necessary.
|
||||
In the event of significant changes, we will notify users within the App or on the website.
|
||||
By continuing to use the App after changes are made, you are deemed to have accepted the updated policy.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2>Contact</h2>
|
||||
<p>
|
||||
For questions or inquiries regarding this Privacy Policy, please contact us at:
|
||||
</p>
|
||||
<div class="contact-info">
|
||||
<p style="margin-bottom: 8px; color: #fff;">
|
||||
<strong>Aicard Support</strong>
|
||||
</p>
|
||||
<p style="margin: 0; color: #fff;">
|
||||
<a href="https://github.com/syui">syui</a>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>© syui</p>
|
||||
<p style="margin-top: 8px;">
|
||||
<a href="/app.html">Back to App Introduction</a>
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user