创建与注册更新

现在可以注册模板并注册标识了
This commit is contained in:
CortexCore 2023-07-08 15:32:06 +08:00
parent 6fc4279878
commit 36a4309730
8 changed files with 205 additions and 76 deletions

File diff suppressed because one or more lines are too long

View File

@ -28,3 +28,4 @@ public partial class RuntimeNode : Node
EmitSignal(nameof(OnUpdate));
}
}

View File

@ -1,52 +1,77 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using BITKit;
namespace BITFactory;
public partial class IDIS_RegisterService : Node
{
[ExportCategory("Services")]
[Export] private IDIS_Service service;
[Export] private IDIS_TemplateService templateService;
[ExportCategory("TemplateList")]
[Export] private ItemList templateList;
[ExportCategory("Register Data")]
[Export] private LineEdit handleEdit;
[Export] private Button generateHandleButton;
[Export] private Control container;
[Export] private Control registerContainer;
[Export] private Button registerButton;
[Export] private ProgressBar registerProgress;
[ExportCategory("Register Reference")]
[Export] private Control referenceContainer;
[Export] private Button addReferenceButton;
[ExportCategory("Hints")]
[Export] private Label hints;
private readonly Dictionary<int,KeyValuePair<string,string>> _currentValues = new();
private readonly Dictionary<int, KeyValuePair<string, string>> _currentValues = new();
private readonly List<string> _currentReferences = new();
public override void _Ready()
{
templateList.ItemClicked += OnItemClicked;
registerButton.Pressed += Register;
generateHandleButton.Pressed += ()=>handleEdit.Text = IDIS_Service.GenerateHandle();
addReferenceButton.Pressed += AddReferenceEdit;
handleEdit.Editable = false;
registerButton.Disabled = true;
Rebuild();
}
private void Rebuild()
{
if (Engine.IsEditorHint()) return;
templateList.Clear();
foreach (var x in templateService.templates)
{
templateList.AddItem(x.TemplateName);
}
templateList.ItemClicked += OnItemClicked;
registerButton.Pressed += Register;
generateHandleButton.Pressed += () =>
{
handleEdit.Text = $"88.123.99/{Mathf.Abs(Guid.NewGuid().GetHashCode())}";
};
handleEdit.Editable = false;
registerButton.Disabled = true;
}
private void OnItemClicked(long index, Vector2 atPosition, long mouseButtonIndex)
{
MathNode.RemoveAllChild(container);
var template = templateService.templates[(int) index];
MathNode.RemoveAllChild(registerContainer);
MathNode.RemoveAllChild(referenceContainer);
var template = templateService.templates[(int)index];
var grid = new GridContainer();
grid.Columns = 2;
grid.AddThemeConstantOverride("h_separation", 64);
container.AddChild(grid);
registerContainer.AddChild(grid);
_currentValues.Clear();
var _dirIndex = 0;
@ -58,17 +83,14 @@ public partial class IDIS_RegisterService : Node
var myIndex = _dirIndex++;
label.Text = x.format;
lineEdit.PlaceholderText = x.hint;
lineEdit.SizeFlagsHorizontal = Control.SizeFlags.ExpandFill;
_currentValues.Add(myIndex,new KeyValuePair<string, string>(x.format,x.hint));
lineEdit.TextChanged += (s) =>
{
_currentValues[myIndex] = new KeyValuePair<string, string>(x.format, s);
};
_currentValues.Add(myIndex, new KeyValuePair<string, string>(x.format, x.hint));
lineEdit.TextChanged += (s) => { _currentValues[myIndex] = new KeyValuePair<string, string>(x.format, s); };
grid.AddChild(label);
grid.AddChild(lineEdit);
}
@ -77,15 +99,58 @@ public partial class IDIS_RegisterService : Node
registerButton.Disabled = false;
}
private void AddReferenceEdit()
{
var lineEdit = new LineEdit();
var currentIndex = referenceContainer.GetChildCount();
_currentReferences.Add(string.Empty);
lineEdit.TextChanged += s =>
{
_currentReferences[currentIndex] = s;
};
lineEdit.Text = "88.123.99/";
referenceContainer.AddChild(lineEdit);
}
private void Register()
{
var handle = handleEdit.Text;
var json = JsonHelper.Get(_currentValues);
var handle = string.IsNullOrEmpty(handleEdit.Text) ? IDIS_Service.GenerateHandle() : handleEdit.Text;
var dataJson = JsonHelper.Get(_currentValues);
var referenceJson = JsonHelper.Get(_currentReferences);
BIT4Log.Log<IDIS_RegisterService>($"注册标识:{handle}");
BIT4Log.Log<IDIS_RegisterService>($"\n{json}");
BIT4Log.Log<IDIS_RegisterService>($"\n{dataJson}");
BIT4Log.Log<IDIS_RegisterService>("注册引用:");
BIT4Log.Log<IDIS_RegisterService>($"\n{referenceJson}");
hints.Text="正在注册...";
service.Register(handle);
foreach (var x in _currentValues)
{
service.Register(handle, x.Value.Key, x.Value.Value);
}
foreach (var x in _currentReferences)
{
service.RegisterReference(handle, x);
}
var tween = CreateTween();
registerButton.Disabled = true;
registerProgress.Value = 0;
tween.TweenProperty(registerProgress, "value", registerProgress.MaxValue, 0.5f);
tween.Finished+= () =>
{
registerProgress.Value = 0;
registerProgress.Visible = false;
registerButton.Disabled = false;
hints.Text = "注册成功";
};
tween.Play();
handleEdit.Text = string.Empty;
}
}

View File

@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net.Mime;
using BITKit;
using Cysharp.Threading.Tasks;
using Godot;
using Microsoft.EntityFrameworkCore;
@ -194,6 +195,16 @@ public class IDIS_DBContext:DbContext
Datas.Add(data);
SaveChanges();
}
public void RegisterReference(string handle, string refenceHandle)
{
References.Add(new IDIS_Reference()
{
Handle = handle,
RelatedHandle = refenceHandle,
});
SaveChanges();
}
}
// ReSharper disable once IdentifierTypo
/// <summary>
@ -206,9 +217,11 @@ public partial class IDIS_Service:Node
{
Context = new IDIS_DBContext();
BIT4Log.Log<IDIS_Service>("已创建标识数据库");
Context.Database.EnsureCreated();
UniTask.Run(()=>Context.Database.EnsureCreatedAsync());
}
public bool Register(string handle) => Context.Register(handle);
public void Register(string handle, string format, string value) => Context.Register(handle, format, value);
public void RegisterReference(string handle,string refenceHandle) => Context.RegisterReference(handle,refenceHandle);
public static string GenerateHandle() => $"88.123.99/{Mathf.Abs(Guid.NewGuid().GetHashCode())}";
}

View File

@ -1,6 +1,7 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using BITKit;
@ -14,6 +15,8 @@ public class IDIS_Template
public string TemplateName="标识注册模板";
public string TemplateDescription="该模板通常用于xxx用途";
public string IconPath="Register";
public DateTime CreateTime=DateTime.Now;
public DateTime UpdateTime=DateTime.Now;
public List<(string format,string hint)> Formats=new();
}
public partial class IDIS_TemplateService : Node
@ -29,6 +32,8 @@ public partial class IDIS_TemplateService : Node
[Export] private LineEdit templateNameEdit;
[Export] private LineEdit templateDescriptionEdit;
[Export] private Control container;
[Export] private Label templateCreateTimeLabel;
[Export] private Label templateUpdateTimeLabel;
[ExportCategory("Template")]
[Export] private PackedScene templateContainer;
@ -67,6 +72,7 @@ public partial class IDIS_TemplateService : Node
if (_selectedTemplate is null) return;
_selectedTemplate.Formats ??= new();
_selectedTemplate.Formats.Add(("新的数据格式","格式类型"));
_selectedTemplate.UpdateTime= DateTime.Now;
EnsureConfigure();
}
@ -91,11 +97,13 @@ public partial class IDIS_TemplateService : Node
{
if (_selectedTemplate is null) return;
_selectedTemplate.TemplateName = text;
_selectedTemplate.UpdateTime= DateTime.Now;
}
private void OnTemplateDescriptionChanged(string text)
{
if (_selectedTemplate is null) return;
_selectedTemplate.TemplateDescription = text;
_selectedTemplate.UpdateTime= DateTime.Now;
}
private void EnsureConfigure()
{
@ -108,9 +116,10 @@ public partial class IDIS_TemplateService : Node
}
if (_selectedTemplate is null) return;
{
templateNameEdit.Text=_selectedTemplate.TemplateName;
templateDescriptionEdit.Text=_selectedTemplate.TemplateDescription;
templateCreateTimeLabel.Text = _selectedTemplate.CreateTime.ToString(CultureInfo.InvariantCulture);
templateUpdateTimeLabel.Text = _selectedTemplate.UpdateTime.ToString(CultureInfo.InvariantCulture);
for (var i = 0; i < _selectedTemplate.Formats.Count; i++)
{
@ -127,6 +136,7 @@ public partial class IDIS_TemplateService : Node
var current = _selectedTemplate.Formats[index];
current.format = s;
_selectedTemplate.Formats[index] = current;
_selectedTemplate.UpdateTime= DateTime.Now;
};
_container.lineEdits[1].TextChanged += s =>
{
@ -142,7 +152,6 @@ public partial class IDIS_TemplateService : Node
container.AddChild(_container);
}
}
}
private void OnItemSelected(long id)
{

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=10 format=3 uid="uid://cngf2h2a5ne4a"]
[gd_scene load_steps=11 format=3 uid="uid://cngf2h2a5ne4a"]
[ext_resource type="Script" path="res://BITKit/Scripts/UX/UXPanel.cs" id="1_c78kh"]
[ext_resource type="PackedScene" uid="uid://d1po2qljd0jh2" path="res://Mods/教育平台/教程header.tscn" id="2_mn1rn"]
@ -11,6 +11,8 @@
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_clkje"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_1rin1"]
[node name="标识注册与解析" type="Control"]
layout_mode = 3
anchors_preset = 15
@ -47,8 +49,8 @@ layout_mode = 2
size_flags_vertical = 3
theme_type_variation = &"Margin_16px"
script = ExtResource("3_sfip0")
tabs = [NodePath("Horizontal Layout/导航栏/标识模板-button"), NodePath("Horizontal Layout/导航栏/Button3"), NodePath("Horizontal Layout/导航栏/Button2"), NodePath("Horizontal Layout/导航栏/Button4"), NodePath("Horizontal Layout/导航栏/Button5"), NodePath("Horizontal Layout/导航栏/Button6")]
windows = [NodePath("Horizontal Layout/内容/标识模板"), NodePath("Horizontal Layout/内容/标注注册"), NodePath("Horizontal Layout/内容/Container2"), NodePath("Horizontal Layout/内容/Container3"), NodePath("Horizontal Layout/内容/Container4"), NodePath("Horizontal Layout/内容/Container5")]
tabs = [NodePath("Horizontal Layout/导航栏/标识模板-button"), NodePath("Horizontal Layout/导航栏/Button3"), NodePath("Horizontal Layout/导航栏/Button2"), NodePath("Horizontal Layout/导航栏/Button4")]
windows = [NodePath("Horizontal Layout/内容/标识模板"), NodePath("Horizontal Layout/内容/标注注册"), NodePath("Horizontal Layout/内容/Container2"), NodePath("Horizontal Layout/内容/Container3")]
[node name="Horizontal Layout" type="HBoxContainer" parent="Layout/UX Window Service"]
layout_mode = 2
@ -72,42 +74,35 @@ text = "管理标识模板"
[node name="Label3" type="Label" parent="Layout/UX Window Service/Horizontal Layout/导航栏"]
layout_mode = 2
theme_type_variation = &"HeaderMedium"
text = "准备生产"
text = "注册"
[node name="Button3" type="Button" parent="Layout/UX Window Service/Horizontal Layout/导航栏"]
layout_mode = 2
toggle_mode = true
button_group = ExtResource("3_wv1s6")
text = "注册设备"
text = "注册标识"
[node name="Label4" type="Label" parent="Layout/UX Window Service/Horizontal Layout/导航栏"]
layout_mode = 2
theme_type_variation = &"HeaderMedium"
text = "开始生产"
text = "查询"
[node name="Button2" type="Button" parent="Layout/UX Window Service/Horizontal Layout/导航栏"]
layout_mode = 2
toggle_mode = true
button_group = ExtResource("3_wv1s6")
text = "注册订单"
text = "标识解析"
[node name="Label5" type="Label" parent="Layout/UX Window Service/Horizontal Layout/导航栏"]
layout_mode = 2
theme_type_variation = &"HeaderMedium"
text = "实训"
[node name="Button4" type="Button" parent="Layout/UX Window Service/Horizontal Layout/导航栏"]
layout_mode = 2
toggle_mode = true
button_group = ExtResource("3_wv1s6")
text = "内容1"
[node name="Button5" type="Button" parent="Layout/UX Window Service/Horizontal Layout/导航栏"]
layout_mode = 2
toggle_mode = true
button_group = ExtResource("3_wv1s6")
text = "内容1"
[node name="Button6" type="Button" parent="Layout/UX Window Service/Horizontal Layout/导航栏"]
layout_mode = 2
toggle_mode = true
button_group = ExtResource("3_wv1s6")
text = "内容1"
text = "温湿度传感器"
[node name="内容" type="PanelContainer" parent="Layout/UX Window Service/Horizontal Layout"]
layout_mode = 2
@ -115,7 +110,6 @@ size_flags_horizontal = 3
theme_override_styles/panel = SubResource("StyleBoxEmpty_clkje")
[node name="标识模板" type="MarginContainer" parent="Layout/UX Window Service/Horizontal Layout/内容"]
visible = false
layout_mode = 2
theme_type_variation = &"Margin_16px"
@ -193,7 +187,7 @@ columns = 2
layout_mode = 2
text = "创建时间:"
[node name="Label6" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/GridContainer"]
[node name="createTime-label" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/GridContainer"]
layout_mode = 2
text = "2023年7月7日23:42:40"
@ -201,7 +195,7 @@ text = "2023年7月7日23:42:40"
layout_mode = 2
text = "更新时间:"
[node name="Label8" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/GridContainer"]
[node name="updateTime-label" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/GridContainer"]
layout_mode = 2
text = "2023年7月7日23:42:40"
@ -261,6 +255,7 @@ layout_mode = 2
text = "保存注册模板"
[node name="标注注册" type="MarginContainer" parent="Layout/UX Window Service/Horizontal Layout/内容"]
visible = false
layout_mode = 2
theme_type_variation = &"Margin_16px"
@ -286,6 +281,10 @@ item_1/text = "2"
item_2/text = "3"
item_3/text = "4"
[node name="VSeparator" type="VSeparator" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 64
[node name="VBoxContainer2" type="VBoxContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
@ -301,7 +300,7 @@ layout_mode = 2
[node name="handle-edit" type="LineEdit" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "需要注册的标识码"
placeholder_text = "留空则自动创建标识"
caret_blink = true
caret_blink_interval = 0.5
@ -314,15 +313,50 @@ layout_mode = 2
size_flags_vertical = 3
theme_type_variation = &"Margin_16px"
[node name="register-container" type="VBoxContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer"]
[node name="VBoxContainer" type="VBoxContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_type_variation = &"HeaderSmall"
text = "标识值"
[node name="register-container" type="VBoxContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Label2" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_type_variation = &"HeaderSmall"
text = "标识引用"
[node name="reference-container" type="VBoxContainer" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="addReference-button" type="Button" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer/VBoxContainer"]
layout_mode = 2
text = "添加引用"
[node name="Label2" type="Label" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2"]
layout_mode = 2
text = "等待操作"
[node name="register-button" type="Button" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2"]
layout_mode = 2
text = "注册标识"
[node name="ProgressBar" type="ProgressBar" parent="Layout/UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/register-button"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme_override_styles/background = SubResource("StyleBoxEmpty_1rin1")
show_percentage = false
[node name="Container2" type="Container" parent="Layout/UX Window Service/Horizontal Layout/内容"]
visible = false
layout_mode = 2
@ -331,18 +365,10 @@ layout_mode = 2
visible = false
layout_mode = 2
[node name="Container4" type="Container" parent="Layout/UX Window Service/Horizontal Layout/内容"]
visible = false
layout_mode = 2
[node name="Container5" type="Container" parent="Layout/UX Window Service/Horizontal Layout/内容"]
visible = false
layout_mode = 2
[node name="标识解析服务" type="Node" parent="Layout"]
script = ExtResource("3_xbtmk")
[node name="标识模板服务" type="Node" parent="Layout" node_paths=PackedStringArray("createButton", "newFormatButton", "itemList", "templateNameEdit", "templateDescriptionEdit", "container")]
[node name="标识模板服务" type="Node" parent="Layout" node_paths=PackedStringArray("createButton", "newFormatButton", "itemList", "templateNameEdit", "templateDescriptionEdit", "container", "templateCreateTimeLabel", "templateUpdateTimeLabel")]
script = ExtResource("4_oj8cs")
createButton = NodePath("../UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer/Button")
newFormatButton = NodePath("../UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/Button")
@ -350,14 +376,22 @@ itemList = NodePath("../UX Window Service/Horizontal Layout/内容/标识模板/
templateNameEdit = NodePath("../UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/name-edit")
templateDescriptionEdit = NodePath("../UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/description-edit")
container = NodePath("../UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/Format-Container")
templateCreateTimeLabel = NodePath("../UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/GridContainer/createTime-label")
templateUpdateTimeLabel = NodePath("../UX Window Service/Horizontal Layout/内容/标识模板/VBoxContainer/HBoxContainer/VBoxContainer2/VBoxContainer/GridContainer/updateTime-label")
templateContainer = ExtResource("3_gmthc")
[node name="标识注册服务" type="Node" parent="Layout" node_paths=PackedStringArray("service", "templateService", "templateList", "handleEdit", "generateHandleButton", "container", "registerButton")]
[node name="标识注册服务" type="Node" parent="Layout" node_paths=PackedStringArray("service", "templateService", "templateList", "handleEdit", "generateHandleButton", "registerContainer", "registerButton", "registerProgress", "referenceContainer", "addReferenceButton", "hints")]
script = ExtResource("8_6uwr0")
service = NodePath("../标识解析服务")
templateService = NodePath("../标识模板服务")
templateList = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer/ItemList")
handleEdit = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/HBoxContainer/handle-edit")
generateHandleButton = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/HBoxContainer/generate-button")
container = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer/register-container")
registerContainer = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer/VBoxContainer/register-container")
registerButton = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/register-button")
registerProgress = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/register-button/ProgressBar")
referenceContainer = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer/VBoxContainer/reference-container")
addReferenceButton = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/MarginContainer/VBoxContainer/addReference-button")
hints = NodePath("../UX Window Service/Horizontal Layout/内容/标注注册/HBoxContainer/VBoxContainer2/Label2")
[connection signal="draw" from="Layout/UX Window Service/Horizontal Layout/内容/标注注册" to="Layout/标识注册服务" method="Rebuild"]

View File

@ -71,4 +71,5 @@
- [ ] 解析错误
- [ ] 给出错误提示和原因
## 更改记录
- 完成部分功能
- 创建文档

View File

@ -8,6 +8,7 @@
<ProjectReference Include="..\BITKit\BITKit.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FuzzySharp" Version="2.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.19" />