Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
games
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
熊东起
games
Commits
73761d34
Commit
73761d34
authored
Nov 03, 2020
by
熊东起
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first
parent
4906038f
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
236 additions
and
186 deletions
+236
-186
index.html
index.html
+1
-1
layers.ts
module/views/layers.ts
+4
-0
output.js
output.js
+89
-60
output.js.map
output.js.map
+1
-1
bubble_next.png
resource/bubbleBubble/bubble_next.png
+0
-0
catBath.svga
resource/bubbleSvga/catBath.svga
+0
-0
GuideMgr.ts
src/Mgr/GuideMgr.ts
+5
-0
ResJson.ts
src/ResJson.ts
+4
-4
Bubble.ts
src/game/Bubble.ts
+1
-1
BubbleBath.ts
src/game/BubbleBath.ts
+14
-7
GuideMask.ts
src/game/GuideMask.ts
+1
-1
TimerCount.ts
src/game/TimerCount.ts
+94
-93
MConst.ts
src/global/MConst.ts
+3
-3
GameFailPanel.ts
src/panels/GameFailPanel.ts
+9
-7
GameSuccessPanel.ts
src/panels/GameSuccessPanel.ts
+8
-7
GameScenes.ts
src/scenes/GameScenes.ts
+2
-1
No files found.
index.html
View file @
73761d34
...
...
@@ -49,7 +49,7 @@
<script>
window
.
addEventListener
(
"load"
,
function
()
{
//是否完成新手
const
scheduleFinished
=
0
;
const
scheduleFinished
=
1
;
//目标分数
const
targetScore
=
120
;
//是否音乐
...
...
module/views/layers.ts
View file @
73761d34
...
...
@@ -28,6 +28,10 @@ class Layers extends FYGE.Container {
//有些时候,定宽的时候,部分layer置顶,部分居中,再处理
//为了都置顶和置左,stage的方式永远居中视窗,要么改stage永远左上为00
// this[arr[i]].y = this.stageOffsetY;
if
(
this
.
stageHeight
>
1624
)
{
this
[
arr
[
i
]].
scaleY
=
this
.
stageHeight
/
1624
;
this
[
arr
[
i
]].
y
=
this
.
stageOffsetY
;
}
//如果定宽这里没必要,肯定是0
// this[arr[i]].x = this.stageOffsetX;//去掉,定高时就居中了
this
.
addChild
(
this
[
arr
[
i
]]);
...
...
output.js
View file @
73761d34
This diff is collapsed.
Click to expand it.
output.js.map
View file @
73761d34
This diff is collapsed.
Click to expand it.
resource/bubbleBubble/bubble_next.png
View replaced file @
4906038f
View file @
73761d34
2.56 KB
|
W:
|
H:
4.13 KB
|
W:
|
H:
2-up
Swipe
Onion skin
resource/bubbleSvga/catBath.svga
View file @
73761d34
No preview for this file type
src/Mgr/GuideMgr.ts
View file @
73761d34
import
{
DataMgr
}
from
"./DataMgr"
;
import
{
MConfigs
}
from
"../Global/MConfigs"
;
import
GuideMask
from
"../game/GuideMask"
;
import
{
GDispatcher
}
from
"../BubbleBathMain"
;
import
TimerCountMgr
from
"./TimerCountMgr"
;
// import Pot from "../game/Pot";
// import Food from "../game/Food";
...
...
@@ -48,10 +50,13 @@ export default class GuideMgr {
DataMgr
.
game
.
pause
=
true
;
this
.
currentGuideMask
=
new
GuideMask
();
this
.
currentGuideMask
.
onClick
=
(
context
)
=>
{
//新手引导
GDispatcher
.
dispatchEvent
(
"new-guide"
);
//@ts-ignore
context
.
dispose
();
this
.
currentGuideMask
=
null
;
DataMgr
.
game
.
pause
=
false
;
TimerCountMgr
.
instance
.
drawTimerCount
();
if
(
isEnd
)
{
this
.
guideFlag
=
false
;
}
...
...
src/ResJson.ts
View file @
73761d34
...
...
@@ -27,7 +27,7 @@ export const ResJson = {
"ro"
:
true
},
"bubble_count.png"
:
{
"x"
:
100
7
,
"x"
:
100
8
,
"y"
:
368
,
"w"
:
113
,
"h"
:
112
,
...
...
@@ -51,11 +51,11 @@ export const ResJson = {
"bubble_next.png"
:
{
"x"
:
754
,
"y"
:
1136
,
"w"
:
25
1
,
"w"
:
25
2
,
"h"
:
68
,
"ox"
:
0
,
"oy"
:
0
,
"sw"
:
25
1
,
"sw"
:
25
2
,
"sh"
:
68
,
"ro"
:
false
},
...
...
@@ -607,5 +607,5 @@ export const ResJson = {
}
}
],
"path"
:
"https://yun.duiba.com.cn/db_games/activity/kickball-feile/160
1606821
/resource/"
"path"
:
"https://yun.duiba.com.cn/db_games/activity/kickball-feile/160
2988706
/resource/"
}
\ No newline at end of file
src/game/Bubble.ts
View file @
73761d34
...
...
@@ -101,7 +101,7 @@ export default class Bubble extends MoveObjcet implements PoolElement {
if
(
!
DataMgr
.
game
.
pause
)
{
FYGE
.
Tween
.
get
(
this
)
.
set
({
scaleX
:
0.2
,
scaleY
:
0.2
})
.
to
({
x
:
BaseX
,
y
:
BaseY
,
scaleX
:
1
,
scaleY
:
1
},
10
00
)
.
to
({
x
:
BaseX
,
y
:
BaseY
,
scaleX
:
1
,
scaleY
:
1
},
5
00
)
.
call
(()
=>
{
this
.
pause
=
false
;
});
...
...
src/game/BubbleBath.ts
View file @
73761d34
...
...
@@ -54,7 +54,7 @@ export default class BubbleBath extends FYGE.Container {
GDispatcher
.
once
(
"gameDead"
,
this
.
gameDead
,
this
);
//弹窗测试
// showPanel(Game
Fail
Panel);
// showPanel(Game
Success
Panel);
//引导
GuideMgr
.
instance
.
container
=
parent
;
...
...
@@ -190,6 +190,9 @@ export default class BubbleBath extends FYGE.Container {
public
set
score
(
v
:
number
)
{
this
.
_score
=
v
;
this
.
totalBubbleCountLabel
.
text
=
this
.
_score
+
""
;
if
(
this
.
_score
>=
100
){
this
.
totalBubbleCountLabel
.
x
=
76
;
}
}
public
get
score
():
number
{
return
this
.
_score
;
...
...
@@ -247,6 +250,11 @@ export default class BubbleBath extends FYGE.Container {
/** 创建泡泡 */
private
createBubbles
()
{
//新手引导
if
(
MConst
.
options
.
scheduleFinished
==
0
)
{
GuideMgr
.
instance
.
drawFirstGuide
(
true
);
MConst
.
options
.
scheduleFinished
=
1
;
}
let
size
=
MUtils
.
randomInt
(
0
,
MConfigs
.
size
.
length
);
let
dir
:
1
|
-
1
=
Math
.
random
()
>
0.5
?
-
1
:
1
;
let
bubble
=
this
.
bubblePool
.
spwan
(
size
);
...
...
@@ -256,10 +264,7 @@ export default class BubbleBath extends FYGE.Container {
bubble
.
startBubble
(
dir
);
bubble
.
mouseEnable
=
true
;
bubble
.
mouseChildren
=
true
;
//新手引导
if
(
GuideMgr
.
instance
.
guideFlag
==
true
&&
this
.
_bubbleList
.
length
>
1
&&
MConst
.
options
.
scheduleFinished
==
1
)
{
GuideMgr
.
instance
.
drawFirstGuide
(
true
);
}
}
/** 泡泡破灭 */
...
...
@@ -332,6 +337,7 @@ export default class BubbleBath extends FYGE.Container {
if
(
result
.
data
.
leftTimes
>
0
)
{
showPanel
(
GameFailPanel
,
{
isAgain
:
true
});
GDispatcher
.
dispatchEvent
({
type
:
"showBuried"
},
{
md
:
29
});
GDispatcher
.
dispatchEvent
({
type
:
"showBuried"
},
{
md
:
47
});
}
else
{
showPanel
(
GameFailPanel
,
{
isAgain
:
false
});
GDispatcher
.
dispatchEvent
({
type
:
"showBuried"
},
{
md
:
31
});
...
...
@@ -340,16 +346,17 @@ export default class BubbleBath extends FYGE.Container {
if
(
result
.
data
.
leftTimes
>
0
)
{
showPanel
(
GameSuccessPanel
,
{
isAgain
:
true
,
glodCoin
:
result
.
data
.
goldenCo
i
n
,
glodCoin
:
result
.
data
.
goldenCo
r
n
,
});
GDispatcher
.
dispatchEvent
({
type
:
"showBuried"
},
{
md
:
27
});
GDispatcher
.
dispatchEvent
({
type
:
"showBuried"
},
{
md
:
28
});
}
else
{
showPanel
(
GameSuccessPanel
,
{
isAgain
:
false
,
glodCoin
:
result
.
data
.
goldenCo
i
n
,
glodCoin
:
result
.
data
.
goldenCo
r
n
,
});
GDispatcher
.
dispatchEvent
({
type
:
"showBuried"
},
{
md
:
30
});
GDispatcher
.
dispatchEvent
({
type
:
"showBuried"
},
{
md
:
48
});
}
}
}
...
...
src/game/GuideMask.ts
View file @
73761d34
...
...
@@ -48,7 +48,7 @@ export default class GuideMask extends FYGE.Container {
//描述
let
descText
=
Tool
.
getText
(
"在
游戏结束前,手指点击泡泡戳破它
\n
戳破100个泡泡即可闯关成功哦
"
,
"在
限定时间内
\n
戳破100个泡泡就能获得奖励哦~
"
,
30
,
"#ffffff"
,
FYGE
.
TEXT_ALIGN
.
CENTER
,
...
...
src/game/TimerCount.ts
View file @
73761d34
...
...
@@ -28,103 +28,104 @@ export default class TimerCount extends FYGE.Container {
self
=
this
;
this
.
addChild
(
allIn
);
//加入SVGA
let
readySvga
=
new
FYGE
.
MovieClip
(
RES
.
getRes
(
"bubble_ready.svga"
));
allIn
.
addChild
(
readySvga
);
readySvga
.
stop
();
let
time1Svga
=
new
FYGE
.
MovieClip
(
RES
.
getRes
(
"bubble_time_1.svga"
));
allIn
.
addChild
(
time1Svga
);
time1Svga
.
stop
();
let
time2Svga
=
new
FYGE
.
MovieClip
(
RES
.
getRes
(
"bubble_time_2.svga"
));
allIn
.
addChild
(
time2Svga
);
time2Svga
.
stop
();
let
time3Svga
=
new
FYGE
.
MovieClip
(
RES
.
getRes
(
"bubble_time_3.svga"
));
allIn
.
addChild
(
time3Svga
);
time3Svga
.
stop
();
//
let readySvga = new FYGE.MovieClip(RES.getRes("bubble_ready.svga"));
//
allIn.addChild(readySvga);
//
readySvga.stop();
//
let time1Svga = new FYGE.MovieClip(RES.getRes("bubble_time_1.svga"));
//
allIn.addChild(time1Svga);
//
time1Svga.stop();
//
let time2Svga = new FYGE.MovieClip(RES.getRes("bubble_time_2.svga"));
//
allIn.addChild(time2Svga);
//
time2Svga.stop();
//
let time3Svga = new FYGE.MovieClip(RES.getRes("bubble_time_3.svga"));
//
allIn.addChild(time3Svga);
//
time3Svga.stop();
time1Svga
.
visible
=
time2Svga
.
visible
=
time3Svga
.
visible
=
false
;
//倒计时准备音效
// time1Svga.visible = time2Svga.visible = time3Svga.visible = false;
// //倒计时准备音效
// SoundMgr.instance.playSound("timerCount",false);
// readySvga.startAniRange(0, readySvga.totalFrames, 1, () => {
// FYGE.Tween.get(this)
// .call(() => {
// time3Svga.visible = true;
// time3Svga.startAniRange(0, time3Svga.totalFrames, 1, () => {
// time3Svga.visible = false;
// });
// })
// .wait(1000)
// .call(() => {
// time2Svga.visible = true;
// time2Svga.startAniRange(0, time2Svga.totalFrames, 1, () => {
// time2Svga.visible = false;
// });
// })
// .wait(1000)
// .call(() => {
// time1Svga.visible = true;
// time1Svga.startAniRange(0, time1Svga.totalFrames, 1, () => {
// time1Svga.visible = false;
// callback();
// FYGE.Tween.removeTweens(self);
// });
// });
// });
//背景
SoundMgr
.
instance
.
playSound
(
"timerCount"
,
false
);
readySvga
.
startAniRange
(
0
,
readySvga
.
totalFrames
,
1
,
()
=>
{
FYGE
.
Tween
.
get
(
this
)
.
call
(()
=>
{
time3Svga
.
visible
=
true
;
time3Svga
.
startAniRange
(
0
,
time3Svga
.
totalFrames
,
1
,
()
=>
{
time3Svga
.
visible
=
false
;
});
})
.
wait
(
1000
)
.
call
(()
=>
{
time2Svga
.
visible
=
true
;
time2Svga
.
startAniRange
(
0
,
time2Svga
.
totalFrames
,
1
,
()
=>
{
time2Svga
.
visible
=
false
;
});
var
timeBg
=
new
FYGE
.
Sprite
(
RES
.
getRes
(
"timerBg.png"
));
timeBg
.
anchorTexture
.
set
(
0.5
,
0.5
);
timeBg
.
x
=
750
/
2
;
timeBg
.
y
=
1624
/
2
;
timeBg
.
alpha
=
1
;
allIn
.
addChild
(
timeBg
);
var
fourImages
=
[];
var
fourTextures
=
[
"bubble_ready.png"
,
"bubble_time_3.png"
,
"bubble_time_2.png"
,
"bubble_time_1.png"
,
];
for
(
var
i
=
0
;
i
<
fourTextures
.
length
;
i
++
)
{
var
t
:
FYGE
.
Texture
=
RES
.
getRes
(
fourTextures
[
i
]);
var
im
=
new
FYGE
.
Sprite
(
t
);
//都需要居中
im
.
anchorTexture
.
set
(
0.5
,
0.5
);
im
.
x
=
750
/
2
;
im
.
y
=
1624
/
2
;
im
.
alpha
=
0
;
fourImages
.
push
(
im
);
allIn
.
addChild
(
im
);
}
//如果背景音乐开着的话先关闭
// if (getBgOn()) stopBg();
for
(
let
i
=
0
;
i
<
4
;
i
++
)
{
let
im
=
fourImages
[
i
];
let
delta
=
i
*
1000
;
let
t
=
FYGE
.
Tween
.
get
(
im
);
t
.
wait
(
delta
)
.
set
({
alpha
:
1
,
scaleX
:
0.1
,
scaleY
:
0.1
})
.
to
({
scaleX
:
1
,
scaleY
:
1
},
500
,
FYGE
.
Ease
.
backOut
)
.
wait
(
500
);
if
(
i
==
3
)
{
t
.
call
(()
=>
{
callback
();
})
.
wait
(
1000
)
.
call
(()
=>
{
time1Svga
.
visible
=
true
;
time1Svga
.
startAniRange
(
0
,
time1Svga
.
totalFrames
,
1
,
()
=>
{
time1Svga
.
visible
=
false
;
callback
();
FYGE
.
Tween
.
removeTweens
(
self
);
.
to
({
alpha
:
0
},
200
)
.
call
(()
=>
{
//执行完销毁吧,浏览器自己回收吧
// allIn.destroy();
this
.
removeChild
(
allIn
);
// if (getBgOn()) playBg();
});
}
else
{
t
.
set
({
alpha
:
0
});
}
if
(
i
==
0
)
{
t
.
call
(()
=>
{
timeBg
.
alpha
=
1
;
});
});
//背景
// var timeBg = new FYGE.Sprite(RES.getRes("timerBg.png"));
// timeBg.anchorTexture.set(0.5, 0.5);
// timeBg.x = 750 / 2;
// timeBg.y = 1624 / 2;
// timeBg.alpha = 0;
// allIn.addChild(timeBg);
// var fourImages = [];
// var fourTextures = [
// "bubble_ready.png",
// "bubble_time_3.png",
// "bubble_time_2.png",
// "bubble_time_1.png",
// ];
// for (var i = 0; i < fourTextures.length; i++) {
// var t: FYGE.Texture = RES.getRes(fourTextures[i]);
// var im = new FYGE.Sprite(t);
// //都需要居中
// im.anchorTexture.set(0.5, 0.5);
// im.x = 750 / 2;
// im.y = 1624 / 2;
// im.alpha = 0;
// fourImages.push(im);
// allIn.addChild(im);
// }
// //如果背景音乐开着的话先关闭
// // if (getBgOn()) stopBg();
// for (let i = 0; i < 4; i++) {
// let im = fourImages[i];
// let delta = i * 1000;
// let t = FYGE.Tween.get(im);
// t.wait(delta)
// .set({ alpha: 1, scaleX: 0.1, scaleY: 0.1 })
// .to({ scaleX: 1, scaleY: 1 }, 500, FYGE.Ease.backOut)
// .wait(500);
// if (i == 3) {
// t.call(() => {
// callback();
// })
// .to({ alpha: 0 }, 200)
// .call(() => {
// //执行完销毁吧,浏览器自己回收吧
// // allIn.destroy();
// this.removeChild(allIn);
// // if (getBgOn()) playBg();
// });
// } else {
// t.set({ alpha: 0 });
// }
// if (i == 0) {
// t.call(() => {
// timeBg.alpha = 1;
// });
// }
// }
}
}
}
}
src/global/MConst.ts
View file @
73761d34
...
...
@@ -7,12 +7,12 @@ export namespace MConst {
export
const
GroundLine
=
0
;
//地平线
export
const
Gravity
=
0.01
;
//泡泡加速度
export
const
BubbleSplitVelocityX
=
1.2
;
//X方向偏移
export
const
BubbleSplitVelocityY
=
2
.8
;
//每帧上飘距离
export
const
BubbleSplitVelocityY
=
6
.8
;
//每帧上飘距离
export
const
BubbleInitPosY
=
1306
*
0.8
;
//泡泡初始位置——Y
export
const
CurMaxBubbleNum
=
2
0
;
//界面最多存在泡泡数
export
const
CurMaxBubbleNum
=
3
0
;
//界面最多存在泡泡数
export
const
BubbleVelocityX
=
2
;
export
const
BubbleVelocityXRandomFactor
=
0.9
;
export
const
BubbleAppearSpace
=
50
0
;
//泡泡出现间隔 -- 初始
export
const
BubbleAppearSpace
=
32
0
;
//泡泡出现间隔 -- 初始
export
const
countDown
=
1
*
60
;
//倒计时时间
export
let
tickSeconds
=
60
;
export
let
options
=
{
...
...
src/panels/GameFailPanel.ts
View file @
73761d34
...
...
@@ -29,28 +29,28 @@ export class GameFailPanel extends Panel {
//数据
const
{
isAgain
}
=
this
.
data
;
// var isAgain =
fals
e;//是否只有一颗 按钮
// var isAgain =
tru
e;//是否只有一颗 按钮
//描述
let
title
=
Tool
.
getText
(
`
${
isAgain
?
"不想失去奖励"
:
"猫咪累了"
}
`
,
`
${
isAgain
?
"不想失去奖励
?
"
:
"猫咪累了"
}
`
,
38
,
"#333333"
,
FYGE
.
TEXT_ALIGN
.
CENTER
,
2
3
0
2
8
0
);
this
.
addChild
(
title
);
title
.
position
.
set
(
2
7
0
,
820
);
title
.
position
.
set
(
2
4
0
,
820
);
//获得奖励
let
getPrizeText
=
Tool
.
getText
(
`
${
isAgain
?
"
不如再试一次"
:
"等等再来玩
"
}
`
,
`
${
isAgain
?
"
那再试一次吧~"
:
"过会儿再来陪它玩吧~
"
}
`
,
32
,
`
${
isAgain
?
"#3b8edd"
:
"#333333"
}
`
,
FYGE
.
TEXT_ALIGN
.
CENTER
,
23
0
40
0
);
this
.
addChild
(
getPrizeText
);
getPrizeText
.
position
.
set
(
27
0
,
880
);
getPrizeText
.
position
.
set
(
18
0
,
880
);
//看猫
this
.
seeCat
=
new
FYGE
.
Button
(
RES
.
getRes
(
"bubble_seecat.png"
));
...
...
@@ -86,6 +86,8 @@ export class GameFailPanel extends Panel {
//看猫咪
onClickSeeCat
()
{
if
(
this
.
againBtn
.
visible
)
{
GDispatcher
.
dispatchEvent
(
"clickBuried"
,
{
md
:
47
});
}
else
{
GDispatcher
.
dispatchEvent
(
"clickBuried"
,
{
md
:
31
});
}
GDispatcher
.
dispatchEvent
(
"bubble-see-cat"
);
...
...
src/panels/GameSuccessPanel.ts
View file @
73761d34
...
...
@@ -36,18 +36,18 @@ export class GameSuccessPanel extends Panel {
//数据
const
{
isAgain
,
glodCoin
}
=
this
.
data
;
// var isAgain =
false
;
// var isAgain =
true,glodCoin=100
;
//描述
let
title
=
Tool
.
getText
(
"
达成目标分数
"
,
"
太棒了,目标达成!
"
,
34
,
"#333333"
,
FYGE
.
TEXT_ALIGN
.
CENTER
,
23
0
32
0
);
this
.
addChild
(
title
);
title
.
position
.
set
(
2
70
,
780
);
title
.
position
.
set
(
2
35
,
780
);
//获得奖励
let
getPrizeText
=
Tool
.
getText
(
"获得奖励"
,
...
...
@@ -62,7 +62,7 @@ export class GameSuccessPanel extends Panel {
//金币
let
coin
=
new
FYGE
.
Sprite
(
RES
.
getRes
(
"bubble_coin.png"
));
this
.
addChild
(
coin
);
coin
.
position
.
set
(
3
15
,
900
);
coin
.
position
.
set
(
3
30
,
900
);
let
coinText
=
Tool
.
getText
(
`X
${
glodCoin
}
`
,
...
...
@@ -72,7 +72,7 @@ export class GameSuccessPanel extends Panel {
90
);
this
.
addChild
(
coinText
);
coinText
.
position
.
set
(
36
5
,
908
);
coinText
.
position
.
set
(
36
0
,
908
);
//爱心
// let love = new FYGE.Sprite(RES.getRes("bubble_love.png"));
// this.addChild(love);
...
...
@@ -119,6 +119,7 @@ export class GameSuccessPanel extends Panel {
//等等再来玩
onClickAwait
()
{
GDispatcher
.
dispatchEvent
(
"bubble-await"
);
GDispatcher
.
dispatchEvent
(
"clickBuried"
,
{
md
:
48
});
this
.
hidePanel
();
}
...
...
@@ -131,7 +132,7 @@ export class GameSuccessPanel extends Panel {
GDispatcher
.
dispatchEvent
(
"clickBuried"
,
{
md
:
29
});
}
GDispatcher
.
dispatchEvent
(
"bubble-share"
);
this
.
hidePanel
();
//
this.hidePanel();
}
initEvents
()
{
...
...
src/scenes/GameScenes.ts
View file @
73761d34
...
...
@@ -34,7 +34,8 @@ export class GameScenes extends Scene {
if
(
!
this
.
game
)
{
this
.
game
=
new
BubbleBath
(
this
);
}
TimerCountMgr
.
instance
.
drawTimerCount
();
if
(
MConst
.
options
.
scheduleFinished
==
1
)
TimerCountMgr
.
instance
.
drawTimerCount
();
//设置隐藏属性和改变可见属性的事件的名称
let
hidden
:
string
,
visibilityChange
:
string
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment