732 lines
24 KiB
JavaScript
732 lines
24 KiB
JavaScript
// GSAP动画配置文件
|
||
// 确保在DOM加载完成后执行动画
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// 检查GSAP是否已加载
|
||
if (typeof gsap === 'undefined') {
|
||
console.warn('GSAP library is not loaded. Please include GSAP before this script.');
|
||
// 如果GSAP未加载,确保所有元素可见
|
||
const allElements = document.querySelectorAll('.navbar, .contact-buttons .btn, .skill-category, .contact-item, .other-experience, .modern-project-showcase');
|
||
allElements.forEach(el => {
|
||
if (el) {
|
||
el.style.opacity = '1';
|
||
el.style.visibility = 'visible';
|
||
el.style.transform = '';
|
||
console.log(`Made ${el.className} visible (GSAP fallback)`);
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
|
||
console.log('GSAP loaded successfully, initializing animations...');
|
||
|
||
// ===== 页面加载动画 =====
|
||
function initLoadingAnimations() {
|
||
// 隐藏加载器的动画
|
||
gsap.to("#loader", {
|
||
opacity: 0,
|
||
duration: 0.5,
|
||
delay: 1,
|
||
onComplete: function() {
|
||
document.getElementById('loader').style.display = 'none';
|
||
}
|
||
});
|
||
|
||
// 导航栏动画
|
||
// 首先确保导航栏存在
|
||
const navbarElement = document.querySelector(".navbar");
|
||
if (navbarElement) {
|
||
gsap.from(".navbar", {
|
||
y: -100,
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
delay: 1.2,
|
||
ease: "back.out(1.7)"
|
||
});
|
||
} else {
|
||
console.warn('Navbar element not found for animation');
|
||
}
|
||
}
|
||
|
||
// ===== 首页英雄区域动画 =====
|
||
function initHeroAnimations() {
|
||
// 确保元素初始可见,然后应用动画
|
||
gsap.set([".hero-avatar", ".hero h1", ".hero .subtitle", ".hero .description", ".contact-buttons .btn"], {
|
||
clearProps: "all"
|
||
});
|
||
|
||
const tl = gsap.timeline({ delay: 1.5 });
|
||
|
||
tl.from(".hero-avatar", {
|
||
scale: 0,
|
||
rotation: 360,
|
||
duration: 1,
|
||
ease: "back.out(1.7)"
|
||
})
|
||
.from(".hero h1", {
|
||
y: 50,
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
ease: "power2.out"
|
||
}, "-=0.5")
|
||
.from(".hero .subtitle", {
|
||
y: 30,
|
||
opacity: 0,
|
||
duration: 0.6,
|
||
ease: "power2.out"
|
||
}, "-=0.3")
|
||
.from(".hero .description", {
|
||
y: 30,
|
||
opacity: 0,
|
||
duration: 0.6,
|
||
ease: "power2.out"
|
||
}, "-=0.2")
|
||
.from(".contact-buttons .btn", {
|
||
y: 30,
|
||
opacity: 0,
|
||
duration: 0.5,
|
||
stagger: 0.1,
|
||
ease: "power2.out"
|
||
}, "-=0.2");
|
||
}
|
||
|
||
// ===== 滚动触发动画 =====
|
||
function initScrollAnimations() {
|
||
// 注册ScrollTrigger插件
|
||
if (typeof ScrollTrigger !== 'undefined') {
|
||
gsap.registerPlugin(ScrollTrigger);
|
||
} else {
|
||
console.warn('ScrollTrigger plugin not found. Elements will be visible immediately.');
|
||
// 如果ScrollTrigger不可用,确保所有元素可见
|
||
gsap.set([".skill-category", ".contact-item", ".other-experience", ".modern-project-showcase"], {
|
||
opacity: 1,
|
||
y: 0,
|
||
x: 0
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 基本资料部分动画
|
||
gsap.from("#basic-info .section-title", {
|
||
scrollTrigger: {
|
||
trigger: "#basic-info",
|
||
start: "top 80%",
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 50,
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
gsap.from("#basic-info .project-card", {
|
||
scrollTrigger: {
|
||
trigger: "#basic-info",
|
||
start: "top 70%",
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 80,
|
||
opacity: 0,
|
||
duration: 1,
|
||
delay: 0.2,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
gsap.from("#basic-info .education-item", {
|
||
scrollTrigger: {
|
||
trigger: "#basic-info .education-item",
|
||
start: "top 80%",
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
x: -80,
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
// 技能卡片动画
|
||
gsap.from("#skills .section-title", {
|
||
scrollTrigger: {
|
||
trigger: "#skills",
|
||
start: "top 80%",
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 50,
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
gsap.to(".skill-category", {
|
||
scrollTrigger: {
|
||
trigger: "#skills",
|
||
start: "top 70%",
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
opacity: 1,
|
||
duration: 2,
|
||
scale: 1,
|
||
delay: 0.5,
|
||
ease: "cire.out"
|
||
});
|
||
|
||
// 项目展示动画
|
||
gsap.from("#experience .section-title", {
|
||
scrollTrigger: {
|
||
trigger: "#experience",
|
||
start: "top 80%",
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 50,
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
// 只为可见的项目卡片设置动画
|
||
gsap.from("#industrial-design-content .modern-project-showcase", {
|
||
scrollTrigger: {
|
||
trigger: "#experience",
|
||
start: "top 70%",
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
x: -100,
|
||
opacity: 0,
|
||
duration: 1.2,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
// 为其他标签的项目卡片设置初始可见状态
|
||
gsap.set("#machining-content .modern-project-showcase, #automation-content .modern-project-showcase, #non-standard-content .modern-project-showcase", {
|
||
opacity: 1,
|
||
x: 0
|
||
});
|
||
|
||
// 实习经历标签动画
|
||
gsap.from(".experience-tab-btn", {
|
||
scrollTrigger: {
|
||
trigger: ".experience-tabs",
|
||
start: "top 80%",
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 30,
|
||
opacity: 0,
|
||
duration: 0.6,
|
||
stagger: 0.1,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
gsap.from(".placeholder-card", {
|
||
scrollTrigger: {
|
||
trigger: ".experience-tab-content",
|
||
start: "top 70%",
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 50,
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
// 个人总结动画 - 极宽松触发条件,适应所有标签页面高度
|
||
gsap.from("#summary .section-title", {
|
||
scrollTrigger: {
|
||
trigger: "#summary",
|
||
start: "top 50%", // 极宽松触发阈值,页面滚动即触发
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 50,
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
gsap.from("#summary .summary-content", {
|
||
scrollTrigger: {
|
||
trigger: "#summary",
|
||
start: "top 50%", // 极宽松触发阈值,页面滚动即触发
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 30,
|
||
opacity: 0,
|
||
duration: 1,
|
||
delay: 0.2,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
// 联系信息动画 - 极宽松触发条件,适应所有标签页面高度
|
||
gsap.from("#contact .section-title", {
|
||
scrollTrigger: {
|
||
trigger: "#contact",
|
||
start: "top 100%", // 极宽松触发阈值,页面滚动即触发
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 50,
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
gsap.from(".contact-item", {
|
||
scrollTrigger: {
|
||
trigger: "#contact",
|
||
start: "top 100%", // 极宽松触发阈值,页面滚动即触发
|
||
toggleActions: "play none none reverse"
|
||
},
|
||
y: 50,
|
||
opacity: 0,
|
||
duration: 0.6,
|
||
stagger: 0.15,
|
||
ease: "power2.out"
|
||
});
|
||
}
|
||
|
||
// ===== 悬停交互动画 =====
|
||
function initHoverAnimations() {
|
||
// 项目卡片悬停动画
|
||
const projectCard = document.querySelector('.modern-project-showcase');
|
||
if (projectCard) {
|
||
projectCard.addEventListener('mouseenter', function() {
|
||
gsap.to(this, {
|
||
y: -15,
|
||
scale: 1.02,
|
||
duration: 0.3,
|
||
ease: "power2.out"
|
||
});
|
||
});
|
||
|
||
projectCard.addEventListener('mouseleave', function() {
|
||
gsap.to(this, {
|
||
y: 0,
|
||
scale: 1,
|
||
duration: 0.3,
|
||
ease: "power2.out"
|
||
});
|
||
});
|
||
}
|
||
|
||
// 技能卡片悬停动画
|
||
document.querySelectorAll('.skill-category').forEach(card => {
|
||
card.addEventListener('mouseenter', function() {
|
||
gsap.to(this, {
|
||
y: -8,
|
||
scale: 1.01,
|
||
duration: 0.3,
|
||
ease: "power2.out"
|
||
});
|
||
});
|
||
|
||
card.addEventListener('mouseleave', function() {
|
||
gsap.to(this, {
|
||
y: 0,
|
||
scale: 1,
|
||
duration: 0.3,
|
||
ease: "power2.out"
|
||
});
|
||
});
|
||
});
|
||
}
|
||
|
||
// ===== 弹窗动画增强 =====
|
||
function initModalAnimations() {
|
||
// 替换原有的职责弹窗动画
|
||
window.openResponsibilitiesModalGSAP = function() {
|
||
const modal = document.getElementById('responsibilitiesModal');
|
||
const content = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
modal.style.display = 'block';
|
||
document.body.style.overflow = 'hidden';
|
||
|
||
// GSAP弹窗动画
|
||
gsap.fromTo(modal,
|
||
{ opacity: 0 },
|
||
{ opacity: 1, duration: 0.3 }
|
||
);
|
||
|
||
gsap.fromTo(content,
|
||
{ x: '-100%', opacity: 0 },
|
||
{ x: '0%', opacity: 1, duration: 0.4, ease: "power2.out" }
|
||
);
|
||
};
|
||
|
||
window.closeResponsibilitiesModalGSAP = function() {
|
||
const modal = document.getElementById('responsibilitiesModal');
|
||
const content = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
// GSAP关闭动画
|
||
gsap.to(content, {
|
||
x: '100%',
|
||
opacity: 0,
|
||
duration: 0.4,
|
||
ease: "power2.in",
|
||
onComplete: function() {
|
||
modal.style.display = 'none';
|
||
document.body.style.overflow = 'auto';
|
||
}
|
||
});
|
||
|
||
gsap.to(modal, {
|
||
opacity: 0,
|
||
duration: 0.3,
|
||
delay: 0.1
|
||
});
|
||
};
|
||
|
||
// 智能手表项目弹窗动画
|
||
window.openWatchProjectModalGSAP = function() {
|
||
const modal = document.getElementById('watchProjectModal');
|
||
const content = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
modal.style.display = 'block';
|
||
document.body.style.overflow = 'hidden';
|
||
|
||
// GSAP弹窗动画
|
||
gsap.fromTo(modal,
|
||
{ opacity: 0 },
|
||
{ opacity: 1, duration: 0.3 }
|
||
);
|
||
|
||
gsap.fromTo(content,
|
||
{ x: '-100%', opacity: 0 },
|
||
{ x: '0%', opacity: 1, duration: 0.4, ease: "power2.out" }
|
||
);
|
||
};
|
||
|
||
window.closeWatchProjectModalGSAP = function() {
|
||
const modal = document.getElementById('watchProjectModal');
|
||
const content = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
// GSAP关闭动画
|
||
gsap.to(content, {
|
||
x: '100%',
|
||
opacity: 0,
|
||
duration: 0.4,
|
||
ease: "power2.in",
|
||
onComplete: function() {
|
||
modal.style.display = 'none';
|
||
document.body.style.overflow = 'auto';
|
||
}
|
||
});
|
||
|
||
gsap.to(modal, {
|
||
opacity: 0,
|
||
duration: 0.3,
|
||
delay: 0.1
|
||
});
|
||
};
|
||
}
|
||
|
||
// ===== 机械加工工艺项目弹窗动画 =====
|
||
function initMachiningProjectModalAnimations() {
|
||
window.openMachiningProjectModalGSAP = function() {
|
||
const modal = document.getElementById('machiningProjectModal');
|
||
if (!modal) return;
|
||
|
||
modal.style.display = 'flex';
|
||
document.body.style.overflow = 'hidden';
|
||
|
||
const modalContent = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
// 重置初始状态
|
||
gsap.set(modal, { opacity: 0 });
|
||
gsap.set(modalContent, { x: '-100%', opacity: 0 });
|
||
|
||
// 弹窗背景淡入
|
||
gsap.to(modal, {
|
||
opacity: 1,
|
||
duration: 0.3,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
// 内容区域从左侧滑入
|
||
gsap.to(modalContent, {
|
||
x: '0%',
|
||
opacity: 1,
|
||
duration: 0.5,
|
||
delay: 0.1,
|
||
ease: "power3.out"
|
||
});
|
||
};
|
||
|
||
window.closeMachiningProjectModalGSAP = function() {
|
||
const modal = document.getElementById('machiningProjectModal');
|
||
if (!modal) return;
|
||
|
||
const modalContent = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
// 内容区域向右侧滑出
|
||
gsap.to(modalContent, {
|
||
x: '100%',
|
||
opacity: 0,
|
||
duration: 0.4,
|
||
ease: "power2.in",
|
||
onComplete: function() {
|
||
modal.style.display = 'none';
|
||
document.body.style.overflow = 'auto';
|
||
}
|
||
});
|
||
|
||
gsap.to(modal, {
|
||
opacity: 0,
|
||
duration: 0.3,
|
||
delay: 0.1
|
||
});
|
||
};
|
||
}
|
||
|
||
// ===== 自动化控制项目弹窗动画 =====
|
||
function initAutomationProjectModalAnimations() {
|
||
window.openAutomationProjectModalGSAP = function() {
|
||
const modal = document.getElementById('automationProjectModal');
|
||
if (!modal) return;
|
||
|
||
modal.style.display = 'flex';
|
||
document.body.style.overflow = 'hidden';
|
||
|
||
const modalContent = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
// 重置初始状态
|
||
gsap.set(modal, { opacity: 0 });
|
||
gsap.set(modalContent, { x: '-100%', opacity: 0 });
|
||
|
||
// 弹窗背景淡入
|
||
gsap.to(modal, {
|
||
opacity: 1,
|
||
duration: 0.3,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
// 内容区域从左侧滑入
|
||
gsap.to(modalContent, {
|
||
x: '0%',
|
||
opacity: 1,
|
||
duration: 0.5,
|
||
delay: 0.1,
|
||
ease: "power3.out"
|
||
});
|
||
};
|
||
|
||
window.closeAutomationProjectModalGSAP = function() {
|
||
const modal = document.getElementById('automationProjectModal');
|
||
if (!modal) return;
|
||
|
||
const modalContent = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
// 内容区域向右侧滑出
|
||
gsap.to(modalContent, {
|
||
x: '100%',
|
||
opacity: 0,
|
||
duration: 0.4,
|
||
ease: "power2.in",
|
||
onComplete: function() {
|
||
modal.style.display = 'none';
|
||
document.body.style.overflow = 'auto';
|
||
}
|
||
});
|
||
|
||
gsap.to(modal, {
|
||
opacity: 0,
|
||
duration: 0.3,
|
||
delay: 0.1
|
||
});
|
||
};
|
||
}
|
||
|
||
// ===== 非标自动化项目弹窗动画 =====
|
||
function initNonStandardProjectModalAnimations() {
|
||
window.openNonStandardProjectModalGSAP = function() {
|
||
const modal = document.getElementById('nonStandardProjectModal');
|
||
if (!modal) return;
|
||
|
||
modal.style.display = 'flex';
|
||
document.body.style.overflow = 'hidden';
|
||
|
||
const modalContent = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
// 重置初始状态
|
||
gsap.set(modal, { opacity: 0 });
|
||
gsap.set(modalContent, { x: '-100%', opacity: 0 });
|
||
|
||
// 弹窗背景淡入
|
||
gsap.to(modal, {
|
||
opacity: 1,
|
||
duration: 0.3,
|
||
ease: "power2.out"
|
||
});
|
||
|
||
// 内容区域从左侧滑入
|
||
gsap.to(modalContent, {
|
||
x: '0%',
|
||
opacity: 1,
|
||
duration: 0.5,
|
||
delay: 0.1,
|
||
ease: "power3.out"
|
||
});
|
||
};
|
||
|
||
window.closeNonStandardProjectModalGSAP = function() {
|
||
const modal = document.getElementById('nonStandardProjectModal');
|
||
if (!modal) return;
|
||
|
||
const modalContent = modal.querySelector('.responsibilities-modal-content');
|
||
|
||
// 内容区域向右侧滑出
|
||
gsap.to(modalContent, {
|
||
x: '100%',
|
||
opacity: 0,
|
||
duration: 0.4,
|
||
ease: "power2.in",
|
||
onComplete: function() {
|
||
modal.style.display = 'none';
|
||
document.body.style.overflow = 'auto';
|
||
}
|
||
});
|
||
|
||
gsap.to(modal, {
|
||
opacity: 0,
|
||
duration: 0.3,
|
||
delay: 0.1
|
||
});
|
||
};
|
||
}
|
||
|
||
// ===== 粒子背景动画增强 =====
|
||
function initParticleAnimations() {
|
||
// 可以在这里添加与粒子背景的GSAP交互
|
||
// 例如:鼠标移动时的粒子响应动画
|
||
}
|
||
|
||
// ===== 返回顶部按钮动画管理 =====
|
||
function initScrollTopButtonAnimation() {
|
||
let scrollTopAnimation = null;
|
||
const scrollTopButton = document.getElementById('scrollTop');
|
||
|
||
if (!scrollTopButton) return;
|
||
|
||
// 全局函数供外部调用
|
||
window.startScrollTopAnimation = function() {
|
||
if (!scrollTopAnimation) {
|
||
scrollTopAnimation = gsap.to(scrollTopButton, {
|
||
y: -10,
|
||
duration: 1.5,
|
||
repeat: -1,
|
||
yoyo: true,
|
||
ease: "power2.inOut"
|
||
});
|
||
}
|
||
};
|
||
|
||
window.stopScrollTopAnimation = function() {
|
||
if (scrollTopAnimation) {
|
||
scrollTopAnimation.kill();
|
||
gsap.set(scrollTopButton, { y: 0 });
|
||
scrollTopAnimation = null;
|
||
}
|
||
};
|
||
}
|
||
|
||
// ===== 统一的元素可见性确保机制 =====
|
||
function ensureElementsVisible() {
|
||
// 确保关键元素始终可见,防止动画失败导致元素消失
|
||
const criticalElements = [
|
||
'.navbar', // 导航栏
|
||
'.contact-buttons .btn', // 首页按钮
|
||
'.skill-category', // 技能卡片
|
||
'.contact-item', // 联系方式
|
||
'.experience-tab-btn', // 实习经历标签
|
||
'.modern-project-showcase' // 项目展示
|
||
];
|
||
|
||
criticalElements.forEach(selector => {
|
||
const elements = document.querySelectorAll(selector);
|
||
elements.forEach(el => {
|
||
if (el) {
|
||
// 检查元素是否可能被隐藏
|
||
const computedStyle = window.getComputedStyle(el);
|
||
const isHidden = el.style.opacity === '0' ||
|
||
el.style.visibility === 'hidden' ||
|
||
computedStyle.opacity === '0' ||
|
||
computedStyle.visibility === 'hidden';
|
||
|
||
if (isHidden) {
|
||
console.log(`Making ${selector} visible as fallback`);
|
||
if (typeof gsap !== 'undefined') {
|
||
// 优先使用GSAP设置
|
||
gsap.set(el, { opacity: 1, visibility: 'visible', y: 0, x: 0 });
|
||
} else {
|
||
// 回退到原生CSS
|
||
el.style.opacity = '1';
|
||
el.style.visibility = 'visible';
|
||
el.style.transform = '';
|
||
}
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// ===== 初始化所有动画 =====
|
||
function initAllAnimations() {
|
||
try {
|
||
initLoadingAnimations();
|
||
initHeroAnimations();
|
||
initScrollAnimations();
|
||
initHoverAnimations();
|
||
initModalAnimations();
|
||
initMachiningProjectModalAnimations();
|
||
initAutomationProjectModalAnimations();
|
||
initNonStandardProjectModalAnimations();
|
||
initParticleAnimations();
|
||
initScrollTopButtonAnimation();
|
||
|
||
// 延迟检查元素可见性
|
||
setTimeout(ensureElementsVisible, 2000);
|
||
} catch (error) {
|
||
console.error('GSAP animation initialization failed:', error);
|
||
// 如果动画初始化失败,确保所有元素可见
|
||
ensureElementsVisible();
|
||
}
|
||
}
|
||
|
||
// 启动动画系统
|
||
initAllAnimations();
|
||
|
||
// 暴露一些函数到全局作用域,以便HTML中调用
|
||
window.gsapAnimations = {
|
||
openModal: window.openResponsibilitiesModalGSAP,
|
||
closeModal: window.closeResponsibilitiesModalGSAP,
|
||
openWatchModal: window.openWatchProjectModalGSAP,
|
||
closeWatchModal: window.closeWatchProjectModalGSAP
|
||
};
|
||
});
|
||
|
||
// ===== 工具函数 =====
|
||
function createTextAnimation(selector, options = {}) {
|
||
const defaults = {
|
||
y: 30,
|
||
opacity: 0,
|
||
duration: 0.6,
|
||
stagger: 0.1,
|
||
ease: "power2.out"
|
||
};
|
||
|
||
const settings = { ...defaults, ...options };
|
||
|
||
return gsap.from(selector, settings);
|
||
}
|
||
|
||
function createFadeInAnimation(selector, direction = 'up', distance = 50) {
|
||
const transforms = {
|
||
up: { y: distance },
|
||
down: { y: -distance },
|
||
left: { x: distance },
|
||
right: { x: -distance }
|
||
};
|
||
|
||
return gsap.from(selector, {
|
||
...transforms[direction],
|
||
opacity: 0,
|
||
duration: 0.8,
|
||
ease: "power2.out"
|
||
});
|
||
}
|