feat: 中间部分完成上和中
|
@ -20,7 +20,7 @@ VITE_MOCK_BASE_API=/mock
|
|||
VITE_STRICT_PORT=false
|
||||
|
||||
# 是否启用屏幕转vw适配,可以选择 postcss-px-to-viewport-8-plugin || autofit
|
||||
VITE_POST_CSS_PX_TO_VIEWPORT8_PLUGIN="autofit"
|
||||
VITE_POST_CSS_PX_TO_VIEWPORT8_PLUGIN="postcss-px-to-viewport-8-plugin"
|
||||
|
||||
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
|
||||
VITE_CDN=false
|
||||
|
|
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 26 KiB |
|
@ -1,29 +1,35 @@
|
|||
@use "src/element";
|
||||
@use "src/digest";
|
||||
|
||||
/* 定义滚动条高宽及背景高宽分别对应横竖滚动条的尺寸 */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
/* 定义滚动条轨道内阴影+圆角 */
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: #ebecef;
|
||||
border-radius: 5px;
|
||||
box-shadow: inset 0 0 6px #ebecef;
|
||||
}
|
||||
|
||||
/* 定义滑块内阴影+圆角 */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #d0d2d6;
|
||||
border-radius: 5px;
|
||||
box-shadow: inset 0 0 6px #d0d2d6;
|
||||
}
|
||||
///* 定义滚动条高宽及背景高宽分别对应横竖滚动条的尺寸 */
|
||||
//::-webkit-scrollbar {
|
||||
// width: 8px;
|
||||
// height: 8px;
|
||||
// background-color: var(--el-text-color-secondary);
|
||||
//}
|
||||
//
|
||||
///* 定义滚动条轨道内阴影+圆角 */
|
||||
//::-webkit-scrollbar-track {
|
||||
// background-color: #ebecef;
|
||||
// border-radius: 5px;
|
||||
// box-shadow: inset 0 0 6px #ebecef;
|
||||
//}
|
||||
//
|
||||
///* 定义滑块内阴影+圆角 */
|
||||
//::-webkit-scrollbar-thumb {
|
||||
// background-color: #d0d2d6;
|
||||
// border-radius: 5px;
|
||||
// box-shadow: inset 0 0 6px #d0d2d6;
|
||||
//}
|
||||
|
||||
body {
|
||||
background: var(--background-color);
|
||||
//user-select: none;
|
||||
//overflow: hidden;
|
||||
user-select: none;
|
||||
overflow: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, Opera */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
border-radius: 50%; /* 将元素变成圆形 */
|
||||
}
|
||||
|
||||
|
||||
.hover {
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
|
|
|
@ -11,7 +11,7 @@ const route = useRoute();
|
|||
const appStore = useAppStore();
|
||||
|
||||
onBeforeMount(() => {
|
||||
appStore.setBackground('../assets/images/common/bg/bg-layout.png');
|
||||
appStore.setBackground('@/assets/images/common/bg/bg-layout.png');
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ const useAppStore = defineStore('appStore', {
|
|||
const href = new URL(background, import.meta.url).href;
|
||||
this.background = `url(${href})`;
|
||||
} else {
|
||||
const href = new URL('../assets/images/common/bg/bg-layout.png', import.meta.url).href;
|
||||
const href = new URL('@/assets/images/common/bg/bg-layout.png', import.meta.url).href;
|
||||
this.background = `url(${href})`;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useDebounceFn, useEventListener } from '@vueuse/core';
|
||||
|
||||
import type echarts from '@/plugins/echarts';
|
||||
import echarts from '@/plugins/echarts';
|
||||
|
||||
/** 通用重置图表样式 */
|
||||
export const debounceChart = (myChart: echarts.ECharts | undefined) => {
|
||||
|
@ -20,3 +20,21 @@ export const formatter = (number: any) => {
|
|||
|
||||
return segs.join(',').split('').reverse().join('');
|
||||
};
|
||||
|
||||
/** 颜色渲染 */
|
||||
export const graphicLinearGradient = (
|
||||
color1: string,
|
||||
color2: string,
|
||||
coordinate: Array<number> = [0, 0, 0, 1]
|
||||
) => {
|
||||
return new echarts.graphic.LinearGradient(
|
||||
coordinate[0],
|
||||
coordinate[1],
|
||||
coordinate[2],
|
||||
coordinate[3],
|
||||
[
|
||||
{ offset: 0, color: color1 },
|
||||
{ offset: 1, color: color2 },
|
||||
]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export const getImage = (path: string) => {
|
||||
const image = new URL(path, import.meta.url);
|
||||
return image.href;
|
||||
};
|
|
@ -9,7 +9,7 @@ let myChart = null;
|
|||
|
||||
const option = {
|
||||
backgroundColor: 'transparent',
|
||||
grid: { top: 40, right: 0, left: 0, bottom: 24 },
|
||||
grid: { top: '19%', right: 9, left: 9, bottom: '20%' },
|
||||
tooltip: {},
|
||||
legend: {
|
||||
data: [
|
||||
|
@ -29,7 +29,7 @@ const option = {
|
|||
show: true,
|
||||
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
|
||||
itemStyle: { color: '#ccc' },
|
||||
splitLine: { show: true, lineStyle: { color: '#333', width: 1, type: 'dotted' } },
|
||||
splitLine: { show: true, lineStyle: { color: '#333', width: 1, type: 'solid' } },
|
||||
splitArea: { show: false },
|
||||
},
|
||||
yAxis: { show: false, type: 'value' },
|
||||
|
@ -37,7 +37,7 @@ const option = {
|
|||
{
|
||||
name: '入园',
|
||||
type: 'line',
|
||||
data: [3, 9, 2, 8, 3, 4, 8, 2, 8, 3, 4, 8],
|
||||
// data: [3, 9, 2, 8, 3, 4, 8, 2, 8, 3, 4, 8],
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 14,
|
||||
|
@ -47,7 +47,7 @@ const option = {
|
|||
{
|
||||
name: '出园',
|
||||
type: 'line',
|
||||
data: [2, 8, 3, 7, 1, 9, 18, 3, 7, 1, 9, 6],
|
||||
// data: [2, 8, 3, 7, 1, 9, 18, 3, 7, 1, 9, 6],
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 14,
|
||||
|
@ -60,7 +60,7 @@ const option = {
|
|||
/** 渲染图表 */
|
||||
export const renderEcharts = (element: Ref<HTMLDivElement>) => {
|
||||
myChart = echarts.init(element.value, null, {
|
||||
renderer: 'svg',
|
||||
renderer: 'canvas',
|
||||
devicePixelRatio: window.devicePixelRatio,
|
||||
});
|
||||
|
|
@ -4,21 +4,11 @@ import type { EChartsOption, EChartsType } from 'echarts';
|
|||
import { defineComponent, onMounted, type Ref, ref, watch } from 'vue';
|
||||
|
||||
import echarts from '@/plugins/echarts';
|
||||
import { debounceChart } from '@/utils/chart';
|
||||
import { debounceChart, graphicLinearGradient } from '@/utils/chart';
|
||||
|
||||
const itemStyles = [
|
||||
{
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: '#00CCD2' },
|
||||
{ offset: 1, color: '#00A2FF' },
|
||||
]),
|
||||
},
|
||||
{
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: '#CBB668' },
|
||||
{ offset: 1, color: '#FABC00' },
|
||||
]),
|
||||
},
|
||||
{ color: graphicLinearGradient('#00CCD2', '#00A2FF') },
|
||||
{ color: graphicLinearGradient('#CBB668', '#FABC00') },
|
||||
];
|
||||
|
||||
const option: Ref<EChartsOption | undefined> = ref<EChartsOption>();
|
||||
|
@ -44,12 +34,7 @@ option.value = {
|
|||
color: '#fff',
|
||||
formatter: '+{value}%',
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: '环比变化',
|
||||
detail: { valueAnimation: true, offsetCenter: ['0%', '-20%'] },
|
||||
},
|
||||
],
|
||||
data: [{ name: '环比变化', detail: { valueAnimation: true, offsetCenter: ['0%', '-20%'] } }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -68,11 +53,8 @@ const renderEcharts: any = (myChart: Ref<echarts.ECharts>, element: Ref<HTMLDivE
|
|||
|
||||
/* 封装组件 */
|
||||
export const ChartProgress = defineComponent({
|
||||
props: {
|
||||
percent: {
|
||||
type: Number,
|
||||
},
|
||||
},
|
||||
props: { percent: { type: Number } },
|
||||
|
||||
setup(props) {
|
||||
const chart = ref<HTMLDivElement>();
|
||||
const myChart = ref<EChartsType>();
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
<script setup lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
const chart = ref<HTMLDivElement>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
top
|
||||
<div class="content-bottom">
|
||||
<div ref="chart" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.content-bottom {
|
||||
width: 800px;
|
||||
height: 377px;
|
||||
background: mediumpurple;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,84 @@
|
|||
<script lang="ts" setup></script>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
<template>top</template>
|
||||
const isActive = ref(true);
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
onMounted(() => {
|
||||
setInterval(() => {
|
||||
isActive.value = !isActive.value;
|
||||
}, 2000);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="content-middle">
|
||||
<div class="content-middle__inner">
|
||||
<img
|
||||
:class="[isActive ? 'move-top' : 'move-bottom']"
|
||||
alt=""
|
||||
src="@/assets/images/big-data/bg/bg-middle-move.png"
|
||||
/>
|
||||
<h1>工作台</h1>
|
||||
<img
|
||||
:class="[isActive ? 'move-bottom' : 'move-top']"
|
||||
alt=""
|
||||
src="@/assets/images/big-data/bg/bg-middle-move.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content-middle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 189px;
|
||||
|
||||
&__inner {
|
||||
position: relative;
|
||||
width: 267px;
|
||||
height: 189px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
h1 {
|
||||
width: 266px;
|
||||
height: 109px;
|
||||
text-align: center;
|
||||
line-height: 109px;
|
||||
font-size: 34px;
|
||||
color: var(--color-primary-secondary);
|
||||
background: url('@/assets/images/big-data/bg/bg-middle-title.png') no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.move-top {
|
||||
animation: 2s linear 0s infinite normal none running line-move;
|
||||
}
|
||||
|
||||
.move-bottom {
|
||||
animation: 2s linear 0s infinite normal none running line-move-top;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes line-move-top {
|
||||
0% {
|
||||
transform: translateX(200%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes line-move {
|
||||
0% {
|
||||
transform: rotateY(180deg) translateX(100%);
|
||||
}
|
||||
100% {
|
||||
transform: rotateY(180deg) translateX(-200%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,11 +1,63 @@
|
|||
<script setup lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import { getImage } from '@/utils/image';
|
||||
|
||||
const list = [
|
||||
{ title: '员工', img: '../assets/images/big-data/bg/bg-content-top-1.png' },
|
||||
{ title: '智慧大楼', img: '../assets/images/big-data/bg/bg-content-top-2.png' },
|
||||
{ title: '智慧设备', img: '../assets/images/big-data/bg/bg-content-top-3.png' },
|
||||
{ title: '数据报表', img: '../assets/images/big-data/bg/bg-content-top-4.png' },
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
top
|
||||
<ul>
|
||||
<li v-for="(item, index) in list" :key="index">
|
||||
<img :src="getImage(item.img)" alt="" />
|
||||
<h2>{{ item.title }}</h2>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
ul {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 39px 0 0 0;
|
||||
width: 748px;
|
||||
height: 351px;
|
||||
|
||||
</style>
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 171px;
|
||||
height: 283px;
|
||||
|
||||
img {
|
||||
width: 171px;
|
||||
height: 191px;
|
||||
animation: shakeY 4s linear infinite;
|
||||
}
|
||||
|
||||
h2 {
|
||||
width: 130px;
|
||||
height: 52px;
|
||||
font-size: 16px;
|
||||
line-height: 54px;
|
||||
text-align: center;
|
||||
color: var(--color-primary-secondary);
|
||||
background: url('@/assets/images/big-data/bg/bg-content-top-item.png') no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
|
||||
li:nth-child(1) {
|
||||
transform: translateY(68px);
|
||||
}
|
||||
|
||||
li:nth-child(4) {
|
||||
transform: translateY(68px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
|
||||
import { renderEcharts, updateChart } from '@/views/big-data/charts/leftBottom';
|
||||
import { renderEcharts, updateChart } from '@/views/big-data/charts/left-bottom';
|
||||
|
||||
const chart = ref<HTMLDivElement>();
|
||||
const timer = ref(null);
|
||||
|
||||
const randomData = () => {
|
||||
function random() {
|
||||
return Array(11)
|
||||
return Array(12)
|
||||
.fill(0)
|
||||
.map(() => {
|
||||
const num = (Math.random() * 100).toFixed(2);
|
||||
|
@ -16,16 +16,18 @@ const randomData = () => {
|
|||
});
|
||||
}
|
||||
|
||||
timer.value = setInterval(() => {
|
||||
const data: Array<Array<number>> = [random(), random()];
|
||||
const data: Array<Array<number>> = [random(), random()];
|
||||
|
||||
updateChart(data);
|
||||
}, 1000);
|
||||
updateChart(data);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
renderEcharts(chart);
|
||||
randomData();
|
||||
|
||||
timer.value = setInterval(() => {
|
||||
randomData();
|
||||
}, 6000);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
|
|
|
@ -9,7 +9,7 @@ import BigDataRight from '@/views/big-data/components/big-data-right/index.vue';
|
|||
const appStore = useAppStore();
|
||||
|
||||
onBeforeMount(async () => {
|
||||
appStore.setBackground('../assets/images/common/bg/bg-secondary.png');
|
||||
appStore.setBackground('@/assets/images/common/bg/bg-secondary.png');
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@ import type { EChartsOption } from 'echarts';
|
|||
import { type Ref, ref } from 'vue';
|
||||
|
||||
import echarts from '@/plugins/echarts';
|
||||
import { debounceChart } from '@/utils/chart';
|
||||
import { debounceChart, graphicLinearGradient } from '@/utils/chart';
|
||||
|
||||
let myChart = null;
|
||||
const option = ref<EChartsOption>();
|
||||
option.value = {
|
||||
tooltip: {
|
||||
|
@ -47,12 +48,7 @@ option.value = {
|
|||
name: 'Direct',
|
||||
type: 'bar',
|
||||
barWidth: '40%',
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: '#00CCD2' },
|
||||
{ offset: 1, color: '#00A2FF' },
|
||||
]),
|
||||
},
|
||||
itemStyle: { color: graphicLinearGradient('#00CCD2', '#00A2FF') },
|
||||
// emphasis: {
|
||||
// shadowBlur: 10, // 取消阴影模糊
|
||||
// shadowColor: '#000', // 取消阴影颜色
|
||||
|
@ -64,7 +60,7 @@ option.value = {
|
|||
};
|
||||
|
||||
export const renderEcharts = (element: Ref<HTMLDivElement>) => {
|
||||
const myChart: any = echarts.init(element.value, null, {
|
||||
myChart = echarts.init(element.value, null, {
|
||||
renderer: 'svg',
|
||||
devicePixelRatio: window.devicePixelRatio,
|
||||
});
|
||||
|
|
|
@ -1,49 +1,42 @@
|
|||
<script lang="ts" setup></script>
|
||||
<script lang="ts" setup>
|
||||
import { getImage } from '@/utils/image';
|
||||
|
||||
const list = [
|
||||
{
|
||||
img: '../assets/images/business-supervision/bg/content/bg-middle-1.png',
|
||||
title: '员工',
|
||||
describe: '相关员工',
|
||||
amount: 365,
|
||||
},
|
||||
{
|
||||
img: '../assets/images/business-supervision/bg/content/bg-middle-2.png',
|
||||
title: '智慧大楼',
|
||||
describe: '区域面积/㎡',
|
||||
amount: 365,
|
||||
},
|
||||
{
|
||||
img: '../assets/images/business-supervision/bg/content/bg-middle-3.png',
|
||||
title: '智慧设备',
|
||||
describe: '设备总数',
|
||||
amount: 1123,
|
||||
},
|
||||
{
|
||||
img: '../assets/images/business-supervision/bg/content/bg-middle-4.png',
|
||||
title: '数据报表',
|
||||
describe: '报表下载总数',
|
||||
amount: 287,
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul class="business-supervision__middle">
|
||||
<li>
|
||||
<img
|
||||
alt="bg-middle-1"
|
||||
src="@/assets/images/business-supervision/bg/content/bg-middle-1.png"
|
||||
/>
|
||||
<h2>员工</h2>
|
||||
<li v-for="(item, index) in list" :key="index">
|
||||
<img :alt="`bg-middle-${index}`" :src="getImage(item.img)" />
|
||||
<h2>{{ item.title }}</h2>
|
||||
<div class="business-supervision__middle-detail">
|
||||
<strong>365</strong>
|
||||
<span>相关员工</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<img
|
||||
alt="bg-middle-2"
|
||||
src="@/assets/images/business-supervision/bg/content/bg-middle-2.png"
|
||||
/>
|
||||
<h2>智慧大楼</h2>
|
||||
<div class="business-supervision__middle-detail">
|
||||
<strong>365</strong>
|
||||
<span>区域面积/㎡</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<img
|
||||
alt="bg-middle-3"
|
||||
src="@/assets/images/business-supervision/bg/content/bg-middle-3.png"
|
||||
/>
|
||||
<h2>智慧设备</h2>
|
||||
<div class="business-supervision__middle-detail">
|
||||
<strong>1123</strong>
|
||||
<span>设备总数</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<img
|
||||
alt="bg-middle-3"
|
||||
src="@/assets/images/business-supervision/bg/content/bg-middle-3.png"
|
||||
/>
|
||||
<h2>数据报表</h2>
|
||||
<div class="business-supervision__middle-detail">
|
||||
<strong>287</strong>
|
||||
<span>报表下载总数</span>
|
||||
<strong>{{ item.amount }}</strong>
|
||||
<span>{{ item.describe }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<script lang="tsx" setup>
|
||||
import { getImage } from '@/utils/image';
|
||||
|
||||
const list = [
|
||||
{
|
||||
title: '今日出口额 / 万元',
|
||||
|
@ -34,14 +36,6 @@ const list = [
|
|||
|
||||
// 动态顶部元素
|
||||
const contentEl = () => {
|
||||
const getImage = (index) => {
|
||||
const image = new URL(
|
||||
`../../../../../assets/images/business-supervision/bg/content/bg-card-${index + 1}.png`,
|
||||
import.meta.url
|
||||
);
|
||||
return image.href;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{list.map((item, index) => (
|
||||
|
@ -57,7 +51,12 @@ const contentEl = () => {
|
|||
))}
|
||||
</section>
|
||||
</div>
|
||||
<img alt="card-1" src={getImage(index)} />
|
||||
<img
|
||||
alt="card-1"
|
||||
src={getImage(
|
||||
`../assets/images/business-supervision/bg/content/bg-card-${index + 1}.png`
|
||||
)}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</>
|
||||
|
|
|
@ -9,7 +9,7 @@ import BusinessSupervisionRight from '@/views/business-supervision/components/bu
|
|||
const appStore = useAppStore();
|
||||
|
||||
onBeforeMount(() => {
|
||||
appStore.setBackground('../assets/images/common/bg/bg-secondary.png');
|
||||
appStore.setBackground('@/assets/images/common/bg/bg-secondary.png');
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|