$(OBJ)PaneSplitter.o \
$(OBJ)Stacker.o \
$(OBJ)PathBox.o \
+ $(OBJ)ToolTip.o \
$(OBJ)ColorPicker.o \
$(OBJ)FileDialog.o \
$(OBJ)FindDialog.o \
$(OBJ)Socket.o \
$(OBJ)Array.o \
$(OBJ)AVLTree.o \
- $(OBJ)BuiltInContainer.o \
- $(OBJ)Container.o
+ $(OBJ)BuiltInContainer.o
OBJECTS4 = \
+ $(OBJ)Container.o \
$(OBJ)CustomAVLTree.o \
$(OBJ)LinkList.o \
$(OBJ)List.o \
$(OBJ)PaneSplitter.c \
$(OBJ)Stacker.c \
$(OBJ)PathBox.c \
+ $(OBJ)ToolTip.c \
$(OBJ)ColorPicker.c \
$(OBJ)FileDialog.c \
$(OBJ)FindDialog.c \
$(OBJ)WindowList.c \
$(if $(or $(LINUX),$(OSX)),$(OBJ)NCursesInterface.c,) \
$(if $(WINDOWS),$(OBJ)Win32Interface.c,) \
- $(if $(WINDOWS),$(OBJ)Win32ConsoleInterface.c,) \
- $(if $(or $(LINUX),$(OSX)),$(OBJ)XInterface.c,)
+ $(if $(WINDOWS),$(OBJ)Win32ConsoleInterface.c,)
COBJECTS3 = \
+ $(if $(or $(LINUX),$(OSX)),$(OBJ)XInterface.c,) \
$(OBJ)TVisionSkin.c \
$(OBJ)WindowsSkin.c \
$(OBJ)Anchor.c \
$(OBJ)PaneSplitter.sym \
$(OBJ)Stacker.sym \
$(OBJ)PathBox.sym \
+ $(OBJ)ToolTip.sym \
$(OBJ)ColorPicker.sym \
$(OBJ)FileDialog.sym \
$(OBJ)FindDialog.sym \
$(OBJ)PaneSplitter.imp \
$(OBJ)Stacker.imp \
$(OBJ)PathBox.imp \
+ $(OBJ)ToolTip.imp \
$(OBJ)ColorPicker.imp \
$(OBJ)FileDialog.imp \
$(OBJ)FindDialog.imp \
src/gui/controls/PaneSplitter.ec \
src/gui/controls/Stacker.ec \
src/gui/controls/PathBox.ec \
+ src/gui/controls/ToolTip.ec \
src/gui/dialogs/ColorPicker.ec \
src/gui/dialogs/FileDialog.ec \
src/gui/dialogs/FindDialog.ec \
src/com/containers/LinkList.ec \
src/com/containers/List.ec \
src/com/containers/Map.ec \
- src/com/BinaryTree.ec \
- src/com/BTNode.ec
+ src/com/BinaryTree.ec
SOURCES4 = \
+ src/com/BTNode.ec \
src/com/dataTypes.ec \
src/com/instance.ec \
src/com/String.ec \
$(OBJ)PathBox.sym: src/gui/controls/PathBox.ec
$(ECP) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) -c src/gui/controls/PathBox.ec -o $(OBJ)PathBox.sym
+$(OBJ)ToolTip.sym: src/gui/controls/ToolTip.ec
+ $(ECP) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) -c src/gui/controls/ToolTip.ec -o $(OBJ)ToolTip.sym
+
$(OBJ)ColorPicker.sym: src/gui/dialogs/ColorPicker.ec
$(ECP) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) -c src/gui/dialogs/ColorPicker.ec -o $(OBJ)ColorPicker.sym
$(OBJ)PathBox.c: src/gui/controls/PathBox.ec $(OBJ)PathBox.sym | $(SYMBOLS)
$(ECC) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) $(FVISIBILITY) -c src/gui/controls/PathBox.ec -o $(OBJ)PathBox.c -symbols $(OBJ)
+$(OBJ)ToolTip.c: src/gui/controls/ToolTip.ec $(OBJ)ToolTip.sym | $(SYMBOLS)
+ $(ECC) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) $(FVISIBILITY) -c src/gui/controls/ToolTip.ec -o $(OBJ)ToolTip.c -symbols $(OBJ)
+
$(OBJ)ColorPicker.c: src/gui/dialogs/ColorPicker.ec $(OBJ)ColorPicker.sym | $(SYMBOLS)
$(ECC) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) $(FVISIBILITY) -c src/gui/dialogs/ColorPicker.ec -o $(OBJ)ColorPicker.c -symbols $(OBJ)
$(OBJ)PathBox.o: $(OBJ)PathBox.c
$(CC) $(CFLAGS) $(FVISIBILITY) -c $(OBJ)PathBox.c -o $(OBJ)PathBox.o
+$(OBJ)ToolTip.o: $(OBJ)ToolTip.c
+ $(CC) $(CFLAGS) $(FVISIBILITY) -c $(OBJ)ToolTip.c -o $(OBJ)ToolTip.o
+
$(OBJ)ColorPicker.o: $(OBJ)ColorPicker.c
$(CC) $(CFLAGS) $(FVISIBILITY) -c $(OBJ)ColorPicker.c -o $(OBJ)ColorPicker.o
$(OBJ)StatusBar.o \
$(OBJ)Stacker.o \
$(OBJ)PathBox.o \
+ $(OBJ)ToolTip.o \
$(OBJ)ColorPicker.o \
$(OBJ)FileDialog.o \
$(OBJ)FindDialog.o \
COBJECTS2 = \
$(OBJ)Stacker.c \
$(OBJ)PathBox.c \
+ $(OBJ)ToolTip.c \
$(OBJ)ColorPicker.c \
$(OBJ)FileDialog.c \
$(OBJ)FindDialog.c \
$(OBJ)StatusBar.sym \
$(OBJ)Stacker.sym \
$(OBJ)PathBox.sym \
+ $(OBJ)ToolTip.sym \
$(OBJ)ColorPicker.sym \
$(OBJ)FileDialog.sym \
$(OBJ)FindDialog.sym \
$(OBJ)StatusBar.imp \
$(OBJ)Stacker.imp \
$(OBJ)PathBox.imp \
+ $(OBJ)ToolTip.imp \
$(OBJ)ColorPicker.imp \
$(OBJ)FileDialog.imp \
$(OBJ)FindDialog.imp \
src/gui/controls/StatusBar.ec \
src/gui/controls/Stacker.ec \
src/gui/controls/PathBox.ec \
+ src/gui/controls/ToolTip.ec \
src/gui/dialogs/ColorPicker.ec \
src/gui/dialogs/FileDialog.ec \
src/gui/dialogs/FindDialog.ec \
$(OBJ)PathBox.sym: src/gui/controls/PathBox.ec
$(ECP) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) -c src/gui/controls/PathBox.ec -o $(OBJ)PathBox.sym
+$(OBJ)ToolTip.sym: src/gui/controls/ToolTip.ec
+ $(ECP) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) -c src/gui/controls/ToolTip.ec -o $(OBJ)ToolTip.sym
+
$(OBJ)ColorPicker.sym: src/gui/dialogs/ColorPicker.ec
$(ECP) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) -c src/gui/dialogs/ColorPicker.ec -o $(OBJ)ColorPicker.sym
$(OBJ)PathBox.c: src/gui/controls/PathBox.ec $(OBJ)PathBox.sym | $(SYMBOLS)
$(ECC) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) $(FVISIBILITY) -c src/gui/controls/PathBox.ec -o $(OBJ)PathBox.c -symbols $(OBJ)
+$(OBJ)ToolTip.c: src/gui/controls/ToolTip.ec $(OBJ)ToolTip.sym | $(SYMBOLS)
+ $(ECC) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) $(FVISIBILITY) -c src/gui/controls/ToolTip.ec -o $(OBJ)ToolTip.c -symbols $(OBJ)
+
$(OBJ)ColorPicker.c: src/gui/dialogs/ColorPicker.ec $(OBJ)ColorPicker.sym | $(SYMBOLS)
$(ECC) $(CECFLAGS) $(ECFLAGS) $(CFLAGS) $(FVISIBILITY) -c src/gui/dialogs/ColorPicker.ec -o $(OBJ)ColorPicker.c -symbols $(OBJ)
$(OBJ)PathBox.o: $(OBJ)PathBox.c
$(CC) $(CFLAGS) $(FVISIBILITY) -c $(OBJ)PathBox.c -o $(OBJ)PathBox.o
+$(OBJ)ToolTip.o: $(OBJ)ToolTip.c
+ $(CC) $(CFLAGS) $(FVISIBILITY) -c $(OBJ)ToolTip.c -o $(OBJ)ToolTip.o
+
$(OBJ)ColorPicker.o: $(OBJ)ColorPicker.c
$(CC) $(CFLAGS) $(FVISIBILITY) -c $(OBJ)ColorPicker.c -o $(OBJ)ColorPicker.o
{
"Version" : 0.2,
"ModuleName" : "ecere",
- "Description" : "The allmighty Ecere Runtime library.",
- "License" : "Ecere SDK v0.44 Draft 1 - www.ecere.com
-
-The Ecere SDK is Free Open Source Software. It is provided with NO WARRANTY
-expressed or implied to the extent permitted by law.
-
-Applications built with it can be distributed both commercially and non
-commercially, along with the supporting Ecere runtime library(ies):
-
- * libecere.so / ecere.dll
- - Core eC framework + GUI toolkit, 2D/3D graphics engine, networking
- * libecereCOM.so / ecereCOM.dll
- - Core eC framework only
- * libEDA.so / EDA.dll
- - Data Access System
-
-The Ecere SDK is distributed under a revised BSD license:
-
-================================================================================
-
- Copyright (c) 1996-2008, Jerome Jacovella-St-Louis
- Copyright (c) 2005-2008, Ecere Corporation
-
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of Ecere Corporation nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-===============================================================================
-
-This software makes use of other software components whose licenses may also
-apply, which are found in their respective source directories (most under
-deps/). Among them: zlib, libpng, libjpeg, giflib, harfbuzz, freetype...
-
-The IDE also communicates with GCC for compiling (MinGW on Windows), GDB for
-debugging, and UPX for optionally compressing executables. Each of these have
-their own license which can be found in their respective documentation folder
-if distributed along with the SDK (in the case of the Windows version) or
-from wherever you obtained them.",
"Options" : {
"Warnings" : "All",
"IncludeDirs" : [
]
},
"Stacker.ec",
- "PathBox.ec"
+ "PathBox.ec",
+ "ToolTip.ec"
]
},
{
}
]
}
- ]
+ ],
+ "Description" : "The allmighty Ecere Runtime library.",
+ "License" : "Ecere SDK v0.44 Draft 1 - www.ecere.com
+
+The Ecere SDK is Free Open Source Software. It is provided with NO WARRANTY
+expressed or implied to the extent permitted by law.
+
+Applications built with it can be distributed both commercially and non
+commercially, along with the supporting Ecere runtime library(ies):
+
+ * libecere.so / ecere.dll
+ - Core eC framework + GUI toolkit, 2D/3D graphics engine, networking
+ * libecereCOM.so / ecereCOM.dll
+ - Core eC framework only
+ * libEDA.so / EDA.dll
+ - Data Access System
+
+The Ecere SDK is distributed under a revised BSD license:
+
+================================================================================
+
+ Copyright (c) 1996-2008, Jerome Jacovella-St-Louis
+ Copyright (c) 2005-2008, Ecere Corporation
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of Ecere Corporation nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+===============================================================================
+
+This software makes use of other software components whose licenses may also
+apply, which are found in their respective source directories (most under
+deps/). Among them: zlib, libpng, libjpeg, giflib, harfbuzz, freetype...
+
+The IDE also communicates with GCC for compiling (MinGW on Windows), GDB for
+debugging, and UPX for optionally compressing executables. Each of these have
+their own license which can be found in their respective documentation folder
+if distributed along with the SDK (in the case of the Windows version) or
+from wherever you obtained them."
}
\ No newline at end of file
memoryErrorsCount++;
}
printf("Starting Memory Check\n");
+ for(block = (MemInfo)memBlocks.first; block; block = block.next)
+ {
+ if(!block.freed && block._class)
+ leakedObjects++;
+ }
+
for(block = (MemInfo)memBlocks.root; block;)
{
if(block.freed)
{
if(block._class)
{
- leakedObjects++;
// if(!block.internal)
{
// printf("Object of class %s\n", block._class);
block.OutputStacks(false);
}
}
- else
+ else if(!leakedObjects)
{
printf("Memory Leak\n");
block.OutputStacks(false);
import "ProgressBar"
import "EditBox"
import "DataBox"
+import "ToolTip"
#if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
import "Desktop3D"
public class CommonControl : Window
{
// creationActivation = doNothing;
+
+ ToolTip toolTip;
+ public property String toolTip
+ {
+ property_category "Appearance"
+ set
+ {
+ delete toolTip;
+ toolTip = value ? ToolTip { tip = value; } : null;
+ incref toolTip;
+ }
+ get { return toolTip ? toolTip.tip : null; }
+ }
+
+ void OnDestroy()
+ {
+ if(toolTip)
+ // (Very) Ugly work around for the fact that the parent watcher
+ // won't fire when it's already been disconnected...
+ eInstance_FireSelfWatchers(toolTip,
+ __ecereProp___ecereNameSpace__ecere__gui__Window_parent);
+ }
+
+ bool OnCreate()
+ {
+ if(toolTip)
+ toolTip.parent = this;
+ return true;
+ }
+ ~CommonControl()
+ {
+ delete toolTip;
+ }
};
public class Percentage : float
--- /dev/null
+import "Window"
+
+struct ToolTipTextLine
+{
+ char * string;
+ int len;
+ int width;
+};
+
+public class ToolTip : Window
+{
+ borderStyle = contour;
+ background = lightYellow;
+ autoCreate = false;
+ interim = true;
+ clickThrough = true;
+ creationActivation = doNothing;
+
+ Window tippedWindow;
+ Point pos;
+
+ bool (* OrigOnMouseOver)(Window window, int x, int y, Modifiers mods);
+ bool (* OrigOnMouseLeave)(Window window, Modifiers mods);
+ bool (* OrigOnMouseMove)(Window window, int x, int y, Modifiers mods);
+ bool (* OrigOnLeftButtonDown)(Window window, int x, int y, Modifiers mods);
+
+ int lh, maxW;
+ Array<ToolTipTextLine> lines { };
+ String tip;
+ int margin; margin = 2;
+ Point offset; offset = { 0, 20 };
+
+ public property String tip
+ {
+ set
+ {
+ delete tip;
+ lines.Free();
+ if(value)
+ {
+ int c;
+ char ch, next;
+ int start = 0;
+
+ tip = CopyString(value);
+ next = tip[0];
+ for(c = 0; ch = next; c++)
+ {
+ next = tip[c+1];
+ if(ch == '\n' || next == '\0')
+ {
+ lines.Add({ tip + start, c - start + (next == '\0') });
+ start = c+1;
+ }
+ }
+ }
+ }
+ get { return tip; }
+ }
+
+ bool OnLoadGraphics()
+ {
+ maxW = 0;
+ display.FontExtent(fontObject, " ", 1, null, &lh);
+ for(l : lines)
+ {
+ int w;
+ display.FontExtent(fontObject, l.string, l.len, &w, null);
+ l.width = w;
+ if(w > maxW) maxW = w;
+ }
+ clientSize = { maxW + 2*margin, lh * lines.count + 2*margin };
+ return true;
+ }
+
+ bool OnMouseLeave(Modifiers mods)
+ {
+ closeTimer.Start();
+ return true;
+ }
+
+ bool OnMouseOver(int x, int y, Modifiers mods)
+ {
+ closeTimer.Stop();
+ return true;
+ }
+
+ bool OnLeftButtonDown(int x, int y, Modifiers mods)
+ {
+ Destroy(0);
+ return true;
+ }
+
+ Timer timer
+ {
+ this, 0.5, userData = this;
+
+ bool DelayExpired()
+ {
+ timer.Stop();
+ position =
+ {
+ pos.x + offset.x + tippedWindow.clientStart.x +
+ tippedWindow.absPosition.x - parent.position.x;
+ pos.y + offset.y + tippedWindow.clientStart.y +
+ tippedWindow.absPosition.y - parent.position.y;
+ };
+ Create();
+ return true;
+ }
+ };
+
+ Timer closeTimer
+ {
+ this, 0.3, userData = this;
+
+ bool DelayExpired()
+ {
+ closeTimer.Stop();
+ Destroy(0);
+
+ return true;
+ }
+ };
+
+ watch(parent)
+ {
+ if(tippedWindow && tippedWindow == master)
+ {
+ tippedWindow.OnMouseOver = OrigOnMouseOver;
+ tippedWindow.OnMouseLeave = OrigOnMouseLeave;
+ tippedWindow.OnMouseMove = OrigOnMouseMove;
+ tippedWindow.OnLeftButtonDown = OrigOnLeftButtonDown;
+ master = null;
+ delete tippedWindow;
+ }
+ if(parent && parent.parent)
+ {
+ Window value = parent;
+ parent = null;
+ tippedWindow = value;
+ incref tippedWindow;
+ master = tippedWindow;
+ OrigOnMouseOver = value.OnMouseOver;
+ OrigOnMouseLeave = value.OnMouseLeave;
+ OrigOnMouseMove = value.OnMouseMove;
+ OrigOnLeftButtonDown = value.OnLeftButtonDown;
+ tippedWindow.OnMouseOver = OnMouseOverHandler;
+ tippedWindow.OnMouseLeave = OnMouseLeaveHandler;
+ tippedWindow.OnMouseMove = OnMouseMoveHandler;
+ tippedWindow.OnLeftButtonDown = OnLeftButtonDownHandler;
+ }
+ };
+ ~ToolTip()
+ {
+ timer.Stop();
+ closeTimer.Stop();
+ if(tippedWindow)
+ {
+ tippedWindow.OnMouseOver = OrigOnMouseOver;
+ tippedWindow.OnMouseLeave = OrigOnMouseLeave;
+ tippedWindow.OnMouseMove = OrigOnMouseMove;
+ tippedWindow.OnLeftButtonDown = OrigOnLeftButtonDown;
+ delete tippedWindow;
+ }
+ delete tip;
+ }
+
+ ToolTip ::Find(Window window)
+ {
+ Window w;
+ for(w = window.firstSlave; w; w = w.next)
+ {
+ if(eClass_IsDerived(w._class, class(ToolTip)))
+ break;
+ }
+ return (ToolTip)w;
+ }
+
+ bool Window::OnMouseOverHandler(int x, int y, Modifiers mods)
+ {
+ ToolTip toolTip = ToolTip::Find(this);
+ if(toolTip)
+ {
+ toolTip.pos = { x, y };
+ toolTip.closeTimer.Stop();
+ if(!mods.isSideEffect && !toolTip.created && rootWindow.active)
+ toolTip.timer.Start();
+ return toolTip.OrigOnMouseOver(this, x, y, mods);
+ }
+ return true;
+ }
+
+ bool Window::OnMouseLeaveHandler(Modifiers mods)
+ {
+ ToolTip toolTip = ToolTip::Find(this);
+ if(toolTip)
+ {
+ toolTip.timer.Stop();
+ toolTip.closeTimer.Start();
+ return toolTip.OrigOnMouseLeave(this, mods);
+ }
+ return true;
+ }
+
+ bool Window::OnLeftButtonDownHandler(int x, int y, Modifiers mods)
+ {
+ ToolTip toolTip = ToolTip::Find(this);
+ if(toolTip)
+ {
+ toolTip.timer.Stop();
+ toolTip.Destroy(0);
+ return toolTip.OrigOnLeftButtonDown(this, x, y, mods);
+ }
+ return true;
+ }
+
+ bool Window::OnMouseMoveHandler(int x, int y, Modifiers mods)
+ {
+ ToolTip toolTip = ToolTip::Find(this);
+ if(toolTip)
+ {
+ toolTip.pos = { x, y };
+ toolTip.closeTimer.Stop();
+ if(!mods.isSideEffect && !toolTip.created && rootWindow.active)
+ {
+ toolTip.timer.Stop();
+ toolTip.timer.Start();
+ }
+ return toolTip.OrigOnMouseMove(this, x, y, mods);
+ }
+ return true;
+ }
+
+ void OnRedraw(Surface surface)
+ {
+ int y = margin;
+ for(l : lines)
+ {
+ surface.WriteText(margin, y, l.string, l.len);
+ y += lh;
+ }
+ }
+}