コード例 #1
0
        /// <summary>
        /// 执行微信请求
        /// </summary>
        public override void BuildResponseMessage()
        {
            #region NeuChar 执行过程

            //var neuralSystem = NeuralSystem.Instance;
            //var messageHandlerNode = neuralSystem.GetNode("MessageHandlerNode") as MessageHandlerNode;

            //messageHandlerNode = messageHandlerNode ?? new MessageHandlerNode();

            var weixinAppId = this._postModel == null ? "" : this._postModel.AppId;

            switch (RequestMessage.MsgType)
            {
            case RequestMsgType.Text:
            {
                //SenparcTrace.SendCustomLog("wxTest-request", RequestMessage.ToJson());
                ResponseMessage = CurrentMessageHandlerNode.Execute(RequestMessage, this, weixinAppId) ??
                                  OnTextRequest(RequestMessage as RequestMessageText);
                //SenparcTrace.SendCustomLog("wxTest-response", ResponseMessage.ToJson());
                //SenparcTrace.SendCustomLog("WxOpen RequestMsgType", ResponseMessage.ToJson());

                SenparcTrace.SendCustomLog("WXOPEN-TEXT ResponseMessage:", ResponseMessage.ToJson());
            }
            break;

            case RequestMsgType.Image:
            {
                ResponseMessage = CurrentMessageHandlerNode.Execute(RequestMessage, this, weixinAppId) ??
                                  OnImageRequest(RequestMessage as RequestMessageImage);
            }
            break;

            case RequestMsgType.NeuChar:
                ResponseMessage = OnNeuCharRequestAsync(RequestMessage as RequestMessageNeuChar).GetAwaiter().GetResult();
                break;

            case RequestMsgType.Event:
            {
                OnEventRequest(RequestMessage as IRequestMessageEventBase);
            }
            break;

            default:
                throw new UnknownRequestMsgTypeException("未知的MsgType请求类型", null);
            }


            #endregion
        }
コード例 #2
0
        /// <summary>
        /// Event事件类型请求
        /// </summary>
        public virtual IResponseMessageBase OnEventRequest(IRequestMessageEventBase requestMessage)
        {
            var strongRequestMessage             = RequestMessage as IRequestMessageEventBase;
            IResponseMessageBase responseMessage = null;
            var weixinAppId = _postModel.AppId;

            switch (strongRequestMessage.Event)
            {
            case Event.ENTER:
                responseMessage = OnEvent_EnterRequest(RequestMessage as RequestMessageEvent_Enter);
                break;

            case Event.LOCATION:    //自动发送的用户当前位置
                responseMessage = OnEvent_LocationRequest(RequestMessage as RequestMessageEvent_Location);
                break;

            case Event.subscribe:    //订阅
                responseMessage = OnEvent_SubscribeRequest(RequestMessage as RequestMessageEvent_Subscribe);
                break;

            case Event.unsubscribe:    //退订
                responseMessage = OnEvent_UnsubscribeRequest(RequestMessage as RequestMessageEvent_Unsubscribe);
                break;

            case Event.CLICK:    //菜单点击
                responseMessage = CurrentMessageHandlerNode.Execute(RequestMessage, this, weixinAppId) ??
                                  OnEvent_ClickRequest(RequestMessage as RequestMessageEvent_Click);
                break;

            case Event.scan:    //二维码
                responseMessage = OnEvent_ScanRequest(RequestMessage as RequestMessageEvent_Scan);
                break;

            case Event.VIEW:    //URL跳转(view视图)
                responseMessage = OnEvent_ViewRequest(RequestMessage as RequestMessageEvent_View);
                break;

            case Event.MASSSENDJOBFINISH:    //群发消息成功
                responseMessage = OnEvent_MassSendJobFinishRequest(RequestMessage as RequestMessageEvent_MassSendJobFinish);
                break;

            case Event.TEMPLATESENDJOBFINISH:    //推送模板消息成功
                responseMessage = OnEvent_TemplateSendJobFinishRequest(RequestMessage as RequestMessageEvent_TemplateSendJobFinish);
                break;

            case Event.pic_photo_or_album:    //弹出拍照或者相册发图
                responseMessage = OnEvent_PicPhotoOrAlbumRequest(RequestMessage as RequestMessageEvent_Pic_Photo_Or_Album);
                break;

            case Event.scancode_push:    //扫码推事件
                responseMessage = OnEvent_ScancodePushRequest(RequestMessage as RequestMessageEvent_Scancode_Push);
                break;

            case Event.scancode_waitmsg:    //扫码推事件且弹出“消息接收中”提示框
                responseMessage = OnEvent_ScancodeWaitmsgRequest(RequestMessage as RequestMessageEvent_Scancode_Waitmsg);
                break;

            case Event.location_select:    //弹出地理位置选择器
                responseMessage = OnEvent_LocationSelectRequest(RequestMessage as RequestMessageEvent_Location_Select);
                break;

            case Event.pic_weixin:    //弹出微信相册发图器
                responseMessage = OnEvent_PicWeixinRequest(RequestMessage as RequestMessageEvent_Pic_Weixin);
                break;

            case Event.pic_sysphoto:    //弹出系统拍照发图
                responseMessage = OnEvent_PicSysphotoRequest(RequestMessage as RequestMessageEvent_Pic_Sysphoto);
                break;

            case Event.card_pass_check:    //卡券通过审核
                responseMessage = OnEvent_Card_Pass_CheckRequest(RequestMessage as RequestMessageEvent_Card_Pass_Check);
                break;

            case Event.card_not_pass_check:    //卡券未通过审核
                responseMessage = OnEvent_Card_Not_Pass_CheckRequest(RequestMessage as RequestMessageEvent_Card_Not_Pass_Check);
                break;

            case Event.user_get_card:    //领取卡券
                responseMessage = OnEvent_User_Get_CardRequest(RequestMessage as RequestMessageEvent_User_Get_Card);
                break;

            case Event.user_del_card:    //删除卡券
                responseMessage = OnEvent_User_Del_CardRequest(RequestMessage as RequestMessageEvent_User_Del_Card);
                break;

            case Event.kf_create_session:    //多客服接入会话
                responseMessage = OnEvent_Kf_Create_SessionRequest(RequestMessage as RequestMessageEvent_Kf_Create_Session);
                break;

            case Event.kf_close_session:    //多客服关闭会话
                responseMessage = OnEvent_Kf_Close_SessionRequest(RequestMessage as RequestMessageEvent_Kf_Close_Session);
                break;

            case Event.kf_switch_session:    //多客服转接会话
                responseMessage = OnEvent_Kf_Switch_SessionRequest(RequestMessage as RequestMessageEvent_Kf_Switch_Session);
                break;

            case Event.poi_check_notify:    //审核结果事件推送
                responseMessage = OnEvent_Poi_Check_NotifyRequest(RequestMessage as RequestMessageEvent_Poi_Check_Notify);
                break;

            case Event.WifiConnected:    //Wi-Fi连网成功
                responseMessage = OnEvent_WifiConnectedRequest(RequestMessage as RequestMessageEvent_WifiConnected);
                break;

            case Event.user_consume_card:    //卡券核销
                responseMessage = OnEvent_User_Consume_CardRequest(RequestMessage as RequestMessageEvent_User_Consume_Card);
                break;

            case Event.user_enter_session_from_card:    //从卡券进入公众号会话
                responseMessage = OnEvent_User_Enter_Session_From_CardRequest(RequestMessage as RequestMessageEvent_User_Enter_Session_From_Card);
                break;

            case Event.user_view_card:    //进入会员卡
                responseMessage = OnEvent_User_View_CardRequest(RequestMessage as RequestMessageEvent_User_View_Card);
                break;

            case Event.merchant_order:    //微小店订单付款通知
                responseMessage = OnEvent_Merchant_OrderRequest(RequestMessage as RequestMessageEvent_Merchant_Order);
                break;

            case Event.submit_membercard_user_info:    //接收会员信息事件通知
                responseMessage = OnEvent_Submit_Membercard_User_InfoRequest(RequestMessage as RequestMessageEvent_Submit_Membercard_User_Info);
                break;

            case Event.ShakearoundUserShake:    //摇一摇事件通知
                responseMessage = OnEvent_ShakearoundUserShakeRequest(RequestMessage as RequestMessageEvent_ShakearoundUserShake);
                break;

            case Event.user_gifting_card:    //卡券转赠事件推送
                responseMessage = OnEvent_User_Gifting_CardRequest(RequestMessage as RequestMessageEvent_User_Gifting_Card);
                break;

            case Event.user_pay_from_pay_cell:    //微信买单完成
                responseMessage = OnEvent_User_Pay_From_Pay_CellRequest(RequestMessage as RequestMessageEvent_User_Pay_From_Pay_Cell);
                break;

            case Event.update_member_card:    //会员卡内容更新事件:会员卡积分余额发生变动时
                responseMessage = OnEvent_Update_Member_CardRequest(RequestMessage as RequestMessageEvent_Update_Member_Card);
                break;

            case Event.card_sku_remind:    //卡券库存报警事件:当某个card_id的初始库存数大于200且当前库存小于等于100时
                responseMessage = OnEvent_Card_Sku_RemindRequest(RequestMessage as RequestMessageEvent_Card_Sku_Remind);
                break;

            case Event.card_pay_order:    //券点流水详情事件:当商户朋友的券券点发生变动时
                responseMessage = OnEvent_Card_Pay_OrderRequest(RequestMessage as RequestMessageEvent_Card_Pay_Order);
                break;

            case Event.apply_merchant_audit_info:    //创建门店小程序审核事件
                responseMessage = OnEvent_Apply_Merchant_Audit_InfoRequest(RequestMessage as RequestMessageEvent_ApplyMerchantAuditInfo);
                break;

            case Event.add_store_audit_info:    //门店小程序中创建门店审核事件
                responseMessage = OnEvent_Add_Store_Audit_Info(RequestMessage as RequestMessageEvent_AddStoreAuditInfo);
                break;

            case Event.create_map_poi_audit_info:    //从腾讯地图中创建门店审核事件
                responseMessage = OnEvent_Create_Map_Poi_Audit_Info(RequestMessage as RequestMessageEvent_CreateMapPoiAuditInfo);
                break;

            case Event.modify_store_audit_info:    //修改门店图片审核事件
                responseMessage = OnEvent_Modify_Store_Audit_Info(RequestMessage as RequestMessageEvent_ModifyStoreAuditInfo);
                break;

            case Event.view_miniprogram:    //点击菜单跳转小程序的事件推送
                responseMessage = OnEvent_View_Miniprogram(RequestMessage as RequestMessageEvent_View_Miniprogram);
                break;

                #region 卡券回调

            case Event.giftcard_pay_done:
                responseMessage = OnEvent_GiftCard_Pay_DoneRequest(RequestMessage as RequestMessageEvent_GiftCard_Pay_Done);
                break;

            case Event.giftcard_send_to_friend:
                responseMessage = OnEvent_GiftCard_Send_To_FriendRequest(RequestMessage as RequestMessageEvent_GiftCard_Send_To_Friend);
                break;

            case Event.giftcard_user_accept:
                responseMessage = OnEvent_GiftCard_User_AcceptRequest(RequestMessage as RequestMessageEvent_GiftCard_User_Accept);
                break;

                #endregion

                #region 微信认证事件推送

            case Event.qualification_verify_success:    //资质认证成功(此时立即获得接口权限)
                responseMessage = OnEvent_QualificationVerifySuccessRequest(RequestMessage as RequestMessageEvent_QualificationVerifySuccess);
                break;

            case Event.qualification_verify_fail:    //资质认证失败
                responseMessage = OnEvent_QualificationVerifyFailRequest(RequestMessage as RequestMessageEvent_QualificationVerifyFail);
                break;

            case Event.naming_verify_success:    //名称认证成功(即命名成功)
                responseMessage = OnEvent_NamingVerifySuccessRequest(RequestMessage as RequestMessageEvent_NamingVerifySuccess);
                break;

            case Event.naming_verify_fail:    //名称认证失败(这时虽然客户端不打勾,但仍有接口权限)
                responseMessage = OnEvent_NamingVerifyFailRequest(RequestMessage as RequestMessageEvent_NamingVerifyFail);
                break;

            case Event.annual_renew:    //年审通知
                responseMessage = OnEvent_AnnualRenewRequest(RequestMessage as RequestMessageEvent_AnnualRenew);
                break;

            case Event.verify_expired:    //认证过期失效通知
                responseMessage = OnEvent_VerifyExpiredRequest(RequestMessage as RequestMessageEvent_VerifyExpired);
                break;
                #endregion

                #region 小程序审核事件推送
                //该事件已移动到Senparc.Weixin.WxOpen
                //case Event.weapp_audit_success://
                //    responseMessage = OnEvent_WeAppAuditSuccessRequest(RequestMessage as RequestMessageEvent_WeAppAuditSuccess);
                //    break;
                //case Event.weapp_audit_fail://
                //    responseMessage = OnEvent_WeAppAuditFailRequest(RequestMessage as RequestMessageEvent_WeAppAuditFail);
                //    break;
                #endregion
                #region 微信电子发票
            case Event.user_authorize_invoice:
                responseMessage = OnEvent_User_Authorize_Invoice(RequestMessage as RequestMessageEvent_User_Authorize_Invoice);
                break;

                #endregion
            default:
                throw new Exceptions.UnknownRequestMsgTypeException("未知的Event下属请求信息", null);
            }
            return(responseMessage);
        }
コード例 #3
0
ファイル: MessageHandler.cs プロジェクト: shawhu/WeiXinMPSDK
        ///// <summary>
        ///// 根据当前的RequestMessage创建指定类型的ResponseMessage
        ///// </summary>
        ///// <typeparam name="TR">基于ResponseMessageBase的响应消息类型</typeparam>
        ///// <returns></returns>
        //public ResponseMessageText CreateResponseMessage<TR>(string content) where TR : ResponseMessageText
        //{
        //    if (RequestMessage == null)
        //    {
        //        return null;
        //    }

        //    var responseMessage = RequestMessage.CreateResponseMessage<TR>();
        //    responseMessage.Content = content;
        //    return responseMessage;
        //}

        #endregion

        /// <summary>
        /// 执行微信请求
        /// </summary>
        public override void Execute()
        {
            if (CancelExcute)
            {
                return;
            }

            OnExecuting();

            if (CancelExcute)
            {
                return;
            }

            try
            {
                if (RequestMessage == null)
                {
                    return;
                }

                #region NeuChar 执行过程

                #region 添加模拟数据

                //var fakeMessageHandlerNode = new MessageHandlerNode()
                //{
                //    Name = "MessageHandlerNode",
                //};

                //fakeMessageHandlerNode.Config.MessagePair.Add(new MessagePair()
                //{
                //    Request = new Request
                //    {
                //        Type = RequestMsgType.Text,
                //        Keywords = new List<string>() { "nc", "neuchar" }
                //    },
                //    Response = new Response() { Type = ResponseMsgType.Text, Content = "这条消息来自NeuChar\r\n\r\n当前时间:{now}" }
                //});

                //fakeMessageHandlerNode.Config.MessagePair.Add(new MessagePair()
                //{
                //    Request = new Request
                //    {
                //        Type = RequestMsgType.Text,
                //        Keywords = new List<string>() { "senparc", "s" }
                //    },
                //    Response = new Response() { Type = ResponseMsgType.Text, Content = "这条消息同样来自NeuChar\r\n\r\n当前时间:{now}" }
                //});

                //neuralSystem.Root.SetChildNode(fakeMessageHandlerNode);//TODO:模拟添加(应当在初始化的时候就添加)

                #endregion

                var weixinAppId = this._postModel == null ? "" : this._postModel.AppId;

                switch (RequestMessage.MsgType)
                {
                case RequestMsgType.Text:
                {
                    var requestMessage = RequestMessage as RequestMessageText;

                    ResponseMessage = CurrentMessageHandlerNode.Execute(requestMessage, this, weixinAppId) ??
                                      (OnTextOrEventRequest(requestMessage) ?? OnTextRequest(requestMessage));
                }
                break;

                case RequestMsgType.Location:
                    ResponseMessage = OnLocationRequest(RequestMessage as RequestMessageLocation);
                    break;

                case RequestMsgType.Image:
                    ResponseMessage = CurrentMessageHandlerNode.Execute(RequestMessage, this, weixinAppId) ??
                                      OnImageRequest(RequestMessage as RequestMessageImage);
                    break;

                case RequestMsgType.Voice:
                    ResponseMessage = OnVoiceRequest(RequestMessage as RequestMessageVoice);
                    break;

                case RequestMsgType.Video:
                    ResponseMessage = OnVideoRequest(RequestMessage as RequestMessageVideo);
                    break;

                case RequestMsgType.Link:
                    ResponseMessage = OnLinkRequest(RequestMessage as RequestMessageLink);
                    break;

                case RequestMsgType.ShortVideo:
                    ResponseMessage = OnShortVideoRequest(RequestMessage as RequestMessageShortVideo);
                    break;

                case RequestMsgType.File:
                    ResponseMessage = OnFileRequest(RequestMessage as RequestMessageFile);
                    break;

                case RequestMsgType.NeuChar:
                    ResponseMessage = OnNeuCharRequest(RequestMessage as RequestMessageNeuChar);
                    break;

                case RequestMsgType.Unknown:
                    ResponseMessage = OnUnknownTypeRequest(RequestMessage as RequestMessageUnknownType);
                    break;

                case RequestMsgType.Event:
                {
                    var requestMessageText = (RequestMessage as IRequestMessageEventBase).ConvertToRequestMessageText();
                    ResponseMessage = CurrentMessageHandlerNode.Execute(RequestMessage, this, weixinAppId) ??
                                      OnTextOrEventRequest(requestMessageText) ??
                                      OnEventRequest(RequestMessage as IRequestMessageEventBase);
                }
                break;

                default:
                    throw new UnknownRequestMsgTypeException("未知的MsgType请求类型", null);
                }

                #endregion

                //记录上下文
                //此处修改
                if (MessageContextGlobalConfig.UseMessageContext && ResponseMessage != null && !string.IsNullOrEmpty(ResponseMessage.FromUserName))
                {
                    GlobalMessageContext.InsertMessage(ResponseMessage);
                }
            }
            catch (Exception ex)
            {
                throw new MessageHandlerException("MessageHandler中Execute()过程发生错误:" + ex.Message, ex);
            }
            finally
            {
                OnExecuted();
            }
        }
コード例 #4
0
        ///// <summary>
        ///// 根据当前的RequestMessage创建指定类型的ResponseMessage
        ///// </summary>
        ///// <typeparam name="TR">基于ResponseMessageBase的响应消息类型</typeparam>
        ///// <returns></returns>
        //public ResponseMessageText CreateResponseMessage<TR>(string content) where TR : ResponseMessageText
        //{
        //    if (RequestMessage == null)
        //    {
        //        return null;
        //    }

        //    var responseMessage = RequestMessage.CreateResponseMessage<TR>();
        //    responseMessage.Content = content;
        //    return responseMessage;
        //}

        #endregion


        /// <summary>
        /// 执行微信请求
        /// </summary>
        public override void BuildResponseMessage()
        {
            #region NeuChar 执行过程

            #region 添加模拟数据

            //var fakeMessageHandlerNode = new MessageHandlerNode()
            //{
            //    Name = "MessageHandlerNode",
            //};

            //fakeMessageHandlerNode.Config.MessagePair.Add(new MessagePair()
            //{
            //    Request = new Request
            //    {
            //        Type = RequestMsgType.Text,
            //        Keywords = new List<string>() { "nc", "neuchar" }
            //    },
            //    Response = new Response() { Type = ResponseMsgType.Text, Content = "这条消息来自NeuChar\r\n\r\n当前时间:{now}" }
            //});

            //fakeMessageHandlerNode.Config.MessagePair.Add(new MessagePair()
            //{
            //    Request = new Request
            //    {
            //        Type = RequestMsgType.Text,
            //        Keywords = new List<string>() { "senparc", "s" }
            //    },
            //    Response = new Response() { Type = ResponseMsgType.Text, Content = "这条消息同样来自NeuChar\r\n\r\n当前时间:{now}" }
            //});

            //neuralSystem.Root.SetChildNode(fakeMessageHandlerNode);//TODO:模拟添加(应当在初始化的时候就添加)

            #endregion

            var weixinAppId = this._postModel == null ? "" : this._postModel.AppId;

            switch (RequestMessage.MsgType)
            {
            case RequestMsgType.Text:
            {
                var requestMessage = RequestMessage as RequestMessageText;

                ResponseMessage = CurrentMessageHandlerNode.Execute(requestMessage, this, weixinAppId) ??
                                  (OnTextOrEventRequest(requestMessage) ?? OnTextRequest(requestMessage));
            }
            break;

            case RequestMsgType.Location:
                ResponseMessage = OnLocationRequest(RequestMessage as RequestMessageLocation);
                break;

            case RequestMsgType.Image:
                ResponseMessage = CurrentMessageHandlerNode.Execute(RequestMessage, this, weixinAppId) ??
                                  OnImageRequest(RequestMessage as RequestMessageImage);
                break;

            case RequestMsgType.Voice:
                ResponseMessage = OnVoiceRequest(RequestMessage as RequestMessageVoice);
                break;

            case RequestMsgType.Video:
                ResponseMessage = OnVideoRequest(RequestMessage as RequestMessageVideo);
                break;

            case RequestMsgType.Link:
                ResponseMessage = OnLinkRequest(RequestMessage as RequestMessageLink);
                break;

            case RequestMsgType.ShortVideo:
                ResponseMessage = OnShortVideoRequest(RequestMessage as RequestMessageShortVideo);
                break;

            case RequestMsgType.File:
                ResponseMessage = OnFileRequest(RequestMessage as RequestMessageFile);
                break;

            case RequestMsgType.NeuChar:
                ResponseMessage = OnNeuCharRequestAsync(RequestMessage as RequestMessageNeuChar).Result;
                break;

            case RequestMsgType.Unknown:
                ResponseMessage = OnUnknownTypeRequest(RequestMessage as RequestMessageUnknownType);
                break;

            case RequestMsgType.Event:
            {
                var requestMessageText = (RequestMessage as IRequestMessageEventBase).ConvertToRequestMessageText();
                ResponseMessage = CurrentMessageHandlerNode.Execute(RequestMessage, this, weixinAppId) ??
                                  OnTextOrEventRequest(requestMessageText) ??
                                  OnEventRequest(RequestMessage as IRequestMessageEventBase);
            }
            break;

            default:
                throw new UnknownRequestMsgTypeException("未知的MsgType请求类型", null);
            }

            #endregion
        }
コード例 #5
0
        /// <summary>
        /// 执行微信请求
        /// </summary>
        public override void Execute()
        {
            if (CancelExcute)
            {
                return;
            }

            OnExecuting();

            if (CancelExcute)
            {
                return;
            }

            try
            {
                if (RequestMessage == null)
                {
                    return;
                }

                #region NeuChar 执行过程

                //var neuralSystem = NeuralSystem.Instance;
                //var messageHandlerNode = neuralSystem.GetNode("MessageHandlerNode") as MessageHandlerNode;

                //messageHandlerNode = messageHandlerNode ?? new MessageHandlerNode();

                var weixinAppId = this._postModel == null ? "" : this._postModel.AppId;

                switch (RequestMessage.MsgType)
                {
                case RequestMsgType.Text:
                {
                    //SenparcTrace.SendCustomLog("wxTest-request", RequestMessage.ToJson());
                    ResponseMessage = CurrentMessageHandlerNode.Execute(RequestMessage, this, weixinAppId) ??
                                      OnTextRequest(RequestMessage as RequestMessageText);
                    //SenparcTrace.SendCustomLog("wxTest-response", ResponseMessage.ToJson());
                    //SenparcTrace.SendCustomLog("WxOpen RequestMsgType", ResponseMessage.ToJson());
                }
                break;

                case RequestMsgType.Image:
                {
                    ResponseMessage = CurrentMessageHandlerNode.Execute(RequestMessage, this, weixinAppId) ??
                                      OnImageRequest(RequestMessage as RequestMessageImage);
                }
                break;

                case RequestMsgType.NeuChar:
                    ResponseMessage = OnNeuCharRequest(RequestMessage as RequestMessageNeuChar);
                    break;

                case RequestMsgType.Event:
                {
                    OnEventRequest(RequestMessage as IRequestMessageEventBase);
                }
                break;

                default:
                    throw new UnknownRequestMsgTypeException("未知的MsgType请求类型", null);
                }


                #endregion

                //记录上下文
                //此处修改
                if (MessageContextGlobalConfig.UseMessageContext && ResponseMessage != null && !string.IsNullOrEmpty(ResponseMessage.FromUserName))
                {
                    GlobalMessageContext.InsertMessage(ResponseMessage);
                }
            }
            catch (Exception ex)
            {
                throw new MessageHandlerException("MessageHandler中Execute()过程发生错误:" + ex.Message, ex);
            }
            finally
            {
                OnExecuted();
            }
        }