Browse Source

活动审批 撤回,表单提交

Karsa 3 years ago
parent
commit
c6637e7838

+ 51 - 1
api/roadshow/index.js

@@ -94,7 +94,7 @@ export const editMatter = params => {
 }
 
 /**
- * 活动列表
+ * 活动列表 路演、公开会议
  * @param   
  * PageSize CurrentIndex Status 
  */
@@ -102,6 +102,15 @@ export const calendarList = params => {
 	return httpGet('/roadshow/calendar/list', params)
 }
 
+/**
+ * 活动列表 内部会议 电话会
+ * @param   
+ * PageSize CurrentIndex CalendarType  1:内部会议,2:报告电话会
+ */
+export const calendarTypeList = params => {
+	return httpGet('/roadshow/calendar/type/list', params)
+}
+
 /**
  * 事项列表
  * @param   
@@ -109,6 +118,7 @@ export const calendarList = params => {
  */
 export const matterList = params => {
 	return httpGet('/roadshow/matters/list', params)
+	
 }
 
 /**
@@ -126,3 +136,43 @@ export const calendarDetail = params => {
 export const researcherList = params => {
 	return httpGet('/roadshow/researcher/list', params)
 }
+
+
+/**
+ * 电话会类别
+ */
+export const telTypes = params => {
+	return httpGet('/roadshow/activity/type/list', params)
+}
+
+/**
+ * 搜索客户 KeyWord 
+ */
+export const companySearch = params => {
+	return httpGet('/roadshow/company/search', params)
+}
+
+/**
+ * 客户信息 CompanyId 
+ */
+export const companyInfo = params => {
+	return httpGet('/roadshow/company/detail', params)
+}
+
+/**
+ * 研究员日历日程 StartDate  EndDate ResearcherId
+ */
+export const researchEvents = params => {
+	return httpGet('/roadshow/researcher/calendar/detail', params)
+}
+
+/**
+ * 我的日历日程 StartDate  EndDate
+ */
+export const myEvents = params => {
+	return httpGet('/roadshow/my/calendar/detail', params)
+}
+
+
+
+

+ 38 - 0
pages-approve/activity/checkRole.js

@@ -0,0 +1,38 @@
+// 研究员
+const RESEARCHLIST = ['ficc_researcher', 'researcher', 'rai_researcher','ficc_admin', 'rai_admin',];
+
+// 销售/组长
+const SELLERLIST = ['ficc_seller', 'rai_seller', 'ficc_group', 'rai_group'];
+
+// admin
+const ADMINLIST = ['admin'];
+
+/* 获取角色类型 */
+export const getRole = (role) => {
+	return RESEARCHLIST.includes(role) ? 'researcher' : SELLERLIST.includes(role) ? 'seller' : role;
+}
+
+
+/* 回显表单 type回显的研究员是[]还是''  1路演/公开会议 2内部会议/电话会 */
+export const editInfoBack = ({ ActivityType,RoadshowType,RoadshowPlatform,City,Province,CompanyId,CompanyName,ResearcherId,Theme,CooperationName,ActivityCategory,StartDate,EndDate,StartTime,EndTime },type= 1) => {
+	return {
+		activityType: ActivityType, // 活动类型
+		roadshowType: RoadshowType, // 路演形式
+		roadshowPlatform: RoadshowPlatform, // 路演平台
+		roadshowCity: Province ? [Province,City] : [], // 路演城市
+		companyId: CompanyId, // 客户id
+		companyName: CompanyName, // 客户名称
+		meetingTheme: Theme, // 会议主题
+		partnersName: CooperationName, // 合作方名称
+		activityClass: ActivityCategory, // 活动类别
+		selectResearchers: [
+			// 选择的研究员
+			{
+				researcherId: type === 2 ? ResearcherId.split(',').map(item => Number(item)) : Number(ResearcherId),
+				startTime: new Date(`${StartDate} ${StartTime}`).getTime(),
+				endTime: new Date(`${EndDate} ${EndTime}`).getTime(),
+			},
+		],
+	};
+
+}

+ 391 - 254
pages-approve/activity/detail.vue

@@ -1,272 +1,409 @@
 <template>
-    <view class="activity-detail" v-if="info">
-        <image :src="statusImg" mode="aspectFill" class="status-img" v-if="statusImg"></image>
-        <!-- 路演 -->
-        <block v-if="info.RsCalendarItem.ActivityType=='路演'">
-        <view class="section white-wrap">
-            <view class="info-item flex">
-                <view class="label">活动时间:</view>
-                <view>{{info.RsCalendarResearcherItem.StartDate}}({{info.RsCalendarResearcherItem.StartWeek}}) {{info.RsCalendarResearcherItem.StartTime}}-{{info.RsCalendarResearcherItem.EndTime}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">活动类型:</view>
-                <view>{{info.RsCalendarItem.ActivityType}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">路演形式:</view>
-                <view>{{info.RsCalendarItem.RoadshowType}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">路演平台:</view>
-                <view>{{info.RsCalendarItem.RoadshowPlatform}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">客户名称:</view>
-                <view>{{info.CompanyDetail.CompanyName}}</view>
-            </view>
-        </view>
-        <view class="section white-wrap">
-            <view class="info-item flex">
-                <view class="label">客户状态:</view>
-                <view>{{info.CompanyDetail.Status}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">所属行业:</view>
-                <view>{{info.CompanyDetail.IndustryName}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">开通品种:</view>
-                <view>{{info.CompanyDetail.PermissionName}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">累计阅读报告次数:</view>
-                <view>{{info.CompanyDetail.ReportReadTotal}}</view>
-            </view>
-            <view class="line"></view>
-            <view class="info-item flex">
-                <view class="label">提交销售:</view>
-                <view>{{info.RsCalendarItem.SysUserRealName}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">提交时间:</view>
-                <view>{{info.RsCalendarItem.CreateTime|formatTime}}</view>
-            </view>
-        </view>
-        <view class="section white-wrap" v-if="info.RsCalendarResearcherItem.Status==2||info.RsCalendarResearcherItem.Status==3">
-            <view class="info-item flex">
-                <view class="label">审批时间:</view>
-                <view>{{info.RsCalendarResearcherItem.Status==2?info.RsCalendarResearcherItem.ApproveTime:info.RsCalendarResearcherItem.RefuseTime}}</view>
-            </view>
-            <view class="info-item flex" v-if="info.RsCalendarResearcherItem.Status==3">
-                <view class="label">拒绝理由:</view>
-                <view>{{info.RsCalendarResearcherItem.RefuseReason}}</view>
-            </view>
-        </view>
-        <view class="section white-wrap" v-if="info.RsCalendarResearcherItem.Status==4">
-            <view class="info-item flex">
-                <view class="label">删除时间:</view>
-                <view>{{info.RsCalendarResearcherItem.DeleteTime}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">删除原因:</view>
-                <view>{{info.RsCalendarResearcherItem.DeleteReason}}</view>
-            </view>
-        </view>
-        </block>
-        <block v-else>
-        <view class="section white-wrap">
-            <view class="info-item flex">
-                <view class="label">活动时间:</view>
-                <view>{{info.RsCalendarResearcherItem.StartDate}}({{info.RsCalendarResearcherItem.StartWeek}}) {{info.RsCalendarResearcherItem.StartTime}}-{{info.RsCalendarResearcherItem.EndTime}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">活动类型:</view>
-                <view>{{info.RsCalendarItem.ActivityType}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">会议形式:</view>
-                <view>{{info.RsCalendarItem.RoadshowType}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">会议城市:</view>
-                <view>{{info.RsCalendarItem.Province}}{{info.RsCalendarItem.City}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">会议主题:</view>
-                <view>{{info.RsCalendarItem.Theme}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">合作方名称:</view>
-                <view>{{info.RsCalendarItem.CooperationName}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">提交销售:</view>
-                <view>{{info.RsCalendarItem.SysUserRealName}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">提交时间:</view>
-                <view>{{info.RsCalendarItem.CreateTime|formatTime}}</view>
-            </view>
-        </view>
-        <view class="section white-wrap" v-if="info.RsCalendarResearcherItem.Status==2||info.RsCalendarResearcherItem.Status==3">
-            <view class="info-item flex">
-                <view class="label">审批时间:</view>
-                <view>{{info.RsCalendarResearcherItem.Status==2?info.RsCalendarResearcherItem.ApproveTime:info.RsCalendarResearcherItem.RefuseTime}}</view>
-            </view>
-            <view class="info-item flex" v-if="info.RsCalendarResearcherItem.Status==3">
-                <view class="label">拒绝理由:</view>
-                <view>{{info.RsCalendarResearcherItem.RefuseReason}}</view>
-            </view>
-        </view>
-        <view class="section white-wrap" v-if="info.RsCalendarResearcherItem.Status==4">
-            <view class="info-item flex">
-                <view class="label">删除时间:</view>
-                <view>{{info.RsCalendarResearcherItem.DeleteTime}}</view>
-            </view>
-            <view class="info-item flex">
-                <view class="label">删除原因:</view>
-                <view>{{info.RsCalendarResearcherItem.DeleteReason}}</view>
-            </view>
-        </view>
-        </block>
+	<view class="activity-detail" v-if="info">
+		<image :src="statusImg" mode="aspectFill" class="status-img" v-if="statusImg"></image>
+		<!-- 路演 -->
+		<block v-if="info.RsCalendarItem.ActivityType=='路演'">
+			<view class="section white-wrap">
+				<view class="info-item flex">
+					<view class="label">活动时间:</view>
+					<view>{{info.RsCalendarResearcherItem.StartDate}}({{info.RsCalendarResearcherItem.StartWeek}})
+						{{info.RsCalendarResearcherItem.StartTime}}-{{info.RsCalendarResearcherItem.EndTime}}</view>
+				</view>
+				<view class="info-item flex" v-if="Role === 'seller'">
+					<view class="label">研究员:</view>
+					<view>{{info.RsCalendarResearcherItem.ResearcherName}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">活动类型:</view>
+					<view>{{info.RsCalendarItem.ActivityType}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">路演形式:</view>
+					<view>{{info.RsCalendarItem.RoadshowType}}</view>
+				</view>
+				<view class="info-item flex" v-if="info.RsCalendarItem.RoadshowPlatform">
+					<view class="label">路演平台:</view>
+					<view>{{info.RsCalendarItem.RoadshowPlatform}}</view>
+				</view>
+				<view class="info-item flex" v-if="info.RsCalendarItem.City">
+					<view class="label">路演城市:</view>
+					<view>{{info.RsCalendarItem.Province}}{{info.RsCalendarItem.City}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">客户名称:</view>
+					<view>{{info.CompanyDetail.CompanyName}}</view>
+				</view>
+			</view>
+			<view class="section white-wrap">
+				<view class="info-item flex">
+					<view class="label">客户状态:</view>
+					<view>{{info.CompanyDetail.Status}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">所属行业:</view>
+					<view>{{info.CompanyDetail.IndustryName}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">开通品种:</view>
+					<view>{{info.CompanyDetail.PermissionName}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">累计阅读报告次数:</view>
+					<view>{{info.CompanyDetail.ReportReadTotal}}</view>
+				</view>
+				<view class="line"></view>
+				<view class="info-item flex" v-if="Role === 'researcher'">
+					<view class="label">提交销售:</view>
+					<view>{{info.RsCalendarItem.SysUserRealName}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">提交时间:</view>
+					<view>{{info.RsCalendarItem.CreateTime|formatTime}}</view>
+				</view>
+			</view>
+			<view class="section white-wrap"
+				v-if="info.RsCalendarResearcherItem.Status==2||info.RsCalendarResearcherItem.Status==3">
+				<view class="info-item flex">
+					<view class="label">审批时间:</view>
+					<view>
+						{{info.RsCalendarResearcherItem.Status==2?info.RsCalendarResearcherItem.ApproveTime:info.RsCalendarResearcherItem.RefuseTime}}
+					</view>
+				</view>
+				<view class="info-item flex" v-if="info.RsCalendarResearcherItem.Status==3">
+					<view class="label">拒绝理由:</view>
+					<view>{{info.RsCalendarResearcherItem.RefuseReason}}</view>
+				</view>
+			</view>
+			<view class="section white-wrap" v-if="info.RsCalendarResearcherItem.Status==4">
+				<view class="info-item flex">
+					<view class="label">删除时间:</view>
+					<view>{{info.RsCalendarResearcherItem.DeleteTime}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">删除原因:</view>
+					<view>{{info.RsCalendarResearcherItem.DeleteReason}}</view>
+				</view>
+			</view>
+		</block>
+		<block v-else>
+			<view class="section white-wrap">
+				<view class="info-item flex">
+					<view class="label">活动时间:</view>
+					<view>{{info.RsCalendarResearcherItem.StartDate}}({{info.RsCalendarResearcherItem.StartWeek}})
+						{{info.RsCalendarResearcherItem.StartTime}}-{{info.RsCalendarResearcherItem.EndTime}}</view>
+				</view>
+				<view class="info-item flex" v-if="Role === 'seller'">
+					<view class="label">研究员:</view>
+					<view>{{info.RsCalendarResearcherItem.ResearcherName}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">活动类型:</view>
+					<view>{{info.RsCalendarItem.ActivityType}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">会议形式:</view>
+					<view>{{info.RsCalendarItem.RoadshowType}}</view>
+				</view>
+				<view class="info-item flex" v-if="info.RsCalendarItem.RoadshowPlatform">
+					<view class="label">会议平台:</view>
+					<view>{{info.RsCalendarItem.RoadshowPlatform}}</view>
+				</view>
+				<view class="info-item flex" v-if="info.RsCalendarItem.City">
+					<view class="label">会议城市:</view>
+					<view>{{info.RsCalendarItem.Province}}{{info.RsCalendarItem.City}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">会议主题:</view>
+					<view>{{info.RsCalendarItem.Theme}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">合作方名称:</view>
+					<view>{{info.RsCalendarItem.CooperationName}}</view>
+				</view>
+				<view class="info-item flex" v-if="Role === 'researcher'">
+					<view class="label">提交销售:</view>
+					<view>{{info.RsCalendarItem.SysUserRealName}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">提交时间:</view>
+					<view>{{info.RsCalendarItem.CreateTime|formatTime}}</view>
+				</view>
+			</view>
+			<view class="section white-wrap"
+				v-if="info.RsCalendarResearcherItem.Status==2||info.RsCalendarResearcherItem.Status==3">
+				<view class="info-item flex">
+					<view class="label">审批时间:</view>
+					<view>
+						{{info.RsCalendarResearcherItem.Status==2?info.RsCalendarResearcherItem.ApproveTime:info.RsCalendarResearcherItem.RefuseTime}}
+					</view>
+				</view>
+				<view class="info-item flex" v-if="info.RsCalendarResearcherItem.Status==3">
+					<view class="label">拒绝理由:</view>
+					<view>{{info.RsCalendarResearcherItem.RefuseReason}}</view>
+				</view>
+			</view>
+			<view class="section white-wrap" v-if="info.RsCalendarResearcherItem.Status==4">
+				<view class="info-item flex">
+					<view class="label">删除时间:</view>
+					<view>{{info.RsCalendarResearcherItem.DeleteTime}}</view>
+				</view>
+				<view class="info-item flex">
+					<view class="label">删除原因:</view>
+					<view>{{info.RsCalendarResearcherItem.DeleteReason}}</view>
+				</view>
+			</view>
+		</block>
 
-        <!-- 审批按钮 -->
-		<view class="fix-bottom-wrap btns-wrap flex" v-if="info.RsCalendarResearcherItem.Status==1">
-			<button class="refuse-btn" @click="handleRefuse">拒绝</button>
-            <button class="pass-btn" @click="handlePass">接受</button>
+		<!-- 审批按钮 -->
+		<view class="fix-bottom-wrap btns-wrap flex" v-if="haveActiyityStart">
+
+			<block v-if="info.RsCalendarResearcherItem.Status===1 && Role === 'researcher'">
+				<button class="refuse-btn" @click="handleAtions('refuse')">拒绝</button>
+				<button class="pass-btn" @click="handleActions('accept')">接受</button>
+			</block>
+			<block v-else-if="info.RsCalendarResearcherItem.Status===1 && Role === 'seller'">
+				<button class="pass-btn" @click="handleActions('back')">撤回</button>
+			</block>
+
+			<block v-else-if="info.RsCalendarResearcherItem.Status===2 && Role === 'seller'">
+				<button class="pass-btn" @click="handleActions('del')">删除</button>
+			</block>
+
+			<block v-else-if="[3,5].includes(info.RsCalendarResearcherItem.Status) && Role === 'seller'">
+				<button class="pass-btn" @click="handleActions('reEdit')">修改重提</button>
+			</block>
 		</view>
-    </view>
+	</view>
 </template>
 
 <script>
-import {apiRoadShowInfo,apiRoadShowApproved} from '@/api/approve/activity.js'
-export default {
-    computed: {
-        statusImg(){
-		    if(this.info.RsCalendarResearcherItem.Status==2){
-				return require('../static/pass-icon.png')//同意
-			}else if(this.info.RsCalendarResearcherItem.Status==3){
-				return require('../static/fail-icon.png')//拒绝
-			}else if(this.info.RsCalendarResearcherItem.Status==4){
-				return require('../static/delete-icon.png')//删除
+	import {
+		apiRoadShowInfo,
+		apiRoadShowApproved
+	} from '@/api/approve/activity.js';
+	import { backActivity,delActivity  } from '@/api/roadshow/index.js'
+	import {
+		getRole,
+		editInfoBack
+	} from './checkRole.js';
+	import moment from '@/pages-roadshow/utils/_moment.js';
+	export default {
+		computed: {
+			statusImg() {
+				switch (this.info.RsCalendarResearcherItem.Status) {
+					case 2:
+						return require('../static/roadshow/accept-ico.png') //同意
+					case 3:
+						return require('../static/roadshow/refuse-ico.png') //拒绝
+					case 4:
+						return require('../static/roadshow/del-ico.png') //删除
+					case 5:
+						return require('../static/roadshow/back-ico.png') //撤回
+					case 6:
+						return require('../static/roadshow/end-ico.png') //结束
+				}
+			},
+			
+			Role() {
+				let userinfo = JSON.parse(uni.getStorageSync('userInfo'));
+				return getRole(userinfo.RoleTypeCode);
+			},
+			
+			/* 活动是否开始 */
+			haveActiyityStart() {
+				const { StartDate,StartTime } = this.info.RsCalendarResearcherItem;
+				return moment(`${StartDate} ${StartTime}`).valueOf() > new Date().getTime()
 			}
-		}
-    },
-    data () {
-        return {
-            RsCalendarResearcherId:null,//活动研究员id
-            RsCalendarId:null,//路演活动id
-            info:null,
-        }
-    },
-    onLoad(options) {
-        this.RsCalendarResearcherId=options.RsCalendarResearcherId
-        this.RsCalendarId=options.RsCalendarId
-    },
-    onShow() {
-        this.getDetail()
-    },
-    methods: {
-        // 获取详情
-        async getDetail(){
-            const res=await apiRoadShowInfo({
-                RsCalendarId:this.RsCalendarId,
-                RsCalendarResearcherId:this.RsCalendarResearcherId
-            })
-            if(res.code===200){
-                this.info=res.data
-            }
-        },
+		},
+		data() {
+			return {
+				RsCalendarResearcherId: null, //活动研究员id
+				RsCalendarId: null, //路演活动id
+				info: null,
+			}
+		},
+		onLoad(options) {
+			this.RsCalendarResearcherId = options.RsCalendarResearcherId
+			this.RsCalendarId = options.RsCalendarId
+		},
+		onShow() {
+			this.getDetail();
+		},
+		methods: {
+			// 获取详情
+			async getDetail() {
+				const res = await apiRoadShowInfo({
+					RsCalendarId: this.RsCalendarId,
+					RsCalendarResearcherId: this.RsCalendarResearcherId
+				})
+				if (res.code === 200) {
+					this.info = res.data
+				}
+			},
+			
+			/* 所有操作 */
+			handleActions(type) {
+				const handleFns = {
+					refuse: this.handleRefuse,
+					accept: this.handlePass,
+					back: this.revocationHandle,
+					del: this.delHandle,
+					reEdit: this.reEditHandle
+				}
+				handleFns[type]();
+			},
+			
+			/* 撤回操作 */
+			revocationHandle() {
+				uni.showModal({
+					content: '确定要撤回该活动申请吗?',
+					showCancel: true,
+					cancelColor: '#A9AFB8',
+					confirmColor: '#3385FF',
+					success: async ({
+						confirm,
+						cancel
+					}) => {
+						if (confirm) {
+							console.log('用户点击确定');
+							const { code } = await backActivity({
+								RsCalendarId: Number(this.RsCalendarId),
+								RsCalendarResearcherId: Number(this.RsCalendarResearcherId)
+							})
+							
+							if(code !==200) return
+							this.getDetail()
+							uni.$emit('activityApproveListUpdate', {
+								RsCalendarId: this.RsCalendarId,
+								RsCalendarResearcherId: this.RsCalendarResearcherId
+							})
+						} else if (cancel) {
+							console.log('用户点击取消');
+						}
+					}
+				})
+			},
+			
+			/* 修改重提 */
+			reEditHandle() {
+				const { CompanyId,CompanyName  } = this.info.CompanyDetail;
+				const { ActivityType,RoadshowType,RoadshowPlatform,City,Province,Theme,CooperationName,ActivityCategory } = this.info.RsCalendarItem;
+				const { ResearcherId,StartDate,EndDate,StartTime,EndTime,RsCalendarId,RsCalendarResearcherId } = this.info.RsCalendarResearcherItem;
+				
+				let form = editInfoBack({ActivityType,RoadshowType,RoadshowPlatform,City,Province,Theme,CooperationName,ActivityCategory,CompanyId,CompanyName,ResearcherId,StartDate,EndDate,StartTime,EndTime});
+				let edit_id = RsCalendarId,edit_rs_id = RsCalendarResearcherId;
 
-        handlePass(){
-            uni.showModal({
-                content: '接受申请后会加入您的日历,请确认!',
-                showCancel: true,
-                cancelColor:'#A9AFB8',
-                confirmColor:'#3385FF',
-                success: ({ confirm, cancel }) => {
-                    if (confirm) {
-                        console.log('用户点击确定');
-                        this.passApprove()
-                    } else if (cancel) {
-                        console.log('用户点击取消');
-                    }
-                }
-            })
-        },
+				CompanyId && uni.setStorageSync('roadshow_compantyId',CompanyId);
+				uni.navigateTo({
+					url:`/pages-roadshow/addActivity/index?form=${JSON.stringify(form)}&edit_id=${edit_id}&edit_rs_id=${edit_rs_id}`
+				})
+			},
+			
+			/* 删除 需删除理由 */
+			delHandle() {
+				uni.navigateTo({
+					url: `./reason?RsCalendarId=${this.RsCalendarId}&RsCalendarResearcherId=${this.RsCalendarResearcherId}&type=del`
+				})
+			},
+
+			handlePass() {
+				uni.showModal({
+					content: '接受申请后会加入您的日历,请确认!',
+					showCancel: true,
+					cancelColor: '#A9AFB8',
+					confirmColor: '#3385FF',
+					success: ({
+						confirm,
+						cancel
+					}) => {
+						if (confirm) {
+							console.log('用户点击确定');
+							this.passApprove()
+						} else if (cancel) {
+							console.log('用户点击取消');
+						}
+					}
+				})
+			},
 
-        // 通过申请
-        async passApprove(){
-            const res=await apiRoadShowApproved({
-                RsCalendarId:Number(this.RsCalendarId),
-                RsCalendarResearcherId:Number(this.RsCalendarResearcherId)
-            })
-            if(res.code===200){
-                this.getDetail()
-                uni.$emit('activityApproveListUpdate',{
-					RsCalendarId:this.RsCalendarId,
-					RsCalendarResearcherId:this.RsCalendarResearcherId
+			// 通过申请
+			async passApprove() {
+				const res = await apiRoadShowApproved({
+					RsCalendarId: Number(this.RsCalendarId),
+					RsCalendarResearcherId: Number(this.RsCalendarResearcherId)
 				})
-            }
-        },
+				if (res.code === 200) {
+					this.getDetail()
+					uni.$emit('activityApproveListUpdate', {
+						RsCalendarId: this.RsCalendarId,
+						RsCalendarResearcherId: this.RsCalendarResearcherId
+					})
+				}
+			},
 
-        handleRefuse(){
-			uni.navigateTo({
-				url:`./reason?RsCalendarId=${this.RsCalendarId}&RsCalendarResearcherId=${this.RsCalendarResearcherId}`
-			})
-        }
-    }
-}
+			handleRefuse() {
+				uni.navigateTo({
+					url: `./reason?RsCalendarId=${this.RsCalendarId}&RsCalendarResearcherId=${this.RsCalendarResearcherId}type=refuse`
+				})
+			}
+		}
+	}
 </script>
 
 <style lang="scss" scoped>
-.activity-detail{
-    .status-img{
-		position: absolute;
-		right: 0;
-		top: 50rpx;
-		width: 220rpx;
-		height: 220rpx;
-		z-index: 10;
-	}
-    .section{
-        margin-bottom: 14rpx;
-        padding: 33rpx 34rpx;
-        .line{
-            width: 100%;
-            height: 0;
-            border-top: 1px dashed rgba(112, 112, 112, .21);
-            margin: 30rpx 0;
-        }
-    }
-    .info-item{
-        .label{
-            flex-shrink: 0;
-            color: #666;
-            margin-right: 20rpx;
-            margin-bottom: 20rpx;
-        }
-    }
-    .btns-wrap {
-		justify-content: center;
-		button {
-			width: 260rpx;
-			height: 70rpx;
-			border-radius: 28px;
-			border: none;
-			margin: 0 15px;
-			font-size: 15px;
-			color: #fff;
-			line-height: 70rpx;
+	.activity-detail {
+		.status-img {
+			position: absolute;
+			right: 0;
+			top: 50rpx;
+			width: 220rpx;
+			height: 220rpx;
+			z-index: 10;
+		}
+
+		.section {
+			margin-bottom: 14rpx;
+			padding: 33rpx 34rpx;
+
+			.line {
+				width: 100%;
+				height: 0;
+				border-top: 1px dashed rgba(112, 112, 112, .21);
+				margin: 30rpx 0;
+			}
 		}
-		
-		.pass-btn {
-			background-color: #5890fb;
+
+		.info-item {
+			margin-bottom: 20rpx;
+
+			.label {
+				flex-shrink: 0;
+				color: #666;
+				margin-right: 20rpx;
+			}
 		}
-		
-		.refuse-btn {
-			background-color: #f55768;
+
+		.btns-wrap {
+			justify-content: center;
+
+			button {
+				width: 260rpx;
+				height: 70rpx;
+				border-radius: 28px;
+				border: none;
+				margin: 0 15px;
+				font-size: 15px;
+				color: #fff;
+				line-height: 70rpx;
+			}
+
+			.pass-btn {
+				background-color: #5890fb;
+			}
+
+			.refuse-btn {
+				background-color: #f55768;
+			}
 		}
 	}
-}
-</style>
+</style>

+ 252 - 117
pages-approve/activity/list.vue

@@ -1,145 +1,280 @@
 <template>
-    <view>
-        <van-sticky>
-			<view class="top-wrap">
-				<van-tabs swipeable id="tabs" :active="status" title-active-color="#3385FF" color="#3385FF" @change="typeChange">
-					<van-tab title="待审批" name="1"></van-tab>
-					<van-tab title="已审批" name="2"></van-tab>
+	<view>
+		<van-sticky>
+			<view class="top-wrap" v-show="['活动申请','活动审批'].includes(activity_type)">
+				<van-tabs swipeable id="tabs" :active="status" title-active-color="#3385FF" color="#3385FF"
+					@change="typeChange">
+					<van-tab title="待处理" name="1"></van-tab>
+					<van-tab title="已处理" name="2"></van-tab>
 				</van-tabs>
 			</view>
 		</van-sticky>
-        <van-empty description="暂无数据" :image="require('@/static/empty.png')" v-if="finished&&list.length===0"/>
-        <view class="list-wrap" v-else>
-			<view class="item white-wrap" v-for="item in list" :key="item.RsCalendarId" @click="goDetail(item)">
-				<view class="title flex">
-					<image src="../../static/man.png" mode="aspectFill" class="icon" v-if="item.ActivityType=='路演'"></image>
-					<image style="width:16px;height:16px" src="../static/icon-1.png" mode="aspectFill" class="icon" v-else></image>
-					<view>{{item.ActivityType=='路演'?item.CompanyName:item.Theme}}</view>
-				</view>
-				<view class="content">
-					<view class="info">活动类型:{{item.RoadshowType}}{{item.ActivityType}}</view>
-					<view class="info">提交销售:{{item.SysUserRealName}}</view>
-					<view class="info">提交时间:{{item.CreateTime|formatTime}}</view>
-				</view>
-				<view class="status approve-list-status-wait" v-if="item.Status=='1'">待审批</view>
-				<view class="status approve-list-status-success" v-if="item.Status=='2'">已接受</view>
-				<view class="status approve-list-status-fail" v-if="item.Status=='3'">已拒绝</view>
-				<view class="status approve-list-status-cancel" v-if="item.Status=='4'">已删除</view>
+		<van-empty description="暂无数据" :image="require('@/static/empty.png')" v-if="finished&&list.length===0" />
+		<view class="list-wrap" v-else>
+			<view class="item white-wrap" v-for="item in list" :key="item.RsCalendarResearcherId" @click="goDetail(item)">
+				
+				<!-- 路演 公开会议 -->
+				<block v-if="['活动申请','活动审批'].includes(activity_type)">					
+					<view class="title flex">
+						<image src="../../static/man.png" mode="aspectFill" class="icon" v-if="item.ActivityType=='路演'">
+						</image>
+						<image style="width:16px;height:16px" src="../static/icon-1.png" mode="aspectFill" class="icon"
+							v-else></image>
+						<view>{{item.ActivityType=='路演'?item.CompanyName:item.Theme}}</view>
+					</view>
+					<view class="content">
+							<view class="info">活动类型:{{item.RoadshowType}}{{item.ActivityType}}</view>
+							<view class="info">{{activity_type === '活动申请' ? `研究员:${item.ResearcherName}` : `提交销售:${item.SysUserRealName}` }} </view>
+							<view class="info">提交时间:{{item.CreateTime|formatTime}}</view>	
+					</view>
+					<view class="status approve-list-status-wait" v-if="item.Status=='1'">待审批</view>
+					<view class="status approve-list-status-success" v-if="item.Status=='2'">已接受</view>
+					<view class="status approve-list-status-fail" v-if="item.Status=='3'">已拒绝</view>
+					<view class="status approve-list-status-cancel" v-if="item.Status=='4'">已删除</view>
+					<view class="status approve-list-status-cancel" v-if="item.Status=='5'">已撤回</view>
+					<view class="status approve-list-status-cancel" v-if="item.Status=='6'">已结束</view>
+				</block>
+				
+				<!-- 其他 -->
+				<block v-else-if="['内部会议','报告电话会','事项'].includes(activity_type)">
+					<view class="content">
+							<view class="info">{{activity_type==='内部会议' ? '会议' : '活动'}}时间:{{item.StartDate}}({{item.StartWeek}})
+						{{item.StartTime}}-{{item.EndTime}}</view>
+							<view class="info" v-if="item.ActivityCategory">活动类别:{{item.ActivityCategory}} </view>
+							<view class="info" v-if="item.MatterContent">事项内容:{{item.MatterContent}} </view>
+							<view class="info" v-if="['内部会议','报告电话会'].includes(activity_type)">参会人员:{{ item.ResearcherName }} </view>
+							
+							<view class="info">添加时间:{{item.CreateTime|formatTime}}</view>
+							
+							<view class="bot-btns" v-if="haveActiyityStart(item)">
+									<van-button type="primary" plain color="#3385FF" class="btn" size="small" block round @click="handleAction(item,'del')">删除</van-button>
+									<van-button type="primary" color="#3385FF" class="btn" size="small" block round @click="handleAction(item,'edit')">修改</van-button>
+							</view>
+					</view>
+				</block>
 			</view>
 		</view>
-    </view>
+	</view>
 </template>
 
 <script>
-import {apiRoadShowList} from '@/api/approve/activity.js'
-export default {
-    data () {
-        return {
-			status: '1',
-			list:[],
-			page:1,
-			finished:false,
-		}
-    },
-	onLoad(options) {
-		this.getList()
-		uni.$on('activityApproveListUpdate',(e)=>{
-			console.log('activityApproveListUpdate' + e);
-			this.list=this.list.filter(item=>{
-				return item.RsCalendarId!=e.RsCalendarId&&item.RsCalendarResearcherId!=e.RsCalendarResearcherId
-			})
-			if(this.list.length===0){
-				this.finished=true
+	import {
+		apiRoadShowList
+	} from '@/api/approve/activity.js'
+	import {
+		calendarTypeList,
+		matterList,
+		delMatter,
+		delActivity
+	} from '@/api/roadshow/index.js';
+	import { getRole } from './checkRole.js';
+	import moment from '@/pages-roadshow/utils/_moment.js';
+	export default {
+		data() {
+			return {
+				activity_type: '',//活动类型
+				status: '1',
+				list: [],
+				page: 1,
+				finished: false,
 			}
-		})
-	},
-	onUnload(){
-		uni.$off('activityApproveListUpdate')
-	},
-    onShow() {
-	    this.selectComponent('#tabs').resize();// 解决初始渲染 vant tab 底部条
-	},
-	onPullDownRefresh() {
-		this.page=1
-		this.finished=false
-		this.list=[]
-		this.getList()
-		setTimeout(()=>{
-			uni.stopPullDownRefresh()
-		},1500)
-	},
-	onReachBottom() {
-		if(this.finished) return
-		this.page++
-		this.getList()
-	},
-    methods: {
-        typeChange(e){
-			this.status=e.detail.name
-			this.page=1
-			this.finished=false
-			this.list=[]
+		},
+		onLoad(options) {
+			this.activity_type = options.type;
+			this.initState(options.type);
+			// this.getList()
+			uni.$on('activityApproveListUpdate', (e) => {
+				console.log('activityApproveListUpdate' + e);
+				this.list = this.list.filter(item => {
+					return item.RsCalendarId != e.RsCalendarId && item.RsCalendarResearcherId != e
+						.RsCalendarResearcherId
+				})
+				if (this.list.length === 0) {
+					this.finished = true
+				}
+			})
+		},
+		onUnload() {
+			uni.$off('activityApproveListUpdate')
+		},
+		onShow() {
+			this.$nextTick(() => {
+				this.selectComponent('#tabs').resize(); // 解决初始渲染 vant tab 底部条
+			})
+		},
+		onPullDownRefresh() {
+			this.page = 1
+			this.finished = false
+			this.list = []
+			this.getList()
+			setTimeout(() => {
+				uni.stopPullDownRefresh()
+			}, 1500)
+		},
+		onReachBottom() {
+			if (this.finished) return
+			this.page++
 			this.getList()
 		},
+		methods: {
+			
+			/* 默认tab 状态 */
+			initState(title) {
+				uni.setNavigationBarTitle({
+					title
+				})
+				this.getList()
+			},
+			
+			typeChange(e) {
+				this.status = e.detail.name
+				this.page = 1
+				this.finished = false
+				this.list = []
+				this.getList()
+			},
 
-        async getList(){
-			const res=await apiRoadShowList({PageSize:20,CurrentIndex:this.page,Status:this.status})
-			if(res.code===200){
-				if(!res.data.List||res.data.List.length===0){
-					this.finished=true
-				}else{
-					let arr=res.data.List||[]
-					this.list=[...this.list,...arr]
+			async getList() {
+				
+				const res = ['活动申请','活动审批'].includes(this.activity_type) 
+				? await apiRoadShowList({
+					PageSize: 20,
+					CurrentIndex: this.page,
+					Status: this.status
+				})
+				: ['内部会议','报告电话会'].includes(this.activity_type)
+				? await calendarTypeList({
+					PageSize: 20,
+					CurrentIndex: this.page,
+					CalendarType: this.activity_type==='内部会议' ? 1 : 2
+				})
+				: this.activity_type === '事项'
+				? await matterList({
+					PageSize: 20,
+					CurrentIndex: this.page,
+				})
+				: null
+				
+				if (res.code === 200) {
+					if (!res.data.List || res.data.List.length === 0) {
+						this.finished = true
+					} else {
+						let arr = res.data.List || []
+						this.list = [...this.list, ...arr]
+					}
 				}
-			}
-        },
+			},
 
-		goDetail(e){
-			uni.navigateTo({ url: `/pages-approve/activity/detail?RsCalendarId=${e.RsCalendarId}&RsCalendarResearcherId=${e.RsCalendarResearcherId}` })
+			goDetail(e) {
+				if(!['路演','公开会议'].includes(e.ActivityType)) return
+				
+				uni.navigateTo({
+					url: `/pages-approve/activity/detail?RsCalendarId=${e.RsCalendarId}&RsCalendarResearcherId=${e.RsCalendarResearcherId}`
+				})
+			},
+			
+			/* 操作 */
+			handleAction(item,type) {
+				type === 'del' ? this.delActivityHandle(item) : this.editActivityHandle(item);
+			},
+			
+			/* 删除活动 */
+			delActivityHandle({RsCalendarId,RsCalendarResearcherId,RsMattersId}) {
+				uni.showModal({
+					content: '删除该活动后,将从日历中移除,确定继续吗?',
+					showCancel: true,
+					cancelColor: '#A9AFB8',
+					confirmColor: '#3385FF',
+					success: async ({
+						confirm,
+						cancel
+					}) => {
+						if (confirm) {
+							console.log('用户点击确定');
+							const { code } = RsMattersId ? await delMatter({ RsMattersId }) : await delActivity({
+								RsCalendarId,
+								RsCalendarResearcherId
+							})
+							
+							if(code !==200) return
+							
+							this.page = 1;
+							this.list = [];
+							this.getList();
+							
+						} else if (cancel) {
+							console.log('用户点击取消');
+						}
+					}
+				})
+			},
+			
+			/* 修改 */
+			editActivityHandle() {
+				
+			},
+			
+			/* 活动是否已开始 */
+			haveActiyityStart({ StartDate,StartTime }) {
+				return moment(`${StartDate} ${StartTime}`).valueOf() > new Date().getTime()
+			}
 		}
-    }
-}
+	}
 </script>
 
 <style lang="scss" scoped>
-.list-wrap {
-	padding: 20rpx;
-	.item {
-		padding: 30rpx;
-		box-shadow: 0px 3px 12px rgba(175, 175, 175, 0.16);
-		border-radius: 8px;
-		margin-bottom: 20rpx;
+	.list-wrap {
+		padding: 20rpx;
 
-		.title {
-			font-size: 16px;
-			font-weight: bold;
-			margin-bottom: 30rpx;
+		.item {
+			padding: 30rpx;
+			box-shadow: 0px 3px 12px rgba(175, 175, 175, 0.16);
+			border-radius: 8px;
+			margin-bottom: 20rpx;
 
-			.icon {
-				width: 31rpx;
-				height: 34rpx;
-				flex-shrink: 0;
-				margin-right: 10rpx;
-				position: relative;
-				top: 4rpx;
-			}
-		}
+			.title {
+				font-size: 16px;
+				font-weight: bold;
+				margin-bottom: 30rpx;
 
-		.content {
-			font-size: 14px;
-			color: #666;
-			.info {
-				margin-bottom: 16rpx;
+				.icon {
+					width: 31rpx;
+					height: 34rpx;
+					flex-shrink: 0;
+					margin-right: 10rpx;
+					position: relative;
+					top: 4rpx;
+				}
 			}
 
-			.info:last-child {
-				margin-bottom: 0;
+			.content {
+				font-size: 14px;
+				color: #666;
+
+				.info {
+					margin-bottom: 16rpx;
+					text-indent: -140rpx;
+					margin-left: 140rpx;
+				}
+
+				.info:last-child {
+					margin-bottom: 0;
+				}
 			}
-		}
 
-		.status {
-			text-align: right;
+			.status {
+				text-align: right;
+			}
+			.bot-btns {
+				margin-top: 30rpx;
+				display: flex;
+				align-items: center;
+				justify-content: flex-end;
+				.btn {
+					width: 180rpx;
+					margin-left: 20rpx;
+				}
+			}
 		}
 	}
-}
-</style>
+</style>

+ 16 - 4
pages-approve/activity/reason.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<view class="textarea-wrap white-wrap">
-			<textarea placeholder="请输入拒绝理由" v-model="reason" maxlength="-1"></textarea>
+			<textarea :placeholder="`请输入${type === 'del' ? '删除' : '拒绝'}理由`" v-model="reason" maxlength="-1"></textarea>
 		</view>
 		<view class="btns-wrap flex">
 			<button class="cancel-btn" @click="handleCancel">取消</button>
@@ -12,17 +12,24 @@
 
 <script>
 	import {apiRoadShowReject} from '@/api/approve/activity.js'
+	import { delActivity } from '@/api/roadshow/index.js';
 	export default {
 		data() {
 			return {
+				type: '',
 				reason: '',
 				RsCalendarId:null,
 				RsCalendarResearcherId:null,
 			}
 		},
 		onLoad(options) {
-			this.RsCalendarId=options.RsCalendarId
-			this.RsCalendarResearcherId=options.RsCalendarResearcherId
+			const { RsCalendarId,RsCalendarResearcherId,type } = options;
+			this.type = type;
+			this.RsCalendarId=RsCalendarId;
+			this.RsCalendarResearcherId=RsCalendarResearcherId;
+			uni.setNavigationBarTitle({
+				title: type==='del' ? '删除理由' : '拒绝理由'
+			})
 		},
 		methods: {
 			async handleSubmit() {
@@ -33,7 +40,12 @@
 					})
 					return
 				}
-				const res=await apiRoadShowReject({
+				
+				const res = this.type==='del' ? await delActivity({
+					DeleteReason: this.reason,
+					RsCalendarId:Number(this.RsCalendarId),
+					RsCalendarResearcherId:Number(this.RsCalendarResearcherId),
+				}) : await apiRoadShowReject({
 					RsCalendarId:Number(this.RsCalendarId),
 					RsCalendarResearcherId:Number(this.RsCalendarResearcherId),
 					RefuseReason:this.reason

+ 47 - 11
pages-approve/search/index.vue

@@ -15,7 +15,7 @@
 		<view class="search-result" v-else>
 			<view class="result-item flex" v-for="item in list" :key="item" @click="handleGoDetail(item)">
 				<image src="../static/search-icon.png" mode="aspectFill" class="search-icon"></image>
-				<view class="con van-ellipsis">{{item}}</view>
+				<view class="con van-ellipsis">{{ type==='roadshow' ? item.CompanyName : item}}</view>
 				<image src="../static/click-icon.png" mode="aspectFill" class="click-icon"></image>
 			</view>
 		</view>
@@ -27,6 +27,7 @@
 	import {apiCustomeSearch} from '@/api/approve/custome.js'
 	import {apiContractSearch} from '@/api/approve/contract.js'
 	import {apiSealSearch} from '@/api/approve/seal.js'
+	import { companySearch } from '@/api/roadshow/index.js';
 	export default {
 		data() {
 			return {
@@ -38,8 +39,7 @@
 			}
 		},
 		onLoad(options) {
-			this.type = options.type
-			console.log(options.type)
+			this.type = options.type;
 			this.initPage(options.type)
 		},
 		methods: {
@@ -59,6 +59,10 @@
 						navBarTitle = '用印审批'
 						this.placeholder = '客户名称/社会信用码'
 						break;
+					case 'roadshow':
+						navBarTitle = '客户搜索'
+						this.placeholder = '客户名称'
+						break;
 				}
 				uni.setNavigationBarTitle({
 					title: navBarTitle
@@ -72,6 +76,14 @@
 					uni.navigateTo({
 						url:"/pages-approve/contract/search?val="+e
 					})
+				}else if(this.type==='roadshow'){
+					// uni.navigateTo({
+					// 	url:"/pages-approve/contract/search?val="+e
+					// })
+					let id = uni.setStorageSync('roadshow_compantyId',e.CompanyId)
+					uni.navigateBack({
+						delta: 1
+					});
 				}else{
 					uni.navigateTo({
 						url:`./result?type=${this.type}&val=${e}`
@@ -124,6 +136,20 @@
 					}
 				}
 			},
+			
+			/* 路演客户名称搜索 */
+			async companySearchHandle() {
+				const { code,data } = await companySearch({
+					KeyWord: this.value
+				})
+				if(code !== 200) return
+				this.list = data;
+				if(data.length===0){
+					this.empty=true
+				}else{
+					this.empty=false
+				}
+			},
 
 			onChange(e) {
 				this.value = e.detail
@@ -137,17 +163,27 @@
 					})
 					return
 				}
-				if (this.type === 'custome') {
-					this.handleCustome()
-				}
+				
+				// if (this.type === 'custome') {
+				// 	this.handleCustome()
+				// }
 
-				if (this.type === 'contract') {
-					this.handleContract()
-				}
+				// if (this.type === 'contract') {
+				// 	this.handleContract()
+				// }
 				
-				if(this.type==='seal'){
-					this.handleSeal()
+				// if(this.type==='seal'){
+				// 	this.handleSeal()
+				// }
+				
+				const handleFn = {
+					custome: this.handleCustome,
+					contract: this.handleContract,
+					seal: this.handleSeal,
+					roadshow: this.companySearchHandle,
 				}
+				
+				handleFn[this.type]();
 			}
 		}
 	}

BIN
pages-approve/static/roadshow/accept-ico.png


BIN
pages-approve/static/roadshow/back-ico.png


BIN
pages-approve/static/roadshow/del-ico.png


BIN
pages-approve/static/roadshow/end-ico.png


BIN
pages-approve/static/roadshow/refuse-ico.png


+ 8 - 0
pages-roadshow/addActivity/byCell.vue

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

+ 179 - 28
pages-roadshow/addActivity/index.vue

@@ -9,7 +9,8 @@
 				name="picker" 
 				label="活动类型"
 				placeholder="选择活动类型" 
-				@click.native="isActivityPicker = true" 
+				@click.native="() => { if(edit_id) return; isActivityPicker = true }" 
+				:disabled="edit_id"
 			/>
 
 			<van-field 
@@ -29,18 +30,19 @@
 				v-if="['路演','公开会议'].includes(formData.activityType) && formData.roadshowType === '线上'" 
 				clickable
 				:label="`${dynamic_prefix}平台`" 
-				:placeholder="`输入${dynamic_prefix}平台`" 
+				:placeholder="`输入${dynamic_prefix}平台(eg:进门财经、腾讯会议)`" 
 				@change="bindInputHandle('roadshowPlatform',$event)"
 			/>
 
 			<van-field 
 				:value="formData.roadshowCity"
 				v-if="['路演','公开会议'].includes(formData.activityType) && formData.roadshowType === '线下'" 
-				is-link 
+				is-link
+				readonly
 				clickable
 				:label="`${dynamic_prefix}城市`" 
 				:placeholder="`选择${dynamic_prefix}城市`"
-				@click.native="isAreaPicker = true" 
+				@click.native="clickAreaChoose" 
 			/>
 
 			<van-field 
@@ -53,6 +55,13 @@
 				placeholder="客户名称" 
 				@click.native="goSearchCompany" 
 			/>
+			
+			<view class="company-info" v-if="formData.activityType === '路演' && formData.companyId && companyInfo">
+				<view>客户状态:{{companyInfo.Status}}</view>
+				<view>所属行业:{{companyInfo.IndustryName}}</view>
+				<view>开通品种:{{companyInfo.PermissionName}}</view>
+				<view>累计报告阅读次数:{{companyInfo.ReportReadTotal}}</view>
+			</view>
 
 			<van-field 
 				:value="formData.meetingTheme" 
@@ -74,7 +83,7 @@
 				type="textarea" 
 				rows="1" 
 				autosize 
-				placeholder="请输入合作方名称" 
+				placeholder="请输入合作方名称(多个合作方用','隔开)" 
 				@change="bindInputHandle('partnersName',$event)"
 			/>
 
@@ -85,7 +94,7 @@
 				clickable 
 				label="活动类别" 
 				placeholder="请选择活动类别" 
-				@click.native="isResearcherPicker = true" 
+				@click.native="isActivityClassPicker = true" 
 			/>
 
 			<van-field 
@@ -100,6 +109,7 @@
 				autosize
 				placeholder="选择研究员"
 				@click.native="clickRsChoose(0)"
+				:disabled="edit_id"
 			/>
 			<van-field 
 				:value="formatterLabelTime(formData.selectResearchers[0].startTime)"
@@ -126,7 +136,7 @@
 			<!-- 追加后的研究员 -->
 			<view class="add-user-list" v-for="addindex in addResearchersIdx" :key="addindex" v-if="addResearchersIdx.length">
 				<view class="del-cont" @click="delResearcherHandle(addindex)">
-					<van-icon name="minus" />
+					<van-icon name="close" />
 				</view>
 				<van-field 
 					:value="formatRsLable(formData.selectResearchers[addindex].researcherId)"
@@ -137,6 +147,7 @@
 					label="研究员"
 					placeholder="选择研究员"
 					@click.native="clickRsChoose(addindex)"
+					:disabled="edit_id"
 				/>
 				<van-field
 					:value="formatterLabelTime(formData.selectResearchers[addindex].startTime)"
@@ -164,14 +175,14 @@
 			</view>
 
 			<view class="add-user-btn" @click="addResearcherHandle"
-				v-if="['路演', '公开会议'].includes(formData.activityType)">
-				<van-icon name="plus" />添加研究员
-
+				v-if="['路演', '公开会议'].includes(formData.activityType) && !edit_id">
+				<van-icon name="add-o" />添加研究员
 			</view>
 		</van-form>
 
 		<div class="submit-bot">
-			<van-button type="primary" color="#3385FF" class="btn" round block @click="submitHandle">提交</van-button>
+			<van-button type="primary" plain color="#3385FF" class="btn" size="small" block round @click="cancelHandle">取消</van-button>
+			<van-button type="primary" color="#3385FF" class="btn" size="small" block round @click="submitHandle">确定</van-button>
 		</div>
 
 
@@ -185,6 +196,17 @@
 				@cancel="isActivityPicker=false" 
 			/>
 		</van-popup>
+		
+		<!-- 选择活动类别 -->
+		<van-popup :show="isActivityClassPicker" position="bottom">
+			<van-picker 
+				show-toolbar 
+				:columns="telTypeList"
+				:default-index="telTypeList.indexOf(formData.activityClass)" 
+				@confirm="confirmActivityClass"
+				@cancel="isActivityClassPicker=false" 
+			/>
+		</van-popup>
 
 		<!-- 选择路演形式 -->
 		<van-popup :show="isRoadshowTypePicker" position="bottom">
@@ -225,7 +247,8 @@
 
 		<!-- 选择地区 -->
 		<van-popup :show="isAreaPicker" position="bottom">
-			<van-area 
+			<van-area
+				:value="pickerForm.area"
 				:area-list="areaList" 
 				:columns-num="2"
 				@confirm="confirmArea" 
@@ -236,10 +259,18 @@
 </template>
 
 <script>
+	import {
+		addActivity,
+		editActivity
+	} from '@/api/roadshow/index.js';
 	import {
 		getDefaultOption
 	} from './common.js';
 	import mixin from './mixin.js';
+	import { validateForm } from '../utils/validate.js';
+	
+	const moment = require('../utils/_moment.js');
+	moment.locale('zh-cn'); 
 	export default {
 		mixins: [mixin],
 		data() {
@@ -248,7 +279,7 @@
 		methods: {
 
 			/* 设置默认状态 */
-			initSetState() {
+			initSetState(options) {
 				const {
 					RoleTypeCode
 				} = JSON.parse(uni.getStorageSync('userInfo')) || null;
@@ -266,16 +297,115 @@
 					startTime: startTime,
 					endTime: endTime,
 				}];
-
-			}
+				
+				/* 编辑时回显表单 */
+				if(options.edit_id) {
+					const { form,edit_id,edit_rs_id } = options;
+					this.formData = {...this.formData,...JSON.parse(form)};
+					this.edit_id = Number(edit_id);
+					this.edit_rs_id = Number(edit_rs_id);
+				}
+				console.log(this.formData)
+				
+				uni.setNavigationBarTitle({
+					title: this.edit_id ? '修改活动' : '添加活动'
+				})
+
+			},
+			
+			/* 提交表单 */
+			async submitHandle() {
+				
+				let isCheck = validateForm(this.formData.activityType,this.formData);
+				console.log(isCheck)
+				if(!isCheck) return
+				
+				// console.log(this.formData)
+			
+				let parmas;
+				const param_research = ['公开会议', '路演'].includes(
+						this.formData.activityType
+					) ?
+					this.formData.selectResearchers.map((item) => ({
+						ResearcherId: Number(item.researcherId),
+						ResearcherName: this.findName(item.researcherId),
+						StartDate: moment(item.startTime).format('YYYY-MM-DD'),
+						EndDate: moment(item.endTime).format('YYYY-MM-DD'),
+						StartTime: moment(item.startTime).format('HH:mm:ss'),
+						EndTime: moment(item.endTime).format('HH:mm:ss'),
+						StartWeek: moment(item.startTime).format('ddd'),
+						EndWeek: moment(item.endTime).format('ddd'),
+					})) :
+					this.formData.selectResearchers[0].researcherId.map((item) => ({
+						ResearcherId: Number(item),
+						ResearcherName: item === 99 ? 'ficc全体' : this.findName(item),
+						StartDate: moment(
+							this.formData.selectResearchers[0].startTime
+						).format('YYYY-MM-DD'),
+						EndDate: moment(
+							this.formData.selectResearchers[0].endTime
+						).format('YYYY-MM-DD'),
+						StartTime: moment(
+							this.formData.selectResearchers[0].startTime
+						).format('HH:mm:ss'),
+						EndTime: moment(
+							this.formData.selectResearchers[0].endTime
+						).format('HH:mm:ss'),
+						StartWeek: moment(this.formData.selectResearchers[0].startTime).format('ddd'),
+						EndWeek: moment(this.formData.selectResearchers[0].endTime).format('ddd'),
+					}));
+						
+				parmas = {
+					ActivityType: this.formData.activityType,
+					ActivityCategory: this.formData.activityClass,
+					City: this.formData.roadshowCity[1],
+					Province: this.formData.roadshowCity[0],
+					CooperationName: this.formData.partnersName,
+					Theme: this.formData.meetingTheme,
+					RoadshowType: this.formData.roadshowType,
+					RoadshowPlatform: this.formData.roadshowPlatform,
+					CompanyId: this.formData.companyId || 0,
+					CompanyName: this.formData.companyName || '',
+					ResearcherList: param_research,
+				};
+			
+				// console.log(parmas);
+			
+				const res = this.edit_id ?
+					await editActivity({
+						...parmas,
+						RsCalendarId: Number(this.edit_id),
+						RsCalendarResearcherId: Number(this.edit_rs_id),
+						EditType: ['公开会议', '路演'].includes(this.formData.activityType) ? 2 : 1
+					}) : await addActivity(parmas);
+			
+				if (res.code !== 200) return;
+				
+				const { text,content,link,query } = this.setDynamicLink(this.formData.activityType);
+				
+				
+				this.edit_id ? uni.showToast({
+					title: '提交成功',
+					icon: 'success'
+				}) : this.addActivityLink({text,content,link,query});
+				
+				this.edit_id && setTimeout(() => { this.cancelHandle(); },1500);
+			},
 		},
 
-		onLoad() {
-			this.initSetState();
+		onLoad(options) {
+			this.initSetState(options);
 		},
 
 		onShow() {
 			this.getResearcherList();
+			this.getTelType();
+			
+			if(uni.getStorageSync('roadshow_compantyId')) {
+				this.formData.companyId = Number(uni.getStorageSync('roadshow_compantyId'));
+				this.getCompanyInfo();
+				uni.removeStorageSync('roadshow_compantyId');
+			}
 		}
 	}
 </script>
@@ -285,9 +415,13 @@
 		padding-bottom: 200rpx;
 
 		.add-user-btn {
+			background-color: #fff;
+			margin-top: 20rpx;
+			padding: 20rpx 0;
 			color: #3385ff;
-			font-size: 32rpx;
-			padding: 20rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
 		}
 
 		.del-cont {
@@ -304,17 +438,21 @@
 			right: 0;
 			bottom: 0;
 			z-index: 99;
-			height: 160rpx;
+			height: 140rpx;
 			padding: 0 150rpx;
 			background-color: #fff;
 			display: flex;
 			align-items: center;
+			justify-content: center;
 			padding-bottom: constant(safe-area-inset-bottom);
 			padding-bottom: env(safe-area-inset-bottom);
 			box-shadow: 0px -2px 6px rgba(110, 119, 141, 0.07);
 
 			.btn {
-				width: 100%;
+				// width: 100%;
+				width: 260rpx;
+				height: 60rpx;
+				margin-right: 30rpx;
 			}
 		}
 
@@ -336,14 +474,27 @@
 	}
 </style>
 <style lang="scss">
-	.van-tree-select {
-		.van-tree-select__item--active {
-			color: #1989fa !important;
-		}
+	.addactiyity-container {
+		.van-tree-select {
+			.van-tree-select__item--active {
+				color: #1989fa !important;
+			}
 
-		.van-sidebar-item--selected {
-			border-color: #1989fa !important;
+			.van-sidebar-item--selected {
+				border-color: #1989fa !important;
+			}
+		}
+		
+		.company-info {
+			background: #D5E6FF;
+			padding: 10rpx 30rpx;
+			margin-bottom: 20rpx;
+			view {
+				margin: 12rpx 0;
+				color: #666;
+				text-indent: -140rpx;
+				margin-left: 140rpx;
+			}
 		}
-
 	}
 </style>

+ 115 - 139
pages-roadshow/addActivity/mixin.js

@@ -1,12 +1,13 @@
 import {
 	researcherList,
-	addActivity,
-	editActivity
+	telTypes,
+	companyInfo
 } from '@/api/roadshow/index.js';
 import { getDefaultOption } from './common.js';
 import { areaList } from '../utils/area.js';
 
-const moment = require('../utils/moment.js');
+const moment = require('../utils/_moment.js');
+moment.locale('zh-cn'); 
 
 
 export default {
@@ -22,9 +23,6 @@ export default {
 				roadshowCity: '', // 路演/会议城市
 				companyId: 0, // 客户id
 				companyName: '', // 客户名称
-				// meetingType: '', // 会议形式
-				// meetingPlatform: '', // 会议平台
-				// meetingCity: '', // 会议城市
 				meetingTheme: '', // 会议主题
 				partnersName: '', // 合作方名称
 				selectResearchers: [
@@ -36,12 +34,12 @@ export default {
 				], // 选择的研究员
 			},
 			
-			
 			isActivityPicker: false, //活动类型弹窗
 			isResearcherPicker: false, //研究员弹窗
 			isTimePicker: false, //时间弹窗
 			isAreaPicker: false, //地区弹窗
 			isRoadshowTypePicker: false, //路演/会议形式弹窗
+			isActivityClassPicker: false,//活动类别弹窗
 
 			rs_picker: {
 				firstindex:0,
@@ -49,7 +47,8 @@ export default {
 			},
 
 			pickerForm: {
-				time: '',
+				time: '',//时间默认
+				area:'',//地区默认
 			}, //picker的默认选中
 			selectObj: {}, //选中的日期信息 下标
 			selectRsIndex: '', //选中的研究员下标
@@ -65,7 +64,9 @@ export default {
 			]),
 			activiytyTypes: [],//活动类型
 			researcherList: [],//研究员列表
+			telTypeList: [],//电话会类别
 			areaList,//地区数据
+			companyInfo: null,//客户信息
 		}
 	},
 	computed: {
@@ -79,38 +80,6 @@ export default {
 		},
 	},
 	watch: {
-		'formData.activityType': {
-			handler() {
-				
-				const {
-					RoleTypeCode
-				} = JSON.parse(uni.getStorageSync('userInfo')) || null;
-				const {
-					defaultActivityType,
-					activityTypeList,
-					startTime,
-					endTime
-				} = getDefaultOption(RoleTypeCode, 2);
-				
-				this.formData.roadshowType = '';
-				this.formData.roadshowPlatform = '';
-				this.formData.roadshowCity = '';
-				this.formData.companyId = 0;
-				this.formData.companyName = '';
-				this.formData.meetingTheme = '';
-				this.formData.partnersName = '';
-				this.formData.activityClass = '';
-				this.companyInfo = '';
-				this.formData.selectResearchers = [
-					{
-						researcherId: '',
-						startTime: startTime,
-						endTime: endTime,
-					},
-				];
-				// this.$refs.form.clearValidate();
-			}
-		}
 	},
 	methods: {
 
@@ -128,6 +97,47 @@ export default {
 				})) : []
 			}));
 		},
+		
+		/* 获取客户信息 */
+		async getCompanyInfo() {
+			const res = await companyInfo({ 
+				CompanyId: this.formData.companyId
+			})
+			if(res.code !== 200) return
+			this.companyInfo = res.data;
+			this.formData.companyName = res.data.CompanyName;
+			
+		},
+		
+		/* 获取电话会类别 */
+		async getTelType() {
+			const { code,data } = await telTypes();
+			if (code !== 200) return
+			this.telTypeList = data[0].ChildList.map(_ => _.ActivityTypeName);
+		},
+		
+		/* 新增活动成功后操作 */
+		addActivityLink({text,content,link,query}) {
+			uni.showModal({
+				title:text,
+				content,
+				confirmText:'去查看',
+				cancelColor: '#A9AFB8',
+				confirmColor: '#3385FF',
+				success: function(res) {
+					if(res.confirm){
+						uni.redirectTo({
+							url:`${link}?type=${query.type}`,
+						})
+					}else {
+						uni.navigateBack({
+							delta:1
+						})
+					}
+				}
+			})
+		},
+		
 
 		/* 添加研究员 */
 		addResearcherHandle() {
@@ -148,95 +158,12 @@ export default {
 		delResearcherHandle(index) {
 			this.formData.selectResearchers.splice(index, 1);
 		},
-
-		/* 提交表单 */
-		async submitHandle() {
-			console.log(this.formData)
-			if (this.formData.companyName && !this.formData.companyId) return uni.showToast({
-				title: '请选择客户',
-				icon: 'none'
-			})
-
-			let parmas;
-
-			const param_research = ['公开会议', '路演'].includes(
-					this.formData.activityType
-				) ?
-				this.formData.selectResearchers.map((item) => ({
-					ResearcherId: Number(item.researcherId),
-					ResearcherName: this.findName(item.researcherId),
-					StartDate: moment(item.startTime).format('YYYY-MM-DD'),
-					EndDate: moment(item.endTime).format('YYYY-MM-DD'),
-					StartTime: moment(item.startTime).format('HH:mm:ss'),
-					EndTime: moment(item.endTime).format('HH:mm:ss'),
-					StartWeek: this.weekMap.get(moment(this.formData.selectResearchers[0].startTime
-					).format('E')),
-					EndWeek: this.weekMap.get(moment(this.formData.selectResearchers[0].endTime
-					).format('E')),
-				})) :
-				this.formData.selectResearchers[0].researcherId.map((item) => ({
-					ResearcherId: Number(item),
-					ResearcherName: item === 99 ? 'ficc全体' : this.findName(item),
-					StartDate: moment(
-						this.formData.selectResearchers[0].startTime
-					).format('YYYY-MM-DD'),
-					EndDate: moment(
-						this.formData.selectResearchers[0].endTime
-					).format('YYYY-MM-DD'),
-					StartTime: moment(
-						this.formData.selectResearchers[0].startTime
-					).format('HH:mm:ss'),
-					EndTime: moment(
-						this.formData.selectResearchers[0].endTime
-					).format('HH:mm:ss'),
-					StartWeek: this.weekMap.get(moment(this.formData.selectResearchers[0].startTime
-					).format('E')),
-					EndWeek: this.weekMap.get(moment(this.formData.selectResearchers[0].endTime
-					).format('E')),
-				}));
-
-
-			parmas = {
-				ActivityType: this.formData.activityType,
-				ActivityCategory: this.formData.activityClass,
-				City: this.formData.roadshowCity[1],
-				Province: this.formData.roadshowCity[0],
-				CooperationName: this.formData.partnersName,
-				Theme: this.formData.meetingTheme,
-				RoadshowType: this.formData.roadshowType,
-				RoadshowPlatform: this.formData.roadshowPlatform,
-				CompanyId: this.formData.companyId || 0,
-				CompanyName: this.formData.companyName || '',
-				ResearcherList: param_research,
-			};
-
-			console.log(parmas);
-
-			// return
-			const res = this.edit_id ?
-				await editActivity({
-					...parmas,
-					RsCalendarId: Number(this.edit_id),
-			 	RsCalendarResearcherId: Number(this.edit_rs_id),
-					EditType: ['公开会议', '路演'].includes(this.formData.activityType) ? 2 : 1
-				}) : await addActivity(parmas);
-
-			if (res.code !== 200) return;
-			
-			const { text,content,link,query } = this.setDynamicLink(this.formData.activityType);
-			
-			uni.showModal({
-				title:text,
-				content,
-				confirmText:'去查看',
-				confirmColor: '#576b95',
-				success: function(res) {
-					if(res.confirm) uni.navigateTo({
-						url:`${link}?type=${query.type}`,
-					})
-				}
+		
+		/* 取消 */
+		cancelHandle() {
+			uni.navigateBack({
+				delta:1
 			})
-
 		},
 
 		findName(id) {
@@ -251,10 +178,46 @@ export default {
 		
 		/* 选择活动 */
 		confirmActivityType({detail}) {
-			console.log(detail.value)
 			this.formData.activityType = detail.value;
+			this.initOtherForm();
 			this.isActivityPicker = false;
 		},
+		
+		/* 切换类型时重置部分表单 */
+		initOtherForm() {
+			const {
+				RoleTypeCode
+			} = JSON.parse(uni.getStorageSync('userInfo')) || null;
+			const {
+				defaultActivityType,
+				activityTypeList,
+				startTime,
+				endTime
+			} = getDefaultOption(RoleTypeCode, 2);
+			
+			this.formData.roadshowType = '';
+			this.formData.roadshowPlatform = '';
+			this.formData.roadshowCity = '';
+			this.formData.companyId = 0;
+			this.formData.companyName = '';
+			this.formData.meetingTheme = '';
+			this.formData.partnersName = '';
+			this.formData.activityClass = '';
+			this.companyInfo = '';
+			this.formData.selectResearchers = [
+				{
+					researcherId: '',
+					startTime: startTime,
+					endTime: endTime,
+				},
+			];
+		},
+		
+		/* 选择活动类别 */
+		confirmActivityClass({detail}) {
+			this.formData.activityClass = detail.value;
+			this.isActivityClassPicker = false;
+		},
 
 		/* 前往客户搜索 */
 		goSearchCompany() {
@@ -265,6 +228,8 @@ export default {
 		
 		/* 选择研究员弹窗展开 */
 		clickRsChoose(index) {
+			if(this.edit_id) return;
+			
 			this.isResearcherPicker = true;
 			this.rs_picker= {
 				firstindex:0,
@@ -332,6 +297,21 @@ export default {
 			this.isRoadshowTypePicker = false;
 		},
 		
+		/* 选择地区弹窗 */
+		clickAreaChoose() {
+			const city = this.formData.roadshowCity.length ? this.formData.roadshowCity[1] : '';
+			let cityCode = '';
+			if(city)	for(let i in this.areaList.city_list) {
+					if(this.areaList.city_list[i] === city){
+						 cityCode = String(i);
+						 break;
+					}
+				}
+			// console.log(cityCode)
+			this.pickerForm.area = cityCode;
+			this.isAreaPicker = true
+		},
+		
 		/* 选择地区 */
 		confirmArea({detail}) {
 			const { values } = detail;
@@ -380,7 +360,7 @@ export default {
 					content: `可前往【我的日历】-【${type}】查看`,
 					link: '/pages-approve/activity/list',
 					query: {
-						type: 3
+						type
 					},
 				}
 				case '报告电话会' : return {
@@ -388,7 +368,7 @@ export default {
 					content: `可前往【我的日历】-【${type}】查看`,
 					link: '/pages-approve/activity/list',
 					query: {
-						type: 4
+						type
 					},
 				}
 				case '路演' : return {
@@ -396,7 +376,7 @@ export default {
 					content: `可前往【我的日历】-【活动申请】查看`,
 					link: '/pages-approve/activity/list',
 					query: {
-						type: 1
+						type: '活动申请'
 					},
 				}
 				case '公开会议' : return {
@@ -404,7 +384,7 @@ export default {
 					content: `可前往【我的日历】-【活动申请】查看`,
 					link: '/pages-approve/activity/list',
 					query: {
-						type: 1
+						type: '活动申请'
 					},
 				}
 			}
@@ -412,18 +392,14 @@ export default {
 
 		/* 绑定input输入value */
 		bindInputHandle(key,{detail}) {
-			console.log(key,detail)
 			this.formData[key] = detail;
-			console.log(this.formData.meetingTheme)
 		},
 
 		/* 格式化时间显示 */
 		formatterLabelTime(val) {
 			if(!val) return '';
-			// (星期d) 
-			// let week =  this.weekMap.get(moment(val).format('E'));
-			// console.log(week)
-			const date = moment(val).format('MM.DD  HH:mm');
+
+			const date = moment(val).format('MM.DD(ddd)  HH:mm');
 			return date;
 
 		},

+ 255 - 0
pages-roadshow/addMatter/index.vue

@@ -0,0 +1,255 @@
+<template>
+	<view class="addactiyity-container">
+		<van-form>
+			<van-field 
+				:value="formatterLabelTime(formData.startTime)"
+				is-link 
+				readonly 
+				clickable
+				name="datetimePicker" 
+				label="开始时间" 
+				placeholder="选择开始时间"
+				@click.native="clickTimeChoose('start')"
+			/>
+
+			<van-field 
+				:value="formatterLabelTime(formData.endTime)"
+				is-link
+				readonly
+				clickable
+				name="datetimePicker"
+				label="结束时间"
+				placeholder="选择结束时间"
+				@click.native="clickTimeChoose('end')"
+			/>
+			
+			<van-field
+				:value="formData.matterContent"
+				clickable
+				label="事项内容" 
+				type="textarea" 
+				rows="1" 
+				autosize 
+				placeholder="请输入事项内容" 
+				@change="bindInputHandle('matterContent',$event)"
+			/>
+		</van-form>
+
+		<div class="submit-bot">
+			<van-button type="primary" plain color="#3385FF" size="small" class="btn" block round @click="cancelHandle">取消</van-button>
+			
+			<van-button type="primary" color="#3385FF" size="small" class="btn" block round @click="submitHandle">确定</van-button>
+		</div>
+
+		<!-- 选择时间 -->
+		<van-popup :show="isTimePicker" position="bottom">
+			<van-datetime-picker 
+				:value="pickerForm.time" 
+				type="datetime" 
+				:formatter="formatterPickerTime"
+				@confirm="confirmTime" 
+				@cancel="() => {isTimePicker = false;pickerForm.time=''}" 
+			/>
+		</van-popup>
+		
+	</view>
+</template>
+
+<script>
+	import {
+		getDefaultOption
+	} from '../addActivity/common.js';
+	import { validateForm } from '../utils/validate.js';
+	import { addMatter,editMatter } from '@/api/roadshow/index.js';
+	
+	const moment = require('../utils/_moment.js');
+	export default {
+		data() {
+			return {
+				edit_matter_id:'',
+				isTimePicker: false,
+				select_type: '',
+				
+				pickerForm: {
+					time: ''
+				},
+				
+				formData: {
+					startTime: '',
+					endTime: '',
+					matterContent: "",
+				},
+				weekMap: new Map([
+					['1','周一'],
+					['2','周二'],
+					['3','周三'],
+					['4','周四'],
+					['5','周五'],
+					['6','周六'],
+					['7','周日']
+				]),
+			};
+		},
+		methods: {
+			
+			/* 取消 */
+			cancelHandle() {
+				uni.navigateBack({
+					delta:1
+				})
+			},
+			
+			/* 提交表单 */
+			async submitHandle() {
+				let isCheck = validateForm('事项',this.formData);
+				console.log(isCheck)
+				if(!isCheck) return
+				
+				let params = {
+					MatterContent: this.formData.matterContent,
+					StartDate: moment(this.formData.startTime).format('YYYY-MM-DD'),
+					EndDate: moment(this.formData.endTime).format('YYYY-MM-DD'),
+					StartTime: moment(this.formData.startTime).format('HH:mm:ss'),
+					EndTime: moment(this.formData.endTime).format('HH:mm:ss'),
+					StartWeek: moment(this.formData.startTime
+					).format('ddd'),
+					EndWeek: moment(this.formData.endTime
+					).format('ddd')
+				}
+	
+				// 发送请求
+				const { code } = this.edit_matter_id ? await editMatter({
+					RsMattersId: this.edit_matter_id,
+					...params
+				}) : await addMatter(params);
+	
+				if(code !== 200) return;
+				// this.$message.success(this.edit_matter_id ? '提交成功' : '添加成功');
+				uni.showToast({
+					title: this.edit_matter_id ? '提交成功' : '添加成功',
+					icon: 'success',
+				})
+				setTimeout(() => {
+					this.cancelHandle();
+				},1800)
+			},
+			
+			/* 点击选择时间 */
+			clickTimeChoose(type) {
+				this.pickerForm.time = type === 'start' ? this.formData.startTime : this.formData.endTime;
+				this.select_type = type;
+				setTimeout(() => {
+					this.isTimePicker = true;
+				})
+			},
+			
+			/* 选择时间 */
+			confirmTime({detail}) {
+				// console.log(val)
+			
+				if (this.select_type === 'start') {
+					this.formData.startTime = detail;
+				} else {
+					this.formData.endTime = detail;
+				}
+			
+				this.isTimePicker = false;
+				this.pickerForm.time = '';
+			},
+			
+			/* 绑定input输入value */
+			bindInputHandle(key,{detail}) {
+				this.formData[key] = detail;
+			},
+			
+			/* 格式化时间显示 */
+			formatterLabelTime(val) {
+				if(!val) return '';
+				const date = moment(val).format('MM.DD(ddd)  HH:mm');
+				return date;
+			
+			},
+			
+			/* 格式化弹窗时间显示 */
+			formatterPickerTime(type, val) {
+				switch (type) {
+					case 'year':
+						return val + '年';
+					case 'month':
+						return val + '月';
+					case 'day':
+						return val + '日';
+					case 'hour':
+						return val + '时';
+					case 'minute':
+						return val + '分';
+				}
+			},
+
+			/* 设置默认状态 */
+			initSetState() {
+				const {
+					RoleTypeCode
+				} = JSON.parse(uni.getStorageSync('userInfo')) || null;
+				const {
+					startTime,
+					endTime
+				} = getDefaultOption(RoleTypeCode, 2);
+				this.formData = {
+					startTime: startTime,
+					endTime: endTime,
+					matterContent: ''
+				};
+			}
+		},
+
+		onLoad() {
+			this.initSetState();
+		},
+
+		onShow() {
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.addactiyity-container {
+		padding-bottom: 200rpx;
+
+
+		.submit-bot {
+			position: fixed;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			z-index: 99;
+			height: 140rpx;
+			padding: 0 150rpx;
+			background-color: #fff;
+			display: flex;
+			align-items: center;
+			padding-bottom: constant(safe-area-inset-bottom);
+			padding-bottom: env(safe-area-inset-bottom);
+			box-shadow: 0px -2px 6px rgba(110, 119, 141, 0.07);
+
+			.btn {
+				width: 220rpx;
+				height: 60rpx;
+				margin-right: 30rpx;
+			}
+		}
+
+	}
+</style>
+<style lang="scss">
+	.van-tree-select {
+		.van-tree-select__item--active {
+			color: #1989fa !important;
+		}
+
+		.van-sidebar-item--selected {
+			border-color: #1989fa !important;
+		}
+
+	}
+</style>

+ 8 - 1
pages-roadshow/myCalendar/index.vue

@@ -5,11 +5,18 @@
 </template>
 
 <script>
+	import { linkRoadshowUrl } from '@/utils/config.js';
 	export default {
 		data() {
 			return {
-				linkUrl: 'http://192.168.77.17:3000/xcx_h5/ssbg/roadshow/mine'
 			};
+		},
+		computed: {
+			linkUrl() {
+				const token = uni.getStorageSync('token');
+				const { RoleTypeCode } = JSON.parse(uni.getStorageSync('userInfo'));
+				return `${linkRoadshowUrl}/roadshow/mine?token=${token}&role=${RoleTypeCode}`;
+			}
 		}
 	}
 </script>

+ 7 - 1
pages-roadshow/researcherCalendar/index.vue

@@ -5,12 +5,18 @@
 </template>
 
 <script>
+	import { linkRoadshowUrl } from '@/utils/config.js';
 	export default {
 		data() {
 			return {
-				linkUrl: 'http://192.168.77.17:3000/xcx_h5/ssbg/roadshow/researcher'
 			};
 			
+		},
+		computed: {
+			linkUrl() {
+				const token = uni.getStorageSync('token');
+				return `${linkRoadshowUrl}/roadshow/researcher?token=${token}`;
+			}
 		}
 	}
 </script>

File diff suppressed because it is too large
+ 0 - 0
pages-roadshow/utils/_moment.js


+ 0 - 4602
pages-roadshow/utils/moment.js

@@ -1,4602 +0,0 @@
-//! moment.js
-
-;(function (global, factory) {
-    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
-    typeof define === 'function' && define.amd ? define(factory) :
-    global.moment = factory()
-}(this, (function () { 'use strict';
-
-    var hookCallback;
-
-    function hooks () {
-        return hookCallback.apply(null, arguments);
-    }
-
-    // This is done to register the method called with moment()
-    // without creating circular dependencies.
-    function setHookCallback (callback) {
-        hookCallback = callback;
-    }
-
-    function isArray(input) {
-        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
-    }
-
-    function isObject(input) {
-        // IE8 will treat undefined and null as object if it wasn't for
-        // input != null
-        return input != null && Object.prototype.toString.call(input) === '[object Object]';
-    }
-
-    function isObjectEmpty(obj) {
-        if (Object.getOwnPropertyNames) {
-            return (Object.getOwnPropertyNames(obj).length === 0);
-        } else {
-            var k;
-            for (k in obj) {
-                if (obj.hasOwnProperty(k)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    function isUndefined(input) {
-        return input === void 0;
-    }
-
-    function isNumber(input) {
-        return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
-    }
-
-    function isDate(input) {
-        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
-    }
-
-    function map(arr, fn) {
-        var res = [], i;
-        for (i = 0; i < arr.length; ++i) {
-            res.push(fn(arr[i], i));
-        }
-        return res;
-    }
-
-    function hasOwnProp(a, b) {
-        return Object.prototype.hasOwnProperty.call(a, b);
-    }
-
-    function extend(a, b) {
-        for (var i in b) {
-            if (hasOwnProp(b, i)) {
-                a[i] = b[i];
-            }
-        }
-
-        if (hasOwnProp(b, 'toString')) {
-            a.toString = b.toString;
-        }
-
-        if (hasOwnProp(b, 'valueOf')) {
-            a.valueOf = b.valueOf;
-        }
-
-        return a;
-    }
-
-    function createUTC (input, format, locale, strict) {
-        return createLocalOrUTC(input, format, locale, strict, true).utc();
-    }
-
-    function defaultParsingFlags() {
-        // We need to deep clone this object.
-        return {
-            empty           : false,
-            unusedTokens    : [],
-            unusedInput     : [],
-            overflow        : -2,
-            charsLeftOver   : 0,
-            nullInput       : false,
-            invalidMonth    : null,
-            invalidFormat   : false,
-            userInvalidated : false,
-            iso             : false,
-            parsedDateParts : [],
-            meridiem        : null,
-            rfc2822         : false,
-            weekdayMismatch : false
-        };
-    }
-
-    function getParsingFlags(m) {
-        if (m._pf == null) {
-            m._pf = defaultParsingFlags();
-        }
-        return m._pf;
-    }
-
-    var some;
-    if (Array.prototype.some) {
-        some = Array.prototype.some;
-    } else {
-        some = function (fun) {
-            var t = Object(this);
-            var len = t.length >>> 0;
-
-            for (var i = 0; i < len; i++) {
-                if (i in t && fun.call(this, t[i], i, t)) {
-                    return true;
-                }
-            }
-
-            return false;
-        };
-    }
-
-    function isValid(m) {
-        if (m._isValid == null) {
-            var flags = getParsingFlags(m);
-            var parsedParts = some.call(flags.parsedDateParts, function (i) {
-                return i != null;
-            });
-            var isNowValid = !isNaN(m._d.getTime()) &&
-                flags.overflow < 0 &&
-                !flags.empty &&
-                !flags.invalidMonth &&
-                !flags.invalidWeekday &&
-                !flags.weekdayMismatch &&
-                !flags.nullInput &&
-                !flags.invalidFormat &&
-                !flags.userInvalidated &&
-                (!flags.meridiem || (flags.meridiem && parsedParts));
-
-            if (m._strict) {
-                isNowValid = isNowValid &&
-                    flags.charsLeftOver === 0 &&
-                    flags.unusedTokens.length === 0 &&
-                    flags.bigHour === undefined;
-            }
-
-            if (Object.isFrozen == null || !Object.isFrozen(m)) {
-                m._isValid = isNowValid;
-            }
-            else {
-                return isNowValid;
-            }
-        }
-        return m._isValid;
-    }
-
-    function createInvalid (flags) {
-        var m = createUTC(NaN);
-        if (flags != null) {
-            extend(getParsingFlags(m), flags);
-        }
-        else {
-            getParsingFlags(m).userInvalidated = true;
-        }
-
-        return m;
-    }
-
-    // Plugins that add properties should also add the key here (null value),
-    // so we can properly clone ourselves.
-    var momentProperties = hooks.momentProperties = [];
-
-    function copyConfig(to, from) {
-        var i, prop, val;
-
-        if (!isUndefined(from._isAMomentObject)) {
-            to._isAMomentObject = from._isAMomentObject;
-        }
-        if (!isUndefined(from._i)) {
-            to._i = from._i;
-        }
-        if (!isUndefined(from._f)) {
-            to._f = from._f;
-        }
-        if (!isUndefined(from._l)) {
-            to._l = from._l;
-        }
-        if (!isUndefined(from._strict)) {
-            to._strict = from._strict;
-        }
-        if (!isUndefined(from._tzm)) {
-            to._tzm = from._tzm;
-        }
-        if (!isUndefined(from._isUTC)) {
-            to._isUTC = from._isUTC;
-        }
-        if (!isUndefined(from._offset)) {
-            to._offset = from._offset;
-        }
-        if (!isUndefined(from._pf)) {
-            to._pf = getParsingFlags(from);
-        }
-        if (!isUndefined(from._locale)) {
-            to._locale = from._locale;
-        }
-
-        if (momentProperties.length > 0) {
-            for (i = 0; i < momentProperties.length; i++) {
-                prop = momentProperties[i];
-                val = from[prop];
-                if (!isUndefined(val)) {
-                    to[prop] = val;
-                }
-            }
-        }
-
-        return to;
-    }
-
-    var updateInProgress = false;
-
-    // Moment prototype object
-    function Moment(config) {
-        copyConfig(this, config);
-        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
-        if (!this.isValid()) {
-            this._d = new Date(NaN);
-        }
-        // Prevent infinite loop in case updateOffset creates new moment
-        // objects.
-        if (updateInProgress === false) {
-            updateInProgress = true;
-            hooks.updateOffset(this);
-            updateInProgress = false;
-        }
-    }
-
-    function isMoment (obj) {
-        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
-    }
-
-    function absFloor (number) {
-        if (number < 0) {
-            // -0 -> 0
-            return Math.ceil(number) || 0;
-        } else {
-            return Math.floor(number);
-        }
-    }
-
-    function toInt(argumentForCoercion) {
-        var coercedNumber = +argumentForCoercion,
-            value = 0;
-
-        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
-            value = absFloor(coercedNumber);
-        }
-
-        return value;
-    }
-
-    // compare two arrays, return the number of differences
-    function compareArrays(array1, array2, dontConvert) {
-        var len = Math.min(array1.length, array2.length),
-            lengthDiff = Math.abs(array1.length - array2.length),
-            diffs = 0,
-            i;
-        for (i = 0; i < len; i++) {
-            if ((dontConvert && array1[i] !== array2[i]) ||
-                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
-                diffs++;
-            }
-        }
-        return diffs + lengthDiff;
-    }
-
-    function warn(msg) {
-        if (hooks.suppressDeprecationWarnings === false &&
-                (typeof console !==  'undefined') && console.warn) {
-            console.warn('Deprecation warning: ' + msg);
-        }
-    }
-
-    function deprecate(msg, fn) {
-        var firstTime = true;
-
-        return extend(function () {
-            if (hooks.deprecationHandler != null) {
-                hooks.deprecationHandler(null, msg);
-            }
-            if (firstTime) {
-                var args = [];
-                var arg;
-                for (var i = 0; i < arguments.length; i++) {
-                    arg = '';
-                    if (typeof arguments[i] === 'object') {
-                        arg += '\n[' + i + '] ';
-                        for (var key in arguments[0]) {
-                            arg += key + ': ' + arguments[0][key] + ', ';
-                        }
-                        arg = arg.slice(0, -2); // Remove trailing comma and space
-                    } else {
-                        arg = arguments[i];
-                    }
-                    args.push(arg);
-                }
-                warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
-                firstTime = false;
-            }
-            return fn.apply(this, arguments);
-        }, fn);
-    }
-
-    var deprecations = {};
-
-    function deprecateSimple(name, msg) {
-        if (hooks.deprecationHandler != null) {
-            hooks.deprecationHandler(name, msg);
-        }
-        if (!deprecations[name]) {
-            warn(msg);
-            deprecations[name] = true;
-        }
-    }
-
-    hooks.suppressDeprecationWarnings = false;
-    hooks.deprecationHandler = null;
-
-    function isFunction(input) {
-        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
-    }
-
-    function set (config) {
-        var prop, i;
-        for (i in config) {
-            prop = config[i];
-            if (isFunction(prop)) {
-                this[i] = prop;
-            } else {
-                this['_' + i] = prop;
-            }
-        }
-        this._config = config;
-        // Lenient ordinal parsing accepts just a number in addition to
-        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
-        // TODO: Remove "ordinalParse" fallback in next major release.
-        this._dayOfMonthOrdinalParseLenient = new RegExp(
-            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
-                '|' + (/\d{1,2}/).source);
-    }
-
-    function mergeConfigs(parentConfig, childConfig) {
-        var res = extend({}, parentConfig), prop;
-        for (prop in childConfig) {
-            if (hasOwnProp(childConfig, prop)) {
-                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
-                    res[prop] = {};
-                    extend(res[prop], parentConfig[prop]);
-                    extend(res[prop], childConfig[prop]);
-                } else if (childConfig[prop] != null) {
-                    res[prop] = childConfig[prop];
-                } else {
-                    delete res[prop];
-                }
-            }
-        }
-        for (prop in parentConfig) {
-            if (hasOwnProp(parentConfig, prop) &&
-                    !hasOwnProp(childConfig, prop) &&
-                    isObject(parentConfig[prop])) {
-                // make sure changes to properties don't modify parent config
-                res[prop] = extend({}, res[prop]);
-            }
-        }
-        return res;
-    }
-
-    function Locale(config) {
-        if (config != null) {
-            this.set(config);
-        }
-    }
-
-    var keys;
-
-    if (Object.keys) {
-        keys = Object.keys;
-    } else {
-        keys = function (obj) {
-            var i, res = [];
-            for (i in obj) {
-                if (hasOwnProp(obj, i)) {
-                    res.push(i);
-                }
-            }
-            return res;
-        };
-    }
-
-    var defaultCalendar = {
-        sameDay : '[Today at] LT',
-        nextDay : '[Tomorrow at] LT',
-        nextWeek : 'dddd [at] LT',
-        lastDay : '[Yesterday at] LT',
-        lastWeek : '[Last] dddd [at] LT',
-        sameElse : 'L'
-    };
-
-    function calendar (key, mom, now) {
-        var output = this._calendar[key] || this._calendar['sameElse'];
-        return isFunction(output) ? output.call(mom, now) : output;
-    }
-
-    var defaultLongDateFormat = {
-        LTS  : 'h:mm:ss A',
-        LT   : 'h:mm A',
-        L    : 'MM/DD/YYYY',
-        LL   : 'MMMM D, YYYY',
-        LLL  : 'MMMM D, YYYY h:mm A',
-        LLLL : 'dddd, MMMM D, YYYY h:mm A'
-    };
-
-    function longDateFormat (key) {
-        var format = this._longDateFormat[key],
-            formatUpper = this._longDateFormat[key.toUpperCase()];
-
-        if (format || !formatUpper) {
-            return format;
-        }
-
-        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
-            return val.slice(1);
-        });
-
-        return this._longDateFormat[key];
-    }
-
-    var defaultInvalidDate = 'Invalid date';
-
-    function invalidDate () {
-        return this._invalidDate;
-    }
-
-    var defaultOrdinal = '%d';
-    var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
-
-    function ordinal (number) {
-        return this._ordinal.replace('%d', number);
-    }
-
-    var defaultRelativeTime = {
-        future : 'in %s',
-        past   : '%s ago',
-        s  : 'a few seconds',
-        ss : '%d seconds',
-        m  : 'a minute',
-        mm : '%d minutes',
-        h  : 'an hour',
-        hh : '%d hours',
-        d  : 'a day',
-        dd : '%d days',
-        M  : 'a month',
-        MM : '%d months',
-        y  : 'a year',
-        yy : '%d years'
-    };
-
-    function relativeTime (number, withoutSuffix, string, isFuture) {
-        var output = this._relativeTime[string];
-        return (isFunction(output)) ?
-            output(number, withoutSuffix, string, isFuture) :
-            output.replace(/%d/i, number);
-    }
-
-    function pastFuture (diff, output) {
-        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
-        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
-    }
-
-    var aliases = {};
-
-    function addUnitAlias (unit, shorthand) {
-        var lowerCase = unit.toLowerCase();
-        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
-    }
-
-    function normalizeUnits(units) {
-        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
-    }
-
-    function normalizeObjectUnits(inputObject) {
-        var normalizedInput = {},
-            normalizedProp,
-            prop;
-
-        for (prop in inputObject) {
-            if (hasOwnProp(inputObject, prop)) {
-                normalizedProp = normalizeUnits(prop);
-                if (normalizedProp) {
-                    normalizedInput[normalizedProp] = inputObject[prop];
-                }
-            }
-        }
-
-        return normalizedInput;
-    }
-
-    var priorities = {};
-
-    function addUnitPriority(unit, priority) {
-        priorities[unit] = priority;
-    }
-
-    function getPrioritizedUnits(unitsObj) {
-        var units = [];
-        for (var u in unitsObj) {
-            units.push({unit: u, priority: priorities[u]});
-        }
-        units.sort(function (a, b) {
-            return a.priority - b.priority;
-        });
-        return units;
-    }
-
-    function zeroFill(number, targetLength, forceSign) {
-        var absNumber = '' + Math.abs(number),
-            zerosToFill = targetLength - absNumber.length,
-            sign = number >= 0;
-        return (sign ? (forceSign ? '+' : '') : '-') +
-            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
-    }
-
-    var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
-
-    var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
-
-    var formatFunctions = {};
-
-    var formatTokenFunctions = {};
-
-    // token:    'M'
-    // padded:   ['MM', 2]
-    // ordinal:  'Mo'
-    // callback: function () { this.month() + 1 }
-    function addFormatToken (token, padded, ordinal, callback) {
-        var func = callback;
-        if (typeof callback === 'string') {
-            func = function () {
-                return this[callback]();
-            };
-        }
-        if (token) {
-            formatTokenFunctions[token] = func;
-        }
-        if (padded) {
-            formatTokenFunctions[padded[0]] = function () {
-                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
-            };
-        }
-        if (ordinal) {
-            formatTokenFunctions[ordinal] = function () {
-                return this.localeData().ordinal(func.apply(this, arguments), token);
-            };
-        }
-    }
-
-    function removeFormattingTokens(input) {
-        if (input.match(/\[[\s\S]/)) {
-            return input.replace(/^\[|\]$/g, '');
-        }
-        return input.replace(/\\/g, '');
-    }
-
-    function makeFormatFunction(format) {
-        var array = format.match(formattingTokens), i, length;
-
-        for (i = 0, length = array.length; i < length; i++) {
-            if (formatTokenFunctions[array[i]]) {
-                array[i] = formatTokenFunctions[array[i]];
-            } else {
-                array[i] = removeFormattingTokens(array[i]);
-            }
-        }
-
-        return function (mom) {
-            var output = '', i;
-            for (i = 0; i < length; i++) {
-                output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
-            }
-            return output;
-        };
-    }
-
-    // format date using native date object
-    function formatMoment(m, format) {
-        if (!m.isValid()) {
-            return m.localeData().invalidDate();
-        }
-
-        format = expandFormat(format, m.localeData());
-        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
-
-        return formatFunctions[format](m);
-    }
-
-    function expandFormat(format, locale) {
-        var i = 5;
-
-        function replaceLongDateFormatTokens(input) {
-            return locale.longDateFormat(input) || input;
-        }
-
-        localFormattingTokens.lastIndex = 0;
-        while (i >= 0 && localFormattingTokens.test(format)) {
-            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
-            localFormattingTokens.lastIndex = 0;
-            i -= 1;
-        }
-
-        return format;
-    }
-
-    var match1         = /\d/;            //       0 - 9
-    var match2         = /\d\d/;          //      00 - 99
-    var match3         = /\d{3}/;         //     000 - 999
-    var match4         = /\d{4}/;         //    0000 - 9999
-    var match6         = /[+-]?\d{6}/;    // -999999 - 999999
-    var match1to2      = /\d\d?/;         //       0 - 99
-    var match3to4      = /\d\d\d\d?/;     //     999 - 9999
-    var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
-    var match1to3      = /\d{1,3}/;       //       0 - 999
-    var match1to4      = /\d{1,4}/;       //       0 - 9999
-    var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999
-
-    var matchUnsigned  = /\d+/;           //       0 - inf
-    var matchSigned    = /[+-]?\d+/;      //    -inf - inf
-
-    var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
-    var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
-
-    var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
-
-    // any word (or two) characters or numbers including two/three word month in arabic.
-    // includes scottish gaelic two word and hyphenated months
-    var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;
-
-    var regexes = {};
-
-    function addRegexToken (token, regex, strictRegex) {
-        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
-            return (isStrict && strictRegex) ? strictRegex : regex;
-        };
-    }
-
-    function getParseRegexForToken (token, config) {
-        if (!hasOwnProp(regexes, token)) {
-            return new RegExp(unescapeFormat(token));
-        }
-
-        return regexes[token](config._strict, config._locale);
-    }
-
-    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
-    function unescapeFormat(s) {
-        return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
-            return p1 || p2 || p3 || p4;
-        }));
-    }
-
-    function regexEscape(s) {
-        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
-    }
-
-    var tokens = {};
-
-    function addParseToken (token, callback) {
-        var i, func = callback;
-        if (typeof token === 'string') {
-            token = [token];
-        }
-        if (isNumber(callback)) {
-            func = function (input, array) {
-                array[callback] = toInt(input);
-            };
-        }
-        for (i = 0; i < token.length; i++) {
-            tokens[token[i]] = func;
-        }
-    }
-
-    function addWeekParseToken (token, callback) {
-        addParseToken(token, function (input, array, config, token) {
-            config._w = config._w || {};
-            callback(input, config._w, config, token);
-        });
-    }
-
-    function addTimeToArrayFromToken(token, input, config) {
-        if (input != null && hasOwnProp(tokens, token)) {
-            tokens[token](input, config._a, config, token);
-        }
-    }
-
-    var YEAR = 0;
-    var MONTH = 1;
-    var DATE = 2;
-    var HOUR = 3;
-    var MINUTE = 4;
-    var SECOND = 5;
-    var MILLISECOND = 6;
-    var WEEK = 7;
-    var WEEKDAY = 8;
-
-    // FORMATTING
-
-    addFormatToken('Y', 0, 0, function () {
-        var y = this.year();
-        return y <= 9999 ? '' + y : '+' + y;
-    });
-
-    addFormatToken(0, ['YY', 2], 0, function () {
-        return this.year() % 100;
-    });
-
-    addFormatToken(0, ['YYYY',   4],       0, 'year');
-    addFormatToken(0, ['YYYYY',  5],       0, 'year');
-    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
-
-    // ALIASES
-
-    addUnitAlias('year', 'y');
-
-    // PRIORITIES
-
-    addUnitPriority('year', 1);
-
-    // PARSING
-
-    addRegexToken('Y',      matchSigned);
-    addRegexToken('YY',     match1to2, match2);
-    addRegexToken('YYYY',   match1to4, match4);
-    addRegexToken('YYYYY',  match1to6, match6);
-    addRegexToken('YYYYYY', match1to6, match6);
-
-    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
-    addParseToken('YYYY', function (input, array) {
-        array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
-    });
-    addParseToken('YY', function (input, array) {
-        array[YEAR] = hooks.parseTwoDigitYear(input);
-    });
-    addParseToken('Y', function (input, array) {
-        array[YEAR] = parseInt(input, 10);
-    });
-
-    // HELPERS
-
-    function daysInYear(year) {
-        return isLeapYear(year) ? 366 : 365;
-    }
-
-    function isLeapYear(year) {
-        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
-    }
-
-    // HOOKS
-
-    hooks.parseTwoDigitYear = function (input) {
-        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
-    };
-
-    // MOMENTS
-
-    var getSetYear = makeGetSet('FullYear', true);
-
-    function getIsLeapYear () {
-        return isLeapYear(this.year());
-    }
-
-    function makeGetSet (unit, keepTime) {
-        return function (value) {
-            if (value != null) {
-                set$1(this, unit, value);
-                hooks.updateOffset(this, keepTime);
-                return this;
-            } else {
-                return get(this, unit);
-            }
-        };
-    }
-
-    function get (mom, unit) {
-        return mom.isValid() ?
-            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
-    }
-
-    function set$1 (mom, unit, value) {
-        if (mom.isValid() && !isNaN(value)) {
-            if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
-                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
-            }
-            else {
-                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
-            }
-        }
-    }
-
-    // MOMENTS
-
-    function stringGet (units) {
-        units = normalizeUnits(units);
-        if (isFunction(this[units])) {
-            return this[units]();
-        }
-        return this;
-    }
-
-
-    function stringSet (units, value) {
-        if (typeof units === 'object') {
-            units = normalizeObjectUnits(units);
-            var prioritized = getPrioritizedUnits(units);
-            for (var i = 0; i < prioritized.length; i++) {
-                this[prioritized[i].unit](units[prioritized[i].unit]);
-            }
-        } else {
-            units = normalizeUnits(units);
-            if (isFunction(this[units])) {
-                return this[units](value);
-            }
-        }
-        return this;
-    }
-
-    function mod(n, x) {
-        return ((n % x) + x) % x;
-    }
-
-    var indexOf;
-
-    if (Array.prototype.indexOf) {
-        indexOf = Array.prototype.indexOf;
-    } else {
-        indexOf = function (o) {
-            // I know
-            var i;
-            for (i = 0; i < this.length; ++i) {
-                if (this[i] === o) {
-                    return i;
-                }
-            }
-            return -1;
-        };
-    }
-
-    function daysInMonth(year, month) {
-        if (isNaN(year) || isNaN(month)) {
-            return NaN;
-        }
-        var modMonth = mod(month, 12);
-        year += (month - modMonth) / 12;
-        return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);
-    }
-
-    // FORMATTING
-
-    addFormatToken('M', ['MM', 2], 'Mo', function () {
-        return this.month() + 1;
-    });
-
-    addFormatToken('MMM', 0, 0, function (format) {
-        return this.localeData().monthsShort(this, format);
-    });
-
-    addFormatToken('MMMM', 0, 0, function (format) {
-        return this.localeData().months(this, format);
-    });
-
-    // ALIASES
-
-    addUnitAlias('month', 'M');
-
-    // PRIORITY
-
-    addUnitPriority('month', 8);
-
-    // PARSING
-
-    addRegexToken('M',    match1to2);
-    addRegexToken('MM',   match1to2, match2);
-    addRegexToken('MMM',  function (isStrict, locale) {
-        return locale.monthsShortRegex(isStrict);
-    });
-    addRegexToken('MMMM', function (isStrict, locale) {
-        return locale.monthsRegex(isStrict);
-    });
-
-    addParseToken(['M', 'MM'], function (input, array) {
-        array[MONTH] = toInt(input) - 1;
-    });
-
-    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
-        var month = config._locale.monthsParse(input, token, config._strict);
-        // if we didn't find a month name, mark the date as invalid.
-        if (month != null) {
-            array[MONTH] = month;
-        } else {
-            getParsingFlags(config).invalidMonth = input;
-        }
-    });
-
-    // LOCALES
-
-    var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
-    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
-    function localeMonths (m, format) {
-        if (!m) {
-            return isArray(this._months) ? this._months :
-                this._months['standalone'];
-        }
-        return isArray(this._months) ? this._months[m.month()] :
-            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
-    }
-
-    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
-    function localeMonthsShort (m, format) {
-        if (!m) {
-            return isArray(this._monthsShort) ? this._monthsShort :
-                this._monthsShort['standalone'];
-        }
-        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
-            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
-    }
-
-    function handleStrictParse(monthName, format, strict) {
-        var i, ii, mom, llc = monthName.toLocaleLowerCase();
-        if (!this._monthsParse) {
-            // this is not used
-            this._monthsParse = [];
-            this._longMonthsParse = [];
-            this._shortMonthsParse = [];
-            for (i = 0; i < 12; ++i) {
-                mom = createUTC([2000, i]);
-                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
-                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
-            }
-        }
-
-        if (strict) {
-            if (format === 'MMM') {
-                ii = indexOf.call(this._shortMonthsParse, llc);
-                return ii !== -1 ? ii : null;
-            } else {
-                ii = indexOf.call(this._longMonthsParse, llc);
-                return ii !== -1 ? ii : null;
-            }
-        } else {
-            if (format === 'MMM') {
-                ii = indexOf.call(this._shortMonthsParse, llc);
-                if (ii !== -1) {
-                    return ii;
-                }
-                ii = indexOf.call(this._longMonthsParse, llc);
-                return ii !== -1 ? ii : null;
-            } else {
-                ii = indexOf.call(this._longMonthsParse, llc);
-                if (ii !== -1) {
-                    return ii;
-                }
-                ii = indexOf.call(this._shortMonthsParse, llc);
-                return ii !== -1 ? ii : null;
-            }
-        }
-    }
-
-    function localeMonthsParse (monthName, format, strict) {
-        var i, mom, regex;
-
-        if (this._monthsParseExact) {
-            return handleStrictParse.call(this, monthName, format, strict);
-        }
-
-        if (!this._monthsParse) {
-            this._monthsParse = [];
-            this._longMonthsParse = [];
-            this._shortMonthsParse = [];
-        }
-
-        // TODO: add sorting
-        // Sorting makes sure if one month (or abbr) is a prefix of another
-        // see sorting in computeMonthsParse
-        for (i = 0; i < 12; i++) {
-            // make the regex if we don't have it already
-            mom = createUTC([2000, i]);
-            if (strict && !this._longMonthsParse[i]) {
-                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
-                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
-            }
-            if (!strict && !this._monthsParse[i]) {
-                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
-                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
-            }
-            // test the regex
-            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
-                return i;
-            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
-                return i;
-            } else if (!strict && this._monthsParse[i].test(monthName)) {
-                return i;
-            }
-        }
-    }
-
-    // MOMENTS
-
-    function setMonth (mom, value) {
-        var dayOfMonth;
-
-        if (!mom.isValid()) {
-            // No op
-            return mom;
-        }
-
-        if (typeof value === 'string') {
-            if (/^\d+$/.test(value)) {
-                value = toInt(value);
-            } else {
-                value = mom.localeData().monthsParse(value);
-                // TODO: Another silent failure?
-                if (!isNumber(value)) {
-                    return mom;
-                }
-            }
-        }
-
-        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
-        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
-        return mom;
-    }
-
-    function getSetMonth (value) {
-        if (value != null) {
-            setMonth(this, value);
-            hooks.updateOffset(this, true);
-            return this;
-        } else {
-            return get(this, 'Month');
-        }
-    }
-
-    function getDaysInMonth () {
-        return daysInMonth(this.year(), this.month());
-    }
-
-    var defaultMonthsShortRegex = matchWord;
-    function monthsShortRegex (isStrict) {
-        if (this._monthsParseExact) {
-            if (!hasOwnProp(this, '_monthsRegex')) {
-                computeMonthsParse.call(this);
-            }
-            if (isStrict) {
-                return this._monthsShortStrictRegex;
-            } else {
-                return this._monthsShortRegex;
-            }
-        } else {
-            if (!hasOwnProp(this, '_monthsShortRegex')) {
-                this._monthsShortRegex = defaultMonthsShortRegex;
-            }
-            return this._monthsShortStrictRegex && isStrict ?
-                this._monthsShortStrictRegex : this._monthsShortRegex;
-        }
-    }
-
-    var defaultMonthsRegex = matchWord;
-    function monthsRegex (isStrict) {
-        if (this._monthsParseExact) {
-            if (!hasOwnProp(this, '_monthsRegex')) {
-                computeMonthsParse.call(this);
-            }
-            if (isStrict) {
-                return this._monthsStrictRegex;
-            } else {
-                return this._monthsRegex;
-            }
-        } else {
-            if (!hasOwnProp(this, '_monthsRegex')) {
-                this._monthsRegex = defaultMonthsRegex;
-            }
-            return this._monthsStrictRegex && isStrict ?
-                this._monthsStrictRegex : this._monthsRegex;
-        }
-    }
-
-    function computeMonthsParse () {
-        function cmpLenRev(a, b) {
-            return b.length - a.length;
-        }
-
-        var shortPieces = [], longPieces = [], mixedPieces = [],
-            i, mom;
-        for (i = 0; i < 12; i++) {
-            // make the regex if we don't have it already
-            mom = createUTC([2000, i]);
-            shortPieces.push(this.monthsShort(mom, ''));
-            longPieces.push(this.months(mom, ''));
-            mixedPieces.push(this.months(mom, ''));
-            mixedPieces.push(this.monthsShort(mom, ''));
-        }
-        // Sorting makes sure if one month (or abbr) is a prefix of another it
-        // will match the longer piece.
-        shortPieces.sort(cmpLenRev);
-        longPieces.sort(cmpLenRev);
-        mixedPieces.sort(cmpLenRev);
-        for (i = 0; i < 12; i++) {
-            shortPieces[i] = regexEscape(shortPieces[i]);
-            longPieces[i] = regexEscape(longPieces[i]);
-        }
-        for (i = 0; i < 24; i++) {
-            mixedPieces[i] = regexEscape(mixedPieces[i]);
-        }
-
-        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
-        this._monthsShortRegex = this._monthsRegex;
-        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
-        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
-    }
-
-    function createDate (y, m, d, h, M, s, ms) {
-        // can't just apply() to create a date:
-        // https://stackoverflow.com/q/181348
-        var date;
-        // the date constructor remaps years 0-99 to 1900-1999
-        if (y < 100 && y >= 0) {
-            // preserve leap years using a full 400 year cycle, then reset
-            date = new Date(y + 400, m, d, h, M, s, ms);
-            if (isFinite(date.getFullYear())) {
-                date.setFullYear(y);
-            }
-        } else {
-            date = new Date(y, m, d, h, M, s, ms);
-        }
-
-        return date;
-    }
-
-    function createUTCDate (y) {
-        var date;
-        // the Date.UTC function remaps years 0-99 to 1900-1999
-        if (y < 100 && y >= 0) {
-            var args = Array.prototype.slice.call(arguments);
-            // preserve leap years using a full 400 year cycle, then reset
-            args[0] = y + 400;
-            date = new Date(Date.UTC.apply(null, args));
-            if (isFinite(date.getUTCFullYear())) {
-                date.setUTCFullYear(y);
-            }
-        } else {
-            date = new Date(Date.UTC.apply(null, arguments));
-        }
-
-        return date;
-    }
-
-    // start-of-first-week - start-of-year
-    function firstWeekOffset(year, dow, doy) {
-        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
-            fwd = 7 + dow - doy,
-            // first-week day local weekday -- which local weekday is fwd
-            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
-
-        return -fwdlw + fwd - 1;
-    }
-
-    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
-    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
-        var localWeekday = (7 + weekday - dow) % 7,
-            weekOffset = firstWeekOffset(year, dow, doy),
-            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
-            resYear, resDayOfYear;
-
-        if (dayOfYear <= 0) {
-            resYear = year - 1;
-            resDayOfYear = daysInYear(resYear) + dayOfYear;
-        } else if (dayOfYear > daysInYear(year)) {
-            resYear = year + 1;
-            resDayOfYear = dayOfYear - daysInYear(year);
-        } else {
-            resYear = year;
-            resDayOfYear = dayOfYear;
-        }
-
-        return {
-            year: resYear,
-            dayOfYear: resDayOfYear
-        };
-    }
-
-    function weekOfYear(mom, dow, doy) {
-        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
-            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
-            resWeek, resYear;
-
-        if (week < 1) {
-            resYear = mom.year() - 1;
-            resWeek = week + weeksInYear(resYear, dow, doy);
-        } else if (week > weeksInYear(mom.year(), dow, doy)) {
-            resWeek = week - weeksInYear(mom.year(), dow, doy);
-            resYear = mom.year() + 1;
-        } else {
-            resYear = mom.year();
-            resWeek = week;
-        }
-
-        return {
-            week: resWeek,
-            year: resYear
-        };
-    }
-
-    function weeksInYear(year, dow, doy) {
-        var weekOffset = firstWeekOffset(year, dow, doy),
-            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
-        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
-    }
-
-    // FORMATTING
-
-    addFormatToken('w', ['ww', 2], 'wo', 'week');
-    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
-
-    // ALIASES
-
-    addUnitAlias('week', 'w');
-    addUnitAlias('isoWeek', 'W');
-
-    // PRIORITIES
-
-    addUnitPriority('week', 5);
-    addUnitPriority('isoWeek', 5);
-
-    // PARSING
-
-    addRegexToken('w',  match1to2);
-    addRegexToken('ww', match1to2, match2);
-    addRegexToken('W',  match1to2);
-    addRegexToken('WW', match1to2, match2);
-
-    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
-        week[token.substr(0, 1)] = toInt(input);
-    });
-
-    // HELPERS
-
-    // LOCALES
-
-    function localeWeek (mom) {
-        return weekOfYear(mom, this._week.dow, this._week.doy).week;
-    }
-
-    var defaultLocaleWeek = {
-        dow : 0, // Sunday is the first day of the week.
-        doy : 6  // The week that contains Jan 6th is the first week of the year.
-    };
-
-    function localeFirstDayOfWeek () {
-        return this._week.dow;
-    }
-
-    function localeFirstDayOfYear () {
-        return this._week.doy;
-    }
-
-    // MOMENTS
-
-    function getSetWeek (input) {
-        var week = this.localeData().week(this);
-        return input == null ? week : this.add((input - week) * 7, 'd');
-    }
-
-    function getSetISOWeek (input) {
-        var week = weekOfYear(this, 1, 4).week;
-        return input == null ? week : this.add((input - week) * 7, 'd');
-    }
-
-    // FORMATTING
-
-    addFormatToken('d', 0, 'do', 'day');
-
-    addFormatToken('dd', 0, 0, function (format) {
-        return this.localeData().weekdaysMin(this, format);
-    });
-
-    addFormatToken('ddd', 0, 0, function (format) {
-        return this.localeData().weekdaysShort(this, format);
-    });
-
-    addFormatToken('dddd', 0, 0, function (format) {
-        return this.localeData().weekdays(this, format);
-    });
-
-    addFormatToken('e', 0, 0, 'weekday');
-    addFormatToken('E', 0, 0, 'isoWeekday');
-
-    // ALIASES
-
-    addUnitAlias('day', 'd');
-    addUnitAlias('weekday', 'e');
-    addUnitAlias('isoWeekday', 'E');
-
-    // PRIORITY
-    addUnitPriority('day', 11);
-    addUnitPriority('weekday', 11);
-    addUnitPriority('isoWeekday', 11);
-
-    // PARSING
-
-    addRegexToken('d',    match1to2);
-    addRegexToken('e',    match1to2);
-    addRegexToken('E',    match1to2);
-    addRegexToken('dd',   function (isStrict, locale) {
-        return locale.weekdaysMinRegex(isStrict);
-    });
-    addRegexToken('ddd',   function (isStrict, locale) {
-        return locale.weekdaysShortRegex(isStrict);
-    });
-    addRegexToken('dddd',   function (isStrict, locale) {
-        return locale.weekdaysRegex(isStrict);
-    });
-
-    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
-        var weekday = config._locale.weekdaysParse(input, token, config._strict);
-        // if we didn't get a weekday name, mark the date as invalid
-        if (weekday != null) {
-            week.d = weekday;
-        } else {
-            getParsingFlags(config).invalidWeekday = input;
-        }
-    });
-
-    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
-        week[token] = toInt(input);
-    });
-
-    // HELPERS
-
-    function parseWeekday(input, locale) {
-        if (typeof input !== 'string') {
-            return input;
-        }
-
-        if (!isNaN(input)) {
-            return parseInt(input, 10);
-        }
-
-        input = locale.weekdaysParse(input);
-        if (typeof input === 'number') {
-            return input;
-        }
-
-        return null;
-    }
-
-    function parseIsoWeekday(input, locale) {
-        if (typeof input === 'string') {
-            return locale.weekdaysParse(input) % 7 || 7;
-        }
-        return isNaN(input) ? null : input;
-    }
-
-    // LOCALES
-    function shiftWeekdays (ws, n) {
-        return ws.slice(n, 7).concat(ws.slice(0, n));
-    }
-
-    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
-    function localeWeekdays (m, format) {
-        var weekdays = isArray(this._weekdays) ? this._weekdays :
-            this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];
-        return (m === true) ? shiftWeekdays(weekdays, this._week.dow)
-            : (m) ? weekdays[m.day()] : weekdays;
-    }
-
-    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
-    function localeWeekdaysShort (m) {
-        return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)
-            : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
-    }
-
-    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
-    function localeWeekdaysMin (m) {
-        return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)
-            : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
-    }
-
-    function handleStrictParse$1(weekdayName, format, strict) {
-        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
-        if (!this._weekdaysParse) {
-            this._weekdaysParse = [];
-            this._shortWeekdaysParse = [];
-            this._minWeekdaysParse = [];
-
-            for (i = 0; i < 7; ++i) {
-                mom = createUTC([2000, 1]).day(i);
-                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
-                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
-                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
-            }
-        }
-
-        if (strict) {
-            if (format === 'dddd') {
-                ii = indexOf.call(this._weekdaysParse, llc);
-                return ii !== -1 ? ii : null;
-            } else if (format === 'ddd') {
-                ii = indexOf.call(this._shortWeekdaysParse, llc);
-                return ii !== -1 ? ii : null;
-            } else {
-                ii = indexOf.call(this._minWeekdaysParse, llc);
-                return ii !== -1 ? ii : null;
-            }
-        } else {
-            if (format === 'dddd') {
-                ii = indexOf.call(this._weekdaysParse, llc);
-                if (ii !== -1) {
-                    return ii;
-                }
-                ii = indexOf.call(this._shortWeekdaysParse, llc);
-                if (ii !== -1) {
-                    return ii;
-                }
-                ii = indexOf.call(this._minWeekdaysParse, llc);
-                return ii !== -1 ? ii : null;
-            } else if (format === 'ddd') {
-                ii = indexOf.call(this._shortWeekdaysParse, llc);
-                if (ii !== -1) {
-                    return ii;
-                }
-                ii = indexOf.call(this._weekdaysParse, llc);
-                if (ii !== -1) {
-                    return ii;
-                }
-                ii = indexOf.call(this._minWeekdaysParse, llc);
-                return ii !== -1 ? ii : null;
-            } else {
-                ii = indexOf.call(this._minWeekdaysParse, llc);
-                if (ii !== -1) {
-                    return ii;
-                }
-                ii = indexOf.call(this._weekdaysParse, llc);
-                if (ii !== -1) {
-                    return ii;
-                }
-                ii = indexOf.call(this._shortWeekdaysParse, llc);
-                return ii !== -1 ? ii : null;
-            }
-        }
-    }
-
-    function localeWeekdaysParse (weekdayName, format, strict) {
-        var i, mom, regex;
-
-        if (this._weekdaysParseExact) {
-            return handleStrictParse$1.call(this, weekdayName, format, strict);
-        }
-
-        if (!this._weekdaysParse) {
-            this._weekdaysParse = [];
-            this._minWeekdaysParse = [];
-            this._shortWeekdaysParse = [];
-            this._fullWeekdaysParse = [];
-        }
-
-        for (i = 0; i < 7; i++) {
-            // make the regex if we don't have it already
-
-            mom = createUTC([2000, 1]).day(i);
-            if (strict && !this._fullWeekdaysParse[i]) {
-                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
-                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
-                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
-            }
-            if (!this._weekdaysParse[i]) {
-                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
-                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
-            }
-            // test the regex
-            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
-                return i;
-            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
-                return i;
-            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
-                return i;
-            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
-                return i;
-            }
-        }
-    }
-
-    // MOMENTS
-
-    function getSetDayOfWeek (input) {
-        if (!this.isValid()) {
-            return input != null ? this : NaN;
-        }
-        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
-        if (input != null) {
-            input = parseWeekday(input, this.localeData());
-            return this.add(input - day, 'd');
-        } else {
-            return day;
-        }
-    }
-
-    function getSetLocaleDayOfWeek (input) {
-        if (!this.isValid()) {
-            return input != null ? this : NaN;
-        }
-        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
-        return input == null ? weekday : this.add(input - weekday, 'd');
-    }
-
-    function getSetISODayOfWeek (input) {
-        if (!this.isValid()) {
-            return input != null ? this : NaN;
-        }
-
-        // behaves the same as moment#day except
-        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
-        // as a setter, sunday should belong to the previous week.
-
-        if (input != null) {
-            var weekday = parseIsoWeekday(input, this.localeData());
-            return this.day(this.day() % 7 ? weekday : weekday - 7);
-        } else {
-            return this.day() || 7;
-        }
-    }
-
-    var defaultWeekdaysRegex = matchWord;
-    function weekdaysRegex (isStrict) {
-        if (this._weekdaysParseExact) {
-            if (!hasOwnProp(this, '_weekdaysRegex')) {
-                computeWeekdaysParse.call(this);
-            }
-            if (isStrict) {
-                return this._weekdaysStrictRegex;
-            } else {
-                return this._weekdaysRegex;
-            }
-        } else {
-            if (!hasOwnProp(this, '_weekdaysRegex')) {
-                this._weekdaysRegex = defaultWeekdaysRegex;
-            }
-            return this._weekdaysStrictRegex && isStrict ?
-                this._weekdaysStrictRegex : this._weekdaysRegex;
-        }
-    }
-
-    var defaultWeekdaysShortRegex = matchWord;
-    function weekdaysShortRegex (isStrict) {
-        if (this._weekdaysParseExact) {
-            if (!hasOwnProp(this, '_weekdaysRegex')) {
-                computeWeekdaysParse.call(this);
-            }
-            if (isStrict) {
-                return this._weekdaysShortStrictRegex;
-            } else {
-                return this._weekdaysShortRegex;
-            }
-        } else {
-            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
-                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
-            }
-            return this._weekdaysShortStrictRegex && isStrict ?
-                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
-        }
-    }
-
-    var defaultWeekdaysMinRegex = matchWord;
-    function weekdaysMinRegex (isStrict) {
-        if (this._weekdaysParseExact) {
-            if (!hasOwnProp(this, '_weekdaysRegex')) {
-                computeWeekdaysParse.call(this);
-            }
-            if (isStrict) {
-                return this._weekdaysMinStrictRegex;
-            } else {
-                return this._weekdaysMinRegex;
-            }
-        } else {
-            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
-                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
-            }
-            return this._weekdaysMinStrictRegex && isStrict ?
-                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
-        }
-    }
-
-
-    function computeWeekdaysParse () {
-        function cmpLenRev(a, b) {
-            return b.length - a.length;
-        }
-
-        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
-            i, mom, minp, shortp, longp;
-        for (i = 0; i < 7; i++) {
-            // make the regex if we don't have it already
-            mom = createUTC([2000, 1]).day(i);
-            minp = this.weekdaysMin(mom, '');
-            shortp = this.weekdaysShort(mom, '');
-            longp = this.weekdays(mom, '');
-            minPieces.push(minp);
-            shortPieces.push(shortp);
-            longPieces.push(longp);
-            mixedPieces.push(minp);
-            mixedPieces.push(shortp);
-            mixedPieces.push(longp);
-        }
-        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
-        // will match the longer piece.
-        minPieces.sort(cmpLenRev);
-        shortPieces.sort(cmpLenRev);
-        longPieces.sort(cmpLenRev);
-        mixedPieces.sort(cmpLenRev);
-        for (i = 0; i < 7; i++) {
-            shortPieces[i] = regexEscape(shortPieces[i]);
-            longPieces[i] = regexEscape(longPieces[i]);
-            mixedPieces[i] = regexEscape(mixedPieces[i]);
-        }
-
-        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
-        this._weekdaysShortRegex = this._weekdaysRegex;
-        this._weekdaysMinRegex = this._weekdaysRegex;
-
-        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
-        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
-        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
-    }
-
-    // FORMATTING
-
-    function hFormat() {
-        return this.hours() % 12 || 12;
-    }
-
-    function kFormat() {
-        return this.hours() || 24;
-    }
-
-    addFormatToken('H', ['HH', 2], 0, 'hour');
-    addFormatToken('h', ['hh', 2], 0, hFormat);
-    addFormatToken('k', ['kk', 2], 0, kFormat);
-
-    addFormatToken('hmm', 0, 0, function () {
-        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
-    });
-
-    addFormatToken('hmmss', 0, 0, function () {
-        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
-            zeroFill(this.seconds(), 2);
-    });
-
-    addFormatToken('Hmm', 0, 0, function () {
-        return '' + this.hours() + zeroFill(this.minutes(), 2);
-    });
-
-    addFormatToken('Hmmss', 0, 0, function () {
-        return '' + this.hours() + zeroFill(this.minutes(), 2) +
-            zeroFill(this.seconds(), 2);
-    });
-
-    function meridiem (token, lowercase) {
-        addFormatToken(token, 0, 0, function () {
-            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
-        });
-    }
-
-    meridiem('a', true);
-    meridiem('A', false);
-
-    // ALIASES
-
-    addUnitAlias('hour', 'h');
-
-    // PRIORITY
-    addUnitPriority('hour', 13);
-
-    // PARSING
-
-    function matchMeridiem (isStrict, locale) {
-        return locale._meridiemParse;
-    }
-
-    addRegexToken('a',  matchMeridiem);
-    addRegexToken('A',  matchMeridiem);
-    addRegexToken('H',  match1to2);
-    addRegexToken('h',  match1to2);
-    addRegexToken('k',  match1to2);
-    addRegexToken('HH', match1to2, match2);
-    addRegexToken('hh', match1to2, match2);
-    addRegexToken('kk', match1to2, match2);
-
-    addRegexToken('hmm', match3to4);
-    addRegexToken('hmmss', match5to6);
-    addRegexToken('Hmm', match3to4);
-    addRegexToken('Hmmss', match5to6);
-
-    addParseToken(['H', 'HH'], HOUR);
-    addParseToken(['k', 'kk'], function (input, array, config) {
-        var kInput = toInt(input);
-        array[HOUR] = kInput === 24 ? 0 : kInput;
-    });
-    addParseToken(['a', 'A'], function (input, array, config) {
-        config._isPm = config._locale.isPM(input);
-        config._meridiem = input;
-    });
-    addParseToken(['h', 'hh'], function (input, array, config) {
-        array[HOUR] = toInt(input);
-        getParsingFlags(config).bigHour = true;
-    });
-    addParseToken('hmm', function (input, array, config) {
-        var pos = input.length - 2;
-        array[HOUR] = toInt(input.substr(0, pos));
-        array[MINUTE] = toInt(input.substr(pos));
-        getParsingFlags(config).bigHour = true;
-    });
-    addParseToken('hmmss', function (input, array, config) {
-        var pos1 = input.length - 4;
-        var pos2 = input.length - 2;
-        array[HOUR] = toInt(input.substr(0, pos1));
-        array[MINUTE] = toInt(input.substr(pos1, 2));
-        array[SECOND] = toInt(input.substr(pos2));
-        getParsingFlags(config).bigHour = true;
-    });
-    addParseToken('Hmm', function (input, array, config) {
-        var pos = input.length - 2;
-        array[HOUR] = toInt(input.substr(0, pos));
-        array[MINUTE] = toInt(input.substr(pos));
-    });
-    addParseToken('Hmmss', function (input, array, config) {
-        var pos1 = input.length - 4;
-        var pos2 = input.length - 2;
-        array[HOUR] = toInt(input.substr(0, pos1));
-        array[MINUTE] = toInt(input.substr(pos1, 2));
-        array[SECOND] = toInt(input.substr(pos2));
-    });
-
-    // LOCALES
-
-    function localeIsPM (input) {
-        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
-        // Using charAt should be more compatible.
-        return ((input + '').toLowerCase().charAt(0) === 'p');
-    }
-
-    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
-    function localeMeridiem (hours, minutes, isLower) {
-        if (hours > 11) {
-            return isLower ? 'pm' : 'PM';
-        } else {
-            return isLower ? 'am' : 'AM';
-        }
-    }
-
-
-    // MOMENTS
-
-    // Setting the hour should keep the time, because the user explicitly
-    // specified which hour they want. So trying to maintain the same hour (in
-    // a new timezone) makes sense. Adding/subtracting hours does not follow
-    // this rule.
-    var getSetHour = makeGetSet('Hours', true);
-
-    var baseConfig = {
-        calendar: defaultCalendar,
-        longDateFormat: defaultLongDateFormat,
-        invalidDate: defaultInvalidDate,
-        ordinal: defaultOrdinal,
-        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
-        relativeTime: defaultRelativeTime,
-
-        months: defaultLocaleMonths,
-        monthsShort: defaultLocaleMonthsShort,
-
-        week: defaultLocaleWeek,
-
-        weekdays: defaultLocaleWeekdays,
-        weekdaysMin: defaultLocaleWeekdaysMin,
-        weekdaysShort: defaultLocaleWeekdaysShort,
-
-        meridiemParse: defaultLocaleMeridiemParse
-    };
-
-    // internal storage for locale config files
-    var locales = {};
-    var localeFamilies = {};
-    var globalLocale;
-
-    function normalizeLocale(key) {
-        return key ? key.toLowerCase().replace('_', '-') : key;
-    }
-
-    // pick the locale from the array
-    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
-    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
-    function chooseLocale(names) {
-        var i = 0, j, next, locale, split;
-
-        while (i < names.length) {
-            split = normalizeLocale(names[i]).split('-');
-            j = split.length;
-            next = normalizeLocale(names[i + 1]);
-            next = next ? next.split('-') : null;
-            while (j > 0) {
-                locale = loadLocale(split.slice(0, j).join('-'));
-                if (locale) {
-                    return locale;
-                }
-                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
-                    //the next array item is better than a shallower substring of this one
-                    break;
-                }
-                j--;
-            }
-            i++;
-        }
-        return globalLocale;
-    }
-
-    function loadLocale(name) {
-        var oldLocale = null;
-        // TODO: Find a better way to register and load all the locales in Node
-        if (!locales[name] && (typeof module !== 'undefined') &&
-                module && module.exports) {
-            try {
-                oldLocale = globalLocale._abbr;
-                var aliasedRequire = require;
-                aliasedRequire('./locale/' + name);
-                getSetGlobalLocale(oldLocale);
-            } catch (e) {}
-        }
-        return locales[name];
-    }
-
-    // This function will load locale and then set the global locale.  If
-    // no arguments are passed in, it will simply return the current global
-    // locale key.
-    function getSetGlobalLocale (key, values) {
-        var data;
-        if (key) {
-            if (isUndefined(values)) {
-                data = getLocale(key);
-            }
-            else {
-                data = defineLocale(key, values);
-            }
-
-            if (data) {
-                // moment.duration._locale = moment._locale = data;
-                globalLocale = data;
-            }
-            else {
-                if ((typeof console !==  'undefined') && console.warn) {
-                    //warn user if arguments are passed but the locale could not be set
-                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
-                }
-            }
-        }
-
-        return globalLocale._abbr;
-    }
-
-    function defineLocale (name, config) {
-        if (config !== null) {
-            var locale, parentConfig = baseConfig;
-            config.abbr = name;
-            if (locales[name] != null) {
-                deprecateSimple('defineLocaleOverride',
-                        'use moment.updateLocale(localeName, config) to change ' +
-                        'an existing locale. moment.defineLocale(localeName, ' +
-                        'config) should only be used for creating a new locale ' +
-                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
-                parentConfig = locales[name]._config;
-            } else if (config.parentLocale != null) {
-                if (locales[config.parentLocale] != null) {
-                    parentConfig = locales[config.parentLocale]._config;
-                } else {
-                    locale = loadLocale(config.parentLocale);
-                    if (locale != null) {
-                        parentConfig = locale._config;
-                    } else {
-                        if (!localeFamilies[config.parentLocale]) {
-                            localeFamilies[config.parentLocale] = [];
-                        }
-                        localeFamilies[config.parentLocale].push({
-                            name: name,
-                            config: config
-                        });
-                        return null;
-                    }
-                }
-            }
-            locales[name] = new Locale(mergeConfigs(parentConfig, config));
-
-            if (localeFamilies[name]) {
-                localeFamilies[name].forEach(function (x) {
-                    defineLocale(x.name, x.config);
-                });
-            }
-
-            // backwards compat for now: also set the locale
-            // make sure we set the locale AFTER all child locales have been
-            // created, so we won't end up with the child locale set.
-            getSetGlobalLocale(name);
-
-
-            return locales[name];
-        } else {
-            // useful for testing
-            delete locales[name];
-            return null;
-        }
-    }
-
-    function updateLocale(name, config) {
-        if (config != null) {
-            var locale, tmpLocale, parentConfig = baseConfig;
-            // MERGE
-            tmpLocale = loadLocale(name);
-            if (tmpLocale != null) {
-                parentConfig = tmpLocale._config;
-            }
-            config = mergeConfigs(parentConfig, config);
-            locale = new Locale(config);
-            locale.parentLocale = locales[name];
-            locales[name] = locale;
-
-            // backwards compat for now: also set the locale
-            getSetGlobalLocale(name);
-        } else {
-            // pass null for config to unupdate, useful for tests
-            if (locales[name] != null) {
-                if (locales[name].parentLocale != null) {
-                    locales[name] = locales[name].parentLocale;
-                } else if (locales[name] != null) {
-                    delete locales[name];
-                }
-            }
-        }
-        return locales[name];
-    }
-
-    // returns locale data
-    function getLocale (key) {
-        var locale;
-
-        if (key && key._locale && key._locale._abbr) {
-            key = key._locale._abbr;
-        }
-
-        if (!key) {
-            return globalLocale;
-        }
-
-        if (!isArray(key)) {
-            //short-circuit everything else
-            locale = loadLocale(key);
-            if (locale) {
-                return locale;
-            }
-            key = [key];
-        }
-
-        return chooseLocale(key);
-    }
-
-    function listLocales() {
-        return keys(locales);
-    }
-
-    function checkOverflow (m) {
-        var overflow;
-        var a = m._a;
-
-        if (a && getParsingFlags(m).overflow === -2) {
-            overflow =
-                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
-                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
-                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
-                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
-                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
-                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
-                -1;
-
-            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
-                overflow = DATE;
-            }
-            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
-                overflow = WEEK;
-            }
-            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
-                overflow = WEEKDAY;
-            }
-
-            getParsingFlags(m).overflow = overflow;
-        }
-
-        return m;
-    }
-
-    // Pick the first defined of two or three arguments.
-    function defaults(a, b, c) {
-        if (a != null) {
-            return a;
-        }
-        if (b != null) {
-            return b;
-        }
-        return c;
-    }
-
-    function currentDateArray(config) {
-        // hooks is actually the exported moment object
-        var nowValue = new Date(hooks.now());
-        if (config._useUTC) {
-            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
-        }
-        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
-    }
-
-    // convert an array to a date.
-    // the array should mirror the parameters below
-    // note: all values past the year are optional and will default to the lowest possible value.
-    // [year, month, day , hour, minute, second, millisecond]
-    function configFromArray (config) {
-        var i, date, input = [], currentDate, expectedWeekday, yearToUse;
-
-        if (config._d) {
-            return;
-        }
-
-        currentDate = currentDateArray(config);
-
-        //compute day of the year from weeks and weekdays
-        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
-            dayOfYearFromWeekInfo(config);
-        }
-
-        //if the day of the year is set, figure out what it is
-        if (config._dayOfYear != null) {
-            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
-
-            if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
-                getParsingFlags(config)._overflowDayOfYear = true;
-            }
-
-            date = createUTCDate(yearToUse, 0, config._dayOfYear);
-            config._a[MONTH] = date.getUTCMonth();
-            config._a[DATE] = date.getUTCDate();
-        }
-
-        // Default to current date.
-        // * if no year, month, day of month are given, default to today
-        // * if day of month is given, default month and year
-        // * if month is given, default only year
-        // * if year is given, don't default anything
-        for (i = 0; i < 3 && config._a[i] == null; ++i) {
-            config._a[i] = input[i] = currentDate[i];
-        }
-
-        // Zero out whatever was not defaulted, including time
-        for (; i < 7; i++) {
-            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
-        }
-
-        // Check for 24:00:00.000
-        if (config._a[HOUR] === 24 &&
-                config._a[MINUTE] === 0 &&
-                config._a[SECOND] === 0 &&
-                config._a[MILLISECOND] === 0) {
-            config._nextDay = true;
-            config._a[HOUR] = 0;
-        }
-
-        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
-        expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();
-
-        // Apply timezone offset from input. The actual utcOffset can be changed
-        // with parseZone.
-        if (config._tzm != null) {
-            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
-        }
-
-        if (config._nextDay) {
-            config._a[HOUR] = 24;
-        }
-
-        // check for mismatching day of week
-        if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
-            getParsingFlags(config).weekdayMismatch = true;
-        }
-    }
-
-    function dayOfYearFromWeekInfo(config) {
-        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
-
-        w = config._w;
-        if (w.GG != null || w.W != null || w.E != null) {
-            dow = 1;
-            doy = 4;
-
-            // TODO: We need to take the current isoWeekYear, but that depends on
-            // how we interpret now (local, utc, fixed offset). So create
-            // a now version of current config (take local/utc/offset flags, and
-            // create now).
-            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
-            week = defaults(w.W, 1);
-            weekday = defaults(w.E, 1);
-            if (weekday < 1 || weekday > 7) {
-                weekdayOverflow = true;
-            }
-        } else {
-            dow = config._locale._week.dow;
-            doy = config._locale._week.doy;
-
-            var curWeek = weekOfYear(createLocal(), dow, doy);
-
-            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
-
-            // Default to current week.
-            week = defaults(w.w, curWeek.week);
-
-            if (w.d != null) {
-                // weekday -- low day numbers are considered next week
-                weekday = w.d;
-                if (weekday < 0 || weekday > 6) {
-                    weekdayOverflow = true;
-                }
-            } else if (w.e != null) {
-                // local weekday -- counting starts from beginning of week
-                weekday = w.e + dow;
-                if (w.e < 0 || w.e > 6) {
-                    weekdayOverflow = true;
-                }
-            } else {
-                // default to beginning of week
-                weekday = dow;
-            }
-        }
-        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
-            getParsingFlags(config)._overflowWeeks = true;
-        } else if (weekdayOverflow != null) {
-            getParsingFlags(config)._overflowWeekday = true;
-        } else {
-            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
-            config._a[YEAR] = temp.year;
-            config._dayOfYear = temp.dayOfYear;
-        }
-    }
-
-    // iso 8601 regex
-    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
-    var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
-    var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
-
-    var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
-
-    var isoDates = [
-        ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
-        ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
-        ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
-        ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
-        ['YYYY-DDD', /\d{4}-\d{3}/],
-        ['YYYY-MM', /\d{4}-\d\d/, false],
-        ['YYYYYYMMDD', /[+-]\d{10}/],
-        ['YYYYMMDD', /\d{8}/],
-        // YYYYMM is NOT allowed by the standard
-        ['GGGG[W]WWE', /\d{4}W\d{3}/],
-        ['GGGG[W]WW', /\d{4}W\d{2}/, false],
-        ['YYYYDDD', /\d{7}/]
-    ];
-
-    // iso time formats and regexes
-    var isoTimes = [
-        ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
-        ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
-        ['HH:mm:ss', /\d\d:\d\d:\d\d/],
-        ['HH:mm', /\d\d:\d\d/],
-        ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
-        ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
-        ['HHmmss', /\d\d\d\d\d\d/],
-        ['HHmm', /\d\d\d\d/],
-        ['HH', /\d\d/]
-    ];
-
-    var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
-
-    // date from iso format
-    function configFromISO(config) {
-        var i, l,
-            string = config._i,
-            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
-            allowTime, dateFormat, timeFormat, tzFormat;
-
-        if (match) {
-            getParsingFlags(config).iso = true;
-
-            for (i = 0, l = isoDates.length; i < l; i++) {
-                if (isoDates[i][1].exec(match[1])) {
-                    dateFormat = isoDates[i][0];
-                    allowTime = isoDates[i][2] !== false;
-                    break;
-                }
-            }
-            if (dateFormat == null) {
-                config._isValid = false;
-                return;
-            }
-            if (match[3]) {
-                for (i = 0, l = isoTimes.length; i < l; i++) {
-                    if (isoTimes[i][1].exec(match[3])) {
-                        // match[2] should be 'T' or space
-                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
-                        break;
-                    }
-                }
-                if (timeFormat == null) {
-                    config._isValid = false;
-                    return;
-                }
-            }
-            if (!allowTime && timeFormat != null) {
-                config._isValid = false;
-                return;
-            }
-            if (match[4]) {
-                if (tzRegex.exec(match[4])) {
-                    tzFormat = 'Z';
-                } else {
-                    config._isValid = false;
-                    return;
-                }
-            }
-            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
-            configFromStringAndFormat(config);
-        } else {
-            config._isValid = false;
-        }
-    }
-
-    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
-    var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;
-
-    function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
-        var result = [
-            untruncateYear(yearStr),
-            defaultLocaleMonthsShort.indexOf(monthStr),
-            parseInt(dayStr, 10),
-            parseInt(hourStr, 10),
-            parseInt(minuteStr, 10)
-        ];
-
-        if (secondStr) {
-            result.push(parseInt(secondStr, 10));
-        }
-
-        return result;
-    }
-
-    function untruncateYear(yearStr) {
-        var year = parseInt(yearStr, 10);
-        if (year <= 49) {
-            return 2000 + year;
-        } else if (year <= 999) {
-            return 1900 + year;
-        }
-        return year;
-    }
-
-    function preprocessRFC2822(s) {
-        // Remove comments and folding whitespace and replace multiple-spaces with a single space
-        return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
-    }
-
-    function checkWeekday(weekdayStr, parsedInput, config) {
-        if (weekdayStr) {
-            // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
-            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
-                weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
-            if (weekdayProvided !== weekdayActual) {
-                getParsingFlags(config).weekdayMismatch = true;
-                config._isValid = false;
-                return false;
-            }
-        }
-        return true;
-    }
-
-    var obsOffsets = {
-        UT: 0,
-        GMT: 0,
-        EDT: -4 * 60,
-        EST: -5 * 60,
-        CDT: -5 * 60,
-        CST: -6 * 60,
-        MDT: -6 * 60,
-        MST: -7 * 60,
-        PDT: -7 * 60,
-        PST: -8 * 60
-    };
-
-    function calculateOffset(obsOffset, militaryOffset, numOffset) {
-        if (obsOffset) {
-            return obsOffsets[obsOffset];
-        } else if (militaryOffset) {
-            // the only allowed military tz is Z
-            return 0;
-        } else {
-            var hm = parseInt(numOffset, 10);
-            var m = hm % 100, h = (hm - m) / 100;
-            return h * 60 + m;
-        }
-    }
-
-    // date and time from ref 2822 format
-    function configFromRFC2822(config) {
-        var match = rfc2822.exec(preprocessRFC2822(config._i));
-        if (match) {
-            var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
-            if (!checkWeekday(match[1], parsedArray, config)) {
-                return;
-            }
-
-            config._a = parsedArray;
-            config._tzm = calculateOffset(match[8], match[9], match[10]);
-
-            config._d = createUTCDate.apply(null, config._a);
-            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
-
-            getParsingFlags(config).rfc2822 = true;
-        } else {
-            config._isValid = false;
-        }
-    }
-
-    // date from iso format or fallback
-    function configFromString(config) {
-        var matched = aspNetJsonRegex.exec(config._i);
-
-        if (matched !== null) {
-            config._d = new Date(+matched[1]);
-            return;
-        }
-
-        configFromISO(config);
-        if (config._isValid === false) {
-            delete config._isValid;
-        } else {
-            return;
-        }
-
-        configFromRFC2822(config);
-        if (config._isValid === false) {
-            delete config._isValid;
-        } else {
-            return;
-        }
-
-        // Final attempt, use Input Fallback
-        hooks.createFromInputFallback(config);
-    }
-
-    hooks.createFromInputFallback = deprecate(
-        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
-        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
-        'discouraged and will be removed in an upcoming major release. Please refer to ' +
-        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
-        function (config) {
-            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
-        }
-    );
-
-    // constant that refers to the ISO standard
-    hooks.ISO_8601 = function () {};
-
-    // constant that refers to the RFC 2822 form
-    hooks.RFC_2822 = function () {};
-
-    // date from string and format string
-    function configFromStringAndFormat(config) {
-        // TODO: Move this to another part of the creation flow to prevent circular deps
-        if (config._f === hooks.ISO_8601) {
-            configFromISO(config);
-            return;
-        }
-        if (config._f === hooks.RFC_2822) {
-            configFromRFC2822(config);
-            return;
-        }
-        config._a = [];
-        getParsingFlags(config).empty = true;
-
-        // This array is used to make a Date, either with `new Date` or `Date.UTC`
-        var string = '' + config._i,
-            i, parsedInput, tokens, token, skipped,
-            stringLength = string.length,
-            totalParsedInputLength = 0;
-
-        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
-
-        for (i = 0; i < tokens.length; i++) {
-            token = tokens[i];
-            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
-            // console.log('token', token, 'parsedInput', parsedInput,
-            //         'regex', getParseRegexForToken(token, config));
-            if (parsedInput) {
-                skipped = string.substr(0, string.indexOf(parsedInput));
-                if (skipped.length > 0) {
-                    getParsingFlags(config).unusedInput.push(skipped);
-                }
-                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
-                totalParsedInputLength += parsedInput.length;
-            }
-            // don't parse if it's not a known token
-            if (formatTokenFunctions[token]) {
-                if (parsedInput) {
-                    getParsingFlags(config).empty = false;
-                }
-                else {
-                    getParsingFlags(config).unusedTokens.push(token);
-                }
-                addTimeToArrayFromToken(token, parsedInput, config);
-            }
-            else if (config._strict && !parsedInput) {
-                getParsingFlags(config).unusedTokens.push(token);
-            }
-        }
-
-        // add remaining unparsed input length to the string
-        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
-        if (string.length > 0) {
-            getParsingFlags(config).unusedInput.push(string);
-        }
-
-        // clear _12h flag if hour is <= 12
-        if (config._a[HOUR] <= 12 &&
-            getParsingFlags(config).bigHour === true &&
-            config._a[HOUR] > 0) {
-            getParsingFlags(config).bigHour = undefined;
-        }
-
-        getParsingFlags(config).parsedDateParts = config._a.slice(0);
-        getParsingFlags(config).meridiem = config._meridiem;
-        // handle meridiem
-        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
-
-        configFromArray(config);
-        checkOverflow(config);
-    }
-
-
-    function meridiemFixWrap (locale, hour, meridiem) {
-        var isPm;
-
-        if (meridiem == null) {
-            // nothing to do
-            return hour;
-        }
-        if (locale.meridiemHour != null) {
-            return locale.meridiemHour(hour, meridiem);
-        } else if (locale.isPM != null) {
-            // Fallback
-            isPm = locale.isPM(meridiem);
-            if (isPm && hour < 12) {
-                hour += 12;
-            }
-            if (!isPm && hour === 12) {
-                hour = 0;
-            }
-            return hour;
-        } else {
-            // this is not supposed to happen
-            return hour;
-        }
-    }
-
-    // date from string and array of format strings
-    function configFromStringAndArray(config) {
-        var tempConfig,
-            bestMoment,
-
-            scoreToBeat,
-            i,
-            currentScore;
-
-        if (config._f.length === 0) {
-            getParsingFlags(config).invalidFormat = true;
-            config._d = new Date(NaN);
-            return;
-        }
-
-        for (i = 0; i < config._f.length; i++) {
-            currentScore = 0;
-            tempConfig = copyConfig({}, config);
-            if (config._useUTC != null) {
-                tempConfig._useUTC = config._useUTC;
-            }
-            tempConfig._f = config._f[i];
-            configFromStringAndFormat(tempConfig);
-
-            if (!isValid(tempConfig)) {
-                continue;
-            }
-
-            // if there is any input that was not parsed add a penalty for that format
-            currentScore += getParsingFlags(tempConfig).charsLeftOver;
-
-            //or tokens
-            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
-
-            getParsingFlags(tempConfig).score = currentScore;
-
-            if (scoreToBeat == null || currentScore < scoreToBeat) {
-                scoreToBeat = currentScore;
-                bestMoment = tempConfig;
-            }
-        }
-
-        extend(config, bestMoment || tempConfig);
-    }
-
-    function configFromObject(config) {
-        if (config._d) {
-            return;
-        }
-
-        var i = normalizeObjectUnits(config._i);
-        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
-            return obj && parseInt(obj, 10);
-        });
-
-        configFromArray(config);
-    }
-
-    function createFromConfig (config) {
-        var res = new Moment(checkOverflow(prepareConfig(config)));
-        if (res._nextDay) {
-            // Adding is smart enough around DST
-            res.add(1, 'd');
-            res._nextDay = undefined;
-        }
-
-        return res;
-    }
-
-    function prepareConfig (config) {
-        var input = config._i,
-            format = config._f;
-
-        config._locale = config._locale || getLocale(config._l);
-
-        if (input === null || (format === undefined && input === '')) {
-            return createInvalid({nullInput: true});
-        }
-
-        if (typeof input === 'string') {
-            config._i = input = config._locale.preparse(input);
-        }
-
-        if (isMoment(input)) {
-            return new Moment(checkOverflow(input));
-        } else if (isDate(input)) {
-            config._d = input;
-        } else if (isArray(format)) {
-            configFromStringAndArray(config);
-        } else if (format) {
-            configFromStringAndFormat(config);
-        }  else {
-            configFromInput(config);
-        }
-
-        if (!isValid(config)) {
-            config._d = null;
-        }
-
-        return config;
-    }
-
-    function configFromInput(config) {
-        var input = config._i;
-        if (isUndefined(input)) {
-            config._d = new Date(hooks.now());
-        } else if (isDate(input)) {
-            config._d = new Date(input.valueOf());
-        } else if (typeof input === 'string') {
-            configFromString(config);
-        } else if (isArray(input)) {
-            config._a = map(input.slice(0), function (obj) {
-                return parseInt(obj, 10);
-            });
-            configFromArray(config);
-        } else if (isObject(input)) {
-            configFromObject(config);
-        } else if (isNumber(input)) {
-            // from milliseconds
-            config._d = new Date(input);
-        } else {
-            hooks.createFromInputFallback(config);
-        }
-    }
-
-    function createLocalOrUTC (input, format, locale, strict, isUTC) {
-        var c = {};
-
-        if (locale === true || locale === false) {
-            strict = locale;
-            locale = undefined;
-        }
-
-        if ((isObject(input) && isObjectEmpty(input)) ||
-                (isArray(input) && input.length === 0)) {
-            input = undefined;
-        }
-        // object construction must be done this way.
-        // https://github.com/moment/moment/issues/1423
-        c._isAMomentObject = true;
-        c._useUTC = c._isUTC = isUTC;
-        c._l = locale;
-        c._i = input;
-        c._f = format;
-        c._strict = strict;
-
-        return createFromConfig(c);
-    }
-
-    function createLocal (input, format, locale, strict) {
-        return createLocalOrUTC(input, format, locale, strict, false);
-    }
-
-    var prototypeMin = deprecate(
-        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
-        function () {
-            var other = createLocal.apply(null, arguments);
-            if (this.isValid() && other.isValid()) {
-                return other < this ? this : other;
-            } else {
-                return createInvalid();
-            }
-        }
-    );
-
-    var prototypeMax = deprecate(
-        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
-        function () {
-            var other = createLocal.apply(null, arguments);
-            if (this.isValid() && other.isValid()) {
-                return other > this ? this : other;
-            } else {
-                return createInvalid();
-            }
-        }
-    );
-
-    // Pick a moment m from moments so that m[fn](other) is true for all
-    // other. This relies on the function fn to be transitive.
-    //
-    // moments should either be an array of moment objects or an array, whose
-    // first element is an array of moment objects.
-    function pickBy(fn, moments) {
-        var res, i;
-        if (moments.length === 1 && isArray(moments[0])) {
-            moments = moments[0];
-        }
-        if (!moments.length) {
-            return createLocal();
-        }
-        res = moments[0];
-        for (i = 1; i < moments.length; ++i) {
-            if (!moments[i].isValid() || moments[i][fn](res)) {
-                res = moments[i];
-            }
-        }
-        return res;
-    }
-
-    // TODO: Use [].sort instead?
-    function min () {
-        var args = [].slice.call(arguments, 0);
-
-        return pickBy('isBefore', args);
-    }
-
-    function max () {
-        var args = [].slice.call(arguments, 0);
-
-        return pickBy('isAfter', args);
-    }
-
-    var now = function () {
-        return Date.now ? Date.now() : +(new Date());
-    };
-
-    var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
-
-    function isDurationValid(m) {
-        for (var key in m) {
-            if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
-                return false;
-            }
-        }
-
-        var unitHasDecimal = false;
-        for (var i = 0; i < ordering.length; ++i) {
-            if (m[ordering[i]]) {
-                if (unitHasDecimal) {
-                    return false; // only allow non-integers for smallest unit
-                }
-                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
-                    unitHasDecimal = true;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    function isValid$1() {
-        return this._isValid;
-    }
-
-    function createInvalid$1() {
-        return createDuration(NaN);
-    }
-
-    function Duration (duration) {
-        var normalizedInput = normalizeObjectUnits(duration),
-            years = normalizedInput.year || 0,
-            quarters = normalizedInput.quarter || 0,
-            months = normalizedInput.month || 0,
-            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
-            days = normalizedInput.day || 0,
-            hours = normalizedInput.hour || 0,
-            minutes = normalizedInput.minute || 0,
-            seconds = normalizedInput.second || 0,
-            milliseconds = normalizedInput.millisecond || 0;
-
-        this._isValid = isDurationValid(normalizedInput);
-
-        // representation for dateAddRemove
-        this._milliseconds = +milliseconds +
-            seconds * 1e3 + // 1000
-            minutes * 6e4 + // 1000 * 60
-            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
-        // Because of dateAddRemove treats 24 hours as different from a
-        // day when working around DST, we need to store them separately
-        this._days = +days +
-            weeks * 7;
-        // It is impossible to translate months into days without knowing
-        // which months you are are talking about, so we have to store
-        // it separately.
-        this._months = +months +
-            quarters * 3 +
-            years * 12;
-
-        this._data = {};
-
-        this._locale = getLocale();
-
-        this._bubble();
-    }
-
-    function isDuration (obj) {
-        return obj instanceof Duration;
-    }
-
-    function absRound (number) {
-        if (number < 0) {
-            return Math.round(-1 * number) * -1;
-        } else {
-            return Math.round(number);
-        }
-    }
-
-    // FORMATTING
-
-    function offset (token, separator) {
-        addFormatToken(token, 0, 0, function () {
-            var offset = this.utcOffset();
-            var sign = '+';
-            if (offset < 0) {
-                offset = -offset;
-                sign = '-';
-            }
-            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
-        });
-    }
-
-    offset('Z', ':');
-    offset('ZZ', '');
-
-    // PARSING
-
-    addRegexToken('Z',  matchShortOffset);
-    addRegexToken('ZZ', matchShortOffset);
-    addParseToken(['Z', 'ZZ'], function (input, array, config) {
-        config._useUTC = true;
-        config._tzm = offsetFromString(matchShortOffset, input);
-    });
-
-    // HELPERS
-
-    // timezone chunker
-    // '+10:00' > ['10',  '00']
-    // '-1530'  > ['-15', '30']
-    var chunkOffset = /([\+\-]|\d\d)/gi;
-
-    function offsetFromString(matcher, string) {
-        var matches = (string || '').match(matcher);
-
-        if (matches === null) {
-            return null;
-        }
-
-        var chunk   = matches[matches.length - 1] || [];
-        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
-        var minutes = +(parts[1] * 60) + toInt(parts[2]);
-
-        return minutes === 0 ?
-          0 :
-          parts[0] === '+' ? minutes : -minutes;
-    }
-
-    // Return a moment from input, that is local/utc/zone equivalent to model.
-    function cloneWithOffset(input, model) {
-        var res, diff;
-        if (model._isUTC) {
-            res = model.clone();
-            diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
-            // Use low-level api, because this fn is low-level api.
-            res._d.setTime(res._d.valueOf() + diff);
-            hooks.updateOffset(res, false);
-            return res;
-        } else {
-            return createLocal(input).local();
-        }
-    }
-
-    function getDateOffset (m) {
-        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
-        // https://github.com/moment/moment/pull/1871
-        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
-    }
-
-    // HOOKS
-
-    // This function will be called whenever a moment is mutated.
-    // It is intended to keep the offset in sync with the timezone.
-    hooks.updateOffset = function () {};
-
-    // MOMENTS
-
-    // keepLocalTime = true means only change the timezone, without
-    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
-    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
-    // +0200, so we adjust the time as needed, to be valid.
-    //
-    // Keeping the time actually adds/subtracts (one hour)
-    // from the actual represented time. That is why we call updateOffset
-    // a second time. In case it wants us to change the offset again
-    // _changeInProgress == true case, then we have to adjust, because
-    // there is no such time in the given timezone.
-    function getSetOffset (input, keepLocalTime, keepMinutes) {
-        var offset = this._offset || 0,
-            localAdjust;
-        if (!this.isValid()) {
-            return input != null ? this : NaN;
-        }
-        if (input != null) {
-            if (typeof input === 'string') {
-                input = offsetFromString(matchShortOffset, input);
-                if (input === null) {
-                    return this;
-                }
-            } else if (Math.abs(input) < 16 && !keepMinutes) {
-                input = input * 60;
-            }
-            if (!this._isUTC && keepLocalTime) {
-                localAdjust = getDateOffset(this);
-            }
-            this._offset = input;
-            this._isUTC = true;
-            if (localAdjust != null) {
-                this.add(localAdjust, 'm');
-            }
-            if (offset !== input) {
-                if (!keepLocalTime || this._changeInProgress) {
-                    addSubtract(this, createDuration(input - offset, 'm'), 1, false);
-                } else if (!this._changeInProgress) {
-                    this._changeInProgress = true;
-                    hooks.updateOffset(this, true);
-                    this._changeInProgress = null;
-                }
-            }
-            return this;
-        } else {
-            return this._isUTC ? offset : getDateOffset(this);
-        }
-    }
-
-    function getSetZone (input, keepLocalTime) {
-        if (input != null) {
-            if (typeof input !== 'string') {
-                input = -input;
-            }
-
-            this.utcOffset(input, keepLocalTime);
-
-            return this;
-        } else {
-            return -this.utcOffset();
-        }
-    }
-
-    function setOffsetToUTC (keepLocalTime) {
-        return this.utcOffset(0, keepLocalTime);
-    }
-
-    function setOffsetToLocal (keepLocalTime) {
-        if (this._isUTC) {
-            this.utcOffset(0, keepLocalTime);
-            this._isUTC = false;
-
-            if (keepLocalTime) {
-                this.subtract(getDateOffset(this), 'm');
-            }
-        }
-        return this;
-    }
-
-    function setOffsetToParsedOffset () {
-        if (this._tzm != null) {
-            this.utcOffset(this._tzm, false, true);
-        } else if (typeof this._i === 'string') {
-            var tZone = offsetFromString(matchOffset, this._i);
-            if (tZone != null) {
-                this.utcOffset(tZone);
-            }
-            else {
-                this.utcOffset(0, true);
-            }
-        }
-        return this;
-    }
-
-    function hasAlignedHourOffset (input) {
-        if (!this.isValid()) {
-            return false;
-        }
-        input = input ? createLocal(input).utcOffset() : 0;
-
-        return (this.utcOffset() - input) % 60 === 0;
-    }
-
-    function isDaylightSavingTime () {
-        return (
-            this.utcOffset() > this.clone().month(0).utcOffset() ||
-            this.utcOffset() > this.clone().month(5).utcOffset()
-        );
-    }
-
-    function isDaylightSavingTimeShifted () {
-        if (!isUndefined(this._isDSTShifted)) {
-            return this._isDSTShifted;
-        }
-
-        var c = {};
-
-        copyConfig(c, this);
-        c = prepareConfig(c);
-
-        if (c._a) {
-            var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
-            this._isDSTShifted = this.isValid() &&
-                compareArrays(c._a, other.toArray()) > 0;
-        } else {
-            this._isDSTShifted = false;
-        }
-
-        return this._isDSTShifted;
-    }
-
-    function isLocal () {
-        return this.isValid() ? !this._isUTC : false;
-    }
-
-    function isUtcOffset () {
-        return this.isValid() ? this._isUTC : false;
-    }
-
-    function isUtc () {
-        return this.isValid() ? this._isUTC && this._offset === 0 : false;
-    }
-
-    // ASP.NET json date format regex
-    var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
-
-    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
-    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
-    // and further modified to allow for strings containing both week and day
-    var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
-
-    function createDuration (input, key) {
-        var duration = input,
-            // matching against regexp is expensive, do it on demand
-            match = null,
-            sign,
-            ret,
-            diffRes;
-
-        if (isDuration(input)) {
-            duration = {
-                ms : input._milliseconds,
-                d  : input._days,
-                M  : input._months
-            };
-        } else if (isNumber(input)) {
-            duration = {};
-            if (key) {
-                duration[key] = input;
-            } else {
-                duration.milliseconds = input;
-            }
-        } else if (!!(match = aspNetRegex.exec(input))) {
-            sign = (match[1] === '-') ? -1 : 1;
-            duration = {
-                y  : 0,
-                d  : toInt(match[DATE])                         * sign,
-                h  : toInt(match[HOUR])                         * sign,
-                m  : toInt(match[MINUTE])                       * sign,
-                s  : toInt(match[SECOND])                       * sign,
-                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
-            };
-        } else if (!!(match = isoRegex.exec(input))) {
-            sign = (match[1] === '-') ? -1 : 1;
-            duration = {
-                y : parseIso(match[2], sign),
-                M : parseIso(match[3], sign),
-                w : parseIso(match[4], sign),
-                d : parseIso(match[5], sign),
-                h : parseIso(match[6], sign),
-                m : parseIso(match[7], sign),
-                s : parseIso(match[8], sign)
-            };
-        } else if (duration == null) {// checks for null or undefined
-            duration = {};
-        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
-            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
-
-            duration = {};
-            duration.ms = diffRes.milliseconds;
-            duration.M = diffRes.months;
-        }
-
-        ret = new Duration(duration);
-
-        if (isDuration(input) && hasOwnProp(input, '_locale')) {
-            ret._locale = input._locale;
-        }
-
-        return ret;
-    }
-
-    createDuration.fn = Duration.prototype;
-    createDuration.invalid = createInvalid$1;
-
-    function parseIso (inp, sign) {
-        // We'd normally use ~~inp for this, but unfortunately it also
-        // converts floats to ints.
-        // inp may be undefined, so careful calling replace on it.
-        var res = inp && parseFloat(inp.replace(',', '.'));
-        // apply sign while we're at it
-        return (isNaN(res) ? 0 : res) * sign;
-    }
-
-    function positiveMomentsDifference(base, other) {
-        var res = {};
-
-        res.months = other.month() - base.month() +
-            (other.year() - base.year()) * 12;
-        if (base.clone().add(res.months, 'M').isAfter(other)) {
-            --res.months;
-        }
-
-        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
-
-        return res;
-    }
-
-    function momentsDifference(base, other) {
-        var res;
-        if (!(base.isValid() && other.isValid())) {
-            return {milliseconds: 0, months: 0};
-        }
-
-        other = cloneWithOffset(other, base);
-        if (base.isBefore(other)) {
-            res = positiveMomentsDifference(base, other);
-        } else {
-            res = positiveMomentsDifference(other, base);
-            res.milliseconds = -res.milliseconds;
-            res.months = -res.months;
-        }
-
-        return res;
-    }
-
-    // TODO: remove 'name' arg after deprecation is removed
-    function createAdder(direction, name) {
-        return function (val, period) {
-            var dur, tmp;
-            //invert the arguments, but complain about it
-            if (period !== null && !isNaN(+period)) {
-                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
-                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
-                tmp = val; val = period; period = tmp;
-            }
-
-            val = typeof val === 'string' ? +val : val;
-            dur = createDuration(val, period);
-            addSubtract(this, dur, direction);
-            return this;
-        };
-    }
-
-    function addSubtract (mom, duration, isAdding, updateOffset) {
-        var milliseconds = duration._milliseconds,
-            days = absRound(duration._days),
-            months = absRound(duration._months);
-
-        if (!mom.isValid()) {
-            // No op
-            return;
-        }
-
-        updateOffset = updateOffset == null ? true : updateOffset;
-
-        if (months) {
-            setMonth(mom, get(mom, 'Month') + months * isAdding);
-        }
-        if (days) {
-            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
-        }
-        if (milliseconds) {
-            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
-        }
-        if (updateOffset) {
-            hooks.updateOffset(mom, days || months);
-        }
-    }
-
-    var add      = createAdder(1, 'add');
-    var subtract = createAdder(-1, 'subtract');
-
-    function getCalendarFormat(myMoment, now) {
-        var diff = myMoment.diff(now, 'days', true);
-        return diff < -6 ? 'sameElse' :
-                diff < -1 ? 'lastWeek' :
-                diff < 0 ? 'lastDay' :
-                diff < 1 ? 'sameDay' :
-                diff < 2 ? 'nextDay' :
-                diff < 7 ? 'nextWeek' : 'sameElse';
-    }
-
-    function calendar$1 (time, formats) {
-        // We want to compare the start of today, vs this.
-        // Getting start-of-today depends on whether we're local/utc/offset or not.
-        var now = time || createLocal(),
-            sod = cloneWithOffset(now, this).startOf('day'),
-            format = hooks.calendarFormat(this, sod) || 'sameElse';
-
-        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
-
-        return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
-    }
-
-    function clone () {
-        return new Moment(this);
-    }
-
-    function isAfter (input, units) {
-        var localInput = isMoment(input) ? input : createLocal(input);
-        if (!(this.isValid() && localInput.isValid())) {
-            return false;
-        }
-        units = normalizeUnits(units) || 'millisecond';
-        if (units === 'millisecond') {
-            return this.valueOf() > localInput.valueOf();
-        } else {
-            return localInput.valueOf() < this.clone().startOf(units).valueOf();
-        }
-    }
-
-    function isBefore (input, units) {
-        var localInput = isMoment(input) ? input : createLocal(input);
-        if (!(this.isValid() && localInput.isValid())) {
-            return false;
-        }
-        units = normalizeUnits(units) || 'millisecond';
-        if (units === 'millisecond') {
-            return this.valueOf() < localInput.valueOf();
-        } else {
-            return this.clone().endOf(units).valueOf() < localInput.valueOf();
-        }
-    }
-
-    function isBetween (from, to, units, inclusivity) {
-        var localFrom = isMoment(from) ? from : createLocal(from),
-            localTo = isMoment(to) ? to : createLocal(to);
-        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
-            return false;
-        }
-        inclusivity = inclusivity || '()';
-        return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&
-            (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
-    }
-
-    function isSame (input, units) {
-        var localInput = isMoment(input) ? input : createLocal(input),
-            inputMs;
-        if (!(this.isValid() && localInput.isValid())) {
-            return false;
-        }
-        units = normalizeUnits(units) || 'millisecond';
-        if (units === 'millisecond') {
-            return this.valueOf() === localInput.valueOf();
-        } else {
-            inputMs = localInput.valueOf();
-            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
-        }
-    }
-
-    function isSameOrAfter (input, units) {
-        return this.isSame(input, units) || this.isAfter(input, units);
-    }
-
-    function isSameOrBefore (input, units) {
-        return this.isSame(input, units) || this.isBefore(input, units);
-    }
-
-    function diff (input, units, asFloat) {
-        var that,
-            zoneDelta,
-            output;
-
-        if (!this.isValid()) {
-            return NaN;
-        }
-
-        that = cloneWithOffset(input, this);
-
-        if (!that.isValid()) {
-            return NaN;
-        }
-
-        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
-
-        units = normalizeUnits(units);
-
-        switch (units) {
-            case 'year': output = monthDiff(this, that) / 12; break;
-            case 'month': output = monthDiff(this, that); break;
-            case 'quarter': output = monthDiff(this, that) / 3; break;
-            case 'second': output = (this - that) / 1e3; break; // 1000
-            case 'minute': output = (this - that) / 6e4; break; // 1000 * 60
-            case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60
-            case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst
-            case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst
-            default: output = this - that;
-        }
-
-        return asFloat ? output : absFloor(output);
-    }
-
-    function monthDiff (a, b) {
-        // difference in months
-        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
-            // b is in (anchor - 1 month, anchor + 1 month)
-            anchor = a.clone().add(wholeMonthDiff, 'months'),
-            anchor2, adjust;
-
-        if (b - anchor < 0) {
-            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
-            // linear across the month
-            adjust = (b - anchor) / (anchor - anchor2);
-        } else {
-            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
-            // linear across the month
-            adjust = (b - anchor) / (anchor2 - anchor);
-        }
-
-        //check for negative zero, return zero if negative zero
-        return -(wholeMonthDiff + adjust) || 0;
-    }
-
-    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
-    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
-
-    function toString () {
-        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
-    }
-
-    function toISOString(keepOffset) {
-        if (!this.isValid()) {
-            return null;
-        }
-        var utc = keepOffset !== true;
-        var m = utc ? this.clone().utc() : this;
-        if (m.year() < 0 || m.year() > 9999) {
-            return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
-        }
-        if (isFunction(Date.prototype.toISOString)) {
-            // native implementation is ~50x faster, use it when we can
-            if (utc) {
-                return this.toDate().toISOString();
-            } else {
-                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
-            }
-        }
-        return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
-    }
-
-    /**
-     * Return a human readable representation of a moment that can
-     * also be evaluated to get a new moment which is the same
-     *
-     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
-     */
-    function inspect () {
-        if (!this.isValid()) {
-            return 'moment.invalid(/* ' + this._i + ' */)';
-        }
-        var func = 'moment';
-        var zone = '';
-        if (!this.isLocal()) {
-            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
-            zone = 'Z';
-        }
-        var prefix = '[' + func + '("]';
-        var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
-        var datetime = '-MM-DD[T]HH:mm:ss.SSS';
-        var suffix = zone + '[")]';
-
-        return this.format(prefix + year + datetime + suffix);
-    }
-
-    function format (inputString) {
-        if (!inputString) {
-            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
-        }
-        var output = formatMoment(this, inputString);
-        return this.localeData().postformat(output);
-    }
-
-    function from (time, withoutSuffix) {
-        if (this.isValid() &&
-                ((isMoment(time) && time.isValid()) ||
-                 createLocal(time).isValid())) {
-            return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
-        } else {
-            return this.localeData().invalidDate();
-        }
-    }
-
-    function fromNow (withoutSuffix) {
-        return this.from(createLocal(), withoutSuffix);
-    }
-
-    function to (time, withoutSuffix) {
-        if (this.isValid() &&
-                ((isMoment(time) && time.isValid()) ||
-                 createLocal(time).isValid())) {
-            return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
-        } else {
-            return this.localeData().invalidDate();
-        }
-    }
-
-    function toNow (withoutSuffix) {
-        return this.to(createLocal(), withoutSuffix);
-    }
-
-    // If passed a locale key, it will set the locale for this
-    // instance.  Otherwise, it will return the locale configuration
-    // variables for this instance.
-    function locale (key) {
-        var newLocaleData;
-
-        if (key === undefined) {
-            return this._locale._abbr;
-        } else {
-            newLocaleData = getLocale(key);
-            if (newLocaleData != null) {
-                this._locale = newLocaleData;
-            }
-            return this;
-        }
-    }
-
-    var lang = deprecate(
-        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
-        function (key) {
-            if (key === undefined) {
-                return this.localeData();
-            } else {
-                return this.locale(key);
-            }
-        }
-    );
-
-    function localeData () {
-        return this._locale;
-    }
-
-    var MS_PER_SECOND = 1000;
-    var MS_PER_MINUTE = 60 * MS_PER_SECOND;
-    var MS_PER_HOUR = 60 * MS_PER_MINUTE;
-    var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
-
-    // actual modulo - handles negative numbers (for dates before 1970):
-    function mod$1(dividend, divisor) {
-        return (dividend % divisor + divisor) % divisor;
-    }
-
-    function localStartOfDate(y, m, d) {
-        // the date constructor remaps years 0-99 to 1900-1999
-        if (y < 100 && y >= 0) {
-            // preserve leap years using a full 400 year cycle, then reset
-            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
-        } else {
-            return new Date(y, m, d).valueOf();
-        }
-    }
-
-    function utcStartOfDate(y, m, d) {
-        // Date.UTC remaps years 0-99 to 1900-1999
-        if (y < 100 && y >= 0) {
-            // preserve leap years using a full 400 year cycle, then reset
-            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
-        } else {
-            return Date.UTC(y, m, d);
-        }
-    }
-
-    function startOf (units) {
-        var time;
-        units = normalizeUnits(units);
-        if (units === undefined || units === 'millisecond' || !this.isValid()) {
-            return this;
-        }
-
-        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
-
-        switch (units) {
-            case 'year':
-                time = startOfDate(this.year(), 0, 1);
-                break;
-            case 'quarter':
-                time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
-                break;
-            case 'month':
-                time = startOfDate(this.year(), this.month(), 1);
-                break;
-            case 'week':
-                time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
-                break;
-            case 'isoWeek':
-                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
-                break;
-            case 'day':
-            case 'date':
-                time = startOfDate(this.year(), this.month(), this.date());
-                break;
-            case 'hour':
-                time = this._d.valueOf();
-                time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
-                break;
-            case 'minute':
-                time = this._d.valueOf();
-                time -= mod$1(time, MS_PER_MINUTE);
-                break;
-            case 'second':
-                time = this._d.valueOf();
-                time -= mod$1(time, MS_PER_SECOND);
-                break;
-        }
-
-        this._d.setTime(time);
-        hooks.updateOffset(this, true);
-        return this;
-    }
-
-    function endOf (units) {
-        var time;
-        units = normalizeUnits(units);
-        if (units === undefined || units === 'millisecond' || !this.isValid()) {
-            return this;
-        }
-
-        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
-
-        switch (units) {
-            case 'year':
-                time = startOfDate(this.year() + 1, 0, 1) - 1;
-                break;
-            case 'quarter':
-                time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
-                break;
-            case 'month':
-                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
-                break;
-            case 'week':
-                time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
-                break;
-            case 'isoWeek':
-                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
-                break;
-            case 'day':
-            case 'date':
-                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
-                break;
-            case 'hour':
-                time = this._d.valueOf();
-                time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
-                break;
-            case 'minute':
-                time = this._d.valueOf();
-                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
-                break;
-            case 'second':
-                time = this._d.valueOf();
-                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
-                break;
-        }
-
-        this._d.setTime(time);
-        hooks.updateOffset(this, true);
-        return this;
-    }
-
-    function valueOf () {
-        return this._d.valueOf() - ((this._offset || 0) * 60000);
-    }
-
-    function unix () {
-        return Math.floor(this.valueOf() / 1000);
-    }
-
-    function toDate () {
-        return new Date(this.valueOf());
-    }
-
-    function toArray () {
-        var m = this;
-        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
-    }
-
-    function toObject () {
-        var m = this;
-        return {
-            years: m.year(),
-            months: m.month(),
-            date: m.date(),
-            hours: m.hours(),
-            minutes: m.minutes(),
-            seconds: m.seconds(),
-            milliseconds: m.milliseconds()
-        };
-    }
-
-    function toJSON () {
-        // new Date(NaN).toJSON() === null
-        return this.isValid() ? this.toISOString() : null;
-    }
-
-    function isValid$2 () {
-        return isValid(this);
-    }
-
-    function parsingFlags () {
-        return extend({}, getParsingFlags(this));
-    }
-
-    function invalidAt () {
-        return getParsingFlags(this).overflow;
-    }
-
-    function creationData() {
-        return {
-            input: this._i,
-            format: this._f,
-            locale: this._locale,
-            isUTC: this._isUTC,
-            strict: this._strict
-        };
-    }
-
-    // FORMATTING
-
-    addFormatToken(0, ['gg', 2], 0, function () {
-        return this.weekYear() % 100;
-    });
-
-    addFormatToken(0, ['GG', 2], 0, function () {
-        return this.isoWeekYear() % 100;
-    });
-
-    function addWeekYearFormatToken (token, getter) {
-        addFormatToken(0, [token, token.length], 0, getter);
-    }
-
-    addWeekYearFormatToken('gggg',     'weekYear');
-    addWeekYearFormatToken('ggggg',    'weekYear');
-    addWeekYearFormatToken('GGGG',  'isoWeekYear');
-    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
-
-    // ALIASES
-
-    addUnitAlias('weekYear', 'gg');
-    addUnitAlias('isoWeekYear', 'GG');
-
-    // PRIORITY
-
-    addUnitPriority('weekYear', 1);
-    addUnitPriority('isoWeekYear', 1);
-
-
-    // PARSING
-
-    addRegexToken('G',      matchSigned);
-    addRegexToken('g',      matchSigned);
-    addRegexToken('GG',     match1to2, match2);
-    addRegexToken('gg',     match1to2, match2);
-    addRegexToken('GGGG',   match1to4, match4);
-    addRegexToken('gggg',   match1to4, match4);
-    addRegexToken('GGGGG',  match1to6, match6);
-    addRegexToken('ggggg',  match1to6, match6);
-
-    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
-        week[token.substr(0, 2)] = toInt(input);
-    });
-
-    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
-        week[token] = hooks.parseTwoDigitYear(input);
-    });
-
-    // MOMENTS
-
-    function getSetWeekYear (input) {
-        return getSetWeekYearHelper.call(this,
-                input,
-                this.week(),
-                this.weekday(),
-                this.localeData()._week.dow,
-                this.localeData()._week.doy);
-    }
-
-    function getSetISOWeekYear (input) {
-        return getSetWeekYearHelper.call(this,
-                input, this.isoWeek(), this.isoWeekday(), 1, 4);
-    }
-
-    function getISOWeeksInYear () {
-        return weeksInYear(this.year(), 1, 4);
-    }
-
-    function getWeeksInYear () {
-        var weekInfo = this.localeData()._week;
-        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
-    }
-
-    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
-        var weeksTarget;
-        if (input == null) {
-            return weekOfYear(this, dow, doy).year;
-        } else {
-            weeksTarget = weeksInYear(input, dow, doy);
-            if (week > weeksTarget) {
-                week = weeksTarget;
-            }
-            return setWeekAll.call(this, input, week, weekday, dow, doy);
-        }
-    }
-
-    function setWeekAll(weekYear, week, weekday, dow, doy) {
-        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
-            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
-
-        this.year(date.getUTCFullYear());
-        this.month(date.getUTCMonth());
-        this.date(date.getUTCDate());
-        return this;
-    }
-
-    // FORMATTING
-
-    addFormatToken('Q', 0, 'Qo', 'quarter');
-
-    // ALIASES
-
-    addUnitAlias('quarter', 'Q');
-
-    // PRIORITY
-
-    addUnitPriority('quarter', 7);
-
-    // PARSING
-
-    addRegexToken('Q', match1);
-    addParseToken('Q', function (input, array) {
-        array[MONTH] = (toInt(input) - 1) * 3;
-    });
-
-    // MOMENTS
-
-    function getSetQuarter (input) {
-        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
-    }
-
-    // FORMATTING
-
-    addFormatToken('D', ['DD', 2], 'Do', 'date');
-
-    // ALIASES
-
-    addUnitAlias('date', 'D');
-
-    // PRIORITY
-    addUnitPriority('date', 9);
-
-    // PARSING
-
-    addRegexToken('D',  match1to2);
-    addRegexToken('DD', match1to2, match2);
-    addRegexToken('Do', function (isStrict, locale) {
-        // TODO: Remove "ordinalParse" fallback in next major release.
-        return isStrict ?
-          (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
-          locale._dayOfMonthOrdinalParseLenient;
-    });
-
-    addParseToken(['D', 'DD'], DATE);
-    addParseToken('Do', function (input, array) {
-        array[DATE] = toInt(input.match(match1to2)[0]);
-    });
-
-    // MOMENTS
-
-    var getSetDayOfMonth = makeGetSet('Date', true);
-
-    // FORMATTING
-
-    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
-
-    // ALIASES
-
-    addUnitAlias('dayOfYear', 'DDD');
-
-    // PRIORITY
-    addUnitPriority('dayOfYear', 4);
-
-    // PARSING
-
-    addRegexToken('DDD',  match1to3);
-    addRegexToken('DDDD', match3);
-    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
-        config._dayOfYear = toInt(input);
-    });
-
-    // HELPERS
-
-    // MOMENTS
-
-    function getSetDayOfYear (input) {
-        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
-        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
-    }
-
-    // FORMATTING
-
-    addFormatToken('m', ['mm', 2], 0, 'minute');
-
-    // ALIASES
-
-    addUnitAlias('minute', 'm');
-
-    // PRIORITY
-
-    addUnitPriority('minute', 14);
-
-    // PARSING
-
-    addRegexToken('m',  match1to2);
-    addRegexToken('mm', match1to2, match2);
-    addParseToken(['m', 'mm'], MINUTE);
-
-    // MOMENTS
-
-    var getSetMinute = makeGetSet('Minutes', false);
-
-    // FORMATTING
-
-    addFormatToken('s', ['ss', 2], 0, 'second');
-
-    // ALIASES
-
-    addUnitAlias('second', 's');
-
-    // PRIORITY
-
-    addUnitPriority('second', 15);
-
-    // PARSING
-
-    addRegexToken('s',  match1to2);
-    addRegexToken('ss', match1to2, match2);
-    addParseToken(['s', 'ss'], SECOND);
-
-    // MOMENTS
-
-    var getSetSecond = makeGetSet('Seconds', false);
-
-    // FORMATTING
-
-    addFormatToken('S', 0, 0, function () {
-        return ~~(this.millisecond() / 100);
-    });
-
-    addFormatToken(0, ['SS', 2], 0, function () {
-        return ~~(this.millisecond() / 10);
-    });
-
-    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
-    addFormatToken(0, ['SSSS', 4], 0, function () {
-        return this.millisecond() * 10;
-    });
-    addFormatToken(0, ['SSSSS', 5], 0, function () {
-        return this.millisecond() * 100;
-    });
-    addFormatToken(0, ['SSSSSS', 6], 0, function () {
-        return this.millisecond() * 1000;
-    });
-    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
-        return this.millisecond() * 10000;
-    });
-    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
-        return this.millisecond() * 100000;
-    });
-    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
-        return this.millisecond() * 1000000;
-    });
-
-
-    // ALIASES
-
-    addUnitAlias('millisecond', 'ms');
-
-    // PRIORITY
-
-    addUnitPriority('millisecond', 16);
-
-    // PARSING
-
-    addRegexToken('S',    match1to3, match1);
-    addRegexToken('SS',   match1to3, match2);
-    addRegexToken('SSS',  match1to3, match3);
-
-    var token;
-    for (token = 'SSSS'; token.length <= 9; token += 'S') {
-        addRegexToken(token, matchUnsigned);
-    }
-
-    function parseMs(input, array) {
-        array[MILLISECOND] = toInt(('0.' + input) * 1000);
-    }
-
-    for (token = 'S'; token.length <= 9; token += 'S') {
-        addParseToken(token, parseMs);
-    }
-    // MOMENTS
-
-    var getSetMillisecond = makeGetSet('Milliseconds', false);
-
-    // FORMATTING
-
-    addFormatToken('z',  0, 0, 'zoneAbbr');
-    addFormatToken('zz', 0, 0, 'zoneName');
-
-    // MOMENTS
-
-    function getZoneAbbr () {
-        return this._isUTC ? 'UTC' : '';
-    }
-
-    function getZoneName () {
-        return this._isUTC ? 'Coordinated Universal Time' : '';
-    }
-
-    var proto = Moment.prototype;
-
-    proto.add               = add;
-    proto.calendar          = calendar$1;
-    proto.clone             = clone;
-    proto.diff              = diff;
-    proto.endOf             = endOf;
-    proto.format            = format;
-    proto.from              = from;
-    proto.fromNow           = fromNow;
-    proto.to                = to;
-    proto.toNow             = toNow;
-    proto.get               = stringGet;
-    proto.invalidAt         = invalidAt;
-    proto.isAfter           = isAfter;
-    proto.isBefore          = isBefore;
-    proto.isBetween         = isBetween;
-    proto.isSame            = isSame;
-    proto.isSameOrAfter     = isSameOrAfter;
-    proto.isSameOrBefore    = isSameOrBefore;
-    proto.isValid           = isValid$2;
-    proto.lang              = lang;
-    proto.locale            = locale;
-    proto.localeData        = localeData;
-    proto.max               = prototypeMax;
-    proto.min               = prototypeMin;
-    proto.parsingFlags      = parsingFlags;
-    proto.set               = stringSet;
-    proto.startOf           = startOf;
-    proto.subtract          = subtract;
-    proto.toArray           = toArray;
-    proto.toObject          = toObject;
-    proto.toDate            = toDate;
-    proto.toISOString       = toISOString;
-    proto.inspect           = inspect;
-    proto.toJSON            = toJSON;
-    proto.toString          = toString;
-    proto.unix              = unix;
-    proto.valueOf           = valueOf;
-    proto.creationData      = creationData;
-    proto.year       = getSetYear;
-    proto.isLeapYear = getIsLeapYear;
-    proto.weekYear    = getSetWeekYear;
-    proto.isoWeekYear = getSetISOWeekYear;
-    proto.quarter = proto.quarters = getSetQuarter;
-    proto.month       = getSetMonth;
-    proto.daysInMonth = getDaysInMonth;
-    proto.week           = proto.weeks        = getSetWeek;
-    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
-    proto.weeksInYear    = getWeeksInYear;
-    proto.isoWeeksInYear = getISOWeeksInYear;
-    proto.date       = getSetDayOfMonth;
-    proto.day        = proto.days             = getSetDayOfWeek;
-    proto.weekday    = getSetLocaleDayOfWeek;
-    proto.isoWeekday = getSetISODayOfWeek;
-    proto.dayOfYear  = getSetDayOfYear;
-    proto.hour = proto.hours = getSetHour;
-    proto.minute = proto.minutes = getSetMinute;
-    proto.second = proto.seconds = getSetSecond;
-    proto.millisecond = proto.milliseconds = getSetMillisecond;
-    proto.utcOffset            = getSetOffset;
-    proto.utc                  = setOffsetToUTC;
-    proto.local                = setOffsetToLocal;
-    proto.parseZone            = setOffsetToParsedOffset;
-    proto.hasAlignedHourOffset = hasAlignedHourOffset;
-    proto.isDST                = isDaylightSavingTime;
-    proto.isLocal              = isLocal;
-    proto.isUtcOffset          = isUtcOffset;
-    proto.isUtc                = isUtc;
-    proto.isUTC                = isUtc;
-    proto.zoneAbbr = getZoneAbbr;
-    proto.zoneName = getZoneName;
-    proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
-    proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
-    proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
-    proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
-    proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
-
-    function createUnix (input) {
-        return createLocal(input * 1000);
-    }
-
-    function createInZone () {
-        return createLocal.apply(null, arguments).parseZone();
-    }
-
-    function preParsePostFormat (string) {
-        return string;
-    }
-
-    var proto$1 = Locale.prototype;
-
-    proto$1.calendar        = calendar;
-    proto$1.longDateFormat  = longDateFormat;
-    proto$1.invalidDate     = invalidDate;
-    proto$1.ordinal         = ordinal;
-    proto$1.preparse        = preParsePostFormat;
-    proto$1.postformat      = preParsePostFormat;
-    proto$1.relativeTime    = relativeTime;
-    proto$1.pastFuture      = pastFuture;
-    proto$1.set             = set;
-
-    proto$1.months            =        localeMonths;
-    proto$1.monthsShort       =        localeMonthsShort;
-    proto$1.monthsParse       =        localeMonthsParse;
-    proto$1.monthsRegex       = monthsRegex;
-    proto$1.monthsShortRegex  = monthsShortRegex;
-    proto$1.week = localeWeek;
-    proto$1.firstDayOfYear = localeFirstDayOfYear;
-    proto$1.firstDayOfWeek = localeFirstDayOfWeek;
-
-    proto$1.weekdays       =        localeWeekdays;
-    proto$1.weekdaysMin    =        localeWeekdaysMin;
-    proto$1.weekdaysShort  =        localeWeekdaysShort;
-    proto$1.weekdaysParse  =        localeWeekdaysParse;
-
-    proto$1.weekdaysRegex       =        weekdaysRegex;
-    proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
-    proto$1.weekdaysMinRegex    =        weekdaysMinRegex;
-
-    proto$1.isPM = localeIsPM;
-    proto$1.meridiem = localeMeridiem;
-
-    function get$1 (format, index, field, setter) {
-        var locale = getLocale();
-        var utc = createUTC().set(setter, index);
-        return locale[field](utc, format);
-    }
-
-    function listMonthsImpl (format, index, field) {
-        if (isNumber(format)) {
-            index = format;
-            format = undefined;
-        }
-
-        format = format || '';
-
-        if (index != null) {
-            return get$1(format, index, field, 'month');
-        }
-
-        var i;
-        var out = [];
-        for (i = 0; i < 12; i++) {
-            out[i] = get$1(format, i, field, 'month');
-        }
-        return out;
-    }
-
-    // ()
-    // (5)
-    // (fmt, 5)
-    // (fmt)
-    // (true)
-    // (true, 5)
-    // (true, fmt, 5)
-    // (true, fmt)
-    function listWeekdaysImpl (localeSorted, format, index, field) {
-        if (typeof localeSorted === 'boolean') {
-            if (isNumber(format)) {
-                index = format;
-                format = undefined;
-            }
-
-            format = format || '';
-        } else {
-            format = localeSorted;
-            index = format;
-            localeSorted = false;
-
-            if (isNumber(format)) {
-                index = format;
-                format = undefined;
-            }
-
-            format = format || '';
-        }
-
-        var locale = getLocale(),
-            shift = localeSorted ? locale._week.dow : 0;
-
-        if (index != null) {
-            return get$1(format, (index + shift) % 7, field, 'day');
-        }
-
-        var i;
-        var out = [];
-        for (i = 0; i < 7; i++) {
-            out[i] = get$1(format, (i + shift) % 7, field, 'day');
-        }
-        return out;
-    }
-
-    function listMonths (format, index) {
-        return listMonthsImpl(format, index, 'months');
-    }
-
-    function listMonthsShort (format, index) {
-        return listMonthsImpl(format, index, 'monthsShort');
-    }
-
-    function listWeekdays (localeSorted, format, index) {
-        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
-    }
-
-    function listWeekdaysShort (localeSorted, format, index) {
-        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
-    }
-
-    function listWeekdaysMin (localeSorted, format, index) {
-        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
-    }
-
-    getSetGlobalLocale('en', {
-        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
-        ordinal : function (number) {
-            var b = number % 10,
-                output = (toInt(number % 100 / 10) === 1) ? 'th' :
-                (b === 1) ? 'st' :
-                (b === 2) ? 'nd' :
-                (b === 3) ? 'rd' : 'th';
-            return number + output;
-        }
-    });
-
-    // Side effect imports
-
-    hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
-    hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
-
-    var mathAbs = Math.abs;
-
-    function abs () {
-        var data           = this._data;
-
-        this._milliseconds = mathAbs(this._milliseconds);
-        this._days         = mathAbs(this._days);
-        this._months       = mathAbs(this._months);
-
-        data.milliseconds  = mathAbs(data.milliseconds);
-        data.seconds       = mathAbs(data.seconds);
-        data.minutes       = mathAbs(data.minutes);
-        data.hours         = mathAbs(data.hours);
-        data.months        = mathAbs(data.months);
-        data.years         = mathAbs(data.years);
-
-        return this;
-    }
-
-    function addSubtract$1 (duration, input, value, direction) {
-        var other = createDuration(input, value);
-
-        duration._milliseconds += direction * other._milliseconds;
-        duration._days         += direction * other._days;
-        duration._months       += direction * other._months;
-
-        return duration._bubble();
-    }
-
-    // supports only 2.0-style add(1, 's') or add(duration)
-    function add$1 (input, value) {
-        return addSubtract$1(this, input, value, 1);
-    }
-
-    // supports only 2.0-style subtract(1, 's') or subtract(duration)
-    function subtract$1 (input, value) {
-        return addSubtract$1(this, input, value, -1);
-    }
-
-    function absCeil (number) {
-        if (number < 0) {
-            return Math.floor(number);
-        } else {
-            return Math.ceil(number);
-        }
-    }
-
-    function bubble () {
-        var milliseconds = this._milliseconds;
-        var days         = this._days;
-        var months       = this._months;
-        var data         = this._data;
-        var seconds, minutes, hours, years, monthsFromDays;
-
-        // if we have a mix of positive and negative values, bubble down first
-        // check: https://github.com/moment/moment/issues/2166
-        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
-                (milliseconds <= 0 && days <= 0 && months <= 0))) {
-            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
-            days = 0;
-            months = 0;
-        }
-
-        // The following code bubbles up values, see the tests for
-        // examples of what that means.
-        data.milliseconds = milliseconds % 1000;
-
-        seconds           = absFloor(milliseconds / 1000);
-        data.seconds      = seconds % 60;
-
-        minutes           = absFloor(seconds / 60);
-        data.minutes      = minutes % 60;
-
-        hours             = absFloor(minutes / 60);
-        data.hours        = hours % 24;
-
-        days += absFloor(hours / 24);
-
-        // convert days to months
-        monthsFromDays = absFloor(daysToMonths(days));
-        months += monthsFromDays;
-        days -= absCeil(monthsToDays(monthsFromDays));
-
-        // 12 months -> 1 year
-        years = absFloor(months / 12);
-        months %= 12;
-
-        data.days   = days;
-        data.months = months;
-        data.years  = years;
-
-        return this;
-    }
-
-    function daysToMonths (days) {
-        // 400 years have 146097 days (taking into account leap year rules)
-        // 400 years have 12 months === 4800
-        return days * 4800 / 146097;
-    }
-
-    function monthsToDays (months) {
-        // the reverse of daysToMonths
-        return months * 146097 / 4800;
-    }
-
-    function as (units) {
-        if (!this.isValid()) {
-            return NaN;
-        }
-        var days;
-        var months;
-        var milliseconds = this._milliseconds;
-
-        units = normalizeUnits(units);
-
-        if (units === 'month' || units === 'quarter' || units === 'year') {
-            days = this._days + milliseconds / 864e5;
-            months = this._months + daysToMonths(days);
-            switch (units) {
-                case 'month':   return months;
-                case 'quarter': return months / 3;
-                case 'year':    return months / 12;
-            }
-        } else {
-            // handle milliseconds separately because of floating point math errors (issue #1867)
-            days = this._days + Math.round(monthsToDays(this._months));
-            switch (units) {
-                case 'week'   : return days / 7     + milliseconds / 6048e5;
-                case 'day'    : return days         + milliseconds / 864e5;
-                case 'hour'   : return days * 24    + milliseconds / 36e5;
-                case 'minute' : return days * 1440  + milliseconds / 6e4;
-                case 'second' : return days * 86400 + milliseconds / 1000;
-                // Math.floor prevents floating point math errors here
-                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
-                default: throw new Error('Unknown unit ' + units);
-            }
-        }
-    }
-
-    // TODO: Use this.as('ms')?
-    function valueOf$1 () {
-        if (!this.isValid()) {
-            return NaN;
-        }
-        return (
-            this._milliseconds +
-            this._days * 864e5 +
-            (this._months % 12) * 2592e6 +
-            toInt(this._months / 12) * 31536e6
-        );
-    }
-
-    function makeAs (alias) {
-        return function () {
-            return this.as(alias);
-        };
-    }
-
-    var asMilliseconds = makeAs('ms');
-    var asSeconds      = makeAs('s');
-    var asMinutes      = makeAs('m');
-    var asHours        = makeAs('h');
-    var asDays         = makeAs('d');
-    var asWeeks        = makeAs('w');
-    var asMonths       = makeAs('M');
-    var asQuarters     = makeAs('Q');
-    var asYears        = makeAs('y');
-
-    function clone$1 () {
-        return createDuration(this);
-    }
-
-    function get$2 (units) {
-        units = normalizeUnits(units);
-        return this.isValid() ? this[units + 's']() : NaN;
-    }
-
-    function makeGetter(name) {
-        return function () {
-            return this.isValid() ? this._data[name] : NaN;
-        };
-    }
-
-    var milliseconds = makeGetter('milliseconds');
-    var seconds      = makeGetter('seconds');
-    var minutes      = makeGetter('minutes');
-    var hours        = makeGetter('hours');
-    var days         = makeGetter('days');
-    var months       = makeGetter('months');
-    var years        = makeGetter('years');
-
-    function weeks () {
-        return absFloor(this.days() / 7);
-    }
-
-    var round = Math.round;
-    var thresholds = {
-        ss: 44,         // a few seconds to seconds
-        s : 45,         // seconds to minute
-        m : 45,         // minutes to hour
-        h : 22,         // hours to day
-        d : 26,         // days to month
-        M : 11          // months to year
-    };
-
-    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
-    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
-        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
-    }
-
-    function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
-        var duration = createDuration(posNegDuration).abs();
-        var seconds  = round(duration.as('s'));
-        var minutes  = round(duration.as('m'));
-        var hours    = round(duration.as('h'));
-        var days     = round(duration.as('d'));
-        var months   = round(duration.as('M'));
-        var years    = round(duration.as('y'));
-
-        var a = seconds <= thresholds.ss && ['s', seconds]  ||
-                seconds < thresholds.s   && ['ss', seconds] ||
-                minutes <= 1             && ['m']           ||
-                minutes < thresholds.m   && ['mm', minutes] ||
-                hours   <= 1             && ['h']           ||
-                hours   < thresholds.h   && ['hh', hours]   ||
-                days    <= 1             && ['d']           ||
-                days    < thresholds.d   && ['dd', days]    ||
-                months  <= 1             && ['M']           ||
-                months  < thresholds.M   && ['MM', months]  ||
-                years   <= 1             && ['y']           || ['yy', years];
-
-        a[2] = withoutSuffix;
-        a[3] = +posNegDuration > 0;
-        a[4] = locale;
-        return substituteTimeAgo.apply(null, a);
-    }
-
-    // This function allows you to set the rounding function for relative time strings
-    function getSetRelativeTimeRounding (roundingFunction) {
-        if (roundingFunction === undefined) {
-            return round;
-        }
-        if (typeof(roundingFunction) === 'function') {
-            round = roundingFunction;
-            return true;
-        }
-        return false;
-    }
-
-    // This function allows you to set a threshold for relative time strings
-    function getSetRelativeTimeThreshold (threshold, limit) {
-        if (thresholds[threshold] === undefined) {
-            return false;
-        }
-        if (limit === undefined) {
-            return thresholds[threshold];
-        }
-        thresholds[threshold] = limit;
-        if (threshold === 's') {
-            thresholds.ss = limit - 1;
-        }
-        return true;
-    }
-
-    function humanize (withSuffix) {
-        if (!this.isValid()) {
-            return this.localeData().invalidDate();
-        }
-
-        var locale = this.localeData();
-        var output = relativeTime$1(this, !withSuffix, locale);
-
-        if (withSuffix) {
-            output = locale.pastFuture(+this, output);
-        }
-
-        return locale.postformat(output);
-    }
-
-    var abs$1 = Math.abs;
-
-    function sign(x) {
-        return ((x > 0) - (x < 0)) || +x;
-    }
-
-    function toISOString$1() {
-        // for ISO strings we do not use the normal bubbling rules:
-        //  * milliseconds bubble up until they become hours
-        //  * days do not bubble at all
-        //  * months bubble up until they become years
-        // This is because there is no context-free conversion between hours and days
-        // (think of clock changes)
-        // and also not between days and months (28-31 days per month)
-        if (!this.isValid()) {
-            return this.localeData().invalidDate();
-        }
-
-        var seconds = abs$1(this._milliseconds) / 1000;
-        var days         = abs$1(this._days);
-        var months       = abs$1(this._months);
-        var minutes, hours, years;
-
-        // 3600 seconds -> 60 minutes -> 1 hour
-        minutes           = absFloor(seconds / 60);
-        hours             = absFloor(minutes / 60);
-        seconds %= 60;
-        minutes %= 60;
-
-        // 12 months -> 1 year
-        years  = absFloor(months / 12);
-        months %= 12;
-
-
-        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
-        var Y = years;
-        var M = months;
-        var D = days;
-        var h = hours;
-        var m = minutes;
-        var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
-        var total = this.asSeconds();
-
-        if (!total) {
-            // this is the same as C#'s (Noda) and python (isodate)...
-            // but not other JS (goog.date)
-            return 'P0D';
-        }
-
-        var totalSign = total < 0 ? '-' : '';
-        var ymSign = sign(this._months) !== sign(total) ? '-' : '';
-        var daysSign = sign(this._days) !== sign(total) ? '-' : '';
-        var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
-
-        return totalSign + 'P' +
-            (Y ? ymSign + Y + 'Y' : '') +
-            (M ? ymSign + M + 'M' : '') +
-            (D ? daysSign + D + 'D' : '') +
-            ((h || m || s) ? 'T' : '') +
-            (h ? hmsSign + h + 'H' : '') +
-            (m ? hmsSign + m + 'M' : '') +
-            (s ? hmsSign + s + 'S' : '');
-    }
-
-    var proto$2 = Duration.prototype;
-
-    proto$2.isValid        = isValid$1;
-    proto$2.abs            = abs;
-    proto$2.add            = add$1;
-    proto$2.subtract       = subtract$1;
-    proto$2.as             = as;
-    proto$2.asMilliseconds = asMilliseconds;
-    proto$2.asSeconds      = asSeconds;
-    proto$2.asMinutes      = asMinutes;
-    proto$2.asHours        = asHours;
-    proto$2.asDays         = asDays;
-    proto$2.asWeeks        = asWeeks;
-    proto$2.asMonths       = asMonths;
-    proto$2.asQuarters     = asQuarters;
-    proto$2.asYears        = asYears;
-    proto$2.valueOf        = valueOf$1;
-    proto$2._bubble        = bubble;
-    proto$2.clone          = clone$1;
-    proto$2.get            = get$2;
-    proto$2.milliseconds   = milliseconds;
-    proto$2.seconds        = seconds;
-    proto$2.minutes        = minutes;
-    proto$2.hours          = hours;
-    proto$2.days           = days;
-    proto$2.weeks          = weeks;
-    proto$2.months         = months;
-    proto$2.years          = years;
-    proto$2.humanize       = humanize;
-    proto$2.toISOString    = toISOString$1;
-    proto$2.toString       = toISOString$1;
-    proto$2.toJSON         = toISOString$1;
-    proto$2.locale         = locale;
-    proto$2.localeData     = localeData;
-
-    proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
-    proto$2.lang = lang;
-
-    // Side effect imports
-
-    // FORMATTING
-
-    addFormatToken('X', 0, 0, 'unix');
-    addFormatToken('x', 0, 0, 'valueOf');
-
-    // PARSING
-
-    addRegexToken('x', matchSigned);
-    addRegexToken('X', matchTimestamp);
-    addParseToken('X', function (input, array, config) {
-        config._d = new Date(parseFloat(input, 10) * 1000);
-    });
-    addParseToken('x', function (input, array, config) {
-        config._d = new Date(toInt(input));
-    });
-
-    // Side effect imports
-
-
-    hooks.version = '2.24.0';
-
-    setHookCallback(createLocal);
-
-    hooks.fn                    = proto;
-    hooks.min                   = min;
-    hooks.max                   = max;
-    hooks.now                   = now;
-    hooks.utc                   = createUTC;
-    hooks.unix                  = createUnix;
-    hooks.months                = listMonths;
-    hooks.isDate                = isDate;
-    hooks.locale                = getSetGlobalLocale;
-    hooks.invalid               = createInvalid;
-    hooks.duration              = createDuration;
-    hooks.isMoment              = isMoment;
-    hooks.weekdays              = listWeekdays;
-    hooks.parseZone             = createInZone;
-    hooks.localeData            = getLocale;
-    hooks.isDuration            = isDuration;
-    hooks.monthsShort           = listMonthsShort;
-    hooks.weekdaysMin           = listWeekdaysMin;
-    hooks.defineLocale          = defineLocale;
-    hooks.updateLocale          = updateLocale;
-    hooks.locales               = listLocales;
-    hooks.weekdaysShort         = listWeekdaysShort;
-    hooks.normalizeUnits        = normalizeUnits;
-    hooks.relativeTimeRounding  = getSetRelativeTimeRounding;
-    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
-    hooks.calendarFormat        = getCalendarFormat;
-    hooks.prototype             = proto;
-
-    // currently HTML5 input type only supports 24-hour formats
-    hooks.HTML5_FMT = {
-        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type="datetime-local" />
-        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type="datetime-local" step="1" />
-        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type="datetime-local" step="0.001" />
-        DATE: 'YYYY-MM-DD',                             // <input type="date" />
-        TIME: 'HH:mm',                                  // <input type="time" />
-        TIME_SECONDS: 'HH:mm:ss',                       // <input type="time" step="1" />
-        TIME_MS: 'HH:mm:ss.SSS',                        // <input type="time" step="0.001" />
-        WEEK: 'GGGG-[W]WW',                             // <input type="week" />
-        MONTH: 'YYYY-MM'                                // <input type="month" />
-    };
-
-    return hooks;
-
-})));

+ 205 - 0
pages-roadshow/utils/validate.js

@@ -0,0 +1,205 @@
+
+/* 表单校验 */
+
+export const validateForm = (type,form) => {
+	// console.log(type)
+	switch (type) {
+		case '内部会议': return validateInsideMeeting(form);
+		case '公开会议': return validateOpenMeeting(form);
+		case '路演': return validateRoadshow(form);
+		case '报告电话会': return validateTelmeeting(form);
+		case '事项': return validateMatter(form);
+	}
+	
+}
+				
+/* 内部会议校验 */				
+const validateInsideMeeting = ({activityType,selectResearchers}) => {
+	let haveCheck = false;
+	const {researcherId,startTime,endTime} = selectResearchers[0];
+	
+	if(!activityType) {
+		Toast('请选择活动类型');
+		return haveCheck
+	}
+	
+	if(!researcherId.length || !researcherId){
+		Toast('请选择研究员');
+		return haveCheck
+	}
+	
+	if(!startTime){
+		Toast('请选择开始时间');
+		return haveCheck
+	}
+	
+	if(!endTime){
+		Toast('请选择结束时间');
+		return haveCheck
+	}
+	
+	haveCheck = true;
+	
+	return haveCheck
+	
+}
+
+/* 报告电话会校验 */
+const validateTelmeeting = ({activityType,selectResearchers,activityClass}) => {
+	
+	let bol1 = validateInsideMeeting({activityType,selectResearchers})
+	
+	if(bol1) {
+		let haveCheck = false;
+		
+		if(!activityClass){
+			Toast('请选择活动类别 ');
+			return haveCheck
+		}
+		 
+		haveCheck = true;
+		return haveCheck
+	} else {
+		return false
+	}
+
+}
+
+/* 路演校验 */
+const validateRoadshow = ({ activityType,selectResearchers,roadshowType,roadshowPlatform,roadshowCity,companyId  }) => {
+	let haveCheck = false;
+	
+	if(!activityType){
+		Toast('请选择活动类型')
+		return haveCheck 
+	}
+	
+	if(!roadshowType){
+		Toast('请选择路演形式')
+		return haveCheck 
+	}
+	
+	if(!roadshowPlatform && roadshowType === '线上'){
+		Toast('请输入路演平台')
+		return haveCheck 
+	}
+	
+	if(!roadshowCity.length && roadshowType === '线下'){
+		Toast('请选择路演城市')
+		return haveCheck 
+	}
+	
+	if(!companyId){
+		Toast('请选择客户')
+		return haveCheck 
+	}
+	
+	let haveFull_rs = selectResearchers.every(item => item.researcherId);
+	let haveFull_startTime = selectResearchers.every(item => item.startTime);
+	let haveFull_endTime = selectResearchers.every(item => item.endTime);
+	
+	if(!haveFull_rs){
+		Toast('请选择研究员')
+		return haveCheck 
+	}
+	if(!haveFull_startTime){
+		Toast('请选择开始时间')
+		return haveCheck 
+	}
+	if(!haveFull_endTime){
+		Toast('请选择结束时间')
+		return haveCheck 
+	}
+	
+	haveCheck = true;
+	return haveCheck
+	
+}
+
+/* 公开会议校验 */
+const validateOpenMeeting = ({ activityType,selectResearchers,roadshowType,roadshowPlatform,roadshowCity,meetingTheme,partnersName  }) => {
+	let haveCheck = false;
+	
+	if(!activityType){
+		Toast('请选择活动类型')
+		return haveCheck 
+	}
+	
+	if(!roadshowType){
+		Toast('请选择会议形式')
+		return haveCheck 
+	}
+	
+	if(!roadshowPlatform && roadshowType === '线上'){
+		Toast('请输入会议平台')
+		return haveCheck 
+	}
+	
+	if(!roadshowCity.length && roadshowType === '线下'){
+		Toast('请选择会议城市')
+		return haveCheck 
+	}
+	
+	if(!meetingTheme){
+		Toast('请输入会议主题')
+		return haveCheck 
+	}
+	
+	if(!partnersName){
+		Toast('请输入合作方名称')
+		return haveCheck 
+	}
+	
+	let haveFull_rs = selectResearchers.every(item => item.researcherId);
+	let haveFull_startTime = selectResearchers.every(item => item.startTime);
+	let haveFull_endTime = selectResearchers.every(item => item.endTime);
+	
+	if(!haveFull_rs){
+		Toast('请选择研究员')
+		return haveCheck 
+	}
+	if(!haveFull_startTime){
+		Toast('请选择开始时间')
+		return haveCheck 
+	}
+	if(!haveFull_endTime){
+		Toast('请选择结束时间')
+		return haveCheck 
+	}
+	
+	haveCheck = true;
+	return haveCheck
+}
+
+/* 事项校验 */
+const validateMatter = ({ startTime,endTime,matterContent }) => {
+	
+	let haveCheck = false;
+	
+	if(!matterContent) {
+		Toast('请输入事项内容');
+		return haveCheck
+	}
+	
+	if(!startTime){
+		Toast('请选择开始时间');
+		return haveCheck
+	}
+	
+	if(!endTime){
+		Toast('请选择结束时间');
+		return haveCheck
+	}
+	
+	haveCheck = true;
+	return haveCheck
+}
+
+/* 提示框 */
+export const Toast = (title,icon="none",duration=1500) => {
+	uni.showToast({
+		title,
+		icon,
+		duration
+	})
+}

+ 12 - 0
pages.json

@@ -168,6 +168,18 @@
 				"style": {
 				  "navigationBarTitleText": "添加活动"
 				}
+			 },
+			 {
+				"path": "addActivity/byCell",
+				"style": {
+				  "navigationBarTitleText": "添加活动"
+				}
+			 },
+			 {
+				"path": "addMatter/index",
+				"style": {
+				  "navigationBarTitleText": "添加事项"
+				}
 			 }
 		 ]
 	 }

+ 16 - 17
pages/workbench/index.vue

@@ -21,19 +21,12 @@
 			<view class="tab-title">{{item.label}}</view>
 			<view class="tab-ul">
 				<view class="tab-item" @click="handleGoNext(tab.url)" v-for="tab in item.child" :key="tab.label">
-					<image src="@/static/icon-1.png" mode="aspectFill" class="icon" v-if="tab.label==='客户审批'"/>
-					<image src="@/static/icon-2.png" mode="aspectFill" class="icon" v-else-if="tab.label==='合同审批'"/>
-					<image src="@/static/icon-3.png" mode="aspectFill" class="icon" v-else-if="tab.label==='用印审批'"/>
-					<image src="@/static/icon-4.png" mode="aspectFill" class="icon" v-else-if="tab.label==='活动审批'"/>
-					<image src="@/static/icon-5.png" mode="aspectFill" class="icon" v-else-if="tab.label==='研究员日历'"/>
-					<image src="@/static/icon-6.png" mode="aspectFill" class="icon" v-else-if="tab.label==='我的日历'"/>
+					<image :src="tab.img" mode="aspectFill" class="icon"/>
 					<view class="label">{{tab.label}}</view>
 				</view>
 			</view>
 		</view>
 
-
-
 	</view>
 </template>
 
@@ -48,20 +41,24 @@
 						child: [
 							{
 								label: '客户审批',
-								url: '/pages-approve/custome/list'
+								url: '/pages-approve/custome/list',
+								img: require('@/static/icon-1.png')
 							},
 							{
 								label: '合同审批',
-								url: '/pages-approve/contract/list'
+								url: '/pages-approve/contract/list',
+								img: require('@/static/icon-2.png')
 							},
 							{
 								label: '用印审批',
-								url: '/pages-approve/seal/list'
-							},
-							{
-								label: '活动审批',
-								url: '/pages-approve/activity/list'
+								url: '/pages-approve/seal/list',
+								img: require('@/static/icon-3.png')
 							},
+							// {
+							// 	label: '活动审批',
+							// 	url: '/pages-approve/activity/list',
+							// img: require('@/static/icon-4.png')
+							// },
 						]
 					},
 					{
@@ -69,11 +66,13 @@
 						child: [
 							{
 								label: '研究员日历',
-								url: '/pages-roadshow/researcherCalendar/index'
+								url: '/pages-roadshow/researcherCalendar/index',
+								img: require('@/static/icon-5.png')
 							},
 							{
 								label: '我的日历',
-								url: '/pages-approve/myCalendar/index'
+								url: '/pages-roadshow/myCalendar/index',
+								img: require('@/static/icon-6.png')
 							}
 						]
 					}

+ 10 - 5
utils/config.js

@@ -3,13 +3,17 @@
 const env=wx.getAccountInfoSync().miniProgram
 console.log('环境:',env);
 // 请求根路径
-let baseUrl='http://8.136.199.33:8607/h5adminapi'
+let baseUrl='http://8.136.199.33:8607/h5adminapi',linkRoadshowUrl;
+
 if(env.envVersion==='develop'){//开发
-    baseUrl='http://8.136.199.33:8607/h5adminapi'
+    baseUrl='http://8.136.199.33:8607/h5adminapi';
+    linkRoadshowUrl='http://192.168.77.17:3000/xcx_h5/ssbg';
 }else if(env.envVersion==='trial'){//体验版
-    baseUrl='http://8.136.199.33:8607/h5adminapi'
+    baseUrl='http://8.136.199.33:8607/h5adminapi';
+		linkRoadshowUrl='http://192.168.77.17:3000/xcx_h5/ssbg';
 }else if(env.envVersion==='release'){//正式版
-    baseUrl='https://ficc.hzinsights.com/h5adminapi'
+    baseUrl='https://ficc.hzinsights.com/h5adminapi';
+		linkRoadshowUrl='';
 }
 
 // 公共分享
@@ -20,5 +24,6 @@ const shareData={
 
 module.exports={
     baseUrl,
-    shareData
+    shareData,
+		linkRoadshowUrl
 }

Some files were not shown because too many files changed in this diff