private void SaveFiles() { // create directory //HesterConsultants.Properties.Settings settings = // HesterConsultants.Properties.Settings.Default; // job files virtual root string jobFilesRootVirtual = Settings.Default.JobFilesRoot; if (!jobFilesRootVirtual.EndsWith(@"/")) { jobFilesRootVirtual += @"/"; } // get local path string jobFilesRootLocal = this.Server.MapPath(jobFilesRootVirtual); if (!jobFilesRootLocal.EndsWith(@"\")) { jobFilesRootLocal += @"\"; } DirectoryInfo jobInFolder = Directory.CreateDirectory(jobFilesRootLocal + newJob.JobId.ToString() + @"\in"); // "in" for submitted files // six file upload controls for (int k = 1; k <= 6; k++) { FileUpload fu = (FileUpload)this.FindControl("file" + k.ToString()); if (fu.HasFile) { string filename = HesterConsultants.AppCode.SiteUtils.WindowsSafeFilename(fu.FileName); // adjust filename if necessary filename = HesterConsultants.AppCode.SiteUtils.ConflictFreeFilename(jobInFolder.FullName, filename, Settings.Default.FilenameAppendedDigitsMax); string virtualPath = jobFilesRootVirtual + newJob.JobId.ToString() + @"/in/" + filename; try { fu.SaveAs(jobInFolder.FullName + @"\" + filename); } catch (Exception ex) { ClientData.Current.LogErrorAndSendAlert(ex); throw new Exception(SiteUtils.ExceptionMessageForCustomer("Failed to save file.")); } //int jobFileId = ClientData.Current.InsertJobFile(newJob.JobId, filename, virtualPath, false, true); //if (jobFileId == 0) // throw new Exception(SiteUtils.ExceptionMessageForCustomer("Failed to add job file to database.")); JobFile jobFile = JobFile.InsertJobFile(newJob, filename, virtualPath, false, true); if (jobFile == null) { throw new Exception(SiteUtils.ExceptionMessageForCustomer("Job file is null.")); } } } }
private async Task ProcessFile(JobFile jobFile, CancellationToken cancellationToken = default(CancellationToken)) { if ((jobFile == null) || (jobFile.FileFound == false)) { return; } try { XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(TypeLoadHelper); processor.AddJobGroupToNeverDelete(JobInitializationPluginName); processor.AddTriggerGroupToNeverDelete(JobInitializationPluginName); await processor.ProcessFileAndScheduleJobs( jobFile.FileName, jobFile.FileName, // systemId Scheduler, cancellationToken).ConfigureAwait(false); } catch (Exception e) { Log.ErrorException("Error scheduling jobs: " + e.Message, e); } }
private Panel FileDiv(JobFile file) { Panel pnlFile = new Panel(); if (!curJob.IsArchived) { // just url with qs LiteralControl hlFile = new LiteralControl(AdminUtils.LinkToGetFilePage_Image(file, "employees") + " " + AdminUtils.LinkToGetFilePage_Text(file, "employees") + " | "); LinkButton hlDeleteFile = new LinkButton(); //hlDeleteFile.OnClientClick = "return confirm('Are you sure you want to delete this file?');"; hlDeleteFile.Command += new CommandEventHandler(hlDeleteFile_Command); hlDeleteFile.CommandArgument = file.JobFileId.ToString(); hlDeleteFile.Text = "Delete"; pnlFile.Controls.Add(hlFile); pnlFile.Controls.Add(hlDeleteFile); } else // archived - no link { LiteralControl fileWithImg = new LiteralControl(AdminUtils.FileIcon() + " " + file.Name + " (archived)"); pnlFile.Controls.Add(fileWithImg); } return(pnlFile); }
private void ProcessFile(JobFile jobFile) { if ((jobFile == null) || (jobFile.FileFound == false)) { return; } try { XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(TypeLoadHelper); processor.AddJobGroupToNeverDelete(JobInitializationPluginName); processor.AddTriggerGroupToNeverDelete(JobInitializationPluginName); processor.ProcessFileAndScheduleJobs( jobFile.FileName, jobFile.FileName, // systemId scheduler); } catch (Exception e) { var message = "Could not schedule jobs and triggers from file " + jobFile.FileName + ": " + e.Message; if (FailOnSchedulingError) { throw new SchedulerException(message, e); } else { Log.Error(message, e); } } }
/// <summary> /// Called when the associated <see cref="IScheduler"/> is started, in order /// to let the plug-in know it can now make calls into the scheduler if it /// needs to. /// </summary> public virtual async Task Start(CancellationToken cancellationToken = default(CancellationToken)) { try { if (jobFiles.Count > 0) { if (ScanInterval > TimeSpan.Zero) { Scheduler.Context.Put(JobInitializationPluginName + '_' + Name, this); } foreach (KeyValuePair <string, JobFile> pair in jobFiles) { JobFile jobFile = pair.Value; if (ScanInterval > TimeSpan.Zero) { string jobTriggerName = BuildJobTriggerName(jobFile.FileBasename); TriggerKey tKey = new TriggerKey(jobTriggerName, JobInitializationPluginName); // remove pre-existing job/trigger, if any await Scheduler.UnscheduleJob(tKey, cancellationToken).ConfigureAwait(false); // TODO: convert to use builder var trig = new SimpleTriggerImpl(); trig.Name = jobTriggerName; trig.Group = JobInitializationPluginName; trig.StartTimeUtc = SystemTime.UtcNow(); trig.EndTimeUtc = null; trig.RepeatCount = SimpleTriggerImpl.RepeatIndefinitely; trig.RepeatInterval = ScanInterval; // TODO: convert to use builder JobDetailImpl job = new JobDetailImpl( jobTriggerName, JobInitializationPluginName, typeof(FileScanJob)); job.JobDataMap.Put(FileScanJob.FileName, jobFile.FilePath); job.JobDataMap.Put(FileScanJob.FileScanListenerName, JobInitializationPluginName + '_' + Name); await Scheduler.ScheduleJob(job, trig, cancellationToken).ConfigureAwait(false); Log.DebugFormat("Scheduled file scan job for data file: {0}, at interval: {1}", jobFile.FileName, ScanInterval); } await ProcessFile(jobFile, cancellationToken).ConfigureAwait(false); } } } catch (SchedulerException se) { Log.ErrorException("Error starting background-task for watching jobs file.", se); } finally { started = true; } }
/// <summary> /// Called when the associated <see cref="IScheduler"/> is started, in order /// to let the plug-in know it can now make calls into the scheduler if it /// needs to. /// </summary> public virtual void Start() { try { if (jobFiles.Count > 0) { if (scanInterval > TimeSpan.Zero) { scheduler.Context.Put(JobInitializationPluginName + '_' + Name, this); } foreach (KeyValuePair <string, JobFile> pair in jobFiles) { JobFile jobFile = pair.Value; if (scanInterval > TimeSpan.Zero) { string jobTriggerName = BuildJobTriggerName(jobFile.FileBasename); TriggerKey tKey = new TriggerKey(jobTriggerName, JobInitializationPluginName); // remove pre-existing job/trigger, if any Scheduler.UnscheduleJob(tKey); // TODO: convert to use builder SimpleTriggerImpl trig = (SimpleTriggerImpl)Scheduler.GetTrigger(tKey); trig = new SimpleTriggerImpl(); trig.Name = (jobTriggerName); trig.Group = (JobInitializationPluginName); trig.StartTimeUtc = SystemTime.UtcNow(); trig.EndTimeUtc = (null); trig.RepeatCount = (SimpleTriggerImpl.RepeatIndefinitely); trig.RepeatInterval = (scanInterval); // TODO: convert to use builder JobDetailImpl job = new JobDetailImpl( jobTriggerName, JobInitializationPluginName, typeof(FileScanJob)); job.JobDataMap.Put(FileScanJob.FileName, jobFile.FilePath); job.JobDataMap.Put(FileScanJob.FileScanListenerName, JobInitializationPluginName + '_' + Name); scheduler.ScheduleJob(job, trig); Log.DebugFormat("Scheduled file scan job for data file: {0}, at interval: {1}", jobFile.FileName, scanInterval); } ProcessFile(jobFile); } } } catch (SchedulerException se) { Log.Error("Error starting background-task for watching jobs file.", se); } finally { started = true; } }
private async Task ProcessFile(JobFile jobFile, CancellationToken cancellationToken = default) { if (jobFile == null || jobFile.FileFound == false) { return; } try { XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(TypeLoadHelper); processor.AddJobGroupToNeverDelete(JobInitializationPluginName); processor.AddTriggerGroupToNeverDelete(JobInitializationPluginName); await processor.ProcessFileAndScheduleJobs( jobFile.FileName, jobFile.FileName, // systemId Scheduler, cancellationToken).ConfigureAwait(false); } catch (Exception e) { var message = "Could not schedule jobs and triggers from file " + jobFile.FileName + ": " + e.Message; if (FailOnSchedulingError) { throw new SchedulerException(message, e); } else { Log.ErrorException(message, e); } } }
private void DeleteFile(int fileId) { filesChanged = true; JobFile file = JobFile.JobFileFromId(fileId); // remove reference from Job Job job = CacheLayer.JobFromId(file.JobId); if (file.IsReturnedFile) { job.ReturnedFiles.Remove(file); } else if (file.IsSubmittedFile) { job.SubmittedFiles.Remove(file); } else { job.WorkingFiles.Remove(file); } // delete file file.Delete(); }
private void GetSelectedFile() { //jobFile = CacheLayer.JobFileFromId(fileId); //if (jobFile == null) jobFile = JobFile.JobFileFromId(fileId); //Debug.WriteLine("GetSelectedFile(): " + jobFile.Name); }
//private static string OpenLinkToGetFilePage(JobFile file) //{ // // with rel. path, this can be used for either /admin/GetFile.aspx or /clients/GetFile.aspx // return "<a class=\"fileLink\" href=\"./GetFile.aspx?fileId=" + file.JobFileId.ToString() + "\">"; //} private static string OpenLinkToGetFilePage(JobFile file, string folder) { string s = "<a class=\"fileLink\" href=\"/" + folder + "/GetFile.aspx" + "?fileId=" + file.JobFileId.ToString() + "\">"; return(s); }
public void DeleteFile(int id) { JobFile file = GetFile(id); if (file == null) { throw new AppException("File not found in database."); } _context.JobFiles.Remove(file); _context.SaveChanges(); }
public Task ProcessFile(string filePath, CancellationToken cancellationToken = default(CancellationToken)) { JobFile file = null; int idx = jobFiles.FindIndex(pair => pair.Key == filePath); if (idx >= 0) { file = jobFiles[idx].Value; } return(ProcessFile(file, cancellationToken)); }
public void ProcessFile(string filePath) { JobFile file = null; int idx = jobFiles.FindIndex(pair => pair.Key == filePath); if (idx >= 0) { file = jobFiles[idx].Value; } ProcessFile(file); }
public DataReturn SaveAttachmentInJobFile(JobFileClass model) { DataReturn obj = new DataReturn(); try { JobFile fj = db.JobFile.SingleOrDefault(m => m.JobKey == model.JobKey && m.DocumentTypeKey == model.DocumentTypeKey); if (fj == null) { } else { db.JobFile.Remove(fj); db.SaveChanges(); db = new RCSdbEntities(); } JobFile invoice = new JobFile(); Job job = db.Job.Find(model.JobKey); invoice.FileKey = Guid.NewGuid(); invoice.JobKey = (Guid)model.JobKey; invoice.DocumentTypeKey = model.DocumentTypeKey; //invoice.AddedBy = GlobalClass.LoginUser.PersonnelKey; invoice.AddedOn = System.DateTime.Now; if (string.IsNullOrEmpty(model.Comment)) { invoice.Comment = "--"; } else { invoice.Comment = model.Comment; } invoice.Title = model.Title; invoice.Remarks = db.DocumentType.Find(model.DocumentTypeKey).TName + " is Added by " + GlobalClass.LoginUser.Cname; invoice.FileContent = model.FileContent; invoice.FileType = model.FileType; invoice.IsDelete = false; invoice.IsFileNew = true; db.JobFile.Add(invoice); db.SaveChanges(); obj.flag = 1; obj.mess = "Data has been updated successfully."; } catch (Exception ex) { obj.mess = ex.ToString(); obj.flag = 0; } obj.key = model.JobKey; return(obj); }
public ActionResult GetJobFileAttachement(Guid id) { JobFile obj = db.JobFile.Find(id); if (obj.FileContent != null) { return(File(obj.FileContent, obj.FileType)); } else { ImageFile faoimagefile = db.ImageFile.Single(f => f.ImageFileKey == 1); return(File(faoimagefile.FileContent, faoimagefile.FileType)); } }
/// <summary> /// Called during creation of the <see cref="IScheduler"/> in order to give /// the <see cref="ISchedulerPlugin"/> a chance to initialize. /// </summary> /// <param name="pluginName">The name.</param> /// <param name="sched">The scheduler.</param> /// <throws>SchedulerConfigException </throws> public virtual void Initialize(string pluginName, IScheduler sched) { name = pluginName; scheduler = sched; typeLoadHelper = new SimpleTypeLoadHelper(); typeLoadHelper.Initialize(); // Create JobFile objects var tokens = fileNames.Split(FileNameDelimiter).Select(x => x.TrimStart()); foreach (string token in tokens) { JobFile jobFile = new JobFile(this, token); jobFiles.Add(new KeyValuePair <string, JobFile>(jobFile.FilePath, jobFile)); } }
/// <summary> /// Called during creation of the <see cref="IScheduler"/> in order to give /// the <see cref="ISchedulerPlugin"/> a chance to initialize. /// </summary> /// <param name="pluginName">The name.</param> /// <param name="sched">The scheduler.</param> /// <throws>SchedulerConfigException </throws> public virtual void Initialize(string pluginName, IScheduler sched) { name = pluginName; scheduler = sched; classLoadHelper = new CascadingClassLoadHelper(); classLoadHelper.Initialize(); Log.Info("Registering Quartz Job Initialization Plug-in."); // Create JobFile objects string[] tokens = fileNames.Split(FileNameDelimiter); foreach (string token in tokens) { JobFile jobFile = new JobFile(this, token); jobFiles.Add(jobFile.FilePath, jobFile); } }
private void TransmitJobFile(int fileId) { JobFile jobFile = JobFile.JobFileFromId(fileId); if (jobFile != null) { if (!jobFile.Job.IsArchived) { this.Response.AppendHeader("Content-Disposition", "attachment; filename=" + jobFile.Name); this.Response.TransmitFile(this.Server.MapPath(jobFile.Path)); } else { throw new Exception(SiteUtils.ExceptionMessageForCustomer("File is archived or removed per file retention policy.")); } } //this.Response.End(); HttpContext.Current.ApplicationInstance.CompleteRequest(); }
/// <summary> /// Called during creation of the <see cref="IScheduler"/> in order to give /// the <see cref="ISchedulerPlugin"/> a chance to initialize. /// </summary> /// <param name="pluginName">The name.</param> /// <param name="scheduler">The scheduler.</param> /// <throws>SchedulerConfigException </throws> public virtual async Task Initialize(string pluginName, IScheduler scheduler) { Name = pluginName; Scheduler = scheduler; typeLoadHelper = new SimpleTypeLoadHelper(); typeLoadHelper.Initialize(); Log.Info("Registering Quartz Job Initialization Plug-in."); // Create JobFile objects var tokens = FileNames.Split(FileNameDelimiter).Select(x => x.TrimStart()); foreach (string token in tokens) { JobFile jobFile = new JobFile(this, token); await jobFile.Initialize(); jobFiles.Add(new KeyValuePair <string, JobFile>(jobFile.FilePath, jobFile)); } }
private Panel FileDiv(JobFile file) { Panel pnlFile = new Panel(); if (!curJob.IsArchived) { // just url with qs LiteralControl hlFile = new LiteralControl(AdminUtils.LinkToGetFilePage_Image(file, "employees") + " " + AdminUtils.LinkToGetFilePage_Text(file, "employees")); pnlFile.Controls.Add(hlFile); } else // archived - no link { LiteralControl fileWithImg = new LiteralControl(AdminUtils.FileIcon() + " " + file.Name + " (archived)"); pnlFile.Controls.Add(fileWithImg); } return(pnlFile); }
private void ProcessFile(JobFile jobFile) { if ((jobFile == null) || (jobFile.FileFound == false)) { return; } JobSchedulingDataProcessor processor = new JobSchedulingDataProcessor(Validating, ValidatingSchema); try { processor.ProcessFileAndScheduleJobs( jobFile.FilePath, jobFile.FilePath, // systemId scheduler, OverwriteExistingJobs); } catch (Exception e) { Log.Error("Error scheduling jobs: " + e.Message, e); } }
async public Task <ActionResult> DownloadJobFile(int id, string token) { if (!_customAuthService.CheckToken(token)) { return(Unauthorized()); } JobFile file = _jobService.GetFile(id); if (file == null) { throw new AppException("File not found in database."); } string fileName = file.Name; string filePath = file.Path; var provider = new FileExtensionContentTypeProvider(); string contentType; if (!provider.TryGetContentType(fileName, out contentType)) { contentType = "application/octet-stream"; } string fullPath = _fileService.getFullPath(filePath); var memory = new MemoryStream(); using (var stream = new FileStream(fullPath, FileMode.Open)) { await stream.CopyToAsync(memory); } memory.Position = 0; return(File(memory, contentType)); }
/// <summary> /// 删除任务工作文件 /// </summary> /// <param name="deleteInfo">删除信息</param> /// <returns>执行结果</returns> public Result DeleteJobFile(DeleteJobFileCmdDto deleteInfo) { #region 参数判断 if (deleteInfo == null || deleteInfo.JobFileIds.IsNullOrEmpty()) { return(Result.FailedResult("没有指定要删除的任务工作文件")); } #endregion using (var businessWork = WorkFactory.Create()) { var jobFiles = deleteInfo.JobFileIds.Select(c => JobFile.CreateJobFile(c)); var deleteResult = JobFileDomainService.DeleteJobFile(jobFiles); if (!deleteResult.Success) { return(deleteResult); } var commitResult = businessWork.Commit(); return(commitResult.ExecutedSuccess ? Result.SuccessResult("删除成功") : Result.FailedResult("删除失败")); } }
private void ProcessFile(JobFile jobFile) { if ((jobFile == null) || (jobFile.FileFound == false)) { return; } try { XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(TypeLoadHelper); processor.AddJobGroupToNeverDelete(JobInitializationPluginName); processor.AddTriggerGroupToNeverDelete(JobInitializationPluginName); processor.ProcessFileAndScheduleJobs( jobFile.FileName, jobFile.FileName, // systemId scheduler); } catch (Exception) { } }
public ActionResult UploadJobFile([FromForm] JobFileDTO jobFileDTO) { Job job = _jobService.GetById(jobFileDTO.JobId); if (job == null) { throw new AppException("Job not found"); } if (!JobFolder.JobFolderList.Contains(jobFileDTO.Folder)) { throw new AppException("Folder not found in predefined folders."); } var files = jobFileDTO.Files; string path = Path.Combine("Jobs", job.Id.ToString(), jobFileDTO.Folder); foreach (var file in files) { _fileService.Create(file, path); JobFile jobFile = new JobFile { Name = file.FileName, Path = Path.Combine(path, file.FileName), JobId = job.Id, Job = job, Folder = jobFileDTO.Folder }; _jobService.CreateFile(jobFile); } return(Ok()); }
/// <summary> /// 保存任务工作文件 /// </summary> /// <param name="jobFile">任务工作文件信息</param> /// <returns></returns> public static Result <JobFile> SaveJobFile(JobFile jobFile) { return(null); }
private void SaveFiles() { filesChanged = true; // get or create directory // virtual jobfiles root string jobFilesRootVirtual = Settings.Default.JobFilesRoot; if (!jobFilesRootVirtual.EndsWith(@"/")) { jobFilesRootVirtual += @"/"; } // get local path string jobFilesRootLocal = this.Server.MapPath(jobFilesRootVirtual); // file upload controls for (int j = 0; j < 2; j++) { JobFile.JobFileType fileType; string whichFileControl; string whichDirectory; if (j == 0) { fileType = JobFile.JobFileType.Returned; whichFileControl = "returnFile"; whichDirectory = "out"; } else if (j == 1) { fileType = JobFile.JobFileType.Working; whichFileControl = "workingFile"; whichDirectory = "working"; } else { fileType = JobFile.JobFileType.Submitted; whichFileControl = "submittedFile"; whichDirectory = "in"; } FileUpload fu = (FileUpload)this.FindControl(whichFileControl + "1"); if (fu.HasFile) { DirectoryInfo fileFolder = Directory.CreateDirectory(jobFilesRootLocal + @"\" + jobId.ToString() + @"\" + whichDirectory); string filename = HesterConsultants.AppCode.SiteUtils.WindowsSafeFilename(fu.FileName); // adjust filename if necessary filename = HesterConsultants.AppCode.SiteUtils.ConflictFreeFilename(fileFolder.FullName, filename, Settings.Default.FilenameAppendedDigitsMax); string virtualPath = jobFilesRootVirtual + jobId.ToString() + @"/" + whichDirectory + @"/" + filename; // save file try { fu.SaveAs(fileFolder.FullName + @"\" + filename); } catch (Exception ex) { ClientData.Current.LogErrorAndSendAlert(ex); throw new Exception(SiteUtils.ExceptionMessageForCustomer("Failed to save file.")); } JobFile jobFile = JobFile.InsertJobFile(curJob, filename, virtualPath, (fileType == JobFile.JobFileType.Returned), (fileType == JobFile.JobFileType.Submitted)); if (jobFile == null) { throw new Exception(SiteUtils.ExceptionMessageForCustomer("Job file is null.")); } } } }
/// <summary> /// Called during creation of the <see cref="IScheduler"/> in order to give /// the <see cref="ISchedulerPlugin"/> a chance to initialize. /// </summary> /// <param name="pluginName">The name.</param> /// <param name="sched">The scheduler.</param> /// <throws>SchedulerConfigException </throws> public virtual void Initialize(string pluginName, IScheduler sched) { name = pluginName; scheduler = sched; typeLoadHelper = new SimpleTypeLoadHelper(); typeLoadHelper.Initialize(); Log.Info("Registering Quartz Job Initialization Plug-in."); // Create JobFile objects var tokens = fileNames.Split(FileNameDelimiter).Select(x => x.TrimStart()); foreach (string token in tokens) { JobFile jobFile = new JobFile(this, token); jobFiles.Add(new KeyValuePair<string, JobFile>(jobFile.FilePath, jobFile)); } }
/// <summary> /// Called during creation of the <see cref="IScheduler"/> in order to give /// the <see cref="ISchedulerPlugin"/> a chance to initialize. /// </summary> /// <param name="pluginName">The name.</param> /// <param name="sched">The scheduler.</param> /// <throws>SchedulerConfigException </throws> public virtual void Initialize(string pluginName, IScheduler sched) { name = pluginName; scheduler = sched; classLoadHelper = new CascadingClassLoadHelper(); classLoadHelper.Initialize(); Log.Info("Registering Scheduler Job Initialization Plug-in."); // Create JobFile objects string[] tokens = fileNames.Split(FileNameDelimiter); foreach (string token in tokens) { JobFile jobFile = new JobFile(this, token); jobFiles.Add(jobFile.FilePath, jobFile); } }
/// <summary> /// /// </summary> /// <param name="file"></param> /// <param name="whichPath">Either "employees" or "clients".</param> /// <returns></returns> public static string LinkToGetFilePage_Image(JobFile file, string whichPath) { return(OpenLinkToGetFilePage(file, whichPath) + FileIcon() + "</a>"); }
public void CreateFile(JobFile jobFile) { _context.JobFiles.Add(jobFile); _context.SaveChanges(); }
public void Setup() { sut = new JobFile(); }
private void ProcessFile(JobFile jobFile) { if ((jobFile == null) || (jobFile.FileFound == false)) { return; } try { XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(TypeLoadHelper); processor.AddJobGroupToNeverDelete(JobInitializationPluginName); processor.AddTriggerGroupToNeverDelete(JobInitializationPluginName); processor.ProcessFileAndScheduleJobs( jobFile.FileName, jobFile.FileName, // systemId scheduler); } catch (Exception e) { Log.Error("Error scheduling jobs: " + e.Message, e); } }
/// <summary> /// /// </summary> /// <param name="file"></param> /// <param name="whichPath">Either "employees" or "clients".</param> /// <returns></returns> public static string LinkToGetFilePage_Text(JobFile file, string whichPath) { return(OpenLinkToGetFilePage(file, whichPath) + file.Name + "</a>"); }