From c073bad6b29fa3c5167c28c286171a1bda9b5e4a Mon Sep 17 00:00:00 2001
From: Cinder <cinder.roxley@phoenixviewer.com>
Date: Wed, 14 May 2014 11:04:53 -0600
Subject: [PATCH] Begin syntax coloring personalization

---
 indra/llui/llkeywords.cpp                     |   4 +-
 indra/newview/CMakeLists.txt                  |   2 +
 indra/newview/llfloaterscriptedprefs.cpp      |  56 ++
 indra/newview/llfloaterscriptedprefs.h        |  48 ++
 indra/newview/llviewerfloaterreg.cpp          |   2 +
 indra/newview/skins/default/colors.xml        |  12 +-
 .../xui/en/floater_script_ed_prefs.xml        | 478 ++++++++++++++++++
 .../skins/default/xui/en/panel_script_ed.xml  |  11 +-
 .../skins/default/xui/en/script_editor.xml    |  12 +-
 9 files changed, 615 insertions(+), 10 deletions(-)
 create mode 100644 indra/newview/llfloaterscriptedprefs.cpp
 create mode 100644 indra/newview/llfloaterscriptedprefs.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_script_ed_prefs.xml

diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index 2d8bd926c00..f633f3e4af9 100755
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -237,11 +237,11 @@ LLColor4 LLKeywords::getColorGroup(const std::string& key_in)
 	}
 	else if (key_in == "misc-comments_1_sided")
 	{
-		color_group = "SyntaxLslComment1Sided";
+		color_group = "SyntaxLslComment";
 	}
 	else if (key_in == "misc-comments_2_sided")
 	{
-		color_group = "SyntaxLslComment2Sided";	
+		color_group = "SyntaxLslComment";
 	}
 	else
 	{
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f0b75843122..1877db6280f 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -272,6 +272,7 @@ set(viewer_SOURCE_FILES
     llfloaterregionrestarting.cpp
     llfloatersceneloadstats.cpp
     llfloaterscriptdebug.cpp
+    llfloaterscriptedprefs.cpp
     llfloaterscriptlimits.cpp
     llfloatersearch.cpp
     llfloatersellland.cpp
@@ -869,6 +870,7 @@ set(viewer_HEADER_FILES
     llfloaterregionrestarting.h
     llfloatersceneloadstats.h
     llfloaterscriptdebug.h
+    llfloaterscriptedprefs.h
     llfloaterscriptlimits.h
     llfloatersearch.h
     llfloatersellland.h
diff --git a/indra/newview/llfloaterscriptedprefs.cpp b/indra/newview/llfloaterscriptedprefs.cpp
new file mode 100644
index 00000000000..39624186bb4
--- /dev/null
+++ b/indra/newview/llfloaterscriptedprefs.cpp
@@ -0,0 +1,56 @@
+/**
+ * @file llfloaterscriptedprefs.cpp
+ * @brief Color controls for the script editor
+ * @author Cinder Roxley
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterscriptedprefs.h"
+
+#include "llcolorswatch.h"
+
+
+LLFloaterScriptEdPrefs::LLFloaterScriptEdPrefs(const LLSD& key)
+:	LLFloater(key)
+{
+	mCommitCallbackRegistrar.add("ScriptPref.applyUIColor",	boost::bind(&LLFloaterScriptEdPrefs::applyUIColor, this ,_1, _2));
+	mCommitCallbackRegistrar.add("ScriptPref.getUIColor",	boost::bind(&LLFloaterScriptEdPrefs::getUIColor, this ,_1, _2));
+}
+
+BOOL LLFloaterScriptEdPrefs::postBuild()
+{
+	return TRUE;
+}
+
+void LLFloaterScriptEdPrefs::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
+{
+	LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));
+	// *TODO: Signal all active script editors to change colors on the fly.
+}
+
+void LLFloaterScriptEdPrefs::getUIColor(LLUICtrl* ctrl, const LLSD& param)
+{
+	LLColorSwatchCtrl* color_swatch = dynamic_cast<LLColorSwatchCtrl*>(ctrl);
+	color_swatch->setOriginal(LLUIColorTable::instance().getColor(param.asString()));
+}
diff --git a/indra/newview/llfloaterscriptedprefs.h b/indra/newview/llfloaterscriptedprefs.h
new file mode 100644
index 00000000000..360c9adc92f
--- /dev/null
+++ b/indra/newview/llfloaterscriptedprefs.h
@@ -0,0 +1,48 @@
+/**
+ * @file llfloaterscriptedprefs.h
+ * @brief Color controls for the script editor
+ * @author Cinder Roxley
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLFLOATERSCRIPTEDPREFS_H
+#define LLFLOATERSCRIPTEDPREFS_H
+
+#include "llfloater.h"
+
+class LLUICtrl;
+
+class LLFloaterScriptEdPrefs : public LLFloater
+{
+public:
+	LLFloaterScriptEdPrefs(const LLSD& key);
+	BOOL postBuild();
+	
+private:
+	~LLFloaterScriptEdPrefs() {};
+	
+	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
+	void getUIColor(LLUICtrl* ctrl, const LLSD& param);
+};
+
+#endif // LL_FLOATERSCRIPTEDPREFS_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index fae35fe664a..3cd5b54aaff 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -98,6 +98,7 @@
 #include "llfloaterreporter.h"
 #include "llfloatersceneloadstats.h"
 #include "llfloaterscriptdebug.h"
+#include "llfloaterscriptedprefs.h"
 #include "llfloaterscriptlimits.h"
 #include "llfloatersearch.h"
 #include "llfloatersellland.h"
@@ -282,6 +283,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("preview_texture", "floater_preview_texture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewTexture>, "preview");
 	LLFloaterReg::add("properties", "floater_inventory_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProperties>);
 	LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPublishClassifiedFloater>);
+	LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);
 
 	LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
 	LLFloaterReg::add("test_inspectors", "floater_test_inspectors.xml", &LLFloaterReg::build<LLFloaterTestInspectors>);
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index cb1d6aa32b8..bdbece33e0e 100755
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -907,10 +907,16 @@
 
   <!-- syntax highlighting (LSL Scripts) -->
   <color
-    name="SyntaxLslComment1Sided"
-    value=".8 .3 .15 1.0" />
+    name="ScriptText"
+    reference="Black" />
+  <color
+    name="ScriptBackground"
+    reference="White" />
+  <color
+    name="ScriptCursorColor"
+    reference="Black" />
   <color
-    name="SyntaxLslComment2Sided"
+    name="SyntaxLslComment"
     value=".8 .3 .15 1.0" />
   <color
     name="SyntaxLslConstantFloat"
diff --git a/indra/newview/skins/default/xui/en/floater_script_ed_prefs.xml b/indra/newview/skins/default/xui/en/floater_script_ed_prefs.xml
new file mode 100644
index 00000000000..838ed031d6e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_script_ed_prefs.xml
@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ height="400"
+ layout="topleft"
+ name="floater_script_colors"
+ help_topic="script_colors"
+ save_rect="true"
+ title="Customize script colors"
+ width="300">
+    <text
+     follows="left|top"
+     height="15"
+     layout="topleft"
+     left="12"
+     name="color_pickers_label"
+     top="30"
+     width="200">
+     Choose desired colors:
+    </text>
+
+    <color_swatch
+    can_apply_immediately="true"
+    follows="left|top"
+    height="24"
+    label_height="0"
+    layout="topleft"
+    left="15"
+    name="text"
+    top="45"
+    width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="ScriptText" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="ScriptText" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="text_label"
+     top_delta="5"
+     width="100">
+     Text
+	</text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="15"
+     name="cursor"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="ScriptCursorColor" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="ScriptCursorColor" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="cursor_label"
+     top_delta="5"
+     width="100">
+     Cursor
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="15"
+     name="background"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="ScriptBackground" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="ScriptBackground" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="background_label"
+     top_delta="5"
+     width="100">
+    Background
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="15"
+     name="section"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslSection" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxLslSection" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="section_label"
+     top_delta="5"
+     width="100">
+    Sections
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="15"
+     name="datatype"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslDataType" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxLslDataType" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="datatype_label"
+     top_delta="5"
+     width="100">
+    Data Types
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="15"
+     name="event"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslEvent" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxLslEvent" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="event_label"
+     top_delta="5"
+     width="100">
+    Events
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="15"
+     name="comment"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslComment" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxLslComment" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="comment_label"
+     top_delta="5"
+     width="100">
+    Comment
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="170"
+     name="string_literal"
+     top="45"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslStringLiteral" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxLslStringLiteral" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="string_literal_label"
+     top_delta="5"
+     width="100">
+    String Literals
+    </text>
+
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="170"
+     name="i_constant"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslConstantInteger" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxLslConstantInteger" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="i_constant_label"
+     top_delta="5"
+     width="100">
+    Integer Const
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="170"
+     name="s_constant"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslConstantString" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxLslConstantString" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="s_constant_label"
+     top_delta="5"
+     width="100">
+    String Const
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="170"
+     name="f_constant"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslConstantFloat" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxLslConstantFloat" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="f_constant_label"
+     top_delta="5"
+     width="100">
+    Float Const
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="170"
+     name="c_constant"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxCompoundConstant" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxCompoundConstant" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="c_constant_label"
+     top_delta="5"
+     width="100">
+    Compound
+    </text>
+    <color_swatch
+     can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="170"
+     name="flow_control"
+     top_pad="10"
+     width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslControlFlow" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyntaxLslControlFlow" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="flow_control_label"
+     top_delta="5"
+     width="100">
+    Flow Control
+    </text>
+    <color_swatch
+    can_apply_immediately="true"
+    follows="left|top"
+    height="24"
+    label_height="0"
+    layout="topleft"
+    left="170"
+    name="function"
+    top_pad="10"
+    width="44" >
+        <color_swatch.init_callback
+         function="ScriptPref.getUIColor"
+         parameter="SyntaxLslFunction" />
+        <color_swatch.commit_callback
+         function="ScriptPref.applyUIColor"
+         parameter="SyxtaxLslFunction" />
+    </color_swatch>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="function_label"
+     top_delta="5"
+     width="100">
+    Function
+    </text>
+
+    <script_editor
+     left="8"
+     right="-8"
+     top="250"
+     bottom="-8"
+     type="string"
+     length="1"
+     follows="left|top|right|bottom"
+     font="Monospace"
+     height="100"
+     ignore_tab="false"
+     layout="topleft"
+     max_length="300"
+     name="Script Preview"
+     text_color="ScriptText"
+     default_color="ScriptText"
+     bg_writeable_color="ScriptBackground"
+     bg_focus_color="ScriptBackground"
+     text_readonly_color="ScriptText"
+     bg_readonly_color="ScriptBackground"
+     bg_selected_color="ScriptSelectedColor"
+     cursor_color="ScriptCursorColor"
+     show_line_numbers="true"
+     enable_tooltip_paste="true"
+     word_wrap="true">
+default
+{
+    state_entry()
+    {
+        llSay(0, "Hello!");
+    }
+}
+    </script_editor>
+</floater>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index 76a81c48850..755d9eaf391 100755
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -70,6 +70,16 @@
            label="Save to file..."
            layout="topleft"
            name="SaveToFile" />
+          <menu_item_separator
+           layout="topleft" />
+          <menu_item_call
+           label="Colors..."
+           layout="topleft"
+           name="Colors">
+            <menu_item_call.on_click
+             function="Floater.Toggle"
+             parameter="script_colors"/>
+          </menu_item_call>
         </menu>
         <menu
          top="0"
@@ -159,7 +169,6 @@
      layout="topleft"
      max_length="262144"
      name="Script Editor"
-     text_readonly_color="DkGray"
      width="487"
      enable_tooltip_paste="true"
      word_wrap="true"
diff --git a/indra/newview/skins/default/xui/en/script_editor.xml b/indra/newview/skins/default/xui/en/script_editor.xml
index b030a117fc5..f1c6161711c 100644
--- a/indra/newview/skins/default/xui/en/script_editor.xml
+++ b/indra/newview/skins/default/xui/en/script_editor.xml
@@ -1,7 +1,11 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <script_editor
-    name="script_editor"
-    parse_urls="false"
-	show_context_menu="true"
-	show_line_numbers="true">
+ name="script_editor"
+ parse_urls="false"
+ show_context_menu="true"
+ show_line_numbers="true"
+ text_color="ScriptText"
+ default_color="ScriptText"
+ bg_writeable_color="ScriptBackground"
+ bg_focus_color="ScriptBackground">
 </script_editor>
-- 
GitLab