Browse Source

commit

Signed-off-by: 1549469775 <1549469775@qq.com>
master
1549469775 3 years ago
parent
commit
7bfc9e81f9
  1. 1
      App.vue
  2. 238
      assets/style/common.scss
  3. 215
      assets/style/global.scss
  4. 2
      main.js
  5. 5
      pages.json
  6. 152
      pages/Sub/Tabs/Tabs.vue
  7. 7
      pages/index/index.vue
  8. 8
      readme.md
  9. 2
      uni.scss
  10. 125
      uni_modules/niu-ui/assets/style/common.scss
  11. 1
      uni_modules/niu-ui/assets/style/global.scss
  12. 4
      uni_modules/niu-ui/changelog.md
  13. 2
      uni_modules/niu-ui/components/niu-navbar/niu-navbar.vue
  14. 20
      uni_modules/niu-ui/components/niu-page/niu-page.vue
  15. 9
      uni_modules/niu-ui/components/niu-tabs/niu-tabs.vue
  16. 8
      uni_modules/niu-ui/components/niu-ui/niu-ui.vue
  17. 7
      uni_modules/niu-ui/index.js
  18. 16
      uni_modules/niu-ui/package.json
  19. 9
      uni_modules/niu-ui/readme.md

1
App.vue

@ -15,4 +15,5 @@
<style lang="scss">
/*每个页面公共css */
@import '~@/assets/style/common.scss';
@import '~@/uni_modules/niu-ui/assets/style/common.scss'
</style>

238
assets/style/common.scss

@ -1,145 +1,97 @@
page {
// background-color: #FFF8F8;
background-color: #F1F1F1;
// min-height: 100%;
height: 100%;
font-size: 28rpx;
line-height: 1.2; //
color: #000;
}
page .tabpage{
// 怪异盒模型
-webkit-overflow-scrolling: touch;
box-sizing: border-box;
/* #ifdef H5 */
//貌似不需要了已经是去除了tabbar的高度了
//自定义tabbar的时候需要
// 底部tab栏高度
margin-bottom: 0;//var(--window-bottom);
/* #endif */
/* #ifndef H5 */
margin-bottom: 0;
/* #endif */
// 触发BFC
// overflow-x: hidden;
// overflow-y: scroll;
min-height: 100%;
}
page .page{
// 怪异盒模型
-webkit-overflow-scrolling: touch;
box-sizing: border-box;
// 触发BFC
// overflow-x: hidden;
// overflow-y: scroll;
min-height: 100%;
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
display: none;
}
page *{
box-sizing: border-box;
}
.a-flexbox{
display: flex;
&.a-flexbox--fixed{
flex-shrink: 0;
flex-grow: 0;
}
&.a-flexbox--inline{
display: inline-flex;
}
&.a-flexbox__column{
flex-direction: column;
}
&.a-flexbox__row{
flex-direction: row;
}
&.a-flexbox__wrap{
flex-wrap: wrap;
}
&.a-flexbox__center{
align-items: center;
justify-content: center;
}
&.a-flexbox__center--x{
justify-content: center;
}
&.a-flexbox--around{
justify-content: space-around;
}
&.a-flexbox--between{
justify-content: space-between;
}
&.a-flexbox__start--x{
justify-content: flex-start;
}
&.a-flexbox__end--x{
justify-content: flex-end;
}
&.a-flexbox__center--y{
align-items: center;
}
&.a-flexbox__start--y{
align-items: flex-start;
}
&.a-flexbox__end--y{
align-items: flex-end;
}
.a-flexbox__noshrink{
flex-shrink: 0;
}
.a-flexbox__full{
flex: 1;
width: 0;
}
.a-flexbox__full--h{
flex: 1;
height: 0;
}
}
// 单行省略号
.a-ov{
@include ellipsis(1)
}
// 两行省略号
.a-ov2{
@include ellipsis(2)
}
// .a-flexbox{
// display: flex;
// &.a-flexbox--fixed{
// flex-shrink: 0;
// flex-grow: 0;
// }
// &.a-flexbox--inline{
// display: inline-flex;
// }
// &.a-flexbox__column{
// flex-direction: column;
// }
// &.a-flexbox__row{
// flex-direction: row;
// }
// &.a-flexbox__wrap{
// flex-wrap: wrap;
// }
// &.a-flexbox__center{
// align-items: center;
// justify-content: center;
// }
// &.a-flexbox__center--x{
// justify-content: center;
// }
// &.a-flexbox--around{
// justify-content: space-around;
// }
// &.a-flexbox--between{
// justify-content: space-between;
// }
// &.a-flexbox__start--x{
// justify-content: flex-start;
// }
// &.a-flexbox__end--x{
// justify-content: flex-end;
// }
// &.a-flexbox__center--y{
// align-items: center;
// }
// &.a-flexbox__start--y{
// align-items: flex-start;
// }
// &.a-flexbox__end--y{
// align-items: flex-end;
// }
// .a-flexbox__noshrink{
// flex-shrink: 0;
// }
// .a-flexbox__full{
// flex: 1;
// width: 0;
// }
// .a-flexbox__full--h{
// flex: 1;
// height: 0;
// }
// }
// // 单行省略号
// .a-ov{
// @include ellipsis(1)
// }
// // 两行省略号
// .a-ov2{
// @include ellipsis(2)
// }
// 包裹输入框
.a-wrapinput{
position:relative;
display: flex;
align-items: center;
// height: 100%;
>input{
width: 0;
flex: 1;
// height: 100%;
font-size: inherit;
line-height: inherit;
}
.sub{
display: flex;
align-items: center;
margin-right: 8rpx;
}
}
// 包裹文本域
.a-wraptextarea{
min-height: 160rpx;
height: 160rpx;
>textarea{
font-size: inherit;
width: 100%;
height: 100%;
}
}
// // 包裹输入框
// .a-wrapinput{
// position:relative;
// display: flex;
// align-items: center;
// // height: 100%;
// >input{
// width: 0;
// flex: 1;
// // height: 100%;
// font-size: inherit;
// line-height: inherit;
// }
// .sub{
// display: flex;
// align-items: center;
// margin-right: 8rpx;
// }
// }
// // 包裹文本域
// .a-wraptextarea{
// min-height: 160rpx;
// height: 160rpx;
// >textarea{
// font-size: inherit;
// width: 100%;
// height: 100%;
// }
// }

215
assets/style/global.scss

@ -1,112 +1,113 @@
/*
* 内部通用scss
*/
// /*
// * 内部通用scss
// */
@mixin clearfix {
&:after {
clear: both;
content: '.';
display: block;
height: 0;
line-height: 0;
overflow: hidden;
}
// *height: 1%;
}
// @mixin clearfix {
// &:after {
// clear: both;
// content: '.';
// display: block;
// height: 0;
// line-height: 0;
// overflow: hidden;
// }
// // *height: 1%;
// }
@mixin hairline {
&::after {
content: " ";
box-sizing: border-box;
pointer-events: none;
border: 0 solid #ebedf0;
position: absolute;
top: -50%;
right: -50%;
bottom: -50%;
left: -50%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
@content
}
};
@mixin hairline--no {
@include hairline{
border: 0;
};
}
@mixin hairline--all {
@include hairline{
border-width: 1px;
};
}
@mixin hairline--right {
@include hairline{
border-right-width: 1px;
};
}
@mixin hairline--left {
@include hairline{
border-left-width: 1px;
};
}
@mixin hairline--bottom {
@include hairline{
border-bottom-width: 1px;
};
}
// @mixin hairline {
// &::after {
// content: " ";
// box-sizing: border-box;
// pointer-events: none;
// border: 0 solid #ebedf0;
// position: absolute;
// top: -50%;
// right: -50%;
// bottom: -50%;
// left: -50%;
// -webkit-transform: scale(0.5);
// transform: scale(0.5);
// @content
// }
// };
// @mixin hairline--no {
// @include hairline{
// border: 0;
// };
// }
// @mixin hairline--all {
// @include hairline{
// border-width: 1px;
// };
// }
// @mixin hairline--right {
// @include hairline{
// border-right-width: 1px;
// };
// }
// @mixin hairline--left {
// @include hairline{
// border-left-width: 1px;
// };
// }
@mixin hairline--top {
@include hairline{
border-top-width: 1px;
};
}
@mixin hairline--right--bottom {
@include hairline{
border-left-width: 0;
border-top-width: 0;
border-right-width: 1px;
border-bottom-width: 1px;
};
}
@mixin hairline--left--top {
@include hairline{
border-right-width: 0;
border-bottom-width: 0;
border-left-width: 1px;
border-top-width: 1px;
};
}
//一行溢出
@mixin text-overflow{
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
word-break: break-all;
};
// @mixin hairline--bottom {
// @include hairline{
// border-bottom-width: 1px;
// };
// }
//两行溢出
@mixin ov($num: 2){
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: $num;
line-clamp: $num;
-webkit-box-orient: vertical;
}
@mixin ellipsis($lines: 1) {
@if ($lines==1) {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} @else {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: $lines;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
}
}
// @mixin hairline--top {
// @include hairline{
// border-top-width: 1px;
// };
// }
// @mixin hairline--right--bottom {
// @include hairline{
// border-left-width: 0;
// border-top-width: 0;
// border-right-width: 1px;
// border-bottom-width: 1px;
// };
// }
// @mixin hairline--left--top {
// @include hairline{
// border-right-width: 0;
// border-bottom-width: 0;
// border-left-width: 1px;
// border-top-width: 1px;
// };
// }
// //一行溢出
// @mixin text-overflow{
// white-space: nowrap;
// text-overflow: ellipsis;
// overflow: hidden;
// word-break: break-all;
// };
// //两行溢出
// @mixin ov($num: 2){
// text-overflow: -o-ellipsis-lastline;
// overflow: hidden;
// text-overflow: ellipsis;
// display: -webkit-box;
// -webkit-line-clamp: $num;
// line-clamp: $num;
// -webkit-box-orient: vertical;
// }
// @mixin ellipsis($lines: 1) {
// @if ($lines==1) {
// overflow: hidden;
// text-overflow: ellipsis;
// white-space: nowrap;
// } @else {
// display: -webkit-box;
// -webkit-box-orient: vertical;
// -webkit-line-clamp: $lines;
// overflow: hidden;
// text-overflow: ellipsis;
// word-break: break-all;
// }
// }

2
main.js

@ -13,5 +13,5 @@ Vue.use(niuUI)
const app = new Vue({
...App
})
setTimeout(function() {toast.success("asd")}, 10);
app.$mount()

5
pages.json

@ -4,7 +4,10 @@
"path": "pages/index/index",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app"
"navigationBarTitleText": "uni-app",
"app-plus": {
"bounce": "none"
}
}
}
,{

152
pages/Sub/Tabs/Tabs.vue

@ -1,9 +1,11 @@
<template>
<niu-page>
<niu-navbar fixed color="white" bg="#39b54a">
<niu-navbar fixed color="white" middleLayout='left' bg="#39b54a">
Tabs
</niu-navbar>
<niu-tabs :list="colorList" @change="change" v-model="active"></niu-tabs>
<view style="font-size: 35rpx;">
<niu-tabs :list="colorList" @change="change" v-model="active"></niu-tabs>
</view>
<niu-tabs :list="colorList" @change="change" capsule v-model="active"></niu-tabs>
<niu-tabs :list="colorList" :bar="false" @change="change" v-model="active">
<template #bar="{show, barLeft, barWidth, anim, props}">
@ -23,9 +25,10 @@
]"></view>
</template>
</niu-tabs>
<niu-tabs :list="fiveList" full :barPer=".8" @change="change" v-model="active"></niu-tabs>
<niu-tabs :list="fiveList" full :barPer=".8" @change="change" v-model="active"></niu-tabs>
<niu-tabs :list="fiveList" full :barPer=".8" @change="change" capsule v-model="active"></niu-tabs>
<niu-tabs :list="colorList" :active-color="colorList[active]&&colorList[active].color" :bar="false" @change="change" v-model="active">
<niu-tabs :list="colorList" :active-color="colorList[active]&&colorList[active].color" :bar="false"
@change="change" v-model="active">
<template #bar="{show, barLeft, barWidth, anim, props, item}">
<view v-if="show" :style="[
{
@ -58,47 +61,118 @@
},
data() {
return {
formData:{
formData: {
buildingArea: ''
},
active: 2,
fiveList: [
{ text: "金吒" },
{ text: "木吒" },
{ text: "水吒" },
{ text: "火吒" },
{ text: "土吒" }
fiveList: [{
text: "金吒"
},
{
text: "木吒"
},
{
text: "水吒"
},
{
text: "火吒"
},
{
text: "土吒"
}
],
colorList: [
{ text: "嫣红", color: "#e54d42" },
{ text: "桔橙", color: "#f37b1d" },
{ text: "明黄", color: "#fbbd08" },
{ text: "橄榄", color: "#8dc63f" },
{ text: "森绿", color: "#39b54a" },
{ text: "天青", color: "#1cbbb4" },
{ text: "海蓝", color: "#0081ff" },
{ text: "姹紫", color: "#6739b6" },
{ text: "木槿", color: "#9c26b0" },
{ text: "桃粉", color: "#e03997" },
{ text: "棕褐", color: "#a5673f" },
{ text: "玄灰", color: "#8799a3" },
{ text: "草灰", color: "#aaaaaa" },
{ text: "墨黑", color: "#333333" },
{ text: "雅白", color: "#ffffff" },
colorList: [{
text: "嫣红",
color: "#e54d42"
},
{
text: "桔橙",
color: "#f37b1d"
},
{
text: "明黄",
color: "#fbbd08"
},
{
text: "橄榄",
color: "#8dc63f"
},
{
text: "森绿",
color: "#39b54a"
},
{
text: "天青",
color: "#1cbbb4"
},
{
text: "海蓝",
color: "#0081ff"
},
{
text: "姹紫",
color: "#6739b6"
},
{
text: "木槿",
color: "#9c26b0"
},
{
text: "桃粉",
color: "#e03997"
},
{
text: "棕褐",
color: "#a5673f"
},
{
text: "玄灰",
color: "#8799a3"
},
{
text: "草灰",
color: "#aaaaaa"
},
{
text: "墨黑",
color: "#333333"
},
{
text: "雅白",
color: "#ffffff"
},
]
};
},methods: {
cilck(){
this.fiveList = [
{ text: "金吒" },
{ text: "木吒" },
{ text: "土吒" },
{ text: "土吒" },
{ text: "土吒" },
{ text: "土吒22222" },
{ text: "土吒" },
{ text: "土吒" },
{ text: "土吒" },
},
methods: {
cilck() {
this.fiveList = [{
text: "金吒"
},
{
text: "木吒"
},
{
text: "土吒"
},
{
text: "土吒"
},
{
text: "土吒"
},
{
text: "土吒22222"
},
{
text: "土吒"
},
{
text: "土吒"
},
{
text: "土吒"
},
]
},
change(index) {

7
pages/index/index.vue

@ -1,7 +1,10 @@
<template>
<niu-page Tab className="wqeqw">
<niu-navbar fixed :back="false" color="white" bg="#39b54a">
<niu-page Tab>
<niu-navbar fixed adjust middleLayout='left' :back="false" color="white" bg="#39b54a">
爱能森组件库
<template #right>
asd
</template>
</niu-navbar>
<view class="title">
组件池

8
readme.md

@ -0,0 +1,8 @@
# niu-ui
第一个版本,目前仅供个人使用
```
import niuUI, {toast} from '@/uni_modules/niu-ui'
Vue.use(niuUI)
```

2
uni.scss

@ -13,7 +13,7 @@
*/
/* 颜色变量 */
@import '~@/assets/style/global.scss';
@import '~@/uni_modules/niu-ui/assets/style/global.scss';
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;

125
uni_modules/niu-ui/assets/style/common.scss

@ -1,14 +1,12 @@
page {
// background-color: #FFF8F8;
page {
background-color: #F1F1F1;
// min-height: 100%;
height: 100%;
font-size: 28rpx;
line-height: 1.2; //
color: #000;
color: darkred;
}
page .tabpage{
page .tabpage {
// 怪异盒模型
-webkit-overflow-scrolling: touch;
box-sizing: border-box;
@ -16,7 +14,7 @@ page {
//貌似不需要了已经是去除了tabbar的高度了
//自定义tabbar的时候需要
// 底部tab栏高度
margin-bottom: 0;//var(--window-bottom);
margin-bottom: 0; //var(--window-bottom);
/* #endif */
/* #ifndef H5 */
margin-bottom: 0;
@ -26,7 +24,8 @@ page {
// overflow-y: scroll;
min-height: 100%;
}
page .page{
page .page {
// 怪异盒模型
-webkit-overflow-scrolling: touch;
box-sizing: border-box;
@ -37,109 +36,19 @@ page {
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
display: none;
width: 0;
height: 0;
color: transparent;
display: none;
}
page *{
page * {
box-sizing: border-box;
}
.a-flexbox{
display: flex;
&.a-flexbox--fixed{
flex-shrink: 0;
flex-grow: 0;
}
&.a-flexbox--inline{
display: inline-flex;
}
&.a-flexbox__column{
flex-direction: column;
}
&.a-flexbox__row{
flex-direction: row;
}
&.a-flexbox__wrap{
flex-wrap: wrap;
}
&.a-flexbox__center{
align-items: center;
justify-content: center;
}
&.a-flexbox__center--x{
justify-content: center;
}
&.a-flexbox--around{
justify-content: space-around;
}
&.a-flexbox--between{
justify-content: space-between;
}
&.a-flexbox__start--x{
justify-content: flex-start;
}
&.a-flexbox__end--x{
justify-content: flex-end;
}
&.a-flexbox__center--y{
align-items: center;
}
&.a-flexbox__start--y{
align-items: flex-start;
}
&.a-flexbox__end--y{
align-items: flex-end;
}
.a-flexbox__noshrink{
flex-shrink: 0;
}
.a-flexbox__full{
flex: 1;
width: 0;
}
.a-flexbox__full--h{
flex: 1;
height: 0;
}
}
// 单行省略号
.a-ov{
@include ellipsis(1)
}
// 两行省略号
.a-ov2{
@include ellipsis(2)
}
// 包裹输入框
.a-wrapinput{
position:relative;
display: flex;
align-items: center;
// height: 100%;
>input{
width: 0;
flex: 1;
// height: 100%;
font-size: inherit;
line-height: inherit;
}
.sub{
display: flex;
align-items: center;
margin-right: 8rpx;
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
display: none;
}
// 包裹文本域
.a-wraptextarea{
min-height: 160rpx;
height: 160rpx;
>textarea{
font-size: inherit;
width: 100%;
height: 100%;
}
}

1
uni_modules/niu-ui/assets/style/global.scss

@ -51,6 +51,7 @@
border-left-width: 1px;
};
}
@mixin hairline--bottom {
@include hairline{
border-bottom-width: 1px;

4
uni_modules/niu-ui/changelog.md

@ -0,0 +1,4 @@
## 0.0.1.alpha.1(2022-07-18)
版本修改
## 0.0.1(2022-07-18)
第一个版本

2
uni_modules/niu-ui/components/niu-navbar/niu-navbar.vue

@ -17,7 +17,7 @@
backgroundColor: !gradient?bg:'transparent'
}" :class="[toFixed?'fixed':'',border?'border':'']">
<view v-if="!oneline" class="niu-navbar__left" @click="clickLeft"
:style="{color: color,height: x_height?(x_height+'px'):'',lineHeight: x_height?(x_height+'px'):'',top: x_statusHeight?(x_statusHeight+'px'):''}">
:style="{color: color,height: x_height?(x_height+'px'):'',lineHeight: x_height?(x_height+'px'):'',top: x_statusHeight?(x_statusHeight+'px'):'', width: middleLayout=='left'?'auto':'', padding: middleLayout=='left'?'0 10rpx':''}">
<slot name="left">
<!-- <i v-if="back" class="niu-navbar__icon iconfont icon-back_light"></i> -->
<image v-if="!firstPage&&back" class="niu-navbar__icon"

20
uni_modules/niu-ui/components/niu-page/niu-page.vue

@ -1,5 +1,5 @@
<template>
<view :class="[className, Tab?'tabpage':'page']" :style="inStyle">
<view :class="[Tab?'tabpage':'page']">
<slot></slot>
</view>
</template>
@ -11,14 +11,6 @@
Tab: {
type: Boolean,
default: false
},
className: {
type: String || Array,
default: ''
},
inStyle:{
type: String || Object,
default: ''
}
},
data() {
@ -33,12 +25,8 @@
this.curPage = pages[len - 1];
this._curDeep = len;
},
methods:{
methods: {
}
}
</script>
<style lang="scss" scoped>
</style>
</script>

9
uni_modules/niu-ui/components/niu-tabs/niu-tabs.vue

@ -12,8 +12,9 @@
<!-- 循环中使用slot会报警告暂时去除未找到处理办法 -->
<!-- <slot :data="item" :pData="pData" :index="index"> -->
<text>{{item[akey]}}</text>
<view v-if="value==index && activeImage" class="niu-x-tabs__bg">
<image class="image" :src="activeImage" mode="widthFix"></image>
<!-- 必须两个if不然有时app上出错了 -->
<view v-if="value==index && !!activeImage" class="niu-x-tabs__bg">
<image v-if="value==index && !!activeImage" class="image" :src="activeImage" mode="widthFix"></image>
</view>
<!-- </slot> -->
</view>
@ -26,7 +27,7 @@
:item="list[value]"
:props="{normalColor, activeColor}"
>
<view v-if="bar&&value<list.length" class="niu-x-tabs__bar" :class="{capsule}" :style="[{left:barLeft + 'px',width:barWidth + 'px',backgroundColor: barColor},, anim?{transition: 'left .3s ease, width .3s ease'}:{}]"></view>
<view v-if="bar&&value<list.length" class="niu-x-tabs__bar" :class="{capsule}" :style="[{left:barLeft + 'px',width:barWidth + 'px',backgroundColor: barColor}, anim?{transition: 'left .3s ease, width .3s ease'}:{}]"></view>
</slot>
</view>
</view>
@ -201,7 +202,9 @@
if (isClick && this.value == index) return
if (this.allLeft.length) {
this.$emit("change", index)
console.log(this.allLeft, this.barPer);
this.barWidth = this.allLeft[index][1] * this.barPer
console.log(this.barWidth);
this.barLeft = this.allLeft[index][0] + (this.allLeft[index][1] - this.barWidth)/2
this.left = (this.allLeft[index][0] - this.allLeft[index][1] * 2)
}

8
uni_modules/niu-ui/components/niu-ui/niu-ui.vue

@ -0,0 +1,8 @@
<template>
</template>
<script>
</script>
<style>
</style>

7
uni_modules/niu-ui/index.js

@ -6,11 +6,14 @@ export {
util
}
export default {
install(Vue) {
install(Vue, options = {}) {
const data = Vue.observable({
data: {},
util: util,
toast: toast
toast: toast,
config: {
mainColor: "#39b54a"
},
})
Vue.mixin({
computed: {

16
uni_modules/niu-ui/package.json

@ -1,11 +1,11 @@
{
"id": "niu-ui",
"displayName": "niu-ui",
"version": "1.0.0",
"version": "0.0.1.alpha.1",
"description": "niu-ui",
"keywords": [
"niu-ui"
],
"niu-ui"
],
"main": "index.js",
"repository": "",
"engines": {
@ -28,9 +28,9 @@
"qq": ""
},
"declaration": {
"ads": "",
"data": "",
"permissions": ""
"ads": "",
"data": "插件不采集任何数据",
"permissions": ""
},
"npmurl": ""
},
@ -39,8 +39,8 @@
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "u",
"aliyun": "u"
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {

9
uni_modules/niu-ui/readme.md

@ -1 +1,8 @@
# niu-ui
# niu-ui
第一个版本,目前仅供个人使用
```
import niuUI, {toast} from '@/uni_modules/niu-ui'
Vue.use(niuUI)
```
Loading…
Cancel
Save