# HG changeset patch
# User Edouard Tisserant
# Date 1678436009 -3600
# Node ID 65969628e9204e10a1512836612790b4d3b037f0
# Parent ac0e6de439b5d2561c1c6037d9c6026dd541f5f6# Parent 5450dd9e9370f600d3eeb758d95b1d978b4a96a3
merged
diff -r 5450dd9e9370 -r 65969628e920 Beremiz_service.py
--- a/Beremiz_service.py Tue Mar 07 09:00:33 2023 +0000
+++ b/Beremiz_service.py Fri Mar 10 09:13:29 2023 +0100
@@ -185,6 +185,12 @@
return os.path.join(beremiz_dir, *args)
+import locale
+# Matiec's standard library relies on libC's locale-dependent
+# string to/from number convertions, but IEC-61131 counts
+# on '.' for decimal point. Therefore locale is reset to "C" */
+locale.setlocale(locale.LC_NUMERIC, "C")
+
def SetupI18n():
# Get folder containing translation files
localedir = os.path.join(beremiz_dir, "locale")
@@ -205,7 +211,6 @@
# Define locale domain
loc.AddCatalog(domain)
- import locale
global default_locale
default_locale = locale.getdefaultlocale()[1]
diff -r 5450dd9e9370 -r 65969628e920 PLCControler.py
--- a/PLCControler.py Tue Mar 07 09:00:33 2023 +0000
+++ b/PLCControler.py Fri Mar 10 09:13:29 2023 +0100
@@ -448,12 +448,12 @@
return len(self.GetInstanceList(pou_infos, name, debug)) > 0
return False
- def GenerateProgram(self, filepath=None):
+ def GenerateProgram(self, filepath=None, **kwargs):
errors = []
warnings = []
if self.Project is not None:
try:
- self.ProgramChunks = GenerateCurrentProgram(self, self.Project, errors, warnings)
+ self.ProgramChunks = GenerateCurrentProgram(self, self.Project, errors, warnings,**kwargs)
self.NextCompiledProject = self.Copy(self.Project)
program_text = "".join([item[0] for item in self.ProgramChunks])
if filepath is not None:
@@ -1147,28 +1147,35 @@
def GetConfigurationExtraVariables(self):
global_vars = []
- for var_name, var_type, var_initial in self.GetConfNodeGlobalInstances():
- tempvar = PLCOpenParser.CreateElement("variable", "globalVars")
- tempvar.setname(var_name)
-
- tempvartype = PLCOpenParser.CreateElement("type", "variable")
- if var_type in self.GetBaseTypes():
- tempvartype.setcontent(PLCOpenParser.CreateElement(
- var_type.lower()
- if var_type in ["STRING", "WSTRING"]
- else var_type, "dataType"))
+ for global_instance in self.GetConfNodeGlobalInstances():
+ if type(global_instance)==tuple:
+ # usual global without modifier from a CTN or a library
+ var_name, var_type, var_initial = global_instance
+ tempvar = PLCOpenParser.CreateElement("variable", "globalVars")
+ tempvar.setname(var_name)
+
+ tempvartype = PLCOpenParser.CreateElement("type", "variable")
+ if var_type in self.GetBaseTypes():
+ tempvartype.setcontent(PLCOpenParser.CreateElement(
+ var_type.lower()
+ if var_type in ["STRING", "WSTRING"]
+ else var_type, "dataType"))
+ else:
+ tempderivedtype = PLCOpenParser.CreateElement("derived", "dataType")
+ tempderivedtype.setname(var_type)
+ tempvartype.setcontent(tempderivedtype)
+ tempvar.settype(tempvartype)
+
+ if var_initial != "":
+ value = PLCOpenParser.CreateElement("initialValue", "variable")
+ value.setvalue(var_initial)
+ tempvar.setinitialValue(value)
+
+ global_vars.append(tempvar)
else:
- tempderivedtype = PLCOpenParser.CreateElement("derived", "dataType")
- tempderivedtype.setname(var_type)
- tempvartype.setcontent(tempderivedtype)
- tempvar.settype(tempvartype)
-
- if var_initial != "":
- value = PLCOpenParser.CreateElement("initialValue", "variable")
- value.setvalue(var_initial)
- tempvar.setinitialValue(value)
-
- global_vars.append(tempvar)
+ # case of varlists from a TC6 library
+ global_vars.append(global_instance)
+
return global_vars
# Function that returns the block definition associated to the block type given
diff -r 5450dd9e9370 -r 65969628e920 PLCGenerator.py
--- a/PLCGenerator.py Tue Mar 07 09:00:33 2023 +0000
+++ b/PLCGenerator.py Fri Mar 10 09:13:29 2023 +0100
@@ -277,21 +277,27 @@
("\n", ())]
var_number = 0
- varlists = [(varlist, varlist.getvariable()[:]) for varlist in configuration.getglobalVars()]
+ varlists = configuration.getglobalVars()[:]
extra_variables = self.Controler.GetConfigurationExtraVariables()
- extra_global_vars = None
- if len(extra_variables) > 0 and len(varlists) == 0:
- extra_global_vars = PLCOpenParser.CreateElement("globalVars", "interface")
- configuration.setglobalVars([extra_global_vars])
- varlists = [(extra_global_vars, [])]
-
- for variable in extra_variables:
- varlists[-1][0].appendvariable(variable)
- varlists[-1][1].append(variable)
+ extra_CTN_globals = []
+
+ for item in extra_variables:
+ if item.getLocalTag() == "globalVars":
+ varlists.append(item)
+ else:
+ extra_CTN_globals.append(item)
+
+ if len(extra_CTN_globals) > 0:
+ extra_varlist = PLCOpenParser.CreateElement("globalVars", "interface")
+
+ for variable in extra_CTN_globals:
+ extra_varlist.appendvariable(variable)
+
+ varlists.append(extra_varlist)
# Generate any global variable in configuration
- for varlist, varlist_variables in varlists:
+ for varlist in varlists:
variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local")
# Generate variable block with modifier
config += [(" VAR_GLOBAL", ())]
@@ -303,7 +309,7 @@
config += [(" NON_RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "non_retain"))]
config += [("\n", ())]
# Generate any variable of this block
- for var in varlist_variables:
+ for var in varlist.getvariable():
vartype_content = var.gettype().getcontent()
if vartype_content.getLocalTag() == "derived":
var_type = vartype_content.getname()
@@ -331,12 +337,6 @@
var_number += 1
config += [(" END_VAR\n", ())]
- if extra_global_vars is not None:
- configuration.remove(extra_global_vars)
- else:
- for variable in extra_variables:
- varlists[-1][0].remove(variable)
-
# Generate any resource in the configuration
for resource in configuration.getresource():
config += self.GenerateResource(resource, configuration.getname())
@@ -458,7 +458,7 @@
return resrce
# Generate the entire program for current project
- def GenerateProgram(self, log):
+ def GenerateProgram(self, log, noconfig=False):
log("Collecting data types")
# Find all data types defined
for datatype in self.Project.getdataTypes():
@@ -480,6 +480,8 @@
for pou_name in self.PouComputed.keys():
log("Generate POU %s"%pou_name)
self.GeneratePouProgram(pou_name)
+ if noconfig:
+ return
# Generate every configurations defined
log("Generate Config(s)")
for config in self.Project.getconfigurations():
@@ -1765,7 +1767,7 @@
return program
-def GenerateCurrentProgram(controler, project, errors, warnings):
+def GenerateCurrentProgram(controler, project, errors, warnings, **kwargs):
generator = ProgramGenerator(controler, project, errors, warnings)
if hasattr(controler, "logger"):
def log(txt):
@@ -1774,5 +1776,5 @@
def log(txt):
pass
- generator.GenerateProgram(log)
+ generator.GenerateProgram(log,**kwargs)
return generator.GetGeneratedProgram()
diff -r 5450dd9e9370 -r 65969628e920 POULibrary.py
--- a/POULibrary.py Tue Mar 07 09:00:33 2023 +0000
+++ b/POULibrary.py Fri Mar 10 09:13:29 2023 +0100
@@ -44,7 +44,7 @@
def GetSTCode(self):
if not self.program:
- self.program = self.LibraryControler.GenerateProgram()[0]+"\n"
+ self.program = self.LibraryControler.GenerateProgram(noconfig=True)[0]+"\n"
return self.program
def GetName(self):
@@ -65,9 +65,14 @@
def GlobalInstances(self):
"""
- @return: [(instance_name, instance_type),...]
+ @return: [varlist_object, ...]
"""
- return []
+ varlists = []
+ for configuration in self.LibraryControler.Project.getconfigurations():
+ varlist = configuration.getglobalVars()
+ if len(varlist)>0 :
+ varlists += varlist
+ return varlists
def FatalError(self, message):
""" Raise an exception that will trigger error message intended to
diff -r 5450dd9e9370 -r 65969628e920 controls/PouInstanceVariablesPanel.py
--- a/controls/PouInstanceVariablesPanel.py Tue Mar 07 09:00:33 2023 +0000
+++ b/controls/PouInstanceVariablesPanel.py Fri Mar 10 09:13:29 2023 +0100
@@ -174,6 +174,19 @@
self.DebugInstanceImage: _ButtonCallbacks(
self.DebugButtonCallback, self.DebugButtonDClickCallback)}
+ self.FilterCtrl = wx.SearchCtrl(self)
+ self.FilterCtrl.ShowCancelButton(True)
+ self.FilterCtrl.Bind(wx.EVT_TEXT, self.OnFilterUpdate)
+ self.FilterCtrl.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, self.OnFilterCancel)
+
+ searchMenu = wx.Menu()
+ item = searchMenu.AppendCheckItem(-1, _("Match Case"))
+ self.Bind(wx.EVT_MENU, self.OnSearchMenu, item)
+ item = searchMenu.AppendCheckItem(-1, _("Whole Words"))
+ self.Bind(wx.EVT_MENU, self.OnSearchMenu, item)
+ self.FilterCtrl.SetMenu(searchMenu)
+
+
buttons_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0)
buttons_sizer.AddWindow(self.ParentButton)
buttons_sizer.AddWindow(self.InstanceChoice, flag=wx.GROW)
@@ -181,9 +194,10 @@
buttons_sizer.AddGrowableCol(1)
buttons_sizer.AddGrowableRow(0)
- main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
+ main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=0)
main_sizer.AddSizer(buttons_sizer, flag=wx.GROW)
main_sizer.AddWindow(self.VariablesList, flag=wx.GROW)
+ main_sizer.AddWindow(self.FilterCtrl, flag=wx.GROW)
main_sizer.AddGrowableCol(0)
main_sizer.AddGrowableRow(1)
@@ -199,6 +213,11 @@
self.PouInfos = None
self.PouInstance = None
+ self.Filter = None
+ self.FilterCaseSensitive = False
+ self.FilterWholeWord = False
+
+
def __del__(self):
self.Controller = None
@@ -236,6 +255,21 @@
self.RefreshView()
+ def OnSearchMenu(self, event):
+ searchMenu = self.FilterCtrl.GetMenu().GetMenuItems()
+ self.FilterCaseSensitive = searchMenu[0].IsChecked()
+ self.FilterWholeWord = searchMenu[1].IsChecked()
+ self.RefreshView()
+
+ def OnFilterUpdate(self, event):
+ self.Filter = self.FilterCtrl.GetValue()
+ self.RefreshView()
+ event.Skip()
+
+ def OnFilterCancel(self, event):
+ self.FilterCtrl.SetValue('')
+ event.Skip()
+
def RefreshView(self):
self.Freeze()
self.VariablesList.DeleteAllItems()
@@ -252,6 +286,15 @@
if self.PouInfos is not None:
root = self.VariablesList.AddRoot("", data=self.PouInfos)
for var_infos in self.PouInfos.variables:
+ if self.Filter:
+ pattern = self.Filter
+ varname = var_infos.name
+ if not self.FilterCaseSensitive:
+ pattern = pattern.upper()
+ varname = varname.upper()
+ if ((pattern != varname) if self.FilterWholeWord else
+ (pattern not in varname)):
+ continue
if var_infos.type is not None:
text = "%s (%s)" % (var_infos.name, var_infos.type)
else:
diff -r 5450dd9e9370 -r 65969628e920 editors/TextViewer.py
--- a/editors/TextViewer.py Tue Mar 07 09:00:33 2023 +0000
+++ b/editors/TextViewer.py Fri Mar 10 09:13:29 2023 +0100
@@ -130,8 +130,7 @@
self.Editor.SetUseTabs(0)
self.Editor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT |
- wx.stc.STC_MOD_BEFOREDELETE |
- wx.stc.STC_PERFORMED_USER)
+ wx.stc.STC_MOD_BEFOREDELETE)
self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, self.Editor)
self.Editor.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
@@ -213,25 +212,24 @@
self.SearchResults = None
self.CurrentFindHighlight = None
+ Buffering = "Off"
def OnModification(self, event):
if not self.DisableEvents:
mod_type = event.GetModificationType()
if mod_type & wx.stc.STC_MOD_BEFOREINSERT:
if self.CurrentAction is None:
- self.StartBuffering()
+ self.Buffering = "ShouldStart"
elif self.CurrentAction[0] != "Add" or self.CurrentAction[1] != event.GetPosition() - 1:
- self.Controler.EndBuffering()
- self.StartBuffering()
+ self.Buffering = "ShouldRestart"
self.CurrentAction = ("Add", event.GetPosition())
- wx.CallAfter(self.RefreshModel)
+ self.RefreshModelAfter()
elif mod_type & wx.stc.STC_MOD_BEFOREDELETE:
if self.CurrentAction is None:
- self.StartBuffering()
+ self.Buffering = "ShouldStart"
elif self.CurrentAction[0] != "Delete" or self.CurrentAction[1] != event.GetPosition() + 1:
- self.Controler.EndBuffering()
- self.StartBuffering()
+ self.Buffering = "ShouldRestart"
self.CurrentAction = ("Delete", event.GetPosition())
- wx.CallAfter(self.RefreshModel)
+ self.RefreshModelAfter()
event.Skip()
def OnDoDrop(self, event):
@@ -379,7 +377,7 @@
elif values[3] == self.TagName:
self.ResetBuffer()
event.SetDragText(values[0])
- wx.CallAfter(self.RefreshModel)
+ self.RefreshModelAfter()
else:
message = _("Variable don't belong to this POU!")
if message is not None:
@@ -429,10 +427,14 @@
self.ParentWindow.RefreshFileMenu()
self.ParentWindow.RefreshEditMenu()
+ def EndBuffering(self):
+ self.Controler.EndBuffering()
+
def ResetBuffer(self):
if self.CurrentAction is not None:
- self.Controler.EndBuffering()
+ self.EndBuffering()
self.CurrentAction = None
+ self.Buffering == "Off"
def GetBufferState(self):
if not self.Debug and self.TextSyntax != "ALL":
@@ -834,12 +836,29 @@
self.RemoveHighlight(*self.CurrentFindHighlight)
self.CurrentFindHighlight = None
+ pending_model_refresh=False
def RefreshModel(self):
+ self.pending_model_refresh=False
self.RefreshJumpList()
self.Colourise(0, -1)
+
+ if self.Buffering == "ShouldStart":
+ self.StartBuffering()
+ self.Buffering == "On"
+ elif self.Buffering == "ShouldRestart":
+ self.EndBuffering()
+ self.StartBuffering()
+ self.Buffering == "On"
+
self.Controler.SetEditedElementText(self.TagName, self.GetText())
self.ResetSearchResults()
+ def RefreshModelAfter(self):
+ if self.pending_model_refresh:
+ return
+ self.pending_model_refresh=True
+ wx.CallAfter(self.RefreshModel)
+
def OnKeyDown(self, event):
key = event.GetKeyCode()
if self.Controler is not None:
diff -r 5450dd9e9370 -r 65969628e920 exemples/csv_read/beremiz.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/csv_read/beremiz.xml Fri Mar 10 09:13:29 2023 +0100
@@ -0,0 +1,5 @@
+
+
+
+
+
diff -r 5450dd9e9370 -r 65969628e920 exemples/csv_read/plc.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/csv_read/plc.xml Fri Mar 10 09:13:29 2023 +0100
@@ -0,0 +1,341 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CSV_NAME_0
+
+
+
+
+
+
+ CSV_ROWIDX
+
+
+
+
+
+
+ CSV_COLIDX
+
+
+
+
+
+
+ CSV_NAME_1
+
+
+
+
+
+
+ CSV_ROWSTR
+
+
+
+
+
+
+ CSV_COLSTR
+
+
+
+
+
+
+
+
+
+
+ CSV_RES_0
+
+
+
+
+
+
+
+
+
+
+ CSV_ACK_0
+
+
+
+
+
+
+
+
+
+
+ CSV_ACK_1
+
+
+
+
+
+
+
+
+
+
+ CSV_RES_1
+
+
+
+
+
+
+ CSV_RELOAD_BTN
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 5450dd9e9370 -r 65969628e920 exemples/csv_read/project_files/my_int_csv.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/csv_read/project_files/my_int_csv.csv Fri Mar 10 09:13:29 2023 +0100
@@ -0,0 +1,15 @@
+1,1.01,1.02,1.03,1.04,1.05,1.06
+1.1,1.11,1.12,1.13,1.14,1.15,1.16
+1.2,1.21,1.22,1.23,1.24,1.25,1.26
+1.3,1.31,1.32,1.33,1.34,1.35,1.36
+1.4,1.41,1.42,1.43,1.44,1.45,1.46
+1.5,1.51,1.52,1.53,1.54,1.55,1.56
+1.6,1.61,1.62,1.63,1.64,1.65,1.66
+1.7,1.71,1.72,1.73,1.74,1.75,1.76
+1.8,1.81,1.82,1.83,1.84,1.85,1.86
+1.9,1.91,1.92,1.93,1.94,1.95,1.96
+2,2.01,2.02,2.03,2.04,2.05,2.06
+2.1,2.11,2.12,2.13,2.14,2.15,2.16
+2.2,2.21,2.22,2.23,2.24,2.25,2.26
+2.3,2.31,2.32,2.33,2.34,2.35,2.36
+2.4,2.41,2.42,2.43,2.44,2.45,2.46
diff -r 5450dd9e9370 -r 65969628e920 exemples/csv_read/project_files/my_int_csv.ods
Binary file exemples/csv_read/project_files/my_int_csv.ods has changed
diff -r 5450dd9e9370 -r 65969628e920 exemples/csv_read/project_files/my_str_csv.csv
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/csv_read/project_files/my_str_csv.csv Fri Mar 10 09:13:29 2023 +0100
@@ -0,0 +1,8 @@
+Title,Ingredient A,Ingredient B,Ingredient C,Ingredient D,Ingredient E,Ingredient F,Ingredient G
+Recipe 1,1,2,3,4,5,6,7
+Recipe 2,2,3,4,5,6,7,8
+Recipe 3,3,4,5,6,7,8,9
+Recipe 4,4,5,6,7,8,9,10
+Recipe 5,5,6,7,8,9,10,11
+Recipe 6,6,7,8,9,10,11,12
+Recipe 7,7,8,9,10,11,12,13
diff -r 5450dd9e9370 -r 65969628e920 exemples/csv_read/project_files/my_str_csv.ods
Binary file exemples/csv_read/project_files/my_str_csv.ods has changed
diff -r 5450dd9e9370 -r 65969628e920 exemples/csv_read/svghmi_0@svghmi/baseconfnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/csv_read/svghmi_0@svghmi/baseconfnode.xml Fri Mar 10 09:13:29 2023 +0100
@@ -0,0 +1,2 @@
+
+
diff -r 5450dd9e9370 -r 65969628e920 exemples/csv_read/svghmi_0@svghmi/confnode.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/csv_read/svghmi_0@svghmi/confnode.xml Fri Mar 10 09:13:29 2023 +0100
@@ -0,0 +1,2 @@
+
+
diff -r 5450dd9e9370 -r 65969628e920 exemples/csv_read/svghmi_0@svghmi/svghmi.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/exemples/csv_read/svghmi_0@svghmi/svghmi.svg Fri Mar 10 09:13:29 2023 +0100
@@ -0,0 +1,1787 @@
+
+
+
+
diff -r 5450dd9e9370 -r 65969628e920 exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg
--- a/exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg Tue Mar 07 09:00:33 2023 +0000
+++ b/exemples/svghmi_jumps/svghmi_0@svghmi/svghmi.svg Fri Mar 10 09:13:29 2023 +0100
@@ -25,7 +25,7 @@
image/svg+xml
-
+
@@ -40,17 +40,17 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1850"
+ inkscape:window-height="1036"
id="namedview4"
showgrid="false"
- inkscape:zoom="0.23177389"
- inkscape:cx="1999.5317"
- inkscape:cy="-682.74047"
+ inkscape:zoom="0.46354778"
+ inkscape:cx="-544.27948"
+ inkscape:cy="655.56978"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
- inkscape:current-layer="hmi0"
+ inkscape:current-layer="g2496"
showguides="true"
inkscape:guide-bbox="true"
borderlayer="true"
@@ -67,7 +67,7 @@
transform="translate(1320,1520)"
width="100%"
height="100%"
- inkscape:label="HMI:Page:RelativePage@/FB_ZERO" />
+ inkscape:label="HMI:Page:RelativePage:p=6@p=page_number@/FB_ZERO" />
+ inkscape:label="HMI:Page:Relative:p=5@p=page_number" />
HMI:Jump:RelativePage
+ 0
+ transform="translate(620.54487,-11.353461)">
+ transform="translate(4.2410198,-11.353461)">
- Press Ctrl+X to edit SVG elements directly with XML editor
+
+ declaration of user_level HMI local variable(not a PLC variable)
+
diff -r 5450dd9e9370 -r 65969628e920 exemples/svghmi_references/plc.xml
--- a/exemples/svghmi_references/plc.xml Tue Mar 07 09:00:33 2023 +0000
+++ b/exemples/svghmi_references/plc.xml Fri Mar 10 09:13:29 2023 +0100
@@ -1,7 +1,7 @@
-
+
@@ -22,12 +22,12 @@
-
+
-
+
-
+
@@ -39,7 +39,7 @@
- LocalVar0
+ PLCHMIVAR
@@ -50,7 +50,7 @@
- LocalVar1
+ LocalVar0