Commit 0f99ddbc authored by Văn Hoàng's avatar Văn Hoàng

Merge branch 'refactor/generate_api_and_fix_fallback_img' into 'develop-news'

fix: gen api and add img fallback for home and detail category page

See merge request !110
parents 132042dd 1ac757c3

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

import type { NextConfig } from "next"; import type { NextConfig } from "next";
import links from "./src/links/index";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
images: { images: {
remotePatterns: [ remotePatterns: [
...(links.backendHost
? [
{
protocol: links.backendProtocol as "http" | "https",
hostname: links.backendHost,
port: "",
pathname: `${links.backendPathname === "/" ? "" : links.backendPathname}/**`,
},
]
: []),
// Local development
{ {
protocol: "http", protocol: "http",
hostname: "localhost", hostname: "localhost",
...@@ -23,7 +11,7 @@ const nextConfig: NextConfig = { ...@@ -23,7 +11,7 @@ const nextConfig: NextConfig = {
}, },
{ {
protocol: "https", protocol: "https",
hostname: "vcci-hcm.org.vn", // WordPress / media host hostname: "vcci-hcm.org.vn",
port: "", port: "",
pathname: "/wp-content/uploads/**", pathname: "/wp-content/uploads/**",
}, },
......
This diff is collapsed.
import 'dotenv/config'
import { defineConfig } from "orval"; import { defineConfig } from "orval";
import axios from "axios"; import links from "./src/links/index";
import fs from "fs";
import path from "path";
function loadEnvFile(filePath: string) { const orvalConfig = defineConfig({
if (!fs.existsSync(filePath)) return; // VCCI News API
"vcci-news": {
const content = fs.readFileSync(filePath, "utf8");
content.split(/\r?\n/).forEach((line) => {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) return;
const equalsIndex = trimmed.indexOf("=");
if (equalsIndex < 0) return;
const key = trimmed.slice(0, equalsIndex).trim();
const value = trimmed.slice(equalsIndex + 1).trim().replace(/^['"]|['"]$/g, "");
if (key && process.env[key] === undefined) {
process.env[key] = value;
}
});
}
loadEnvFile(path.resolve(process.cwd(), ".env"));
const backendHost = process.env.NEXT_PUBLIC_BACKEND_HOST;
const siteURL = process.env.NEXT_PUBLIC_FRONTEND_HOST;
const swaggerCandidates = [
// 1) Explicit override (highest priority)
process.env.ORVAL_SWAGGER_URL,
// 2) Sibling backend repo (local dev with both repos checked out)
path.resolve(process.cwd(), "..", "vietprodev-cms-backend", "storage", "swagger", "swagger-output.json"),
// 3) Committed spec in repo — deterministic source for CI builds.
// Must be tried BEFORE HTTP URLs: production backend doesn't serve swagger
// and ${backendHost}/swagger/swagger-output.json may return a stale/wrong spec.
path.resolve(process.cwd(), "openapi", "swagger-output.json"),
// 4) HTTP fallbacks (last resort)
`${backendHost}/swagger-output.json`,
`${backendHost}/swagger/swagger-output.json`,
`${backendHost}/swagger.json`,
`${backendHost}/openapi.json`,
`${backendHost}/api/swagger/swagger-output.json`,
`${backendHost}/vcci/swagger/swagger-output.json`,
].filter(Boolean) as string[];
async function fetchSwagger() {
for (const url of swaggerCandidates) {
if (!url) continue;
// 1) Local file path
if (fs.existsSync(url) && fs.statSync(url).isFile()) {
const raw = fs.readFileSync(url, "utf8");
try {
return JSON.parse(raw);
} catch (error) {
throw new Error(`Swagger spec tại ${url} không phải JSON hợp lệ: ${error}`);
}
}
// 2) HTTP fetch — chỉ chấp nhận JSON, bỏ qua HTML (404, page app,...)
if (/^https?:\/\//i.test(url)) {
try {
const { data, headers } = await axios.get(url, {
headers: { Origin: siteURL },
// Ngăn axios tự nhận HTML là JSON — ép raw response để check Content-Type
responseType: "json",
validateStatus: (status) => status >= 200 && status < 400,
});
const contentType = String(headers?.["content-type"] ?? "").toLowerCase();
if (!contentType.includes("application/json") && typeof data === "string") {
// Phản hồi không phải JSON (thường là HTML 404) — bỏ qua candidate này
continue;
}
if (data && typeof data === "object") {
return data;
}
} catch {
continue;
}
}
}
// 3) Fallback cuối: openapi/swagger-output.json nằm trong repo
const localSwagger = path.resolve(process.cwd(), "openapi/swagger-output.json");
if (fs.existsSync(localSwagger)) {
const raw = fs.readFileSync(localSwagger, "utf8");
try {
return JSON.parse(raw);
} catch (error) {
throw new Error(`Swagger spec tại ${localSwagger} không phải JSON hợp lệ: ${error}`);
}
}
throw new Error(
`Unable to load Swagger/OpenAPI JSON. Tried: ${swaggerCandidates.join(", ")}`,
);
}
const orvalConfig = async () => {
const swagger = await fetchSwagger();
return defineConfig({
"saigon-business": {
output: { output: {
mode: "tags", mode: "tags",
target: "src/api/endpoints/index.ts", target: "src/api/vcci-news/endpoints/index.ts",
schemas: "src/api/models", schemas: "src/api/vcci-news/models",
client: "react-query", client: "react-query",
prettier: true,
override: { override: {
query: {
useInfinite: true,
usePrefetch: true,
options: {
retry: 3,
retryDelay: 1000,
}
},
mutator: { mutator: {
path: "src/api/mutator/custom-client.ts", path: "src/api/vcci-news/mutator/custom-client.ts",
name: "useCustomClient", name: "useCustomClient",
}, },
}
},
input: {
target: `${links.apiEndpoint}/swagger-output.json`,
filters: {
tags: undefined,
},
},
},
// VCCI HCM API
"vcci-hcm": {
output: {
mode: "tags",
target: "src/api/vcci-hcm/endpoints/index.ts",
schemas: "src/api/vcci-hcm/models",
client: "react-query",
override: {
query: { query: {
useQuery: true,
useInfinite: true, useInfinite: true,
usePrefetch: true, usePrefetch: true,
// useSuspenseQuery: true,
options: { options: {
retry: 3, retry: 3,
retryDelay: 1000, retryDelay: 1000,
} }
}, },
mutator: {
path: "src/api/vcci-hcm/mutator/custom-client.ts",
name: "useCustomClient",
},
} }
}, },
input: { input: {
target: swagger, target: `${links.externalApiEndpoint}/swagger-output.json`,
validation: false,
parserOptions: { validate: false },
filters: { filters: {
// Tag whitelist dùng tên CHÍNH XÁT trong OpenAPI spec — lấy từ openapi/swagger-output.json. tags: ["Organizations"],
// Cập nhật khi backend thêm/xóa tag. Bỏ hết filter nếu muốn generate toàn bộ.
tags: [
'Authentication',
'Advertisement',
'Banner',
'Business',
'Category',
'CategoryTag',
'Contact',
'File',
'Logo',
'Member',
'NewsletterSubscription',
'PageConfig',
'PasswordResetRequest',
'Permission',
'Position',
'Post',
'PostCategory',
'PostTag',
'Role',
'RolePermission',
'SiteInformation',
'Tag',
'Term',
'User',
'UserRole',
'VCCI',
'Video',
],
},
}, },
}, },
}); }
} });
export default orvalConfig export default orvalConfig
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev --webpack", "dev": "next dev --turbopack",
"build": "next build --webpack", "build": "next build --turbopack",
"start": "next start", "start": "next start",
"lint": "eslint", "lint": "eslint",
"generate:api": "node scripts/generate-api.mjs" "generate:api": "orval"
}, },
"dependencies": { "dependencies": {
"@hookform/resolvers": "^5.2.2", "@hookform/resolvers": "^5.2.2",
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
"jodit-react": "^5.3.21", "jodit-react": "^5.3.21",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"lucide-react": "^0.548.0", "lucide-react": "^0.548.0",
"next": "16.0.10", "next": "16.2.10",
"next-nprogress-bar": "^2.4.7", "next-nprogress-bar": "^2.4.7",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"react": "19.2.0", "react": "19.2.0",
...@@ -73,10 +73,11 @@ ...@@ -73,10 +73,11 @@
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",
"axios": "^1.13.1", "axios": "^1.13.1",
"baseline-browser-mapping": "^2.10.32", "baseline-browser-mapping": "^2.11.20",
"dotenv": "^17.4.2",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "16.0.1", "eslint-config-next": "16.0.1",
"orval": "8.0.0-rc.0", "orval": "^7.17.0",
"tailwindcss": "^4", "tailwindcss": "^4",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "^5" "typescript": "^5"
......
This diff is collapsed.
This diff is collapsed.
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
const cwd = process.cwd();
const endpointsDir = path.join(cwd, "src", "api", "endpoints");
const modelsDir = path.join(cwd, "src", "api", "models");
function hasGeneratedApi() {
if (!fs.existsSync(endpointsDir) || !fs.existsSync(modelsDir)) {
return false;
}
const endpointFiles = fs.readdirSync(endpointsDir).filter((file) => file.endsWith(".ts"));
const modelFiles = fs.readdirSync(modelsDir).filter((file) => file.endsWith(".ts"));
return endpointFiles.length > 0 && modelFiles.length > 0;
}
const result = spawnSync(
process.platform === "win32" ? "npx.cmd" : "npx",
["orval", "-c", "orval.config.ts"],
{
cwd,
stdio: "inherit",
shell: false,
env: process.env,
},
);
if (result.status === 0) {
process.exit(0);
}
if (hasGeneratedApi()) {
console.warn(
"Skipping API regeneration because Swagger is unavailable and generated client files already exist.",
);
process.exit(0);
}
process.exit(result.status ?? 1);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**
* Generated by orval v8.0.0-rc.0 🍺
* Do not edit manually.
* VietProDev CMS Backend API
* Generated API documentation
* OpenAPI spec version: 1.0.0
*/
import type { AdvertisementFile } from './advertisementFile';
import type { AdvertisementType } from './advertisementType';
import type { AdvertisementStatus } from './advertisementStatus';
export interface Advertisement {
id: string;
/** @maxLength 255 */
name: string;
file_id: string;
/** @nullable */
file?: AdvertisementFile;
/**
* @maxLength 255
* @nullable
*/
alt?: string | null;
/** @maxLength 500 */
link: string;
type: AdvertisementType;
status: AdvertisementStatus;
sort_order: number;
/** @nullable */
created_at?: string | null;
/** @nullable */
created_by?: string | null;
/** @nullable */
updated_at?: string | null;
/** @nullable */
updated_by?: string | null;
}
/**
* Generated by orval v8.0.0-rc.0 🍺
* Do not edit manually.
* VietProDev CMS Backend API
* Generated API documentation
* OpenAPI spec version: 1.0.0
*/
import type { AdvertisementCreateType } from './advertisementCreateType';
import type { AdvertisementCreateStatus } from './advertisementCreateStatus';
export interface AdvertisementCreate {
/** @maxLength 255 */
name: string;
file_id: string;
/**
* @maxLength 255
* @nullable
*/
alt?: string | null;
/** @maxLength 500 */
link: string;
type?: AdvertisementCreateType;
status?: AdvertisementCreateStatus;
sort_order?: number;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment