Added missing LookupValueActivity (was excluded from previous upload; minor whoops)
parent
0d85534791
commit
ca2f82f06d
131
Granfeldt.FIM.ActivityLibrary/Activity.LookupValue/Activity.LookupValue.Designer.cs
generated
Normal file
131
Granfeldt.FIM.ActivityLibrary/Activity.LookupValue/Activity.LookupValue.Designer.cs
generated
Normal file
|
@ -0,0 +1,131 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.ComponentModel.Design;
|
||||
using System.Workflow.ComponentModel.Compiler;
|
||||
using System.Workflow.ComponentModel.Serialization;
|
||||
using System.Workflow.Runtime;
|
||||
using System.Workflow.Activities;
|
||||
using System.Workflow.Activities.Rules;
|
||||
|
||||
namespace Granfeldt.FIM.ActivityLibrary
|
||||
{
|
||||
public partial class LookupValueActivity
|
||||
{
|
||||
#region Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCode]
|
||||
[System.CodeDom.Compiler.GeneratedCode("", "")]
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.CanModifyActivities = true;
|
||||
System.Workflow.Activities.CodeCondition codecondition1 = new System.Workflow.Activities.CodeCondition();
|
||||
System.Collections.Generic.List<Microsoft.ResourceManagement.WebServices.WSResourceManagement.ResourceType> list_11 = new System.Collections.Generic.List<Microsoft.ResourceManagement.WebServices.WSResourceManagement.ResourceType>();
|
||||
System.Workflow.ComponentModel.ActivityBind activitybind1 = new System.Workflow.ComponentModel.ActivityBind();
|
||||
System.Workflow.ComponentModel.ActivityBind activitybind2 = new System.Workflow.ComponentModel.ActivityBind();
|
||||
this.UpdateTargetIfNeeded = new Granfeldt.FIM.ActivityLibrary.UpdateSingleValueAttributeAsNeededActivity();
|
||||
this.UpdateWorkflowDataBranch = new System.Workflow.Activities.IfElseBranchActivity();
|
||||
this.UpdateTargetBranch = new System.Workflow.Activities.IfElseBranchActivity();
|
||||
this.UpdateTargetOrWorkflowData = new System.Workflow.Activities.IfElseActivity();
|
||||
this.Enumerate = new Granfeldt.FIM.ActivityLibrary.FindResourcesActivity();
|
||||
this.SetupVariablesActivity = new System.Workflow.Activities.CodeActivity();
|
||||
this.ResolveGrammarForXPathFilter = new Microsoft.ResourceManagement.Workflow.Activities.ResolveGrammarActivity();
|
||||
//
|
||||
// UpdateTargetIfNeeded
|
||||
//
|
||||
this.UpdateTargetIfNeeded.ActorId = new System.Guid("00000000-0000-0000-0000-000000000000");
|
||||
this.UpdateTargetIfNeeded.AttributeName = null;
|
||||
this.UpdateTargetIfNeeded.Name = "UpdateTargetIfNeeded";
|
||||
this.UpdateTargetIfNeeded.NewValue = null;
|
||||
this.UpdateTargetIfNeeded.TargetId = new System.Guid("00000000-0000-0000-0000-000000000000");
|
||||
this.UpdateTargetIfNeeded.TargetResource = null;
|
||||
//
|
||||
// UpdateWorkflowDataBranch
|
||||
//
|
||||
this.UpdateWorkflowDataBranch.Name = "UpdateWorkflowDataBranch";
|
||||
//
|
||||
// UpdateTargetBranch
|
||||
//
|
||||
this.UpdateTargetBranch.Activities.Add(this.UpdateTargetIfNeeded);
|
||||
codecondition1.Condition += new System.EventHandler<System.Workflow.Activities.ConditionalEventArgs>(this.UpdateTargetOrWorkflowData_Condition);
|
||||
this.UpdateTargetBranch.Condition = codecondition1;
|
||||
this.UpdateTargetBranch.Name = "UpdateTargetBranch";
|
||||
//
|
||||
// UpdateTargetOrWorkflowData
|
||||
//
|
||||
this.UpdateTargetOrWorkflowData.Activities.Add(this.UpdateTargetBranch);
|
||||
this.UpdateTargetOrWorkflowData.Activities.Add(this.UpdateWorkflowDataBranch);
|
||||
this.UpdateTargetOrWorkflowData.Name = "UpdateTargetOrWorkflowData";
|
||||
//
|
||||
// Enumerate
|
||||
//
|
||||
this.Enumerate.ActorId = new System.Guid("00000000-0000-0000-0000-000000000000");
|
||||
this.Enumerate.Attributes = null;
|
||||
this.Enumerate.EnumeratedResourceIDs = null;
|
||||
this.Enumerate.EnumeratedResources = list_11;
|
||||
this.Enumerate.Name = "Enumerate";
|
||||
this.Enumerate.PageSize = 0;
|
||||
this.Enumerate.SortingAttributes = null;
|
||||
this.Enumerate.TotalResultsCount = 0;
|
||||
this.Enumerate.XPathFilter = null;
|
||||
//
|
||||
// SetupVariablesActivity
|
||||
//
|
||||
this.SetupVariablesActivity.Name = "SetupVariablesActivity";
|
||||
this.SetupVariablesActivity.ExecuteCode += new System.EventHandler(this.SetupVariablesActivity_ExecuteCode);
|
||||
//
|
||||
// ResolveGrammarForXPathFilter
|
||||
//
|
||||
activitybind1.Name = "LookupAttributeValueActivity";
|
||||
activitybind1.Path = "XPathFilter";
|
||||
this.ResolveGrammarForXPathFilter.Name = "ResolveGrammarForXPathFilter";
|
||||
activitybind2.Name = "LookupAttributeValueActivity";
|
||||
activitybind2.Path = "ResolvedXPathFilter";
|
||||
this.ResolveGrammarForXPathFilter.WorkflowDictionaryKey = null;
|
||||
this.ResolveGrammarForXPathFilter.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.ResolveGrammarActivity.GrammarExpressionProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind1)));
|
||||
this.ResolveGrammarForXPathFilter.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.ResolveGrammarActivity.ResolvedExpressionProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind2)));
|
||||
//
|
||||
// LookupAttributeValueActivity
|
||||
//
|
||||
this.Activities.Add(this.ResolveGrammarForXPathFilter);
|
||||
this.Activities.Add(this.SetupVariablesActivity);
|
||||
this.Activities.Add(this.Enumerate);
|
||||
this.Activities.Add(this.UpdateTargetOrWorkflowData);
|
||||
this.Name = "LookupAttributeValueActivity";
|
||||
this.CanModifyActivities = false;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
//private Microsoft.ResourceManagement.Workflow.Activities.ReadResourceActivity ReadResource;
|
||||
private IfElseBranchActivity UpdateWorkflowDataBranch;
|
||||
private IfElseBranchActivity UpdateTargetBranch;
|
||||
private IfElseActivity UpdateTargetOrWorkflowData;
|
||||
private UpdateSingleValueAttributeAsNeededActivity UpdateTargetIfNeeded;
|
||||
private FindResourcesActivity Enumerate;
|
||||
private CodeActivity SetupVariablesActivity;
|
||||
private Microsoft.ResourceManagement.Workflow.Activities.ResolveGrammarActivity ResolveGrammarForXPathFilter;
|
||||
|
||||
|
||||
#region "Special workflows"
|
||||
|
||||
// October 22, 2010 | Søren Granfeldt
|
||||
// this.ReadEnumeratedResources = new System.Workflow.Activities.CodeActivity();
|
||||
// this.ReadEnumeratedResources.Name = "ReadEnumeratedResources";
|
||||
// this.ReadEnumeratedResources.ExecuteCode += new System.EventHandler(this.ReadEnumeratedResources_ExecuteCode);
|
||||
|
||||
// October 22, 2010 | Søren Granfeldt
|
||||
// this.Enumerate.Activities.Add(this.ReadEnumeratedResources);
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Workflow.ComponentModel;
|
||||
using Microsoft.IdentityManagement.WebUI.Controls;
|
||||
using Microsoft.ResourceManagement.Workflow.Activities;
|
||||
|
||||
namespace Granfeldt.FIM.ActivityLibrary.WebUIs
|
||||
{
|
||||
class LookupValueActivitySettingsPart : BaseActivitySettingsPart
|
||||
{
|
||||
|
||||
const string XPathFilter = "XPathFilter";
|
||||
const string AttributeToRetrieve = "AttributeToRetrieve";
|
||||
const string Destination = "Destination";
|
||||
const string LookupActor = "LookupActor";
|
||||
const string NonUniqueResultAction = "NonUniqueResultAction";
|
||||
|
||||
protected override void CreateChildControls()
|
||||
{
|
||||
Table layoutTable;
|
||||
layoutTable = new Table();
|
||||
|
||||
// width is set to 100% of the control size
|
||||
layoutTable.Width = Unit.Percentage(100.0);
|
||||
layoutTable.BorderWidth = 0;
|
||||
layoutTable.CellPadding = 2;
|
||||
|
||||
// add a TableRow for each textbox in the UI
|
||||
layoutTable.Rows.Add(this.AddTableRowTextBox("XPath Filter:", "txt" + XPathFilter, 400, 100, false, ""));
|
||||
layoutTable.Rows.Add(this.AddTableRowTextBox("Attribute Name:", "txt" + AttributeToRetrieve, 400, 100, false, ""));
|
||||
layoutTable.Rows.Add(this.AddTableRowTextBox("Destination:", "txt" + Destination, 400, 100, false, ""));
|
||||
layoutTable.Rows.Add(this.AddActorDropDownList("Actor (run as):", "txt" + LookupActor, 400, WellKnownGuids.FIMServiceAccount.ToString()));
|
||||
layoutTable.Rows.Add(this.AddLookupActionDropDownList("Action on multiple lookup results:", "txt" + NonUniqueResultAction, 400, ""));
|
||||
this.Controls.Add(layoutTable);
|
||||
base.CreateChildControls();
|
||||
}
|
||||
|
||||
public override Activity GenerateActivityOnWorkflow(SequentialWorkflow workflow)
|
||||
{
|
||||
Debugging.Log("GenerateActivityOnWorkflow");
|
||||
if (!this.ValidateInputs())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
LookupValueActivity LookupActivity = new LookupValueActivity();
|
||||
LookupActivity.AttributeName = this.GetText("txt" + AttributeToRetrieve);
|
||||
LookupActivity.XPathFilter = this.GetText("txt" + XPathFilter);
|
||||
LookupActivity.Destination = this.GetText("txt" + Destination);
|
||||
LookupActivity.LookupActor = this.GetActorDropDownList("txt" + LookupActor);
|
||||
LookupActivity.NonUniqueValueAction = this.GetLookupActionDropDownList("txt" + NonUniqueResultAction);
|
||||
return LookupActivity;
|
||||
}
|
||||
|
||||
public override void LoadActivitySettings(Activity activity)
|
||||
{
|
||||
Debugging.Log("LoadActivitySettings");
|
||||
LookupValueActivity thisActivity = activity as LookupValueActivity;
|
||||
if (thisActivity != null)
|
||||
{
|
||||
this.SetText("txt" + XPathFilter, thisActivity.XPathFilter);
|
||||
this.SetText("txt" + AttributeToRetrieve, thisActivity.AttributeName);
|
||||
this.SetText("txt" + Destination, thisActivity.Destination);
|
||||
this.SetActorDropDownList("txt" + LookupActor, thisActivity.LookupActor);
|
||||
this.SetLookupActionDropDownList("txt" + NonUniqueResultAction, thisActivity.NonUniqueValueAction);
|
||||
}
|
||||
}
|
||||
|
||||
public override ActivitySettingsPartData PersistSettings()
|
||||
{
|
||||
Debugging.Log("PersistSettings");
|
||||
ActivitySettingsPartData data = new ActivitySettingsPartData();
|
||||
data[XPathFilter] = this.GetText("txt" + XPathFilter);
|
||||
data[Destination] = this.GetText("txt" + Destination);
|
||||
data[AttributeToRetrieve] = this.GetText("txt" + AttributeToRetrieve);
|
||||
data[LookupActor] = this.GetActorDropDownList("txt" + LookupActor);
|
||||
data[NonUniqueResultAction] = this.GetLookupActionDropDownList("txt" + NonUniqueResultAction);
|
||||
return data;
|
||||
}
|
||||
|
||||
public override void RestoreSettings(ActivitySettingsPartData data)
|
||||
{
|
||||
Debugging.Log("RestoreSettings");
|
||||
if (null != data)
|
||||
{
|
||||
this.SetText("txt" + XPathFilter, (string)data[XPathFilter]);
|
||||
this.SetText("txt" + Destination, (string)data[Destination]);
|
||||
this.SetText("txt" + AttributeToRetrieve, (string)data[AttributeToRetrieve]);
|
||||
this.SetActorDropDownList("txt" + LookupActor, (string)data[LookupActor]);
|
||||
this.SetLookupActionDropDownList("txt" + NonUniqueResultAction, (string)data[NonUniqueResultAction]);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SwitchMode(ActivitySettingsPartMode mode)
|
||||
{
|
||||
Debugging.Log("SwitchMode");
|
||||
bool isDisabled = (mode != ActivitySettingsPartMode.Edit);
|
||||
this.SetTextBoxReadOnlyOption("txt" + XPathFilter, isDisabled);
|
||||
this.SetTextBoxReadOnlyOption("txt" + Destination, isDisabled);
|
||||
this.SetTextBoxReadOnlyOption("txt" + AttributeToRetrieve, isDisabled);
|
||||
this.SetDropDownListDisabled("txt" + LookupActor, isDisabled);
|
||||
this.SetDropDownListDisabled("txt" + NonUniqueResultAction, isDisabled);
|
||||
}
|
||||
|
||||
public override string Title
|
||||
{
|
||||
get { return "Lookup Value"; }
|
||||
}
|
||||
|
||||
public override bool ValidateInputs()
|
||||
{
|
||||
Debugging.Log("ValidateInputs");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
// January 17, 2013 | Soren Granfeldt
|
||||
// - code revised and partially rewritten before CodePlex release
|
||||
// January 22, 2013 | Kristian Birk Thim
|
||||
// - added support to return results in Enumerate.TotalResultsCount where count is 1.
|
||||
// January 17, 2013 | Soren Granfeldt
|
||||
// - renamed from LookupAttributeValue to LookupValue
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Workflow.Activities;
|
||||
using System.Workflow.ComponentModel;
|
||||
using Microsoft.ResourceManagement.WebServices.WSResourceManagement;
|
||||
using Microsoft.ResourceManagement.Workflow.Activities;
|
||||
|
||||
namespace Granfeldt.FIM.ActivityLibrary
|
||||
{
|
||||
|
||||
public partial class LookupValueActivity : SequenceActivity
|
||||
{
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public static DependencyProperty LookupActorProperty = DependencyProperty.Register("LookupActor", typeof(string), typeof(LookupValueActivity));
|
||||
[Description("LookupActor")]
|
||||
[Category("LookupActor Category")]
|
||||
[Browsable(true)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
||||
public string LookupActor
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((string)(base.GetValue(LookupValueActivity.LookupActorProperty)));
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SetValue(LookupValueActivity.LookupActorProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static DependencyProperty AttributeNameProperty = DependencyProperty.Register("AttributeName", typeof(System.String), typeof(LookupValueActivity));
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
|
||||
[BrowsableAttribute(true)]
|
||||
[CategoryAttribute("Misc")]
|
||||
public String AttributeName
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((string)(base.GetValue(LookupValueActivity.AttributeNameProperty)));
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SetValue(LookupValueActivity.AttributeNameProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static DependencyProperty XPathFilterProperty = DependencyProperty.Register("XPathFilter", typeof(System.String), typeof(LookupValueActivity));
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
|
||||
[BrowsableAttribute(true)]
|
||||
[CategoryAttribute("Misc")]
|
||||
public String XPathFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((string)(base.GetValue(LookupValueActivity.XPathFilterProperty)));
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SetValue(LookupValueActivity.XPathFilterProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static DependencyProperty DestinationProperty = DependencyProperty.Register("Destination", typeof(System.String), typeof(LookupValueActivity));
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
|
||||
[BrowsableAttribute(true)]
|
||||
[CategoryAttribute("Misc")]
|
||||
public String Destination
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((string)(base.GetValue(LookupValueActivity.DestinationProperty)));
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SetValue(LookupValueActivity.DestinationProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static DependencyProperty ResolvedXPathFilterProperty = DependencyProperty.Register("ResolvedXPathFilter", typeof(System.String), typeof(LookupValueActivity));
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
|
||||
[BrowsableAttribute(true)]
|
||||
[CategoryAttribute("Misc")]
|
||||
public String ResolvedXPathFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((string)(base.GetValue(LookupValueActivity.ResolvedXPathFilterProperty)));
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SetValue(LookupValueActivity.ResolvedXPathFilterProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static DependencyProperty NonUniqueValueActionProperty = DependencyProperty.Register("NonUniqueValueAction", typeof(string), typeof(LookupValueActivity));
|
||||
[Description("NonUniqueValueAction")]
|
||||
[Category("NonUniqueValueAction Category")]
|
||||
[Browsable(true)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
||||
public string NonUniqueValueAction
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((string)(base.GetValue(LookupValueActivity.NonUniqueValueActionProperty)));
|
||||
}
|
||||
set
|
||||
{
|
||||
base.SetValue(LookupValueActivity.NonUniqueValueActionProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Code
|
||||
|
||||
public LookupValueActivity()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void SetupVariablesActivity_ExecuteCode(object sender, EventArgs e)
|
||||
{
|
||||
Debugging.Log("Enter SetupVariablesActivity_ExecuteCode");
|
||||
Enumerate.ActorId = new Guid(this.LookupActor);
|
||||
Debugging.Log("XPath (resolved)", this.ResolvedXPathFilter);
|
||||
Enumerate.XPathFilter = this.ResolvedXPathFilter;
|
||||
Enumerate.Attributes = new string[] { this.AttributeName };
|
||||
Enumerate.PageSize = 100;
|
||||
Debugging.Log("Leave SetupVariablesActivity_ExecuteCode");
|
||||
}
|
||||
|
||||
private void UpdateTargetOrWorkflowData_Condition(object sender, ConditionalEventArgs e)
|
||||
{
|
||||
Debugging.Log("Enter UpdateTargetOrWorkflowData_Condition");
|
||||
e.Result = false; // go in workflowdata direction (we'll update workflowdata here, so actually nothing to do)
|
||||
|
||||
object newValue = null;
|
||||
ResourceType r;
|
||||
|
||||
Debugging.Log("Results #", Enumerate.TotalResultsCount);
|
||||
if (Enumerate.TotalResultsCount > 1)
|
||||
{
|
||||
switch (this.NonUniqueValueAction)
|
||||
{
|
||||
case "RETURNLAST":
|
||||
// get the first object in the resultset and grab the
|
||||
// value from the requested attribute
|
||||
r = Enumerate.EnumeratedResources[Enumerate.TotalResultsCount - 1];
|
||||
newValue = r[this.AttributeName];
|
||||
break;
|
||||
case "ERROR":
|
||||
Debugging.Log(new System.ArgumentException("Too many results returned from lookup"));
|
||||
break;
|
||||
default:
|
||||
// get the first object in the resultset and grab the
|
||||
// value from the requested attribute
|
||||
r = Enumerate.EnumeratedResources[0];
|
||||
newValue = r[this.AttributeName];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Enumerate.TotalResultsCount == 1)
|
||||
{
|
||||
r = Enumerate.EnumeratedResources[0];
|
||||
newValue = r[this.AttributeName];
|
||||
}
|
||||
|
||||
SequentialWorkflow containingWorkflow = null;
|
||||
if (!SequentialWorkflow.TryGetContainingWorkflow(this, out containingWorkflow))
|
||||
{
|
||||
throw new InvalidOperationException("Could not get parent workflow!");
|
||||
}
|
||||
|
||||
// separate destination object and destination attribute.
|
||||
string destination = null;
|
||||
string destinationAttribute = null;
|
||||
StringUtilities.ExtractWorkflowExpression(this.Destination, out destination, out destinationAttribute);
|
||||
|
||||
if (!string.IsNullOrEmpty(destinationAttribute))
|
||||
{
|
||||
if (destination.Equals("workflowdata", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// write output value to WorkflowDictionary.
|
||||
if ((containingWorkflow != null) && (newValue != null))
|
||||
{
|
||||
containingWorkflow.WorkflowDictionary.Add(destinationAttribute, newValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (destination.Equals("target", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
e.Result = true;
|
||||
UpdateTargetIfNeeded.ActorId = new Guid(this.LookupActor);
|
||||
UpdateTargetIfNeeded.AttributeName = destinationAttribute;
|
||||
UpdateTargetIfNeeded.NewValue = newValue;
|
||||
UpdateTargetIfNeeded.TargetId = containingWorkflow.TargetId;
|
||||
}
|
||||
}
|
||||
}
|
||||
Debugging.Log("Exit UpdateTargetOrWorkflowData_Condition");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue