public override void ProcessRequest(ICommunicationContext ctx) { if (ctx.Request.QueryString.HasKeys()) { var numberOfLines = GlobalConstants.LogFileNumberOfLines; try { var numberOfLinesString = ctx.Request.QueryString.Get("numLines"); int numLines; if (int.TryParse(numberOfLinesString, out numLines)) { if (numLines > 0) { numberOfLines = numLines; } } } catch (Exception) { //Bad Query return default number of lines } string serverLogFile; var logFile = EnvironmentVariables.ServerLogFile; if (File.Exists(logFile)) { var buffor = new Queue <string>(numberOfLines); Stream stream = File.Open(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); var file = new StreamReader(stream); while (!file.EndOfStream) { string line = file.ReadLine(); if (buffor.Count >= numberOfLines) { buffor.Dequeue(); } buffor.Enqueue(line); } string[] lastLines = buffor.ToArray(); serverLogFile = string.Join(Environment.NewLine, lastLines); } else { serverLogFile = "Could not locate Warewolf Server log file."; } var response = new StringResponseWriter(serverLogFile, "text/xml"); ctx.Send(response); } else { var result = GetFileFromPath(EnvironmentVariables.ServerLogFile); ctx.Send(result); } }
public override void ProcessRequest(ICommunicationContext ctx) { var uriString = ctx.Request.Uri.OriginalString; if(uriString.IndexOf("wwwroot", StringComparison.InvariantCultureIgnoreCase) < 0) { // http://127.0.0.1:1234/services/"/themes/system/js/json2.js" new WebGetRequestHandler().ProcessRequest(ctx); return; } var website = GetWebsite(ctx); var path = GetPath(ctx); var extension = Path.GetExtension(uriString); if(string.IsNullOrEmpty(extension)) { // // REST request e.g. http://localhost:1234/wwwroot/sources/server // const string ContentToken = "getParameterByName(\"content\")"; var layoutFilePath = string.Format("{0}\\webs\\{1}\\layout.htm", Location, website); var contentPath = string.Format("\"/{0}/views/{1}.htm\"", website, path); ctx.Send(new DynamicFileResponseWriter(layoutFilePath, ContentToken, contentPath)); return; } // Should get url's with the following signatures // // http://localhost:1234/wwwroot/sources/Scripts/jquery-1.7.1.js // http://localhost:1234/wwwroot/sources/Content/Site.css // http://localhost:1234/wwwroot/sources/images/error.png // http://localhost:1234/wwwroot/sources/Views/Dialogs/SaveDialog.htm // http://localhost:1234/wwwroot/views/sources/server.htm // // We support only 1 level below the Views folder // If path is a string without a backslash then we are processing the following request // http://localhost:1234/wwwroot/views/sources/server.htm // If path is a string with a backslash then we are processing the following request // http://localhost:1234/wwwroot/sources/Views/Dialogs/SaveDialog.htm // if(!string.IsNullOrEmpty(path) && path.IndexOf('/') == -1) { uriString = uriString.Replace(path, ""); } var result = GetFileFromPath(new Uri(uriString)); ctx.Send(result); }
public override void ProcessRequest(ICommunicationContext ctx) { var uriString = ctx.Request.Uri.OriginalString; if (uriString.IndexOf("wwwroot", StringComparison.InvariantCultureIgnoreCase) < 0) { // http://127.0.0.1:1234/services/"/themes/system/js/json2.js" new WebGetRequestHandler().ProcessRequest(ctx); return; } var website = GetWebsite(ctx); var path = GetPath(ctx); var extension = Path.GetExtension(uriString); if (string.IsNullOrEmpty(extension)) { // // REST request e.g. http://localhost:1234/wwwroot/sources/server // const string ContentToken = "getParameterByName(\"content\")"; var layoutFilePath = string.Format("{0}\\webs\\{1}\\layout.htm", Location, website); var contentPath = string.Format("\"/{0}/views/{1}.htm\"", website, path); ctx.Send(new DynamicFileResponseWriter(layoutFilePath, ContentToken, contentPath)); return; } // Should get url's with the following signatures // // http://localhost:1234/wwwroot/sources/Scripts/jquery-1.7.1.js // http://localhost:1234/wwwroot/sources/Content/Site.css // http://localhost:1234/wwwroot/sources/images/error.png // http://localhost:1234/wwwroot/sources/Views/Dialogs/SaveDialog.htm // http://localhost:1234/wwwroot/views/sources/server.htm // // We support only 1 level below the Views folder // If path is a string without a backslash then we are processing the following request // http://localhost:1234/wwwroot/views/sources/server.htm // If path is a string with a backslash then we are processing the following request // http://localhost:1234/wwwroot/sources/Views/Dialogs/SaveDialog.htm // if (!string.IsNullOrEmpty(path) && path.IndexOf('/') == -1) { uriString = uriString.Replace(path, ""); } var result = GetFileFromPath(new Uri(uriString)); ctx.Send(result); }
public override void ProcessRequest(ICommunicationContext ctx) { var postDataListID = GetDataListID(ctx); if(postDataListID != null) { new WebPostRequestHandler().ProcessRequest(ctx); return; } var serviceName = GetServiceName(ctx); var workspaceID = GetWorkspaceID(ctx); var requestTO = new WebRequestTO { ServiceName = serviceName, WebServerUrl = ctx.Request.Uri.ToString(), Dev2WebServer = String.Format("{0}://{1}", ctx.Request.Uri.Scheme, ctx.Request.Uri.Authority) }; var data = GetPostData(ctx); if(!String.IsNullOrEmpty(data)) { requestTO.RawRequestPayload = data; } var variables = ctx.Request.BoundVariables; if(variables != null) { foreach(string key in variables) { requestTO.Variables.Add(key, variables[key]); } } // Execute in its own thread to give proper context ;) Thread.CurrentPrincipal = ctx.Request.User; var responseWriter = CreateForm(requestTO, serviceName, workspaceID, ctx.FetchHeaders()); ctx.Send(responseWriter); }
public override void ProcessRequest(ICommunicationContext ctx) { var postDataListID = GetDataListID(ctx); if (postDataListID != null) { new WebPostRequestHandler().ProcessRequest(ctx); return; } var serviceName = GetServiceName(ctx); var workspaceID = GetWorkspaceID(ctx); var requestTO = new WebRequestTO { ServiceName = serviceName, WebServerUrl = ctx.Request.Uri.ToString(), Dev2WebServer = String.Format("{0}://{1}", ctx.Request.Uri.Scheme, ctx.Request.Uri.Authority) }; var data = GetPostData(ctx, Guid.Empty.ToString()); if (!String.IsNullOrEmpty(data)) { requestTO.RawRequestPayload = data; } // Execute in its own thread to give proper context ;) Thread.CurrentPrincipal = ctx.Request.User; var responseWriter = CreateForm(requestTO, serviceName, workspaceID, ctx.FetchHeaders(), PublicFormats); ctx.Send(responseWriter); }
public override void ProcessRequest(ICommunicationContext ctx) { var serviceName = GetServiceName(ctx); var instanceId = GetInstanceID(ctx); var bookmark = GetBookmark(ctx); var postDataListID = GetDataListID(ctx); var workspaceID = GetWorkspaceID(ctx); var requestTO = new WebRequestTO(); var xml = GetPostData(ctx, postDataListID); if(!String.IsNullOrEmpty(xml)) { requestTO.RawRequestPayload = xml; } requestTO.ServiceName = serviceName; requestTO.InstanceID = instanceId; requestTO.Bookmark = bookmark; requestTO.WebServerUrl = ctx.Request.Uri.ToString(); requestTO.Dev2WebServer = String.Format("{0}://{1}", ctx.Request.Uri.Scheme, ctx.Request.Uri.Authority); // Execute in its own thread to give proper context ;) Thread.CurrentPrincipal = ctx.Request.User; var responseWriter = CreateForm(requestTO, serviceName, workspaceID, ctx.FetchHeaders(), PublicFormats, ctx.Request.User); ctx.Send(responseWriter); }
public override void ProcessRequest(ICommunicationContext ctx) { var serviceName = GetServiceName(ctx); var instanceId = GetInstanceID(ctx); var bookmark = GetBookmark(ctx); var postDataListID = GetDataListID(ctx); var workspaceID = GetWorkspaceID(ctx); var requestTO = new WebRequestTO(); var xml = GetPostData(ctx, postDataListID); if (!String.IsNullOrEmpty(xml)) { requestTO.RawRequestPayload = xml; } requestTO.ServiceName = serviceName; requestTO.InstanceID = instanceId; requestTO.Bookmark = bookmark; requestTO.WebServerUrl = ctx.Request.Uri.ToString(); requestTO.Dev2WebServer = String.Format("{0}://{1}", ctx.Request.Uri.Scheme, ctx.Request.Uri.Authority); // Execute in its own thread to give proper context ;) Thread.CurrentPrincipal = ctx.Request.User; var responseWriter = CreateForm(requestTO, serviceName, workspaceID, ctx.FetchHeaders(), PublicFormats, ctx.Request.User); ctx.Send(responseWriter); }
public override void ProcessRequest(ICommunicationContext ctx) { var serviceName = ctx.GetServiceName(); var instanceId = ctx.GetInstanceID(); var bookmark = ctx.GetBookmark(); var workspaceId = ctx.GetWorkspaceID(); var requestTo = new WebRequestTO(); var xml = new SubmittedData().GetPostData(ctx); if (!string.IsNullOrEmpty(xml)) { requestTo.RawRequestPayload = xml; } requestTo.ServiceName = serviceName; requestTo.InstanceID = instanceId; requestTo.Bookmark = bookmark; requestTo.WebServerUrl = ctx.Request.Uri.ToString(); requestTo.Dev2WebServer = $"{ctx.Request.Uri.Scheme}://{ctx.Request.Uri.Authority}"; var variables = ctx.Request.BoundVariables; if (variables != null) { foreach (string key in variables) { requestTo.Variables.Add(key, variables[key]); } } Thread.CurrentPrincipal = ctx.Request.User; var responseWriter = CreateForm(requestTo, serviceName, workspaceId, ctx.FetchHeaders(), ctx.Request.User); ctx.Send(responseWriter); }
public override void ProcessRequest(ICommunicationContext ctx) { if(ctx == null) { throw new ArgumentNullException("ctx"); } var basePath = ctx.Request.BoundVariables["path"]; var result = GetApisJson(basePath); ctx.Send(result); }
public override void ProcessRequest(ICommunicationContext ctx) { if (ctx == null) { throw new ArgumentNullException("ctx"); } var basePath = ctx.Request.BoundVariables["path"]; var result = GetApisJson(basePath); ctx.Send(result); }
public override void ProcessRequest(ICommunicationContext ctx) { var serviceName = GetServiceName(ctx); var instanceId = GetInstanceID(ctx); var bookmark = GetBookmark(ctx); GetDataListID(ctx); var workspaceID = GetWorkspaceID(ctx); var formData = new WebRequestTO(); var xml = GetPostData(ctx); if (!String.IsNullOrEmpty(xml)) { formData.RawRequestPayload = xml; } formData.ServiceName = serviceName; formData.InstanceID = instanceId; formData.Bookmark = bookmark; formData.WebServerUrl = ctx.Request.Uri.ToString(); formData.Dev2WebServer = String.Format("{0}://{1}", ctx.Request.Uri.Scheme, ctx.Request.Uri.Authority); if (ExecutingUser == null) { throw new Exception("Null Executing User"); } try { // Execute in its own thread to give proper context ;) var t = new Thread(() => { Thread.CurrentPrincipal = ExecutingUser; var responseWriter = CreateForm(formData, serviceName, workspaceID, ctx.FetchHeaders(), ctx.Request.User); ctx.Send(responseWriter); }); t.Start(); t.Join(); } catch (Exception e) { // ReSharper disable InvokeAsExtensionMethod Dev2Logger.Log.Error(this, e); // ReSharper restore InvokeAsExtensionMethod } }
public override void ProcessRequest(ICommunicationContext ctx) { var serviceName = GetServiceName(ctx); var instanceId = GetInstanceID(ctx); var bookmark = GetBookmark(ctx); GetDataListID(ctx); var workspaceID = GetWorkspaceID(ctx); var formData = new WebRequestTO(); var xml = GetPostData(ctx); if(!String.IsNullOrEmpty(xml)) { formData.RawRequestPayload = xml; } formData.ServiceName = serviceName; formData.InstanceID = instanceId; formData.Bookmark = bookmark; formData.WebServerUrl = ctx.Request.Uri.ToString(); formData.Dev2WebServer = String.Format("{0}://{1}", ctx.Request.Uri.Scheme, ctx.Request.Uri.Authority); if(ExecutingUser == null) { throw new Exception("Null Executing User"); } try { // Execute in its own thread to give proper context ;) var t = new Thread(() => { Thread.CurrentPrincipal = ExecutingUser; var responseWriter = CreateForm(formData, serviceName, workspaceID, ctx.FetchHeaders(),ctx.Request.User); ctx.Send(responseWriter); }); t.Start(); t.Join(); } catch(Exception e) { // ReSharper disable InvokeAsExtensionMethod Dev2Logger.Log.Error(this, e); // ReSharper restore InvokeAsExtensionMethod } }
public override void ProcessRequest(ICommunicationContext ctx) { LoadSecuritySettings(); var serviceName = ctx.GetServiceName(); var instanceId = ctx.GetInstanceID(); var bookmark = ctx.GetBookmark(); var workspaceId = ctx.GetWorkspaceID(); var requestTo = new WebRequestTO { ServiceName = serviceName, InstanceID = instanceId, Bookmark = bookmark, WebServerUrl = $"{ctx.Request.Uri.Scheme}://{ctx.Request.Uri.Authority}/public/{OverrideResource.Name}", Dev2WebServer = $"{ctx.Request.Uri.Scheme}://{ctx.Request.Uri.Authority}" }; var data = SubmittedData.GetPostData(ctx); if (!string.IsNullOrEmpty(data)) { requestTo.RawRequestPayload = data; } var variables = ctx.Request.BoundVariables; if (variables != null) { foreach (string key in variables) { requestTo.Variables.Add(key, variables[key]); } } Thread.CurrentPrincipal = ctx.Request.User; try { var response = ExecuteWorkflow(requestTo, $"{OverrideResource.Name}.json", workspaceId, ctx.FetchHeaders(), ctx.Request.User); ctx.Send(response); } catch (Exception e) { Dev2Logger.Warn($"failed processing login request: {e.Message}", GlobalConstants.WarewolfWarn); throw; } }
public override void ProcessRequest(ICommunicationContext ctx) { var serviceName = GetServiceName(ctx); var instanceId = GetInstanceID(ctx); var bookmark = GetBookmark(ctx); GetDataListID(ctx); var workspaceId = GetWorkspaceID(ctx); var formData = new WebRequestTO(); var xml = GetPostData(ctx); if (!string.IsNullOrEmpty(xml)) { formData.RawRequestPayload = xml; } formData.ServiceName = serviceName; formData.InstanceID = instanceId; formData.Bookmark = bookmark; formData.WebServerUrl = ctx.Request.Uri.ToString(); formData.Dev2WebServer = $"{ctx.Request.Uri.Scheme}://{ctx.Request.Uri.Authority}"; if (ExecutingUser == null) { throw new Exception(ErrorResource.NullExecutingUser); } try { // Execute in its own thread to give proper context ;) var t = new Thread(() => { Thread.CurrentPrincipal = ExecutingUser; var responseWriter = CreateForm(formData, serviceName, workspaceId, ctx.FetchHeaders(), ctx.Request.User); ctx.Send(responseWriter); }); t.Start(); t.Join(); } catch (Exception e) { Dev2Logger.Error(this, e, GlobalConstants.WarewolfError); } }
#pragma warning restore S3010 public override void ProcessRequest(ICommunicationContext ctx) { if (ctx == null) { throw new ArgumentNullException("ctx"); } var basePath = ctx.Request.BoundVariables["path"]; if (!bool.TryParse(ctx.Request.BoundVariables["isPublic"], out bool isPublic)) { isPublic = false; } var result = GetApisJson(basePath, isPublic); ctx.Send(result); }
public override void ProcessRequest(ICommunicationContext ctx) { if(ctx == null) { throw new ArgumentNullException("ctx"); } var basePath = ctx.Request.BoundVariables["path"]; bool isPublic; if (!bool.TryParse(ctx.Request.BoundVariables["isPublic"], out isPublic)) { isPublic = false; } var result = GetApisJson(basePath,isPublic); ctx.Send(result); }
void WriteReponses(string basePath, bool isPublic, ICommunicationContext ctx) { var webPath = basePath.Replace("\\", "/"); var searchPath = basePath.Replace("/", "\\").Replace(".api", ""); var resourceList = ResourceCatalog.Instance.GetResourceList(GlobalConstants.ServerWorkspaceID).Where( resource => resource.GetResourcePath(GlobalConstants.ServerWorkspaceID).Contains(searchPath) && resource.ResourceType == "WorkflowService").ToList(); var builder = new StringBuilder(); var val = ExecutionEnvironmentUtils.GetOpenAPIOutputForServiceList(new List <IWarewolfResource>(resourceList), ctx.Request.Uri.ToString()); builder.AppendLine(val); ctx.Send(new StringResponseWriter(builder.ToString(), "application/json")); }
public override void ProcessRequest(ICommunicationContext ctx) { // Read post data which is expected to be JSON string args; using (var reader = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding)) { args = reader.ReadToEnd(); } var className = GetClassName(ctx); var methodName = GetMethodName(ctx); var dataListID = GetDataListID(ctx); var workspaceID = GetWorkspaceID(ctx); dynamic result; try { Guid workspaceGuid; Guid.TryParse(workspaceID, out workspaceGuid); Guid dataListGuid; Guid.TryParse(dataListID, out dataListGuid); // // NOTE: result.ToString() MUST return JSON // // Ensure we execute as the correct user ;) var userPrinciple = ctx.Request.User; if (userPrinciple != null) { Thread.CurrentPrincipal = userPrinciple; Dev2Logger.Log.Info("WEB EXECUTION USER CONTEXT [ " + userPrinciple.Identity.Name + " ]"); } result = _serviceInvoker.Invoke(className, methodName, args, workspaceGuid, dataListGuid); } catch (Exception ex) { result = new ValidationResult { ErrorMessage = ex.Message }; } ctx.Send(new StringResponseWriter(result.ToString(), ContentTypes.Json)); }
public override void ProcessRequest(ICommunicationContext ctx) { // Read post data which is expected to be JSON string args; using(var reader = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding)) { args = reader.ReadToEnd(); } var className = GetClassName(ctx); var methodName = GetMethodName(ctx); var dataListID = GetDataListID(ctx); var workspaceID = GetWorkspaceID(ctx); dynamic result; try { Guid workspaceGuid; Guid.TryParse(workspaceID, out workspaceGuid); Guid dataListGuid; Guid.TryParse(dataListID, out dataListGuid); // // NOTE: result.ToString() MUST return JSON // // Ensure we execute as the correct user ;) var userPrinciple = ctx.Request.User; if(userPrinciple != null) { Thread.CurrentPrincipal = userPrinciple; Dev2Logger.Log.Info("WEB EXECUTION USER CONTEXT [ " + userPrinciple.Identity.Name + " ]"); } result = _serviceInvoker.Invoke(className, methodName, args, workspaceGuid, dataListGuid); } catch(Exception ex) { result = new ValidationResult { ErrorMessage = ex.Message }; } ctx.Send(new StringResponseWriter(result.ToString(), ContentTypes.Json)); }
public override void ProcessRequest(ICommunicationContext ctx) { // Read post data which is expected to be JSON string args; using(var reader = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding)) { args = reader.ReadToEnd(); } var className = GetClassName(ctx); var methodName = GetMethodName(ctx); var dataListID = GetDataListID(ctx); var workspaceID = GetWorkspaceID(ctx); dynamic result = null; var userPrinciple = ctx.Request.User; Thread.CurrentPrincipal = userPrinciple; try { Guid workspaceGuid; Guid.TryParse(workspaceID, out workspaceGuid); Guid dataListGuid; Guid.TryParse(dataListID, out dataListGuid); Thread.CurrentPrincipal = userPrinciple; Dev2Logger.Log.Info("WEB EXECUTION USER CONTEXT [ " + userPrinciple.Identity.Name + " ]"); Common.Utilities.PerformActionInsideImpersonatedContext(userPrinciple, () => { result = _serviceInvoker.Invoke(className, methodName, args, workspaceGuid, dataListGuid); }); } catch(Exception ex) { result = new ValidationResult { ErrorMessage = ex.Message }; } if(result != null) { ctx.Send(new StringResponseWriter(result.ToString(), ContentTypes.Json)); } }
public override void ProcessRequest(ICommunicationContext ctx) { // Read post data which is expected to be JSON string args; using (var reader = new StreamReader(ctx.Request.InputStream, ctx.Request.ContentEncoding)) { args = reader.ReadToEnd(); } var className = GetClassName(ctx); var methodName = GetMethodName(ctx); var dataListID = GetDataListID(ctx); var workspaceID = GetWorkspaceID(ctx); dynamic result = null; var userPrinciple = ctx.Request.User; Thread.CurrentPrincipal = userPrinciple; try { Guid workspaceGuid; Guid.TryParse(workspaceID, out workspaceGuid); Guid dataListGuid; Guid.TryParse(dataListID, out dataListGuid); Thread.CurrentPrincipal = userPrinciple; Dev2Logger.Log.Info("WEB EXECUTION USER CONTEXT [ " + userPrinciple.Identity.Name + " ]"); Common.Utilities.PerformActionInsideImpersonatedContext(userPrinciple, () => { result = _serviceInvoker.Invoke(className, methodName, args, workspaceGuid, dataListGuid); }); } catch (Exception ex) { result = new ValidationResult { ErrorMessage = ex.Message }; } if (result != null) { ctx.Send(new StringResponseWriter(result.ToString(), ContentTypes.Json)); } }
public override void ProcessRequest(ICommunicationContext ctx) { var postDataListId = ctx.GetDataListID(); if (postDataListId != null) { new WebPostRequestHandler(_resourceCatalog, _testCatalog, _testCoverageCatalog, _esbChannelFactory).ProcessRequest(ctx); return; } var serviceName = ctx.GetServiceName(); var workspaceId = ctx.GetWorkspaceID(); var requestTo = new WebRequestTO { ServiceName = serviceName, WebServerUrl = ctx.Request.Uri.ToString(), Dev2WebServer = $"{ctx.Request.Uri.Scheme}://{ctx.Request.Uri.Authority}", IsUrlWithTokenPrefix = ctx.Request.IsTokenAuthentication }; var data = new SubmittedData().GetPostData(ctx); if (!string.IsNullOrEmpty(data)) { requestTo.RawRequestPayload = data; } var variables = ctx.Request.BoundVariables; if (variables != null) { foreach (string key in variables) { requestTo.Variables.Add(key, variables[key]); } } // Execute in its own thread to give proper context ;) Thread.CurrentPrincipal = ctx.Request.User; var responseWriter = CreateForm(requestTo, serviceName, workspaceId, ctx.FetchHeaders(), ctx.Request.User); ctx.Send(responseWriter); }
public override void ProcessRequest(ICommunicationContext ctx) { var postDataListID = ctx.GetDataListID(); if (postDataListID != null) { _catalog = _catalog ?? ResourceCatalog.Instance; _testCatalog = _testCatalog ?? TestCatalog.Instance; new WebPostRequestHandler(_catalog, _testCatalog).ProcessRequest(ctx); return; } var serviceName = ctx.GetServiceName(); var workspaceID = ctx.GetWorkspaceID(); var requestTO = new WebRequestTO { ServiceName = serviceName, WebServerUrl = ctx.Request.Uri.ToString(), Dev2WebServer = $"{ctx.Request.Uri.Scheme}://{ctx.Request.Uri.Authority}" }; var data = SubmittedData.GetPostData(ctx); if (!string.IsNullOrEmpty(data)) { requestTO.RawRequestPayload = data; } var variables = ctx.Request.BoundVariables; if (variables != null) { foreach (string key in variables) { requestTO.Variables.Add(key, variables[key]); } } // Execute in its own thread to give proper context ;) Thread.CurrentPrincipal = ctx.Request.User; var responseWriter = CreateForm(requestTO, serviceName, workspaceID, ctx.FetchHeaders(), ctx.Request.User); ctx.Send(responseWriter); }
public override void ProcessRequest(ICommunicationContext ctx) { var result = GetFileFromPath("warewolf-Server.log"); ctx.Send(result); }
public override void ProcessRequest(ICommunicationContext ctx) { ctx.Send(new FileResponseWriter(EnvironmentVariables.ServerLogFile)); }