522 lines
18 KiB
Objective-C
522 lines
18 KiB
Objective-C
//
|
|
// GiGaMaskTaskViewController.m
|
|
// GIGA
|
|
//
|
|
// Created by lianxiang on 2018/8/14.
|
|
// Copyright © 2018年 com.giga.ios. All rights reserved.
|
|
//
|
|
|
|
#import "GiGaMaskTaskViewController.h"
|
|
#import "MaskViewBootomWaringView.h"
|
|
#import "GiGaUserLoginVC.h"
|
|
#import "UserGuardViewController.h"
|
|
#import "GiGaUserDefault.h"
|
|
#import "GiGaAppGaurdVC.h"
|
|
#import "GiGaMeViewController.h"
|
|
#import "GiGaAdDetailViewController.h"
|
|
#import "GiGaMasssagesVC.h"
|
|
#import "GiGaQuestionVC.h"
|
|
#import <AVFoundation/AVFoundation.h>
|
|
#import "GiGaLocalNotificationManager.h"
|
|
#import "AppDelegate.h"
|
|
#import "LXCountTimer.h"
|
|
#import "GiGaHelper.h"
|
|
#import <MediaPlayer/MediaPlayer.h>
|
|
#import "GiGaMeViewController.h"
|
|
#import "GiGaFlyingCommitInputView.h"
|
|
#import "GiGaFlingCommitVC.h"
|
|
@interface GiGaMaskTaskViewController ()<UITextFieldDelegate>
|
|
{
|
|
AVAudioPlayer *_musicPalyer;
|
|
}
|
|
@property(nonatomic,strong)MaskViewBootomWaringView *waringView;
|
|
@property(nonatomic,strong)UILabel *countLabel;
|
|
@property (strong ,nonatomic) LXCountTimer *timer;
|
|
//@property (nonatomic,strong) GiGaFlyingCommitInputView *commitInputView;
|
|
@property(nonatomic,strong) UIImageView *maskImageView;
|
|
@property(nonatomic,strong) UIImageView *faceView;
|
|
@property(nonatomic,strong) UIDynamicAnimator *animator;
|
|
@property(nonatomic,strong) UIAttachmentBehavior *attachmentBehavior;
|
|
@property(nonatomic) CGPoint attachPoint;
|
|
@property(nonatomic) UISnapBehavior *snapBehavior;
|
|
|
|
@end
|
|
|
|
@implementation GiGaMaskTaskViewController
|
|
|
|
//倒计时label
|
|
-(UILabel *)countLabel{
|
|
if (!_countLabel) {
|
|
_countLabel = [[UILabel alloc] init];
|
|
_countLabel.textColor = [UIColor redColor];
|
|
_countLabel.text = @"00:00";
|
|
_countLabel.textAlignment = NSTextAlignmentCenter;
|
|
|
|
}
|
|
return _countLabel;
|
|
}
|
|
//面膜
|
|
- (UIImageView *)maskImageView{
|
|
if (!_maskImageView) {
|
|
_maskImageView = [[UIImageView alloc] init];
|
|
_maskImageView.userInteractionEnabled = YES;
|
|
_maskImageView.backgroundColor = [UIColor purpleColor];
|
|
UIPanGestureRecognizer *pangesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureAction:)];
|
|
[_maskImageView addGestureRecognizer:pangesture];
|
|
}
|
|
return _maskImageView;
|
|
}
|
|
//人脸
|
|
- (UIImageView *)faceView{
|
|
if (!_faceView) {
|
|
_faceView = [[UIImageView alloc] init];
|
|
_faceView.backgroundColor = [UIColor lightGrayColor];
|
|
_faceView.userInteractionEnabled = YES;
|
|
}
|
|
return _faceView;
|
|
}
|
|
|
|
-(void)createInputView{
|
|
|
|
GiGaFlingCommitVC* GiGaFlingVC = [[GiGaFlingCommitVC alloc] init];
|
|
if (ISIOS8) {
|
|
GiGaFlingVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
|
}else{
|
|
GiGaFlingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
|
|
}
|
|
GiGaFlingVC.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
|
|
[self presentViewController:GiGaFlingVC animated:NO completion:nil];
|
|
|
|
}
|
|
|
|
-(LXCountTimer *)timer{
|
|
|
|
if (!_timer) {
|
|
_timer = [[LXCountTimer alloc] init];
|
|
}
|
|
return _timer;
|
|
}
|
|
|
|
//滑动手势
|
|
-(void)panGestureAction:(UIPanGestureRecognizer *)pan{
|
|
|
|
CGPoint panLocation = [pan locationInView:self.view];
|
|
NSLog(@"panlocation.y:%f",panLocation.y);
|
|
if (pan.state == UIGestureRecognizerStateBegan) {
|
|
|
|
[self animaMask];
|
|
// self.attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self.faceView attachedToAnchor:self.attachPoint];
|
|
// [self.animator addBehavior: self.attachmentBehavior ];
|
|
|
|
}else if (pan.state == UIGestureRecognizerStateChanged){
|
|
// [self.snapBehavior setSnapPoint:self.attachPoint];
|
|
// [self.attachmentBehavior setAnchorPoint:panLocation];
|
|
|
|
}else if (pan.state == UIGestureRecognizerStateEnded){
|
|
// [self.animator addBehavior:self.snapBehavior];
|
|
// [self.animator removeBehavior:self.attachmentBehavior];
|
|
}else{
|
|
|
|
}
|
|
}
|
|
|
|
#pragma mark -开始面膜时间动画
|
|
-(void)animaMask{
|
|
|
|
[self.view layoutIfNeeded];
|
|
[UIView animateWithDuration:1.0 animations:^{
|
|
[self.maskImageView mas_updateConstraints:^(MASConstraintMaker *make) {
|
|
make.top.mas_equalTo(self.attachPoint.y - 50);
|
|
}];
|
|
[self.faceView mas_updateConstraints:^(MASConstraintMaker *make) {
|
|
make.top.mas_equalTo(self.attachPoint.y - 50);
|
|
}];
|
|
[self.countLabel mas_updateConstraints:^(MASConstraintMaker *make) {
|
|
make.top.mas_equalTo(self.attachPoint.y + 50 + 10);
|
|
}];
|
|
[self.view layoutIfNeeded];
|
|
} completion:^(BOOL finished) {
|
|
self.countLabel.hidden = NO;
|
|
self.maskImageView.userInteractionEnabled = NO;
|
|
//开始面膜时间
|
|
[self startMaskTime];
|
|
}];
|
|
}
|
|
|
|
#pragma mark 面膜时间结束复原动画
|
|
-(void)endMaskAnimation{
|
|
|
|
self.countLabel.hidden = YES;
|
|
[self.view layoutIfNeeded];
|
|
[UIView animateWithDuration:1.0 animations:^{
|
|
[self.maskImageView mas_updateConstraints:^(MASConstraintMaker *make) {
|
|
make.top.mas_equalTo(100 + 100 + 200);
|
|
}];
|
|
|
|
[self.faceView mas_updateConstraints:^(MASConstraintMaker *make) {
|
|
make.top.mas_equalTo(100);
|
|
}];
|
|
|
|
[self.view layoutIfNeeded];
|
|
|
|
} completion:^(BOOL finished) {
|
|
self.maskImageView.userInteractionEnabled = YES;
|
|
}];
|
|
}
|
|
|
|
-(void)viewWillAppear:(BOOL)animated{
|
|
[super viewWillAppear:animated];
|
|
|
|
}
|
|
|
|
- (void)viewDidLoad {
|
|
[super viewDidLoad];
|
|
// Do any additional setup after loading the view.
|
|
[self setUpNav];
|
|
[self initUI];
|
|
[self addNotify];
|
|
[self creatBackGroundMusic];
|
|
}
|
|
|
|
-(void)initUI{
|
|
|
|
[self.view addSubview:self.maskImageView];
|
|
[self.view addSubview:self.faceView];
|
|
[self.view bringSubviewToFront:self.maskImageView];
|
|
[self.view addSubview:self.countLabel];
|
|
|
|
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
|
|
|
|
//face
|
|
[self.faceView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
make.top.mas_equalTo(self.view.mas_top).offset(100);
|
|
make.left.mas_equalTo(self.view.mas_centerX).offset(-50);
|
|
make.size.mas_equalTo(CGSizeMake(100, 100));
|
|
|
|
}];
|
|
|
|
//mask
|
|
[self.maskImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
make.top.mas_equalTo(self.view.mas_top).offset(100 + 100 + 200);
|
|
make.left.mas_equalTo(self.view.mas_centerX).offset(-50);
|
|
make.size.mas_equalTo(CGSizeMake(100, 100));
|
|
|
|
}];
|
|
|
|
[self.countLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
make.top.mas_equalTo(self.view.mas_top).offset(200);
|
|
make.width.and.height.mas_equalTo(100);
|
|
make.centerX.mas_equalTo(self.view.mas_centerX);
|
|
}];
|
|
self.countLabel.hidden = YES;
|
|
|
|
UIButton *testBtn = [UIButton buttonWithType:UIButtonTypeCustom];
|
|
[testBtn setTitle:@"测试肤质" forState:UIControlStateNormal];
|
|
[testBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
|
testBtn.backgroundColor = [UIColor blueColor];
|
|
[testBtn addTarget:self action:@selector(testBtnAcion:) forControlEvents:UIControlEventTouchUpInside];
|
|
testBtn.layer.masksToBounds = YES;
|
|
testBtn.layer.cornerRadius = 4;
|
|
|
|
[self.view addSubview:testBtn];
|
|
[testBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
make.centerX.mas_equalTo(self.view.mas_centerX);
|
|
make.width.mas_equalTo(150);
|
|
make.height.mas_equalTo(40);
|
|
make.bottom.mas_equalTo(self.view.mas_bottom).offset(-130);
|
|
}];
|
|
|
|
[self.view layoutIfNeeded];
|
|
CGFloat Y = CGRectGetMinY(self.maskImageView.frame) - 100;
|
|
CGFloat X = CGRectGetMidX(self.view.frame);
|
|
CGPoint anchorPoint = CGPointMake(X, Y);
|
|
self.attachPoint = anchorPoint;
|
|
// self.snapBehavior = [[UISnapBehavior alloc] initWithItem:self.maskImageView snapToPoint:self.attachPoint];
|
|
}
|
|
|
|
#pragma mark 开始计时
|
|
|
|
-(void)countTimeBegain:(NSUInteger)hour minute:(NSUInteger)minute second:(NSUInteger)second{
|
|
|
|
long nowTimestamp = [GiGaHelper getNowDateTimestamp];
|
|
long futrueTimestamp = [GiGaHelper getFutureTimetstamp:hour minute:minute second:second];
|
|
weakify(self);
|
|
[self.timer countDownWithStratTimeStamp:nowTimestamp finishTimeStamp:futrueTimestamp completeBlock:^(NSInteger day, NSInteger hour, NSInteger minute, NSInteger second) {
|
|
[weakSelf refreshTimeCount:hour minute:minute second:second];
|
|
}];
|
|
}
|
|
|
|
-(void)refreshTimeCount:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second{
|
|
|
|
self.countLabel.text = [NSString stringWithFormat:@"%02ld:%02ld",minute,second];
|
|
if (hour == 0 && minute == 0 && second == 0) {
|
|
//面膜结束
|
|
[self maskTimeEnd];
|
|
}
|
|
}
|
|
|
|
#pragma mark 面膜时间背景音乐
|
|
-(void)creatBackGroundMusic{
|
|
//初始化音频播放器
|
|
NSError *payerError;
|
|
NSURL *musicUrl = [[NSURL alloc] initWithString:[[NSBundle mainBundle] pathForResource:@"pomodoSound" ofType:@"m4a"]] ;
|
|
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:musicUrl error:&payerError];
|
|
player.numberOfLoops = -1;
|
|
_musicPalyer = player;
|
|
[[AVAudioSession sharedInstance] setActive:YES error:nil];
|
|
//设置后台模式和锁屏模式下依然能够播放
|
|
//[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
|
|
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
|
|
}
|
|
|
|
#pragma mark 开始面膜时间
|
|
-(void)startMaskTime{
|
|
|
|
[self createInputView]; //出现弹幕
|
|
AppDelegate *delegate =(AppDelegate *) [[UIApplication sharedApplication] delegate];
|
|
if (delegate.isMasking) {
|
|
return;
|
|
}
|
|
delegate.isMasking = YES;
|
|
[_musicPalyer play];
|
|
[self setBackGroundPlayingInfo];//锁屏音频信息
|
|
|
|
//总时间隔 s
|
|
NSTimeInterval timeInterVal = 61;
|
|
NSString *timeformat = [GiGaHelper stringWithNSTimerinterval:timeInterVal];
|
|
NSArray *timesArr = [timeformat componentsSeparatedByString:@":"];
|
|
NSString *hour = timesArr[0];
|
|
NSString *min = timesArr[1];
|
|
NSString *sec = timesArr[2];
|
|
[self countTimeBegain:hour.integerValue minute:min.integerValue second:sec.integerValue];
|
|
|
|
[self showWaringView];
|
|
|
|
return;
|
|
//app 前台时收到本地通知showAlert 后台时通知提醒
|
|
[[GiGaLocalNotificationManager localNotifiationCenter] sendLocalNotification:@"本地推送" fireTimeInterval:timeInterVal alertAction:@"测试面膜时间" withIdentifier:kLOCALNotifiID_MASKETIMEEND];
|
|
|
|
}
|
|
|
|
#pragma mark 设置后台锁屏音频信息
|
|
-(void)setBackGroundPlayingInfo{
|
|
|
|
MPMediaItemArtwork *arwork = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"MaskTime.png"]];
|
|
NSDictionary *dic = @{
|
|
MPMediaItemPropertyTitle:@"面膜时间",
|
|
MPMediaItemPropertyAlbumArtist:@"专辑专辑专辑专辑",
|
|
MPMediaItemPropertyArtist:@"lianxiang",
|
|
MPMediaItemPropertyAlbumTitle:@"hahah",
|
|
MPMediaItemPropertyGenre:@"???",
|
|
MPMediaItemPropertyLyrics:@"歌词",
|
|
MPMediaItemPropertyPodcastTitle:@"PodcastTitle",
|
|
MPMediaItemPropertyArtwork:arwork
|
|
};
|
|
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:dic];
|
|
|
|
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
|
|
|
|
}
|
|
|
|
- (void)remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
|
|
|
|
if (receivedEvent.type == UIEventTypeRemoteControl) {
|
|
switch (receivedEvent.subtype) {
|
|
|
|
case UIEventSubtypeRemoteControlPlay:
|
|
//暂时不处理
|
|
//[_musicPalyer play];
|
|
break;
|
|
|
|
case UIEventSubtypeRemoteControlPause:
|
|
// [_musicPalyer pause];
|
|
break;
|
|
|
|
default:
|
|
NSLog(@"没有处理过这个事件------receivedEvent.subtype==%ld",(long)receivedEvent.subtype);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma mark 面膜时间结束
|
|
-(void)maskTimeEnd{
|
|
|
|
NC_POST_NAME_OBJECT(kUserNoti_MASKEND, nil);
|
|
//面膜时间结束时设置 全局变量 不再发送本地通知 提醒
|
|
AppDelegate *delegate =(AppDelegate *) [[UIApplication sharedApplication] delegate];
|
|
delegate.isMasking = NO;
|
|
[_musicPalyer stop];
|
|
[self.timer destoryTimer];
|
|
//复原动画
|
|
[self endMaskAnimation];
|
|
}
|
|
|
|
#pragma mark 开始测试
|
|
-(void)testBtnAcion:(UIButton *)btn{
|
|
|
|
|
|
// [self startMaskTime];
|
|
// return ;
|
|
|
|
BOOL isUserLogin = [GiGaUserDefault isUserLogin];
|
|
|
|
if (isUserLogin) {
|
|
|
|
//GIGA_ShowToast(@"userLogin!");
|
|
GiGaQuestionVC *questionVC = [[GiGaQuestionVC alloc] init];
|
|
[self.navigationController pushViewController:questionVC animated:YES];
|
|
|
|
}else{
|
|
GiGaUserLoginVC *userlogInVC= [[GiGaUserLoginVC alloc] init];
|
|
GiGaBaseNavViewController *baseNav = [[GiGaBaseNavViewController alloc] initWithRootViewController:userlogInVC];
|
|
[self presentViewController:baseNav animated:YES completion:nil];
|
|
}
|
|
}
|
|
|
|
-(void)viewDidAppear:(BOOL)animated{
|
|
[super viewDidAppear:animated];
|
|
|
|
BOOL showAppGaurd = [GiGaUserDefault isShowedAppGaurd];
|
|
|
|
if (!showAppGaurd) {
|
|
[self showAPPappGaurdView];
|
|
}
|
|
}
|
|
|
|
-(void)addNotify{
|
|
|
|
NC_ADD_TARGET_NAME_OBJECT(self, @selector(guardViewDissmiss), USER_GUARD_DISSMISS, nil) ;
|
|
NC_ADD_TARGET_NAME_OBJECT(self, @selector(appGauardViewDissmiss),APP_GUARD_DISSMISS, nil) ;
|
|
NC_ADD_TARGET_NAME_OBJECT(self, @selector(pushToAppAdDetailView),APP_PUSHTO_DETAILVIEW, nil) ;
|
|
}
|
|
|
|
#pragma mark 广告详情
|
|
-(void)pushToAppAdDetailView{
|
|
|
|
GiGaAdDetailViewController *detailVC=[[GiGaAdDetailViewController alloc] init];
|
|
[self.navigationController pushViewController:detailVC animated:YES];
|
|
}
|
|
|
|
#pragma mark 新手引导消失
|
|
-(void)guardViewDissmiss{
|
|
[self showWaringView];
|
|
}
|
|
|
|
#pragma mark app引导页消失
|
|
-(void)appGauardViewDissmiss{
|
|
//出现新手引导
|
|
BOOL isshowGaurd = [GiGaUserDefault isShowedGaurd];
|
|
if (!isshowGaurd) {
|
|
NSLog(@"%d",(int)isshowGaurd );
|
|
[self showUserGaurdView];
|
|
}
|
|
}
|
|
|
|
-(void)dealloc{
|
|
|
|
NC_REMOVE_NAME(self, USER_GUARD_DISSMISS, nil);
|
|
NC_REMOVE_NAME(self, APP_GUARD_DISSMISS, nil);
|
|
NC_REMOVE_NAME(self, APP_PUSHTO_DETAILVIEW, nil);
|
|
|
|
}
|
|
|
|
#pragma mark 新手引导
|
|
-(void)showUserGaurdView{
|
|
|
|
UserGuardViewController *userGuardVC = [[UserGuardViewController alloc] init];
|
|
if (ISIOS8) {
|
|
userGuardVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
|
}else{
|
|
userGuardVC.modalPresentationStyle = UIModalPresentationCurrentContext;
|
|
}
|
|
userGuardVC.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
|
|
[self presentViewController:userGuardVC animated:NO completion:nil];
|
|
}
|
|
|
|
#pragma mark App引导页
|
|
-(void)showAPPappGaurdView{
|
|
GiGaAppGaurdVC *gaurdVC = [[GiGaAppGaurdVC alloc] init];
|
|
[self presentViewController:gaurdVC animated:YES completion:nil];
|
|
}
|
|
|
|
#pragma mark - setUpNav
|
|
-(void)setUpNav{
|
|
//leftItem
|
|
UIButton *leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
|
|
leftBtn.frame = CGRectMake(0, 0, 40, 40);
|
|
leftBtn.backgroundColor = [UIColor redColor];
|
|
[leftBtn setImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];
|
|
[leftBtn addTarget:self action:@selector(leftBtnAction) forControlEvents:UIControlEventTouchUpInside];
|
|
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];
|
|
//rightItem
|
|
UIButton *rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
|
|
rightBtn.frame = CGRectMake(0, 0, 40, 40);
|
|
rightBtn.backgroundColor = [UIColor blueColor];
|
|
[rightBtn setImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];
|
|
[rightBtn addTarget:self action:@selector(rightBtnAction) forControlEvents:UIControlEventTouchUpInside];
|
|
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rightBtn];
|
|
}
|
|
|
|
#pragma mark 消息 action
|
|
-(void)leftBtnAction{
|
|
|
|
BOOL isUserLogin = [GiGaUserDefault isUserLogin];
|
|
if (isUserLogin) {
|
|
|
|
GIGA_ShowToast(@"userLogin!");
|
|
GiGaMasssagesVC *masageVC= [[GiGaMasssagesVC alloc] init];
|
|
[self.navigationController pushViewController:masageVC animated:YES];
|
|
|
|
}else{
|
|
GiGaUserLoginVC *userlogInVC= [[GiGaUserLoginVC alloc] init];
|
|
GiGaBaseNavViewController *baseNav = [[GiGaBaseNavViewController alloc] initWithRootViewController:userlogInVC];
|
|
[self presentViewController:baseNav animated:YES completion:nil];
|
|
}
|
|
}
|
|
|
|
#pragma mark 个人中心 action
|
|
-(void)rightBtnAction{
|
|
|
|
GiGaMeViewController *meVC= [[GiGaMeViewController alloc] init];
|
|
[self.navigationController pushViewController:meVC animated:YES];
|
|
|
|
}
|
|
|
|
#pragma mark -bottomView
|
|
-(void)showWaringView{
|
|
|
|
[UIView animateWithDuration:0.4 animations:^{
|
|
self.waringView.frame = CGRectMake(0,self.view.frame.size.height - 60, self.view.frame.size.width, 60);
|
|
}];
|
|
|
|
[self.view addSubview:self.waringView];
|
|
weakify(self);
|
|
[self.waringView.dismissBtn initWithBlock:^(UIButton *btn) {
|
|
NSLog(@"GIGAdismissBtn");
|
|
[UIView animateWithDuration:0.4 animations:^{
|
|
weakSelf.waringView.frame = CGRectMake(0, self.view.frame.size.height, self.view.frame.size.height, 60);
|
|
} completion:^(BOOL finished) {
|
|
[weakSelf.waringView removeFromSuperview];
|
|
}];
|
|
|
|
} for:UIControlEventTouchUpInside ];
|
|
}
|
|
|
|
- (MaskViewBootomWaringView *)waringView{
|
|
|
|
if (!_waringView) {
|
|
self.waringView = [[MaskViewBootomWaringView alloc] initWithFrame: CGRectMake(0, self.view.frame.size.height, self.view.frame.size.height, 60)];
|
|
}
|
|
return _waringView;
|
|
}
|
|
|
|
- (void)didReceiveMemoryWarning {
|
|
[super didReceiveMemoryWarning];
|
|
// Dispose of any resources that can be recreated.
|
|
}
|
|
|
|
|
|
@end
|