/// <summary> /// 回复文本内容 /// </summary> /// <param name="to">接收者</param> /// <param name="from">消息来源</param> /// <param name="content">消息内容</param> /// <returns>生成的输出文本</returns> public static string ResponseTextMsg(string to, string from, string content) { XmlDocument doc = new XmlDocument(); try { doc.LoadXml(content); if (doc.InnerText.Length < 50) { doc = null; } } catch { doc = null; } if (doc == null) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("<xml>"); sb.AppendFormat("<ToUserName><![CDATA[{0}]]></ToUserName>", to); sb.AppendFormat("<FromUserName><![CDATA[{0}]]></FromUserName>", from); sb.AppendFormat("<CreateTime>{0}</CreateTime>", DateTools.GetNow().Ticks); sb.AppendFormat("<MsgType><![CDATA[text]]></MsgType>"); sb.AppendFormat("<Content><![CDATA[{0}]]></Content>", content); sb.AppendFormat("<FuncFlag>0</FuncFlag>"); sb.AppendFormat("</xml>"); return(sb.ToString()); } else { return(doc.InnerXml); } }
/// <summary> /// 生成包括Sig,Method,Api_key在内的全部的参数 /// </summary> /// <param name="method_name"></param> /// <param name="parameters"></param> /// <returns></returns> public KeyValue[] Sign(string method_name, KeyValue[] parameters) { List <KeyValue> list = new List <KeyValue>(parameters); list.Add(KeyValue.Create("method", method_name)); //指定调用的方法名 list.Add(KeyValue.Create("api_key", api_key)); //api_key list.Add(KeyValue.Create("call_id", DateTools.GetNow().Ticks)); //以时间戳作为call_id参数值 list.Sort(); StringBuilder values = new StringBuilder(); foreach (KeyValue param in list) { if (!string.IsNullOrEmpty(param.Value)) { values.Append(param.ToString()); } } values.Append(secret); //指定Secret //生成sig byte[] md5_result = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(values.ToString())); StringBuilder sig_builder = new StringBuilder(); foreach (byte b in md5_result) { sig_builder.Append(b.ToString("x2")); } list.Add(KeyValue.Create("sig", sig_builder.ToString())); return(list.ToArray()); }
public string MPAPI() { string msg = ""; try { StringBuilder sb = new StringBuilder(); sb.AppendFormat("<xml>"); sb.AppendFormat("<ToUserName><![CDATA[{0}]]></ToUserName>", ToId); sb.AppendFormat("<FromUserName><![CDATA[{0}]]></FromUserName>", FromId); sb.AppendFormat("<CreateTime>{0}</CreateTime>", DateTools.GetNow().Ticks); sb.AppendFormat("<MsgType><![CDATA[text]]></MsgType>"); sb.AppendFormat("<Content><![CDATA[{0}]]></Content>", MsgText); sb.AppendFormat("</xml>"); string url = BLL.Fans.GetBy("WeChatOpenId", FromId).CallBackText; byte[] byteArray = Encoding.UTF8.GetBytes(sb.ToString()); HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(url)); webRequest.Method = "POST"; //webRequest.ContentType = "application/x-www-form-urlencoded"; webRequest.ContentLength = byteArray.Length; Stream newStream = webRequest.GetRequestStream(); newStream.Write(byteArray, 0, byteArray.Length); newStream.Close(); HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); StreamReader php = new StreamReader(response.GetResponseStream(), Encoding.UTF8); msg = php.ReadToEnd(); } catch { msg = ""; } return(msg); }
/// <summary> /// 设置会话参数 /// </summary> /// <param name="openid"></param> /// <param name="MsgArgs"></param> /// <returns></returns> public static Model.Fans SetGoOnCmd(string openid, string MsgArgs) { Model.Fans fans = GetBy("WeChatOpenId", openid); if (fans != null && !string.IsNullOrEmpty(MsgArgs)) { fans.GoOnCmd += Rules.Separation[0] + MsgArgs; fans.LastCmdTime = DateTools.GetNow(); fans.update(new string[] { "GoOnCmd", "LastCmdTime" }); } return(fans); }
/// <summary> /// 取消订阅 /// </summary> /// <param name="openid"></param> /// <returns></returns> public static Model.Fans UnSubscribe(string openid) { Model.Fans fans = GetBy("WeChatOpenId", openid); if (fans != null) { fans.Subscribe = 0; fans.LastVisit = DateTools.GetNow(); fans.update(new string[] { "Subscribe", "LastVisit" }); } return(fans); }
public static void Add(string key, string value, string description) { if (GetByKey(key) == null) { List <XmlParamter> xplist = new List <XmlParamter>(); xplist.Add(new XmlParamter("Key", key)); xplist.Add(new XmlParamter("Value", value)); xplist.Add(new XmlParamter("Description", "")); xplist.Add(new XmlParamter("UpdateTime", DateTools.GetNow().ToString("yyyy-MM-dd HH:mm:ss"))); XMLHelper.AddData(GetPath(), "KeyValue", xplist.ToArray()); } }
/// <summary> /// 设置会话 /// </summary> /// <param name="openid"></param> /// <returns></returns> public static Model.Fans SetSession(string openid, string GoOnCmd, string DoMethod, string MsgArgs, string CallBackText) { Model.Fans fans = GetBy("WeChatOpenId", openid); if (fans != null) { fans.GoOnCmd = GoOnCmd; fans.DoMethod = DoMethod; fans.CmdContent = MsgArgs; fans.CallBackText = CallBackText; fans.LastCmdTime = DateTools.GetNow(); fans.update(new string[] { "GoOnCmd", "DoMethod", "CmdContent", "CallBackText", "LastCmdTime" }); } return(fans); }
public static void Edit(string key, string value, string description) { if (GetByKey(key) != null) { XmlParamter xpKey = new XmlParamter("Key", key); xpKey.Direction = System.IO.ParameterDirection.Equal; XmlParamter xpValue = new XmlParamter("Value", value); xpValue.Direction = System.IO.ParameterDirection.Update; XmlParamter xpDescription = new XmlParamter("Description", description); xpDescription.Direction = System.IO.ParameterDirection.Update; XmlParamter xpUpdateTime = new XmlParamter("UpdateTime", DateTools.GetNow().ToString("yyyy-MM-dd HH:mm:ss")); xpUpdateTime.Direction = System.IO.ParameterDirection.Update; XMLHelper.UpdateData(path, "KeyValue", xpKey, xpValue, xpDescription, xpUpdateTime); } }
/// <summary> /// 回复音乐内容 /// </summary> /// <param name="to">接收者</param> /// <param name="from">消息来源</param> /// <param name="title">标题</param> /// <param name="description">描述信息</param> /// <param name="musicurl">音乐链接</param> /// <param name="hqmusicurl">高质量音乐链接,WIFI环境优先使用该链接播放音乐</param> /// <returns>生成的输出文本</returns> public static string ResponseMusicMsg(string to, string from, string title, string description, string musicurl, string hqmusicurl) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("<xml>"); sb.AppendFormat("<ToUserName><![CDATA[{0}]]></ToUserName>", to); sb.AppendFormat("<FromUserName><![CDATA[{0}]]></FromUserName>", from); sb.AppendFormat("<CreateTime>{0}</CreateTime>", DateTools.GetNow().Ticks); sb.AppendFormat("<MsgType><![CDATA[music]]></MsgType>"); sb.AppendFormat("<Music>"); sb.AppendFormat(" <Title><![CDATA[{0}]]></Title>", title); sb.AppendFormat(" <Description><![CDATA[{0}]]></Description>", description); sb.AppendFormat(" <MusicUrl><![CDATA[{0}]]></MusicUrl>", (!string.IsNullOrEmpty(musicurl) && musicurl.Contains("http://")) ? musicurl : ApiUrl + musicurl); sb.AppendFormat(" <HQMusicUrl><![CDATA[{0}]]></HQMusicUrl>", (!string.IsNullOrEmpty(hqmusicurl) && hqmusicurl.Contains("http://")) ? hqmusicurl : ApiUrl + hqmusicurl); sb.AppendFormat(" <FuncFlag>0</FuncFlag>"); sb.AppendFormat("</Music>"); sb.AppendFormat("</xml>"); return(sb.ToString()); }
/// <summary> /// 订阅 /// </summary> /// <param name="openid"></param> /// <returns></returns> public static Model.Fans Subscribe(string openid) { Model.Fans fans = GetBy("WeChatOpenId", openid); if (fans == null) { fans = new Model.Fans(); fans.Guid = Guid.NewGuid().ToString(); fans.WeChatOpenId = openid; fans.Subscribe = 1; fans.LastVisit = DateTools.GetNow(); fans.insert(); } else { fans.Subscribe = 1; fans.LastVisit = DateTools.GetNow(); fans.update(new string[] { "Subscribe", "LastVisit" }); } return(fans); }
void WeChatApi_Load(object sender, EventArgs e) { Response.Clear(); if (string.IsNullOrEmpty(Request.QueryString["echostr"])) { string toUser = Request.QueryString["toUser"]; string fromUser = Request.QueryString["fromUser"]; string MsgType = Request.QueryString["MsgType"]; string Event = Request.QueryString["Event"]; string Content = Request.QueryString["Content"]; string MsgId = ""; try { //声明一个XMLDoc文档对象,LOAD()xml字符串 if (string.IsNullOrEmpty(Content)) { XmlDocument doc = new XmlDocument(); doc.LoadXml(new StreamReader(Request.InputStream).ReadToEnd()); toUser = doc.GetElementsByTagName("ToUserName")[0].InnerText; fromUser = doc.GetElementsByTagName("FromUserName")[0].InnerText; MsgType = doc.GetElementsByTagName("MsgType")[0].InnerText; try { MsgId = doc.GetElementsByTagName("MsgId")[0].InnerText; } catch { } try { Content = doc.GetElementsByTagName("Content")[0].InnerText; } catch { } try { Event = doc.GetElementsByTagName("Event")[0].InnerText; if (string.IsNullOrEmpty(Content) && !string.IsNullOrEmpty(Event)) { Content = Event; } } catch { } } Wlniao.WeChat.Model.Fans fans = Wlniao.WeChat.BLL.Fans.Check(fromUser, Content); switch (MsgType.ToLower()) { case "event": case "text": Wlniao.WeChat.Model.Rules rule = null; string msgArgs = ""; try { rule = Wlniao.WeChat.BLL.Rules.GetRule(Content, fromUser); } catch { } if (rule != null) { if (Content.StartsWith(rule.GoOnCmd)) { msgArgs = Content.Substring(rule.GoOnCmd.Length).Trim(); } Wlniao.WeChat.BLL.Fans.SetSession(fromUser, rule.GoOnCmd, rule.DoMethod, msgArgs, rule.CallBackText); if (!string.IsNullOrEmpty(rule.DoMethod)) { rule.ReContent = RunMethod(rule.DoMethod, fromUser, toUser, Content, msgArgs); } else if (string.IsNullOrEmpty(rule.ReContent)) { string where = "RuleGuid='" + rule.Guid + "'"; if (fans.AllowTest == 1) { where += " and (ContentStatus='normal' or ContentStatus='test')"; } else { where += " and ContentStatus='normal'"; } List <Wlniao.WeChat.Model.RuleContent> listAll = Wlniao.WeChat.Model.RuleContent.find(where + " order by LastStick desc").list(); List <Wlniao.WeChat.Model.RuleContent> listText = Wlniao.WeChat.Model.RuleContent.find(where + " and ContentType='text' order by LastStick desc").list(); List <Wlniao.WeChat.Model.RuleContent> listPicText = Wlniao.WeChat.Model.RuleContent.find(where + " and ContentType='pictext' order by LastStick desc").list(); List <Wlniao.WeChat.Model.RuleContent> listMusic = Wlniao.WeChat.Model.RuleContent.find(where + " and ContentType='music' order by LastStick desc").list(); if (rule.SendMode == "sendgroup" && listPicText != null && listPicText.Count > 0) { rule.ReContent = ResponsePicTextMsg(fromUser, toUser, listPicText); } else if (listAll.Count > 0) { int i = 0; if (rule.SendMode == "sendrandom") { i = new Random().Next(0, listAll.Count); } if (listAll[i].ContentType == "text") { rule.ReContent = listAll[i].TextContent; try { //更新推送次数 listAll[i].PushCount++; listAll[i].update("PushCount"); } catch { } } else if (listAll[i].ContentType == "music") { rule.ReContent = ResponseMusicMsg(fromUser, toUser, listAll[i].Title, listAll[i].TextContent, listAll[i].MusicUrl, listAll[i].MusicUrl); try { //更新推送次数 listAll[i].PushCount++; listAll[i].update("PushCount"); } catch { } } else if (listAll[i].ContentType == "pictext") { List <Wlniao.WeChat.Model.RuleContent> listTemp = new List <Model.RuleContent>(); listTemp.Add(listAll[i]); rule.ReContent = ResponsePicTextMsg(fromUser, toUser, listTemp); } } } Response.Write(ResponseTextMsg(fromUser, toUser, rule.ReContent)); } else { if (string.IsNullOrEmpty(fans.DoMethod) || fans.LastCmdTime < DateTools.GetNow().AddSeconds(0 - BLL.Rules.SessionTimeOut)) { Response.Write(ResponseTextMsg(fromUser, toUser, RunDefaultMethod(fromUser, toUser, Content))); } else { Response.Write(ResponseTextMsg(fromUser, toUser, RunMethod(fans.DoMethod, fromUser, toUser, (fans.GoOnCmd + BLL.Rules.Separation[0] + Content).Trim(), Content))); } } break; default: break; } } catch { } } else if (CheckSignature(Context)) { Response.Write(Request.QueryString["echostr"]); } Response.End(); }
/// <summary> /// 回复图文内容 /// </summary> /// <param name="to">接收者</param> /// <param name="from">消息来源</param> /// <param name="content">消息内容</param> /// <returns>生成的输出文本</returns> public static string ResponsePicTextMsg(string to, string from, List <Model.RuleContent> articles) { if (articles == null) { articles = new List <Model.RuleContent>(); } int count = 0; StringBuilder sbItems = new StringBuilder(); foreach (Model.RuleContent article in articles) { try { if (string.IsNullOrEmpty(article.Title) || string.IsNullOrEmpty(article.PicUrl) || string.IsNullOrEmpty(article.TextContent)) { continue; } StringBuilder sbTemp = new StringBuilder(); sbTemp.AppendFormat("<item>"); sbTemp.AppendFormat(" <Title><![CDATA[{0}]]></Title>", article.Title); sbTemp.AppendFormat(" <Description><![CDATA[{0}]]></Description>", strUtil.RemoveHtmlTag(strUtil.HtmlDecode(article.TextContent))); string urlTemp = article.PicUrl; if (count > 0) { urlTemp = string.IsNullOrEmpty(article.ThumbPicUrl) ? article.PicUrl : article.ThumbPicUrl; } sbTemp.AppendFormat(" <PicUrl><![CDATA[{0}]]></PicUrl>", (!string.IsNullOrEmpty(urlTemp) && urlTemp.Contains("http://")) ? urlTemp : ApiUrl + urlTemp); if (string.IsNullOrEmpty(article.LinkUrl)) { sbTemp.AppendFormat(" <Url><![CDATA[{0}]]></Url>", ApiUrl + "/article.aspx?id=" + article.Id); } else { sbTemp.AppendFormat(" <Url><![CDATA[{0}]]></Url>", article.LinkUrl); } sbTemp.AppendFormat(" <FuncFlag>0</FuncFlag>"); sbTemp.AppendFormat("</item>"); sbItems.Append(sbTemp.ToString()); count++; //更新推送次数 article.PushCount++; article.update("PushCount"); if (count == 9) { break; } } catch { } } StringBuilder sb = new StringBuilder(); sb.AppendFormat("<xml>"); sb.AppendFormat("<ToUserName><![CDATA[{0}]]></ToUserName>", to); sb.AppendFormat("<FromUserName><![CDATA[{0}]]></FromUserName>", from); sb.AppendFormat("<CreateTime>{0}</CreateTime>", DateTools.GetNow().Ticks); sb.AppendFormat("<MsgType><![CDATA[news]]></MsgType>"); sb.AppendFormat("<ArticleCount>{0}></ArticleCount>", count); sb.AppendFormat("<Articles>"); sb.AppendFormat(sbItems.ToString()); sb.AppendFormat("</Articles>"); sb.AppendFormat("<FuncFlag>0</FuncFlag>"); sb.AppendFormat("</xml>"); return(sb.ToString()); }
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { _Guid = Request["guid"]; if (string.IsNullOrEmpty(_Guid)) { _Display = "display:none;"; } else { _DisplayNew = "display:none;"; } if (helper.GetParam("type") == "auto") { _GobackUrl = "rulesauto.aspx"; _DoMethodDisplay = "display:none;"; } else { _ReContentDisplay = "display:none;"; _GobackUrl = "rulesmethod.aspx"; } switch (helper.GetParam("action").ToLower()) { case "get": Wlniao.WeChat.Model.Rules rulesGet = Wlniao.WeChat.BLL.Rules.Get(_Guid); if (rulesGet == null) { rulesGet = new Wlniao.WeChat.Model.Rules(); } try { rulesGet.ReContent = rulesGet.ReContent.Replace("\n", "<br/>"); } catch { } try { rulesGet.RuleHelp = rulesGet.RuleHelp.Replace("\n", "<br/>"); } catch { } helper.Response(rulesGet); break; case "set": Wlniao.WeChat.Model.Rules rulesSet = Wlniao.WeChat.BLL.Rules.Get(_Guid); if (rulesSet == null) { rulesSet = new Wlniao.WeChat.Model.Rules(); rulesSet.Guid = Guid.NewGuid().ToString(); } rulesSet.RuleName = helper.GetParam("RuleName"); rulesSet.DoMethod = helper.GetParam("DoMethod"); rulesSet.ReContent = helper.GetParam("ReContent").Replace("<br/>", "\n"); rulesSet.RuleHelp = helper.GetParam("RuleHelp").Replace("<br/>", "\n"); rulesSet.CallBackText = helper.GetParam("CallBackText"); rulesSet.SendMode = helper.GetParam("SendMode"); if (rulesSet.Id > 0) { if (Tool.GetConfiger("UseXml") == "true") { try { helper.Result.Join(System.IO.XMLHelper.UpdateData(PathHelper.Map("~/xcenter/data/wechat/rules.xml"), "Rules", System.IO.XMLHelper.CreateEqualParameter("Guid", rulesSet.Guid), System.IO.XMLHelper.CreateUpdateParameter("RuleName", rulesSet.RuleName), System.IO.XMLHelper.CreateUpdateParameter("DoMethod", rulesSet.DoMethod), System.IO.XMLHelper.CreateUpdateParameter("ReContent", rulesSet.ReContent), System.IO.XMLHelper.CreateUpdateParameter("RuleHelp", rulesSet.RuleHelp), System.IO.XMLHelper.CreateUpdateParameter("RuleHelp", rulesSet.CallBackText))); } catch (Exception ex) { helper.Result.Add("错误:" + ex.Message); } } else { helper.Result = rulesSet.update(); } } else { if (Tool.GetConfiger("UseXml") == "true") { helper.Result.Join(System.IO.XMLHelper.AddData(PathHelper.Map("~/xcenter/data/wechat/rules.xml"), "Rules", System.IO.XMLHelper.CreateInsertParameter("Guid", rulesSet.Guid), System.IO.XMLHelper.CreateInsertParameter("RuleName", rulesSet.RuleName), System.IO.XMLHelper.CreateInsertParameter("DoMethod", rulesSet.DoMethod), System.IO.XMLHelper.CreateInsertParameter("ReContent", rulesSet.ReContent), System.IO.XMLHelper.CreateInsertParameter("RuleHelp", rulesSet.RuleHelp), System.IO.XMLHelper.CreateInsertParameter("CallBackText", rulesSet.CallBackText))); } else { helper.Result = rulesSet.insert(); } } helper.ResponseResult(); break; case "setcode": Wlniao.WeChat.Model.RuleCode codeSet = Wlniao.WeChat.Model.RuleCode.findByField("StrGuid", _Guid); if (codeSet == null) { helper.Result = Wlniao.WeChat.BLL.Rules.AddRuleCode(helper.GetParam("Code"), helper.GetParam("RuleGuid"), helper.GetParam("SepType")); } else { helper.Result = Wlniao.WeChat.BLL.Rules.EditRuleCode(_Guid, helper.GetParam("Code"), helper.GetParam("RuleGuid"), helper.GetParam("SepType"), helper.GetParam("Status")); } helper.ResponseResult(); break; case "delcode": try { if (Wlniao.WeChat.Model.RuleCode.findByField("StrGuid", helper.GetParam("Guid")).delete() <= 0) { helper.Result.Add("Sorry,删除匹配项失败!"); } } catch (Exception ex) { helper.Result.Add("错误:" + ex.Message); } helper.ResponseResult(); break; case "getlist": int pageIndex = 0; int pageSize = int.MaxValue; try { pageIndex = int.Parse(helper.GetParam("pageIndex")); pageSize = int.Parse(helper.GetParam("pageSize")); } catch { } System.DataPage <Wlniao.WeChat.Model.RuleCode> items = db.findPage <Wlniao.WeChat.Model.RuleCode>("RuleGuid='" + helper.GetParam("RuleGuid") + "'", pageIndex, pageSize); List <Wlniao.WeChat.Model.RuleCode> list = items.Results; if (list == null) { list = new List <Wlniao.WeChat.Model.RuleCode>(); } foreach (Wlniao.WeChat.Model.RuleCode rulecode in list) { rulecode.Code = rulecode.Code.Replace("#", " ").Replace("$", " ").TrimStart().TrimEnd().Replace(" ", ","); } helper.Response("{total:" + items.RecordCount + ",data:" + Json.ToStringList(list) + "}"); break; case "setcontent": Wlniao.WeChat.Model.RuleContent codeContent = Wlniao.WeChat.Model.RuleContent.findByField("StrGuid", _Guid); if (codeContent == null) { helper.Result = Wlniao.WeChat.BLL.Rules.AddRuleContent(helper.GetParam("RuleGuid"), helper.GetParam("ContentType"), helper.GetParam("Title"), helper.GetParam("TextContent").Replace("<br/>", "\n"), helper.GetParam("PicUrl"), helper.GetParam("ThumbPicUrl"), helper.GetParam("MusicUrl"), helper.GetParam("LinkUrl"), helper.GetParam("ContentStatus")); } else { helper.Result = Wlniao.WeChat.BLL.Rules.EditRuleContent(_Guid, helper.GetParam("ContentType"), helper.GetParam("Title"), helper.GetParam("TextContent").Replace("<br/>", "\n"), helper.GetParam("PicUrl"), helper.GetParam("ThumbPicUrl"), helper.GetParam("MusicUrl"), helper.GetParam("LinkUrl"), helper.GetParam("ContentStatus")); } helper.ResponseResult(); break; case "delcontent": try { if (Wlniao.WeChat.Model.RuleContent.findByField("StrGuid", helper.GetParam("Guid")).delete() <= 0) { helper.Result.Add("Sorry,删除内容失败!"); } } catch (Exception ex) { helper.Result.Add("错误:" + ex.Message); } helper.ResponseResult(); break; case "stickcontent": try { Wlniao.WeChat.Model.RuleContent stick = Wlniao.WeChat.Model.RuleContent.findByField("StrGuid", helper.GetParam("Guid")); stick.LastStick = DateTools.GetNow(); stick.update("LastStick"); } catch (Exception ex) { helper.Result.Add("错误:" + ex.Message); } helper.ResponseResult(); break; case "getcontentlist": pageIndex = 0; pageSize = int.MaxValue; try { pageIndex = int.Parse(helper.GetParam("pageIndex")); pageSize = int.Parse(helper.GetParam("pageSize")); } catch { } System.DataPage <Wlniao.WeChat.Model.RuleContent> itemsContent = db.findPage <Wlniao.WeChat.Model.RuleContent>("RuleGuid='" + helper.GetParam("RuleGuid") + "' order by LastStick desc", pageIndex, pageSize); List <Wlniao.WeChat.Model.RuleContent> listContent = itemsContent.Results; if (listContent == null) { listContent = new List <Wlniao.WeChat.Model.RuleContent>(); } foreach (Wlniao.WeChat.Model.RuleContent rulecontent in listContent) { rulecontent.TextContent = rulecontent.TextContent.Replace("\n", "<br/>"); } helper.Response("{total:" + itemsContent.RecordCount + ",data:" + Json.ToStringList(listContent) + "}"); break; default: break; } } }