|
@@ -1,14 +1,26 @@
|
|
|
-// page-dynamic.component.ts
|
|
|
-import { Component, AfterViewInit } from '@angular/core';
|
|
|
+// page-dynamic.ts
|
|
|
+import { Component, AfterViewInit, ChangeDetectorRef, Pipe, PipeTransform } from '@angular/core';
|
|
|
import { FormsModule } from '@angular/forms';
|
|
|
+import { CommonModule,DatePipe} from '@angular/common';
|
|
|
+import { CloudUser, CloudObject, CloudQuery } from '../../../../lib/ncloud';
|
|
|
+
|
|
|
+@Pipe({ name: 'truncate', standalone: true })
|
|
|
+export class TruncatePipe implements PipeTransform {
|
|
|
+ transform(value: string, limit: number = 20, trail: string = '...'): string {
|
|
|
+ return value.length > limit
|
|
|
+ ? value.substring(0, limit) + trail
|
|
|
+ : value;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
@Component({
|
|
|
selector: 'app-page-dynamic',
|
|
|
standalone: true,
|
|
|
templateUrl: './page-dynamic.html',
|
|
|
styleUrls: ['./page-dynamic.scss'],
|
|
|
- imports: [FormsModule]
|
|
|
+ imports: [FormsModule, TruncatePipe,DatePipe]
|
|
|
})
|
|
|
+
|
|
|
export class PageDynamic implements AfterViewInit {
|
|
|
isOcrSuccess: boolean | null = null;
|
|
|
activeLanterns = false;
|
|
@@ -19,12 +31,259 @@ export class PageDynamic implements AfterViewInit {
|
|
|
description: '',
|
|
|
document: null as File | null
|
|
|
};
|
|
|
+
|
|
|
+ currentUser: CloudUser | null = null;
|
|
|
+ achievements: CloudObject[] = []; // 成就列表
|
|
|
+ newAchievement: any = {
|
|
|
+ title: '',
|
|
|
+ description: '',
|
|
|
+ category: '作品',
|
|
|
+ imageUrl: ''
|
|
|
+ };
|
|
|
+ editingAchievement: CloudObject | null = null;
|
|
|
+ isAddingAchievement = false;
|
|
|
+ isEditingAchievement = false;
|
|
|
|
|
|
- ngAfterViewInit() {
|
|
|
+ // 新增属性
|
|
|
+ searchTerm: string = '';
|
|
|
+ selectedCategory: string | null = null;
|
|
|
+ filteredAchievements: CloudObject[] = [];
|
|
|
+ achievementCategories = ['作品', '证书', '奖项', '荣誉'];
|
|
|
+ userMap: Record<string, CloudObject> = {}; // 用户缓存
|
|
|
+ constructor(private cdr: ChangeDetectorRef) {}
|
|
|
+
|
|
|
+ // 三维荣誉墙相关属性
|
|
|
+ awardRecords: CloudObject[] = []; // 奖项记录
|
|
|
+ awardCategories: CloudObject[] = []; // 奖项类别
|
|
|
+ years: number[] = this.generateYears(2015, 2025); // 生成2015-2025年
|
|
|
+ filter = {
|
|
|
+ year: null as number | null, // 默认选中"全部年份"
|
|
|
+ categoryId: null as string | null
|
|
|
+ };
|
|
|
+ selectedAward: CloudObject | null = null;
|
|
|
+ showAwardDetail = false;
|
|
|
+
|
|
|
+ // 生成年份数组方法
|
|
|
+ generateYears(start: number, end: number): number[] {
|
|
|
+ const years = [];
|
|
|
+ for (let year = end; year >= start; year--) {
|
|
|
+ years.push(year);
|
|
|
+ }
|
|
|
+ return years;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 预设的荣誉墙位置
|
|
|
+ honorPositions = [
|
|
|
+ { top: '20px', left: '50px' },
|
|
|
+ { top: '60px', right: '40px' },
|
|
|
+ { bottom: '80px', left: '30px' },
|
|
|
+ { bottom: '40px', right: '60px' },
|
|
|
+ { top: '100px', left: '100px' },
|
|
|
+ { top: '150px', right: '80px' },
|
|
|
+ { bottom: '120px', left: '120px' },
|
|
|
+ { top: '180px', left: '30px' },
|
|
|
+ { bottom: '100px', right: '120px' },
|
|
|
+ { top: '220px', right: '30px' }
|
|
|
+ ];
|
|
|
+
|
|
|
+ async ngAfterViewInit() {
|
|
|
this.initCraneInteraction();
|
|
|
this.initPavilionInteraction();
|
|
|
+ // 初始化当前用户
|
|
|
+ this.currentUser = new CloudUser();
|
|
|
+ await this.currentUser.current();
|
|
|
+
|
|
|
+ // 加载成就列表
|
|
|
+ await this.loadAchievements();
|
|
|
+ await this.loadUsers(); // 加载用户数据
|
|
|
+ // 加载荣誉墙数据
|
|
|
+ await this.loadAwardData();
|
|
|
+
|
|
|
+ // 初始化模拟数据
|
|
|
+ this.createMockAwards();
|
|
|
+ await this.loadAwardData();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载奖项数据
|
|
|
+ async loadAwardData() {
|
|
|
+ // 加载奖项类别
|
|
|
+ const categoryQuery = new CloudQuery("AwardCategory");
|
|
|
+ this.awardCategories = await categoryQuery.find();
|
|
|
+
|
|
|
+ // 如果类别为空,创建模拟类别
|
|
|
+ if (this.awardCategories.length === 0) {
|
|
|
+ this.awardCategories = [
|
|
|
+ this.createMockCategory('1', '创新设计奖'),
|
|
|
+ this.createMockCategory('2', '文化传承奖'),
|
|
|
+ this.createMockCategory('3', '数字技术奖'),
|
|
|
+ this.createMockCategory('4', '社区贡献奖')
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载奖项记录
|
|
|
+ await this.filterAwards();
|
|
|
+
|
|
|
+ // 如果奖项记录为空,创建模拟数据
|
|
|
+ if (this.awardRecords.length === 0) {
|
|
|
+ this.createMockAwards();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建模拟类别
|
|
|
+ createMockCategory(id: string, name: string): CloudObject {
|
|
|
+ const category = new CloudObject("AwardCategory");
|
|
|
+ category.set({
|
|
|
+ name: name,
|
|
|
+ description: `${name}描述`
|
|
|
+ });
|
|
|
+ category.id = id;
|
|
|
+ return category;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建模拟奖项数据
|
|
|
+ createMockAwards() {
|
|
|
+ const awards = [
|
|
|
+ { id: '1', awardName: '最佳创新设计', year: 2023, categoryId: '1', issuer: '江西省文化厅', level: '金奖', description: '表彰在文化产品设计方面的创新突破' },
|
|
|
+ { id: '2', awardName: '传统文化守护者', year: 2023, categoryId: '2', issuer: '江西省非遗保护中心', level: '银奖', description: '对传统文化保护有突出贡献的个人和机构' },
|
|
|
+ { id: '3', awardName: '数字技术先锋', year: 2022, categoryId: '3', issuer: '江西省科技厅', level: '金奖', description: '在文化数字化领域取得重大技术突破' },
|
|
|
+ { id: '4', awardName: '社区服务之星', year: 2022, categoryId: '4', issuer: '江西省民政厅', level: '铜奖', description: '为社区文化建设做出重要贡献' },
|
|
|
+ { id: '5', awardName: '文化传播大使', year: 2021, categoryId: '2', issuer: '江西省宣传部', level: '金奖', description: '有效推广江西文化的杰出代表' },
|
|
|
+ { id: '6', awardName: '数字创意新锐', year: 2021, categoryId: '3', issuer: '江西省文化厅', level: '银奖', description: '年轻一代在数字创意领域的优秀表现' },
|
|
|
+ { id: '7', awardName: '可持续发展奖', year: 2020, categoryId: '1', issuer: '江西省环保厅', level: '金奖', description: '在文化与环保结合方面的创新实践' },
|
|
|
+ { id: '8', awardName: '文化遗产保护', year: 2020, categoryId: '2', issuer: '江西省文物局', level: '银奖', description: '对重要文化遗产的保护和修复工作' },
|
|
|
+ { id: '9', awardName: '数字艺术创新', year: 2019, categoryId: '3', issuer: '江西省文化厅', level: '金奖', description: '在数字艺术创作方面的创新成果' },
|
|
|
+ { id: '10', awardName: '社区文化建设', year: 2018, categoryId: '4', issuer: '江西省民政厅', level: '铜奖', description: '推动社区文化建设的优秀案例' },
|
|
|
+ { id: '11', awardName: '传统工艺传承', year: 2017, categoryId: '2', issuer: '江西省非遗保护中心', level: '金奖', description: '对传统工艺的传承与创新' },
|
|
|
+ { id: '12', awardName: '文化科技创新', year: 2016, categoryId: '3', issuer: '江西省科技厅', level: '银奖', description: '科技创新在文化领域的应用' },
|
|
|
+ { id: '13', awardName: '文化公益项目', year: 2015, categoryId: '4', issuer: '江西省民政厅', level: '铜奖', description: '推动文化公益事业发展的优秀项目' }
|
|
|
+ ];
|
|
|
+
|
|
|
+ this.awardRecords = awards.map(award => {
|
|
|
+ const obj = new CloudObject("AwardRecord");
|
|
|
+ obj.set(award);
|
|
|
+ obj.id = award.id;
|
|
|
+ return obj;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
+ // 筛选奖项
|
|
|
+ async filterAwards() {
|
|
|
+ // 尝试查询真实数据
|
|
|
+ try {
|
|
|
+ const awardQuery = new CloudQuery("AwardRecord");
|
|
|
+
|
|
|
+ // 添加年份筛选条件
|
|
|
+ if (this.filter.year) {
|
|
|
+ awardQuery.equalTo("year", this.filter.year);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加类别筛选条件
|
|
|
+ if (this.filter.categoryId) {
|
|
|
+ awardQuery.equalTo("categoryId", this.filter.categoryId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关联查询类别信息
|
|
|
+ awardQuery.include("categoryId");
|
|
|
+
|
|
|
+ this.awardRecords = await awardQuery.find();
|
|
|
+ } catch (e) {
|
|
|
+ console.log("使用模拟数据");
|
|
|
+ // 应用筛选条件到模拟数据
|
|
|
+ let filtered = [...this.mockAwards];
|
|
|
+
|
|
|
+ if (this.filter.year) {
|
|
|
+ filtered = filtered.filter(a => a.year === this.filter.year);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.filter.categoryId) {
|
|
|
+ filtered = filtered.filter(a => a.categoryId === this.filter.categoryId);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.awardRecords = filtered.map(award => {
|
|
|
+ const obj = new CloudObject("AwardRecord");
|
|
|
+ obj.set(award);
|
|
|
+ obj.id = award.id;
|
|
|
+ return obj;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ mockAwards = [
|
|
|
+ { id: '1', awardName: '最佳创新设计', year: 2023, categoryId: '1', issuer: '江西省文化厅', level: '金奖', description: '表彰在文化产品设计方面的创新突破' },
|
|
|
+ { id: '2', awardName: '传统文化守护者', year: 2023, categoryId: '2', issuer: '江西省非遗保护中心', level: '银奖', description: '对传统文化保护有突出贡献的个人和机构' },
|
|
|
+ { id: '3', awardName: '数字技术先锋', year: 2022, categoryId: '3', issuer: '江西省科技厅', level: '金奖', description: '在文化数字化领域取得重大技术突破' },
|
|
|
+ { id: '4', awardName: '社区服务之星', year: 2022, categoryId: '4', issuer: '江西省民政厅', level: '铜奖', description: '为社区文化建设做出重要贡献' },
|
|
|
+ { id: '5', awardName: '文化传播大使', year: 2021, categoryId: '2', issuer: '江西省宣传部', level: '金奖', description: '有效推广江西文化的杰出代表' },
|
|
|
+ { id: '6', awardName: '数字创意新锐', year: 2021, categoryId: '3', issuer: '江西省文化厅', level: '银奖', description: '年轻一代在数字创意领域的优秀表现' },
|
|
|
+ { id: '7', awardName: '可持续发展奖', year: 2020, categoryId: '1', issuer: '江西省环保厅', level: '金奖', description: '在文化与环保结合方面的创新实践' },
|
|
|
+ { id: '8', awardName: '文化遗产保护', year: 2020, categoryId: '2', issuer: '江西省文物局', level: '银奖', description: '对重要文化遗产的保护和修复工作' },
|
|
|
+ { id: '9', awardName: '数字艺术创新', year: 2019, categoryId: '3', issuer: '江西省文化厅', level: '金奖', description: '在数字艺术创作方面的创新成果' },
|
|
|
+ { id: '10', awardName: '社区文化建设', year: 2018, categoryId: '4', issuer: '江西省民政厅', level: '铜奖', description: '推动社区文化建设的优秀案例' },
|
|
|
+ { id: '11', awardName: '传统工艺传承', year: 2017, categoryId: '2', issuer: '江西省非遗保护中心', level: '金奖', description: '对传统工艺的传承与创新' },
|
|
|
+ { id: '12', awardName: '文化科技创新', year: 2016, categoryId: '3', issuer: '江西省科技厅', level: '银奖', description: '科技创新在文化领域的应用' },
|
|
|
+ { id: '13', awardName: '文化公益项目', year: 2015, categoryId: '4', issuer: '江西省民政厅', level: '铜奖', description: '推动文化公益事业发展的优秀项目' }
|
|
|
+ ];
|
|
|
+ // 查看奖项详情
|
|
|
+ viewAwardDetail(award: CloudObject) {
|
|
|
+ this.selectedAward = award;
|
|
|
+ this.showAwardDetail = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取奖项类别名称
|
|
|
+ getCategoryName(categoryId: string): string {
|
|
|
+ const category = this.awardCategories.find(c => c.id === categoryId);
|
|
|
+ return category ? category.get('name') : '未知类别';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取荣誉项位置
|
|
|
+ getHonorPosition(index: number): any {
|
|
|
+ return this.honorPositions[index % this.honorPositions.length] || {};
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取获奖者(模拟方法)
|
|
|
+ getWinners(award: CloudObject): any[] {
|
|
|
+ // 确保 award.id 是字符串类型
|
|
|
+ const awardId = award.id ? award.id.toString() : '1';
|
|
|
+ // 根据奖项ID返回不同的获奖者
|
|
|
+ const winnersMap: Record<string, any[]> = {
|
|
|
+ '1': [
|
|
|
+ { name: '南昌文化设计院', type: '团队' },
|
|
|
+ { name: '李明', type: '个人' }
|
|
|
+ ],
|
|
|
+ '2': [
|
|
|
+ { name: '景德镇陶瓷研究院', type: '团队' },
|
|
|
+ { name: '王华', type: '个人' }
|
|
|
+ ],
|
|
|
+ '3': [
|
|
|
+ { name: '江西数字科技公司', type: '团队' },
|
|
|
+ { name: '张伟', type: '个人' },
|
|
|
+ { name: '刘芳', type: '个人' }
|
|
|
+ ],
|
|
|
+ '4': [
|
|
|
+ { name: '九江社区文化中心', type: '团队' }
|
|
|
+ ],
|
|
|
+ '5': [
|
|
|
+ { name: '江西电视台文化频道', type: '团队' },
|
|
|
+ { name: '陈明', type: '个人' }
|
|
|
+ ],
|
|
|
+ '6': [
|
|
|
+ { name: '青年创意工作室', type: '团队' },
|
|
|
+ { name: '赵阳', type: '个人' }
|
|
|
+ ],
|
|
|
+ '7': [
|
|
|
+ { name: '赣江环保组织', type: '团队' },
|
|
|
+ { name: '环保设计协会', type: '团队' }
|
|
|
+ ],
|
|
|
+ '8': [
|
|
|
+ { name: '庐山文物保护队', type: '团队' },
|
|
|
+ { name: '黄强', type: '个人' }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+
|
|
|
+ return winnersMap[awardId] || [{ name: '未知获奖者', type: '个人' }];
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
onOcrClick() {
|
|
|
this.isProcessing = true;
|
|
|
this.activeLanterns = false;
|
|
@@ -125,4 +384,184 @@ onFileSelected(event: Event) {
|
|
|
document: null
|
|
|
};
|
|
|
}
|
|
|
+
|
|
|
+// 加载用户数据
|
|
|
+ async loadUsers() {
|
|
|
+ const query = new CloudQuery("_User");
|
|
|
+ const users = await query.find();
|
|
|
+
|
|
|
+ // 创建用户ID到用户对象的映射
|
|
|
+ users.forEach(user => {
|
|
|
+ if (user.id) {
|
|
|
+ this.userMap[user.id] = user;
|
|
|
+} else {
|
|
|
+ console.warn('用户缺少 ID,无法缓存:', user);
|
|
|
+}
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取用户名
|
|
|
+ getUserName(userPointer: any): string {
|
|
|
+ // 添加空值检查
|
|
|
+ if (!userPointer || typeof userPointer !== 'object' || !userPointer.objectId) {
|
|
|
+ return '未知用户';
|
|
|
+ }
|
|
|
+
|
|
|
+ const userId = userPointer.objectId;
|
|
|
+
|
|
|
+ // 检查用户是否存在于缓存中
|
|
|
+ if (this.userMap[userId]) {
|
|
|
+ return this.userMap[userId].get('username') || '未知用户';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果用户不存在,异步加载
|
|
|
+ this.loadUserById(userId);
|
|
|
+ return '加载中...';
|
|
|
+ }
|
|
|
+
|
|
|
+ //按ID加载用户
|
|
|
+ async loadUserById(userId: string) {
|
|
|
+ // 避免重复加载
|
|
|
+ if (this.userMap[userId]) return;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const userQuery = new CloudQuery("_User");
|
|
|
+ const user = await userQuery.get(userId);
|
|
|
+ if (user) {
|
|
|
+ this.userMap[userId] = user;
|
|
|
+ // 触发UI更新
|
|
|
+ this.cdr.detectChanges();
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('加载用户失败:', e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断是否是当前用户的成就
|
|
|
+ isUserAchievement(achievement: CloudObject): boolean {
|
|
|
+ if (!this.currentUser) return false;
|
|
|
+
|
|
|
+ const userPointer = achievement.get('user');
|
|
|
+ return userPointer && userPointer.objectId === this.currentUser.id;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 筛选成就
|
|
|
+ filterAchievements() {
|
|
|
+ this.filteredAchievements = this.achievements.filter(achievement => {
|
|
|
+ // 安全获取属性
|
|
|
+ const title = achievement.get('title') || '';
|
|
|
+ const description = achievement.get('description') || '';
|
|
|
+ const category = achievement.get('category') || '';
|
|
|
+
|
|
|
+ // 匹配搜索词
|
|
|
+ const matchesSearch = this.searchTerm ?
|
|
|
+ title.toLowerCase().includes(this.searchTerm.toLowerCase()) ||
|
|
|
+ description.toLowerCase().includes(this.searchTerm.toLowerCase()) :
|
|
|
+ true;
|
|
|
+
|
|
|
+ // 匹配类别
|
|
|
+ const matchesCategory = this.selectedCategory ?
|
|
|
+ category === this.selectedCategory :
|
|
|
+ true;
|
|
|
+
|
|
|
+ return matchesSearch && matchesCategory;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 选择类别
|
|
|
+ selectCategory(category: string) {
|
|
|
+ if (this.selectedCategory === category) {
|
|
|
+ this.selectedCategory = null; // 取消选择
|
|
|
+ } else {
|
|
|
+ this.selectedCategory = category;
|
|
|
+ }
|
|
|
+ this.filterAchievements();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 加载当前用户的成就
|
|
|
+ async loadAchievements() {
|
|
|
+ if (!this.currentUser?.id) return;
|
|
|
+
|
|
|
+ const query = new CloudQuery("Achievement");
|
|
|
+ query.equalTo("user", this.currentUser.toPointer());
|
|
|
+
|
|
|
+ this.achievements = await query.find();
|
|
|
+ this.filteredAchievements = [...this.achievements];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加新成就
|
|
|
+ async addAchievement() {
|
|
|
+ if (!this.currentUser?.id) return;
|
|
|
+
|
|
|
+ const achievement = new CloudObject("Achievement");
|
|
|
+ achievement.set({
|
|
|
+ ...this.newAchievement,
|
|
|
+ user: this.currentUser.toPointer()
|
|
|
+ });
|
|
|
+
|
|
|
+ await achievement.save();
|
|
|
+ this.resetNewAchievement();
|
|
|
+ await this.loadAchievements();
|
|
|
+ this.filterAchievements(); // 更新筛选后的列表
|
|
|
+ }
|
|
|
+
|
|
|
+ // 开始编辑成就
|
|
|
+ startEditAchievement(achievement: CloudObject) {
|
|
|
+ // 使用类型断言指定 achievement 的 data 结构
|
|
|
+ this.editingAchievement = achievement as CloudObject & {
|
|
|
+ data: {
|
|
|
+ title: string;
|
|
|
+ description: string;
|
|
|
+ category: string;
|
|
|
+ imageUrl: string;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.isEditingAchievement = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新成就
|
|
|
+ async updateAchievement() {
|
|
|
+ if (!this.editingAchievement) return;
|
|
|
+
|
|
|
+ // 创建新对象避免直接修改原对象
|
|
|
+ const updated = new CloudObject("Achievement");
|
|
|
+ updated.id = this.editingAchievement.id;
|
|
|
+ updated.set(this.editingAchievement.data);
|
|
|
+
|
|
|
+ await updated.save();
|
|
|
+ await this.loadAchievements();
|
|
|
+ this.filterAchievements(); // 更新筛选后的列表
|
|
|
+ }
|
|
|
+
|
|
|
+ // 删除成就
|
|
|
+ async deleteAchievement(achievement: CloudObject) {
|
|
|
+ await achievement.destroy();
|
|
|
+ await this.loadAchievements();
|
|
|
+ this.filterAchievements(); // 更新筛选后的列表
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重置新成就表单
|
|
|
+ resetNewAchievement() {
|
|
|
+ this.newAchievement = {
|
|
|
+ title: '',
|
|
|
+ description: '',
|
|
|
+ category: '作品',
|
|
|
+ imageUrl: ''
|
|
|
+ };
|
|
|
+ }
|
|
|
+getAchievementIcon(category: string): string {
|
|
|
+ const icons: Record<string, string> = {
|
|
|
+ '作品': 'palette',
|
|
|
+ '证书': 'certificate',
|
|
|
+ '奖项': 'award',
|
|
|
+ '荣誉': 'medal'
|
|
|
+ };
|
|
|
+ return icons[category] || 'star';
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|