From ad691931c6e000d74f57780305295653385c0da4 Mon Sep 17 00:00:00 2001
From: deltanedas <39013340+deltanedas@users.noreply.github.com>
Date: Sun, 18 Aug 2024 22:34:43 +0000
Subject: [PATCH] add memory cell and rework logic construction (#24983)
* rework construction to be deconstructable, add memory cell
* update textures
* add code
* add memory cell and ports, empty circuit
* d
---------
Co-authored-by: deltanedas <@deltanedas:kde.org>
---
.../Components/MemoryCellComponent.cs | 40 +++++++++
.../DeviceLinking/Systems/MemoryCellSystem.cs | 74 +++++++++++++++
.../en-US/machine-linking/receiver_ports.ftl | 5 ++
.../Prototypes/DeviceLinking/sink_ports.yml | 10 +++
.../Prototypes/Entities/Structures/gates.yml | 49 ++++++++--
.../Construction/Graphs/tools/logic_gate.yml | 84 ++++++++++++++++--
.../Prototypes/Recipes/Construction/tools.yml | 11 +++
.../Objects/Devices/gates.rsi/base.png | Bin 7579 -> 7307 bytes
.../Devices/gates.rsi/edge_detector.png | Bin 7375 -> 7036 bytes
.../Objects/Devices/gates.rsi/logic.png | Bin 0 -> 7196 bytes
.../Objects/Devices/gates.rsi/memory_cell.png | Bin 0 -> 228 bytes
.../Objects/Devices/gates.rsi/meta.json | 8 +-
.../Devices/gates.rsi/power_sensor.png | Bin 7376 -> 7090 bytes
13 files changed, 264 insertions(+), 17 deletions(-)
create mode 100644 Content.Server/DeviceLinking/Components/MemoryCellComponent.cs
create mode 100644 Content.Server/DeviceLinking/Systems/MemoryCellSystem.cs
create mode 100644 Resources/Textures/Objects/Devices/gates.rsi/logic.png
create mode 100644 Resources/Textures/Objects/Devices/gates.rsi/memory_cell.png
diff --git a/Content.Server/DeviceLinking/Components/MemoryCellComponent.cs b/Content.Server/DeviceLinking/Components/MemoryCellComponent.cs
new file mode 100644
index 0000000000..d55042978a
--- /dev/null
+++ b/Content.Server/DeviceLinking/Components/MemoryCellComponent.cs
@@ -0,0 +1,40 @@
+using Content.Server.DeviceLinking.Systems;
+using Content.Shared.DeviceLinking;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.DeviceLinking.Components;
+
+///
+/// Memory cell that sets the output to the input when enabled.
+///
+[RegisterComponent, Access(typeof(MemoryCellSystem))]
+public sealed partial class MemoryCellComponent : Component
+{
+ ///
+ /// Name of the input port.
+ ///
+ [DataField]
+ public ProtoId InputPort = "MemoryInput";
+
+ ///
+ /// Name of the enable port.
+ ///
+ [DataField]
+ public ProtoId EnablePort = "MemoryEnable";
+
+ ///
+ /// Name of the output port.
+ ///
+ [DataField]
+ public ProtoId OutputPort = "Output";
+
+ // State
+ [DataField]
+ public SignalState InputState = SignalState.Low;
+
+ [DataField]
+ public SignalState EnableState = SignalState.Low;
+
+ [DataField]
+ public bool LastOutput;
+}
diff --git a/Content.Server/DeviceLinking/Systems/MemoryCellSystem.cs b/Content.Server/DeviceLinking/Systems/MemoryCellSystem.cs
new file mode 100644
index 0000000000..56a6f45c3b
--- /dev/null
+++ b/Content.Server/DeviceLinking/Systems/MemoryCellSystem.cs
@@ -0,0 +1,74 @@
+using Content.Server.DeviceLinking.Components;
+using Content.Server.DeviceLinking.Events;
+using Content.Server.DeviceNetwork;
+using Content.Shared.DeviceLinking;
+
+namespace Content.Server.DeviceLinking.Systems;
+
+///
+/// Handles the control of output based on the input and enable ports.
+///
+public sealed class MemoryCellSystem : EntitySystem
+{
+ [Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnInit);
+ SubscribeLocalEvent(OnSignalReceived);
+ }
+
+ public override void Update(float deltaTime)
+ {
+ base.Update(deltaTime);
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var comp, out var source))
+ {
+ if (comp.InputState == SignalState.Momentary)
+ comp.InputState = SignalState.Low;
+ if (comp.EnableState == SignalState.Momentary)
+ comp.EnableState = SignalState.Low;
+
+ UpdateOutput((uid, comp, source));
+ }
+ }
+
+ private void OnInit(Entity ent, ref ComponentInit args)
+ {
+ var (uid, comp) = ent;
+ _deviceLink.EnsureSinkPorts(uid, comp.InputPort, comp.EnablePort);
+ _deviceLink.EnsureSourcePorts(uid, comp.OutputPort);
+ }
+
+ private void OnSignalReceived(Entity ent, ref SignalReceivedEvent args)
+ {
+ var state = SignalState.Momentary;
+ args.Data?.TryGetValue(DeviceNetworkConstants.LogicState, out state);
+
+ if (args.Port == ent.Comp.InputPort)
+ ent.Comp.InputState = state;
+ else if (args.Port == ent.Comp.EnablePort)
+ ent.Comp.EnableState = state;
+
+ UpdateOutput(ent);
+ }
+
+ private void UpdateOutput(Entity ent)
+ {
+ if (!Resolve(ent, ref ent.Comp2))
+ return;
+
+ if (ent.Comp1.EnableState == SignalState.Low)
+ return;
+
+ var value = ent.Comp1.InputState != SignalState.Low;
+ if (value == ent.Comp1.LastOutput)
+ return;
+
+ ent.Comp1.LastOutput = value;
+ _deviceLink.SendSignal(ent, ent.Comp1.OutputPort, value, ent.Comp2);
+ }
+}
diff --git a/Resources/Locale/en-US/machine-linking/receiver_ports.ftl b/Resources/Locale/en-US/machine-linking/receiver_ports.ftl
index dc45677c8d..a0d2fd3ec4 100644
--- a/Resources/Locale/en-US/machine-linking/receiver_ports.ftl
+++ b/Resources/Locale/en-US/machine-linking/receiver_ports.ftl
@@ -81,3 +81,8 @@ signal-port-description-logic-input-b = Second input of a logic gate.
signal-port-name-logic-input = Input
signal-port-description-logic-input = Input to the edge detector, cannot be a pulse signal.
+
+signal-port-description-logic-memory-input = Signal to load into the memory cell, when enabled.
+
+signal-port-name-logic-enable = Enable
+signal-port-description-logic-enable = Only loads the input signal into the memory cell when HIGH.
diff --git a/Resources/Prototypes/DeviceLinking/sink_ports.yml b/Resources/Prototypes/DeviceLinking/sink_ports.yml
index 56b10ec4fc..339b814175 100644
--- a/Resources/Prototypes/DeviceLinking/sink_ports.yml
+++ b/Resources/Prototypes/DeviceLinking/sink_ports.yml
@@ -93,6 +93,16 @@
name: signal-port-name-logic-input
description: signal-port-description-logic-input
+- type: sinkPort
+ id: MemoryInput
+ name: signal-port-name-logic-input
+ description: signal-port-description-logic-memory-input
+
+- type: sinkPort
+ id: MemoryEnable
+ name: signal-port-name-logic-enable
+ description: signal-port-description-logic-enable
+
- type: sinkPort
id: SetParticleDelta
name: signal-port-name-set-particle-delta
diff --git a/Resources/Prototypes/Entities/Structures/gates.yml b/Resources/Prototypes/Entities/Structures/gates.yml
index 6b02840ba0..8e60962321 100644
--- a/Resources/Prototypes/Entities/Structures/gates.yml
+++ b/Resources/Prototypes/Entities/Structures/gates.yml
@@ -1,12 +1,24 @@
- type: entity
- abstract: true
parent: BaseItem
- id: BaseLogicItem
+ id: LogicEmptyCircuit
+ name: empty circuit
+ description: Something seems to be missing.
components:
- type: Sprite
sprite: Objects/Devices/gates.rsi
+ layers:
+ - state: base
- type: Anchorable
- type: Rotatable
+ - type: Construction
+ graph: LogicGate
+ node: empty
+
+- type: entity
+ abstract: true
+ parent: LogicEmptyCircuit
+ id: BaseLogicItem
+ components:
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: BasicDevice
@@ -23,6 +35,7 @@
- type: Sprite
layers:
- state: base
+ - state: logic
- state: or
map: [ "enum.LogicGateLayers.Gate" ]
- type: LogicGate
@@ -38,7 +51,6 @@
lastSignals:
Output: false
- type: Construction
- graph: LogicGate
node: logic_gate
- type: Appearance
- type: GenericVisualizer
@@ -124,7 +136,9 @@
description: Splits rising and falling edges into unique pulses and detects how edgy you are.
components:
- type: Sprite
- state: edge_detector
+ layers:
+ - state: base
+ - state: edge_detector
- type: EdgeDetector
- type: DeviceLinkSink
ports:
@@ -137,7 +151,6 @@
OutputHigh: false
OutputLow: false
- type: Construction
- graph: LogicGate
node: edge_detector
- type: entity
@@ -147,7 +160,9 @@
description: Generates signals in response to powernet changes. Can be cycled between cable voltages.
components:
- type: Sprite
- state: power_sensor
+ layers:
+ - state: base
+ - state: power_sensor
- type: PowerSensor
- type: PowerSwitchable
examineText: power-sensor-voltage-examine
@@ -183,5 +198,25 @@
PowerCharging: false
PowerDischarging: false
- type: Construction
- graph: LogicGate
node: power_sensor
+
+- type: entity
+ parent: BaseLogicItem
+ id: MemoryCell
+ name: memory cell
+ description: A D-Latch circuit that stores a signal which can be changed depending on input and enable ports.
+ components:
+ - type: Sprite
+ layers:
+ - state: base
+ - state: memory_cell
+ - type: MemoryCell
+ - type: DeviceLinkSink
+ ports:
+ - MemoryInput
+ - MemoryEnable
+ - type: DeviceLinkSource
+ ports:
+ - Output
+ - type: Construction
+ node: memory_cell
diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/tools/logic_gate.yml b/Resources/Prototypes/Recipes/Construction/Graphs/tools/logic_gate.yml
index d366a2ea59..37c85e07a3 100644
--- a/Resources/Prototypes/Recipes/Construction/Graphs/tools/logic_gate.yml
+++ b/Resources/Prototypes/Recipes/Construction/Graphs/tools/logic_gate.yml
@@ -4,38 +4,104 @@
graph:
- node: start
edges:
- - to: logic_gate
+ - to: empty
steps:
- material: Steel
amount: 3
doAfter: 1
+ - node: empty
+ entity: LogicEmptyCircuit
+ edges:
+ - to: start
+ steps:
+ - tool: Screwing
+ doAfter: 2
+ completed:
+ - !type:SpawnPrototype
+ prototype: SheetSteel1
+ amount: 3
+ - !type:DeleteEntity {}
+ - to: logic_gate
+ steps:
- material: Cable
amount: 2
doAfter: 1
- to: edge_detector
steps:
- - material: Steel
- amount: 3
+ - material: Glass
+ amount: 2
doAfter: 1
- material: Cable
amount: 2
doAfter: 1
- to: power_sensor
steps:
- - material: Steel
- amount: 3
- doAfter: 1
- - material: Cable
- amount: 2
- doAfter: 1
- tag: Multitool
icon:
sprite: Objects/Tools/multitool.rsi
state: icon
name: a multitool
+ - material: Cable
+ amount: 2
+ doAfter: 1
+ - to: memory_cell
+ steps:
+ - tag: CapacitorStockPart
+ icon:
+ sprite: Objects/Misc/stock_parts.rsi
+ state: capacitor
+ name: a capacitor
+ - material: Cable
+ amount: 2
+ doAfter: 1
- node: logic_gate
entity: LogicGateOr
+ edges:
+ - to: empty
+ steps:
+ - tool: Prying
+ doAfter: 2
+ completed:
+ - !type:SpawnPrototype
+ prototype: CableApcStack1
+ amount: 2
- node: edge_detector
entity: EdgeDetector
+ edges:
+ - to: empty
+ steps:
+ - tool: Prying
+ doAfter: 2
+ completed:
+ - !type:SpawnPrototype
+ prototype: SheetGlass1
+ amount: 2
+ - !type:SpawnPrototype
+ prototype: CableApcStack1
+ amount: 2
- node: power_sensor
entity: PowerSensor
+ edges:
+ - to: empty
+ steps:
+ - tool: Prying
+ doAfter: 2
+ completed:
+ - !type:SpawnPrototype
+ prototype: Multitool
+ - !type:SpawnPrototype
+ prototype: CableApcStack1
+ amount: 2
+ - node: memory_cell
+ entity: MemoryCell
+ edges:
+ - to: empty
+ steps:
+ - tool: Prying
+ doAfter: 2
+ completed:
+ - !type:SpawnPrototype
+ prototype: CapacitorStockPart
+ - !type:SpawnPrototype
+ prototype: CableApcStack1
+ amount: 2
diff --git a/Resources/Prototypes/Recipes/Construction/tools.yml b/Resources/Prototypes/Recipes/Construction/tools.yml
index a6d9e33f4c..bb89c5f244 100644
--- a/Resources/Prototypes/Recipes/Construction/tools.yml
+++ b/Resources/Prototypes/Recipes/Construction/tools.yml
@@ -41,3 +41,14 @@
description: A power network checking device for signals.
icon: { sprite: Objects/Devices/gates.rsi, state: power_sensor }
objectType: Item
+
+- type: construction
+ name: memory cell
+ id: MemoryCell
+ graph: LogicGate
+ startNode: start
+ targetNode: memory_cell
+ category: construction-category-tools
+ description: A memory cell for signals.
+ icon: { sprite: Objects/Devices/gates.rsi, state: memory_cell }
+ objectType: Item
diff --git a/Resources/Textures/Objects/Devices/gates.rsi/base.png b/Resources/Textures/Objects/Devices/gates.rsi/base.png
index 946bfb4a29157d41a0cfb1c9a536a9f3d90945e9..dd963225770168488e86fb2669a5b6eb63ea3933 100644
GIT binary patch
delta 570
zcmV-A0>%BCJBvAxBeR_WZw8Z32r>r>He@z2HaC-q2to%6GBPtUGcc3U2tol0lllil
zlNAXNlXeL;2{JG;FfuSVI0};<2}HA}32+jB=H0005fNkl
zRv`o&oTZCHsdOncOE+=p&`;n8aP$L6SHDRohfr|sBBhHKN;m23AOs=)jac8iJ})*o
zW1`Rw`N8Ggy(9PD{obF1u^2I8{4o-;jaI9*PNh;Toldh{E*I+1Y&MHBlgZ%wfJ&u*
zk_dH3v)Np4#7Tx}nroRICCHI_y?(IMqtOVZWm#KYr_*7x*^EVY0O;&r^|$MxHDm?7
zfOE5a!S3G&9z7xdoJTpCOr+O}icetW;p?20&PuqR&*$MCSS%JO
zp$E{7%(9@KjDw+eaf;H@WD>meZQG8{05lTHbO0D@7diEGYel=<$boMH2SJ*IL>qKN
zH|VBDZ;W#ovP7gVxVOrJ97raU2jvDZg9joT9FLzYx&s90=ad5!3T~vk(|km64v0_~
zsu4W|e)Z1dKlN0D`_^Hh99s8APpseWL7bqx$^rPKR;yK<>$>jg?_uCLPWBYy#IX+uL$X=7sm04R}lk-bYoQ5eR5YEqQtP+&xagGEC@6hvd$
z;36Srkkz6$KLS54_bMT+K}&DW*vI>
zDyQIhhO1oNpO>6wzCFq5DMK(jFj
zY!ZKyXfTif00C%8L_t(o!|hg0YJ@Npj{l-v2zrk80<#wJ60U@T2k6pe!4p(GKv!M4
z5!Z8q(i6BBq*U=2+hpo=pkp*zunRv3FGiF1<;#070
zKsim*Ty(y^?;~3j#ppNm)FLd)t`0Pu0+R%Io?q-(RaIoWt|L2w^7X!deEE3}g5c_8
z+qP#BX_|(NfOz{veP;pI5hR8qLDMIJtEwUo!n&@J#nk}ld`uk(P1BIg^Bk!PH%5OP
z14AKMg3ADI-`~g-7-WOha12vN5XbSke{(oevk8105Bz_S6k-)&f
zaM;tuF(l$}a)Jcw;sg;MgM=fhf${PFq1{r_(w>(ceAyouceh^SQ+!e^mc&z7Q1HXQ
z?*^(
zuw5#e6UflD{@d0SsVr48$=&IzS`!Y;_YZ#&CX~d>C^uWV=j+#VEVbUf8VfXd8+49~
znU)kYn94X#En=9h{31#~aI$iNsEdnb!wjRjX@L$!wtl|s0lNc@xZDnENK9d1m>TYG
UcSZSe63{;kp00i_>zopr0NJ&T-2eap
delta 798
zcmV+(1L6GqHqSYbBYy#HX+uL$X=7sm04R}lk
zY|>g~ahaLj*;V^vnwd?Tt8#Hr4&vh1!GFM2xl&4zlHA<=x=7=Bty*dKo!)sqec$){
z^vrj_7tIbTs
zlPSl5x<=tK!?ImrnTF`9Ybo9oZZ|SoQusi4(3Sy(FO{yB`AKoQ%x{YAcx(!Ms%I$u
zhxI>fWbB-9zi>F0EgHY`s4oeo^7C_2yJUCc5M!DMA#{qYki}(4YF;v{?i>E`%}@}J
zA#aNkwm8yc#D6;|YEinTq?)3qRK4?XYe
z2|*rDze8i%VDl000SaNU2F*0Q{FfwK`GB9BZlh6bd0yZ?0p#?G(3N~amH8y28G&eIcW-~D|
zWiv4{W|QFtED16)GchwTGdBv876&5%Ig`Z(BmoMOT?ax3GB7tZHaQBDj0QK8IR_C7
z3N~goWiwFq5DM
zKmiJqe+VocFkvz
z005myL_t(o!|jzz4uBvGMAh_Qa5BQl;AVc75|F|ah)Lhh)H+ipmTglMWiflH;G8=p
zg}nD!Evht$h~L8$YlJj2C;zMy=Of0LF7X&+^&OJR*joE~4k57mNJ^Y5m~yNXhYg_O
zO%bFSx8yuD0u=TMM?4qJ)Cf=$B6}cbV(KD7{s@)<&Q2c|fz*}UWdOa3
c6-D_47w{D{GitNP7XSbN07*qoM6N<$g7E7~IsgCw
diff --git a/Resources/Textures/Objects/Devices/gates.rsi/logic.png b/Resources/Textures/Objects/Devices/gates.rsi/logic.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb120ce4961ab0ffcd9153c0f8d594e19cf9a057
GIT binary patch
literal 7196
zcmd5>3v3is6dkY_94)D)q{aZ*0x|v~v+vEknUMr2P@yIgt-qo`*w3ugh!g=S5>ZjB
zd?eK7ZZpgVvP8q5D6M18u8pWGrRM4x7%IXw9aNe?|1IG
z=iYaxnXb8J){JWX0$tOz>ZX~~n{kiPIs8mqm)w2#@3@`SHgon8O}l&?okQ9;O}(Q*-*DzZ_Sh9-Jn(
znXp9MHgPqXVcWvRv%?J2hMsA1Ad_M)t<^1G&}>K84yQ7MGv;v+!j*G|AA0ahppUMM
zLoOcIxr2rk3=lN=48fxQhdR(O9r}gOe=r6K^KjAJXl+}X(sa7|xe+rR-7!NQwFo4O+21cM(;@){gyx8*raK7n~PFvU)ZMUxJW|G
zwYknyJYyp`A}+W{3d@Gzg5-zj!sBU(mq{j*8OG4>3X^&)n_Fg@8)h0o<(P|f*GZ&k^!cjk5cE?O-pqGm6Gx-foo(t`%%Ltkrs1YdU(g>>VvEh*@)v0
z42ld&umN;%K)z5pMHIqgBO_BADUKXN#(3K$lb^6%Mt
zRQ{6UGy4UILe(!o#Bs2JqIu_QHrR{`BUd(~LT6O4vVqiPg{^@A>dhII)j%*(E%w$@
z7**zs3atRCLzT7q2`KwstIT?_+5N<*4`n1jFoVx1U#AKfIJBjGZg`;lS{RFVN`0VI#vKwzB9c5sl(;B3K*5YRGkT+({-i*NbNY?R-asp
z`qC$$DEq+ziaHbJ(}%y0RG5JT>e(5U(_o3MvWT{dFe=xXD2x=Fz9|&>%1+XCfAlEM)ao^XPHYC+Fz2W+n_mAE<@wSJi)Q&{KZvsXKcCurghuSy0re#(B_-Z
zoYU~Zu(vOH^3j%eM?Uy!*SyY}ofA5qdUi#p{p*6R+A*CI*B{*e)2bQTh*8dFe$j!m
zKRcoAT0EtuDz=+_@!aF%>n~nA_REJqU-r!Ur;hBn_po<<$NuHrPjC6bSy#QOb!~d1
z_rtu}#%C|v{YTY&=jy%P``VBFJ?W~&*VgV|^z-&gs+y>9Xh8WdENL0Cnt7ca$REX
zzL~Q=(H4xV8$JB$y`6hbjA|Tt#g%i;ct1A#fg?ljn0)Z#vBrbdv!;zY++4Hk__lW@
z&V6ZT)uah8{`e%$L-!CR=Rs?#}57ND(jpxUK`o?m-SuK=Ua~+KeGH#*QuR#_l#NGJa6*H
SG5q&NYigV|{q?EySN{i0cq3H+
literal 0
HcmV?d00001
diff --git a/Resources/Textures/Objects/Devices/gates.rsi/memory_cell.png b/Resources/Textures/Objects/Devices/gates.rsi/memory_cell.png
new file mode 100644
index 0000000000000000000000000000000000000000..bcb0d509b96affd4bf078ac7d4fa3c54ae94b59d
GIT binary patch
literal 228
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?31We{epSZZGe6rASi
z;usQfI5|Orb#a17Pt!y`iO#?+_5c6
literal 0
HcmV?d00001
diff --git a/Resources/Textures/Objects/Devices/gates.rsi/meta.json b/Resources/Textures/Objects/Devices/gates.rsi/meta.json
index 9d10f53279..761bdab87a 100644
--- a/Resources/Textures/Objects/Devices/gates.rsi/meta.json
+++ b/Resources/Textures/Objects/Devices/gates.rsi/meta.json
@@ -1,7 +1,7 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
- "copyright": "or.png originally created by Kevin Zheng, 2022. All are modified by deltanedas (github) for SS14, 2023.",
+ "copyright": "or.png originally created by Kevin Zheng, 2022. All are modified by deltanedas (github) for SS14, 2024.",
"size": {
"x": 32,
"y": 32
@@ -10,6 +10,9 @@
{
"name": "base"
},
+ {
+ "name": "logic"
+ },
{
"name": "or"
},
@@ -36,6 +39,9 @@
},
{
"name": "power_sensor"
+ },
+ {
+ "name": "memory_cell"
}
]
}
diff --git a/Resources/Textures/Objects/Devices/gates.rsi/power_sensor.png b/Resources/Textures/Objects/Devices/gates.rsi/power_sensor.png
index 3bd6de6d1039fb6b7b3ffc6e497523e836fa88eb..c374715b4eec6f0b358a0a036303dc9571fb01a5 100644
GIT binary patch
delta 342
zcmV-c0jd7bIkGp9BeR?VI0ln&2o#e{2n+)XGc%LG2Q-r>2oM7_ISP{p2r-jy2tt$e
z2p$0nlb;AMlh6nlvlt2f5`X69$Y1~f0QpHoK~z}7V_+BsqhJ&aFkr+bQD0wARf`%M
z8%fhZO$XpJi-pz>A>?xwVhnL`aQKf)&e72kOz+>nA4BfIfdh<$%*N_~AD1%zbLcfP
z!h8U90A9-}0ZiBgIrL^Q!h#-G6d+rU&G!^JfDjtAeJ^%m!
delta 643
zcmV-}0(||lH_$ndBYy#HX+uL$X=7sm04R}lkv&VpP!xurR>iMM2Sr32I;c1(NCk1!
zI=B>(s$kWnNt0GcYe-T=Tm=^g!9jHKYw#cFD!3{Lf+C2xx%;(9iRT)jBK3xw^YGsL
z9!}msIBDqxw{{c?MbAl1Bw};v`B?okjkE(p#51~Uk4;S_`G0qP+!9jtWLJh*hy6t$vG7ZTU&sMxC+@|LXfWen$orzErvv@RQr~@-2dk3nnUrRdn5sMkG}uf1NGZb-tzs=L*FkS
zLCpi47c2f{$!X+W^sS24y${iKIK8N7+76s;K*znEaWdahjqI>#!pjM?q@nd1nihhr
ze$F|*gPAq?MOU!92fcDXy7&cAmuN5YMaUrl000SaNUEELbI6%1QUPQ9WxyO
z005pzL_t(o!|hc;4!|G?bHs<~%ZxA6pKZ$$Pm_tjVod18L!+hGfO7_eVKEMjNGY9~
zLOJKImLFVF5x>o#oR?fCI{)N7<&h8q%EcI;vy}4UYOTY!LE^57O8^?;J@>yBpe4>K
zKvSF?LhR4649pY;ZZW1hfH^ype2cgP(oDcg@qOn2H}UKc_GWrpQj~cwDnM%`vkH)|
dVuQi31ulAgH!*^}bj1Jw002ovPDHLkV1n^?A(j9D
--
2.51.2