Add NUI content 76/158276/1
authorEditor Lionbridge <TizenEditor.SEL@lionbridge.com>
Mon, 30 Oct 2017 15:22:02 +0000 (17:22 +0200)
committerEditor Lionbridge <TizenEditor.SEL@lionbridge.com>
Mon, 30 Oct 2017 15:22:02 +0000 (17:22 +0200)
This content has been converted from MD to HTML.
A light language check has been performed, but the content has not
been properly edited.

Change-Id: I569bb4e55feaf2a50cadd609b90c027b5d540c73

82 files changed:
nui/NUIoverview.htm [new file with mode: 0644]
nui/animation.htm [new file with mode: 0644]
nui/button.htm [new file with mode: 0644]
nui/creating_custom_view_controls.htm [new file with mode: 0644]
nui/css/snippet.css [new file with mode: 0644]
nui/css/styles.css [new file with mode: 0644]
nui/flexcontainer.htm [new file with mode: 0644]
nui/hello_world.htm [new file with mode: 0644]
nui/images/ArabicBegin.png [new file with mode: 0644]
nui/images/ArabicCenter.png [new file with mode: 0644]
nui/images/ArabicEnd.png [new file with mode: 0644]
nui/images/AutoScroll.gif [new file with mode: 0644]
nui/images/ContactView.png [new file with mode: 0644]
nui/images/HelloWorld.png [new file with mode: 0644]
nui/images/ImageView.png [new file with mode: 0644]
nui/images/LatinBegin.png [new file with mode: 0644]
nui/images/LatinCenter.png [new file with mode: 0644]
nui/images/LatinEnd.png [new file with mode: 0644]
nui/images/NUI_Class_Hierarchy.png [new file with mode: 0644]
nui/images/RedText.png [new file with mode: 0644]
nui/images/SystemProxySettings.png [new file with mode: 0644]
nui/images/TextLabelTopLeft.png [new file with mode: 0644]
nui/images/TextWith1pxUnderline.png [new file with mode: 0644]
nui/images/TextWithBiggerShadow.png [new file with mode: 0644]
nui/images/TextWithColorShadow.png [new file with mode: 0644]
nui/images/TextWithColorUnderline.png [new file with mode: 0644]
nui/images/TextWithShadow.png [new file with mode: 0644]
nui/images/TextWithUnderline.png [new file with mode: 0644]
nui/images/VSC.png [new file with mode: 0644]
nui/images/VSC_ExtandSettings.png [new file with mode: 0644]
nui/images/align-content.jpg [new file with mode: 0644]
nui/images/align-items.jpg [new file with mode: 0644]
nui/images/align-self.jpg [new file with mode: 0644]
nui/images/animated-image-visual.gif [new file with mode: 0644]
nui/images/animated-path.png [new file with mode: 0644]
nui/images/bevelled-cube-high.png [new file with mode: 0644]
nui/images/bevelled-cube-low.png [new file with mode: 0644]
nui/images/border-visual.png [new file with mode: 0644]
nui/images/btn_top.gif [new file with mode: 0644]
nui/images/color-visual.png [new file with mode: 0644]
nui/images/cone.png [new file with mode: 0644]
nui/images/conical-frustrum.png [new file with mode: 0644]
nui/images/content-direction-ltr.jpg [new file with mode: 0644]
nui/images/content-direction-rtl.jpg [new file with mode: 0644]
nui/images/cube.png [new file with mode: 0644]
nui/images/cylinder.png [new file with mode: 0644]
nui/images/flex-container.jpg [new file with mode: 0644]
nui/images/flex-direction.jpg [new file with mode: 0644]
nui/images/flex-margin.jpg [new file with mode: 0644]
nui/images/flex-wrap.jpg [new file with mode: 0644]
nui/images/flex.jpg [new file with mode: 0644]
nui/images/flexbox-demo.jpg [new file with mode: 0644]
nui/images/hello-world.png [new file with mode: 0644]
nui/images/image-visual.png [new file with mode: 0644]
nui/images/justify-content.jpg [new file with mode: 0644]
nui/images/linear-gradient-visual.png [new file with mode: 0644]
nui/images/mesh-visual.png [new file with mode: 0644]
nui/images/multi-threaded-animation-2.png [new file with mode: 0644]
nui/images/multi-threaded-animation.png [new file with mode: 0644]
nui/images/n-patch-visual.png [new file with mode: 0644]
nui/images/octahedron.png [new file with mode: 0644]
nui/images/popup-normal.png [new file with mode: 0644]
nui/images/popup-styled.png [new file with mode: 0644]
nui/images/radial-gradient-visual.png [new file with mode: 0644]
nui/images/slices.png [new file with mode: 0644]
nui/images/sphere.png [new file with mode: 0644]
nui/images/stacks.png [new file with mode: 0644]
nui/images/svg-visual.svg [new file with mode: 0644]
nui/images/wireframe-visual.png [new file with mode: 0644]
nui/imageview.htm [new file with mode: 0644]
nui/scripts/common.js [new file with mode: 0644]
nui/scripts/core.js [new file with mode: 0644]
nui/scripts/jquery.util.js [new file with mode: 0644]
nui/scripts/jquery.zclip.min.js [new file with mode: 0644]
nui/scripts/navi.js [new file with mode: 0644]
nui/scripts/search.js [new file with mode: 0644]
nui/scripts/showhide.js [new file with mode: 0644]
nui/scripts/snippet.js [new file with mode: 0644]
nui/setup_ubuntu.htm [new file with mode: 0644]
nui/styling_controls_with_JSON.htm [new file with mode: 0644]
nui/textlabel.htm [new file with mode: 0644]
nui/visuals.htm [new file with mode: 0644]

diff --git a/nui/NUIoverview.htm b/nui/NUIoverview.htm
new file mode 100644 (file)
index 0000000..2ad50ac
--- /dev/null
@@ -0,0 +1,106 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>NUI Overview</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#concepts">Key Concepts</a></li>
+                       <li><a href="#started">Getting Started</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>NUI Overview</h1>
+
+<p>NUI (Natural User Interface) is a C# toolkit on top of the DALi (Dynamic Animation Library) graphics library, which is written in C++.</p>
+
+<p>NUI is a rich GUI library for creating 2D or 3D applications. These applications are run on a range of Tizen devices, such as TVs and wearables. NUI is built on a multi-threaded architecture enabling realistic smooth animations. In addition, a range of optimization techniques are utilized to obtain low CPU and GPU usage, further increasing graphics performance.</p>
+<p>NUI enables you to quickly create rich UI applications with realistic effects and animations, such as:</p>
+<ul>
+<li>Image and video galleries</li>
+<li>Music players</li>
+<li>Homescreens and launch pads</li>
+<li>Advanced watch faces for wearable devices</li>
+</ul>
+
+<p>NUI offers the following main features:</p>
+
+<ul>
+<li>Provides a UI consisting of hierarchical scene graph nodes.</li>
+<li>Creates images and text.</li>
+<li>Provides layers to aid in 2D UI layouting.</li>
+<li>Allows automatic background loading of resources.</li>
+<li>Provides an easy-to-use animation framework which hides the complexity of the underlying 3D math.</li>
+<li>Provides keyboard, touch, and mouse handling.</li>
+</ul>
+
+<h2 id="concepts">Key Concepts</h2>
+
+<p>To be able to use NUI in your applications, you must become familiar with the following NUI key concepts:</p>
+<ul>
+<li><strong>Scene graph</strong>: Tree data structure, consisting of a collection of nodes.</li>
+<li><strong>Window</strong>: Top level of the scene graph, used for displaying a tree of layers and views.</li>
+<li><strong>View</strong>: Primary object for interaction. Views are effectively nodes that receive input (such as touch events), and act as a container for drawable elements and other views. Views can display content, such as color shapes, images, and text.
+<p>A NUI application uses a hierarchy of view objects to position visible content.</p></li>
+<li><strong>Layer</strong>: Layers provide a mechanism for overlaying groups of views on top of each other.</li>
+</ul>
+
+<h2 id="started">Getting Started</h2>
+
+<p>To get started with NUI development:</p>
+
+<ul>
+<li><a href="setup_ubuntu.htm">Set up the NUI development environment</a>.</li>
+<li><a href="hello_world.htm">Study a "Hello World" sample application</a>.</li>
+<li>Create various controls for your application views, such as:
+       <ul>
+       <li><a href="flexcontainer.htm">Flex container</a></li>
+       <li><a href="imageview.htm">ImageView</a></li>
+       <li><a href="textlabel.htm">TextLabel</a></li>
+       </ul>
+       <p>You can also create <a href="creating_custom_view_controls.htm">custom view controls</a>.</p>
+</li>
+<li>Add <a href="visuals.htm">visuals</a> and <a href="animation.htm">animations</a> to your controls.</li>
+<li><a href="styling_controls_with_JSON.htm">Style your controls</a> based on states and add transitions between states.</li>
+</ul>
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
diff --git a/nui/animation.htm b/nui/animation.htm
new file mode 100644 (file)
index 0000000..39dc6f5
--- /dev/null
@@ -0,0 +1,544 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>Animation</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#animatableproperties">Animatable Properties</a></li>
+            <li><a href="#animatingproperties">Animating Properties</a></li>
+            <li><a href="#control">Controlling Playback</a></li>
+            <li><a href="#notifications">Using Notifications</a></li>
+            <li><a href="#alphafunctions">Using Alpha Functions</a></li>
+            <li><a href="#animationtypes">Animation Types</a></li>
+            <li><a href="#multithreading">Animation Multithreading</a></li>
+            <li><a href="#sample">Sample Animation</a></li>
+            <li><a href="#animationclassmethods">Animation Class Methods</a></li>
+            <li><a href="#animationclassproperties">Animation Class Properties</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>Animation</h1>
+
+<p>You can use animation to allow your objects to move around and change their properties for a specified duration.</p>
+<p>NUI provides a rich and easy to use animation framework which allows you to create visually rich applications. The <code>Animation</code> class can be used to animate the <a href="#animatableproperties">animatable properties</a> of any number of objects, typically View objects.</p>
+<p>NUI animations <a href="#multithreading">occur in a dedicated thread</a>. This allows animations to run smoothly, regardless of the time taken to process the input, events, and other factors in the application code.</p>
+<p>The following figure shows the NUI class hierarchy. The <code>Animatable</code> class contains "property" methods such as <code>GetProperty()</code> and <code>IsPropertyAnimatable()</code>. The <code>Animation</code> class contains <a href="#animationclassmethods">animation methods</a>, such as <code>AnimateBy()</code> and <code>AnimateTo()</code>.</p>
+
+<p align="center"><strong>Figure: NUI class hierarchy</strong></p>
+<p align="center"><img src="images/NUI_Class_Hierarchy.png" alt="NUI class hierarchy" /></p>
+
+
+<p>To implement a basic animation, create an animation object that takes place over 2 seconds:</p>
+<pre class="prettyprint">
+_animation = new Animation( 2000 );
+</pre>
+<p>alternatively,</p>
+<pre class="prettyprint">
+_animation = new Animation
+{
+    Duration = 2000;
+};
+</pre>
+
+<h2 id="animatableproperties">Animatable Properties</h2>
+<p>Some View properties are "animatable", such as <code>Position</code>, <code>Orientation</code>, <code>Scale</code>, and <code>Color</code>. For "standard" controls, you can query whether a property is animatable, using <code>IsPropertyAnimatable()</code>, but cannot change the animatable state.</p>
+<p>You can set a property to "animatable" in the derived classes of custom view controls.</p>
+<p>For more information, see <a href="creating_custom_view_controls.htm#properties">Properties in Custom Views</a> and <a href="creating_custom_view_controls.htm#creatingtransitions">Creating Transitions</a>, which describes the animatable 'Scriptable Properties'.</p>
+
+<h2 id="animatingproperties">Animating Properties</h2>
+<p>To animate the properties within NUI, you can use 2 distinct methods:</p>
+<ul>
+<li><code>AnimateTo()</code>: Property animates TO the value in the given time.</li>
+<li><code>AnimateBy()</code>: Property animates BY the value in the given time (which means that it animates to a value that is the sum of the starting position and the given value).</li>
+
+</ul>
+
+<p>In the following example, <code>view1</code> and <code>view2</code> are at the position 10.0f, 10.0f, 0.0f at the start of the animation.</p>
+<pre class="prettyprint">
+// Animate the position of view1 TO 10.0f, 50.0f, 0.0f
+animation.AnimateTo( view1, "Position", Vector3(10.0f, 50.0f, 0.0f) );         // End position: 10.0f, 50.0f, 0.0f
+
+// Animate the position of view2 BY 10.0f, 50.0f, 0.0f
+animation.AnimateBy( view2, "Position", Vector3(10.0f, 50.0f, 0.0f) );         // End position: 20.0f, 60.0f, 0.0f
+</pre>
+<p>Another example taken from the working example in this tutorial:</p>
+<pre class="prettyprint">
+_animation.AnimateTo(_text, "Orientation", new Rotation(new Radian(new Degree(180.0f)), PositionAxis.X), 0, 500, new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseInOutSine));
+_animation.AnimateTo(_text, "Orientation", new Rotation(new Radian(new Degree(0.0f)), PositionAxis.X), 500, 1000, new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseInOutSine));
+
+_animation.AnimateBy(_text, "ScaleX", 3, 1000, 1500);
+_animation.AnimateBy(_text, "ScaleY", 4.0f, 1500, 2000);
+</pre>
+<p>Properties can also be passed to an animation method through the <code>property</code> class instantiation:</p>
+<pre class="prettyprint">
+_animation.AnimateTo(new Property(_text, View.Property.ORIENTATION), new Property.Value(new Rotation(new Radian(new Degree(180.0f)), ...
+</pre>
+<p>For a description of the parameters, see <a href="#animationclassmethods">Animation Class Methods</a>.</p>
+
+<h2 id="control">Controlling Playback</h2>
+<p>After the animation is created, you can play it:</p>
+
+<ul>
+<li>To play the animation:
+<pre class="prettyprint">
+animation.Play();
+</pre>
+</li>
+<li>To pause or stop the animation:
+<pre class="prettyprint">
+animation.Pause();
+animation.Stop();
+</pre></li>
+<li>To loop the animation to play multiple times:
+<pre class="prettyprint">
+animation.Looping = true;
+</pre></li>
+<li>By default, when the animation ends, the properties that it was animating are baked (saved). To discard the property changes when the animation ends or is stopped:
+<pre class="prettyprint">
+animation.EndAction = Animations.EndActions.Discard;
+</pre></li></ul>
+
+<h2 id="notifications">Using Notifications</h2>
+<p>The application can be notified when the animation finishes:</p>
+<pre class="prettyprint">
+_animation.Finished += AnimationFinished;
+</pre>
+<pre class="prettyprint">
+public void AnimationFinished(object sender, EventArgs e)
+{
+    Tizen.Log.Debug("NUI", "AnimationFinished()");
+}
+</pre>
+<p>The application can be notified when the animation has reached a specific percentage progress:</p>
+<pre class="prettyprint">
+_animation.ProgressNotification = 0.5; // Trigger the 'progress reached' event at 50% of animation time
+
+_animation.ProgressReached += progressReached;
+</pre>
+
+<h2 id="alphafunctions">Using Alpha Functions</h2>
+<p>Alpha functions are used in animations to specify the rate of change of the animation parameter over time. This allows the animation to be, for example, accelerated, decelerated, repeated, or bounced. The built-in supported functions can be viewed in the <code>AlphaFunction</code> class.</p>
+<p>You can specify a different alpha function for each animator in an Animation object:</p>
+<pre class="prettyprint">
+animation.AnimateTo(view1, "Position", Vector3(10.0f, 50.0f, 0.0f), new AlphaFunction.BuiltinFunctions.Linear);
+</pre>
+<p>The <code>AnimateTo()</code> parameters are described in <a href="#animationclassmethods">Animation Class Methods</a>.</p>
+<p>The built-in alpha functions are:</p>
+<pre class="prettyprint">
+public enum BuiltinFunction
+{
+    Default,
+    Linear,
+    Reverse,
+    EaseInSquare,
+    EaseOutSquare,
+    EaseIn,
+    EaseOut,
+    EaseInOut,
+    EaseInSine,
+    EaseOutSine,
+    EaseInOutSine,
+    Bounce,
+    Sin,
+    EaseOutBack,
+    Count
+}
+</pre>
+<p>The <a href="#sample">sample animation</a> includes the use of a built-in alpha function.</p>
+<p>You can also create your own alpha function in 2 ways:</p>
+    <ul>
+        <li>By setting the default alpha function:
+<pre class="prettyprint">
+float alphafunc(float progress)
+{
+    if ( (progress &gt; 0.2f) &amp;&amp; (progress &lt; 0.7f) )
+    {
+        return progress + 0.8f;
+    }
+
+    return progress;
+}
+
+AlphaFunction af(alphafunc);
+animation.SetDefaultAlphaFunction(af);
+</pre></li>
+    <li>By using delegates:
+<pre class="prettyprint">
+private UserAlphaFunctionDelegate _user_alpha_func;
+
+// Declare user alpha function delegate
+[UnmanagedFunctionPointer(CallingConvention.StdCall)]
+delegate float UserAlphaFunctionDelegate(float progress);
+
+_user_alpha_func = new UserAlphaFunctionDelegate(alphafunc);
+
+_animation.AnimateTo(_view2, "Position", new Vector3(150.0f, 150.0f, 0.0f), 5000, 10000, new AlphaFunction(_user_alpha_func));
+</pre></li>
+</ul>
+
+<h2 id="animationtypes">Animation Types</h2>
+<p>NUI supports key frame and path animations.</p>
+
+<h3>Key Frame Animation</h3>
+<p>NUI supports animating between several different values, or key frames. A key frame takes a progress value between 0.0f and 1.0f (0 and 100%, respectively) and portrays the value of the property when the animation has progressed that much. You can create several key frames:</p>
+<pre class="prettyprint">
+KeyFrames keyFrames = new KeyFrames();
+keyFrames.Add( 0.0f, new Vector3( 10.0f, 10.0f, 10.0f ) );
+keyFrames.Add( 0.7f, new Vector3( 200.0f, 200.0f, 200.0f ) );
+keyFrames.Add( 1.0f, new Vector3( 100.0f, 100.0f, 100.0f ) );
+</pre>
+<p>Next, you can add the key frames to your animation.</p>
+<pre class="prettyprint">
+animation.AnimateBetween( view1, "Position", keyFrames );
+</pre>
+<p>When you play the animation, NUI animates the position of <code>view1</code> between the specified key frames. The <code>view1</code> animates from (10.0f, 10.0f, 10.0f) to (200.0f, 200.0f, 200.0f) for 70% of the animation time, and spends the remaining time animating back to (100.0f, 100.0f, 100.0f).</p>
+<p>The advantage of specifying a key frame at 0% is that regardless of where the <code>view1</code> is, it starts from position (10.0f, 10.0f, 10.0f). If <code>AnimateTo()</code> is used, then the start position is the <code>view1</code>'s current position.</p>
+<p>The following comprehensive example of key frame use is taken from <code>FocusEffect.cs</code>:</p>
+<pre class="prettyprint">
+focusData.ImageItem.Size = new Size(100.0f, 100.0f, 0.0f);
+parentItem.Add(focusData.ImageItem);
+
+Size targetSize = focusData.TargetSize;
+Size initSize = focusData.InitSize;
+
+KeyFrames keyFrames = new KeyFrames();
+
+keyFrames.Add(0.0f, initSize);
+keyFrames.Add(focusData.KeyFrameStart, initSize);
+keyFrames.Add(focusData.KeyFrameEnd, targetSize);
+
+// For halo add an extra key frame to shrink it (in 20% of time after it has finished)
+if (focusData.Name == "halo")
+{
+   keyFrames.Add(focusData.KeyFrameEnd + 0.2f, initSize);
+}
+
+_animation.AnimateBetween(focusData.ImageItem, "Size", keyFrames, Animation.Interpolation.Linear, new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutSine));
+</pre>
+
+<h3>Path Animations</h3>
+<p>A <code>Path</code> can be used to animate the position and orientation of views.</p>
+<p>The black points in the following figure are points where the DALi logo travels to. The red points are the control points which express the curvature of the path on the black points.</p>
+
+<p align="center"><strong>Figure: Path animation</strong></p>
+       <p align="center"><img src="images/animated-path.png" alt="Path animation" /></p>
+
+<p>The following code presents the black points:</p>
+<pre class="prettyprint">
+Animation animation = new Animation();
+
+Path path = new Path();
+path.AddPoint( new Position( 50.0f, 10.0f, 0.0f ));
+path.AddPoint( new Position( 90.0f, 50.0f, 0.0f ));
+path.AddPoint( new Position( 10.0f, 90.0f, 0.0f ));
+</pre>
+<p>The control points can be added manually using <code>AddControlPoint()</code>. <code>Path</code> can also auto-generate the control points for you:</p>
+<pre class="prettyprint">
+path.GenerateControlPoints(0.25f);
+</pre>
+<p>Here <code>0.25f</code> represents the curvature of the required path. The generated control points result in a smooth join between the splines of each segment.</p>
+<p>To animate <code>view1</code> along this path:</p>
+<pre class="prettyprint">
+animation.Animate( view1, path, new Position(0.0f, 0.0f, 0.0f) );
+</pre>
+<p>The third parameter is the forward vector (in a local space coordinate system) that is oriented with the path's tangent direction.</p>
+<p>Another example:</p>
+<pre class="prettyprint">
+// Black points
+Position position0 = new Position(200.0f, 200.0f, 0.0f);
+Position position1 = new Position(300.0f, 300.0f, 0.0f);
+Position position2 = new Position(400.0f, 400.0f, 0.0f);
+
+Path path = new Path();
+path.AddPoint(position0);
+path.AddPoint(position1);
+path.AddPoint(position2);
+
+// Control points for first segment
+path.AddControlPoint(new Vector3(39.0f, 90.0f, 0.0f));
+path.AddControlPoint(new Vector3(56.0f, 119.0f, 0.0f));
+
+// Control points for second segment
+path.AddControlPoint(new Vector3(78.0f, 120.0f, 0.0f));
+path.AddControlPoint(new Vector3(93.0f, 104.0f, 0.0f));
+
+Animation animation = new Animation();
+animation.AnimatePath(view, path, Vector3.XAxis, 0, 5000, new AlphaFunction(AlphaFunction.BuiltinFunctions.Linear)); // X Axis
+animation.Play();
+</pre>
+<div class="note">
+       <strong>Note</strong>
+       <code>AnimatePath()</code> invokes <code>Animate</code>.
+</div>
+
+<h2 id="multithreading">Animation Multithreading</h2>
+<p>NUI animations and rendering occur in a dedicated rendering thread. This allows animations to run smoothly, regardless of the time taken to process input events in the application code.</p>
+<p>Internally, NUI contains a scene-graph, which mirrors the views hierarchy. The scene graph objects perform the actual animation and rendering, while the views provide thread-safe access.</p>
+<p>The following figure shows a view hierarchy,  in which one of the views is being animated. The green objects are created by the application code, while the blue private objects are used in the dedicated rendering thread.</p>
+<p align="center"><strong>Figure: Actor hierarchy with an animation</strong></p>
+       <p align="center"><img alt="Actor hierarchy with an animation" src="images/multi-threaded-animation.png"/></p>
+
+<h3>Reading an Animated Value</h3>
+<p>When a property is animatable, it can only be modified in the rendering thread. The value returned from a 'get' property is the value used when the previous frame was rendered.</p>
+<p>For example, <code>pos = view.Position</code> returns the position at which the view was last rendered. Since setting a position with <code>view.Position = pos</code> is asynchronous, <code>pos = view.Position</code> does not immediately return the same value.</p>
+<pre class="prettyprint">
+// While handling an event
+
+View view = new View();
+Window.Instance.Add(view); // Initial position is 0,0,0
+view.Position = new Position(10, 10, 10);
+
+Position current = view.Position;
+Console.WriteLine("Current position: " + current.X + ", " + current.Y + ", " + current.Z);
+Console.WriteLine("...");
+
+// Whilst handling another event
+
+current = view.Position;
+Console.WriteLine("Current position: " + current.X + ", " + current.Y + ", " + current.Z);
+</pre>
+<p>The above code is likely to output:</p>
+<pre class="prettyprint">
+Current position: 0, 0, 0
+...
+Current position: 10, 10, 10
+</pre>
+
+<h3>Setting a Property During an Animation</h3>
+<p>When a property is being animated, the animation overrides all values set with other methods.</p>
+
+<p align="center"><strong>Figure: Actor hierarchy with an animated property</strong></p>
+       <p align="center"><img alt="Actor hierarchy with an animated property" src="images/multi-threaded-animation-2.png"/></p>
+<p>The order of execution in the render thread is:</p>
+<ol>
+<li>Process the message and call the <code>SetPosition()</code> method.</li>
+<li>Apply the animation and call the <code>SetPosition()</code> method.</li>
+<li>Render the frame.</li>
+</ol>
+
+<h2 id="sample">Sample Animation</h2>
+<p>A simple text animation example has been created to illustrate some of the principles outlined in this guide, including the use of the <code>AnimateBy()</code> and <code>AnimateTo()</code> methods, and an alphafunction.</p>
+<p>Read the instructions in <a href="setup-ubuntu.htm#buildsrc">Building the NUI Source Code</a> of the Ubuntu setup guide, which includes an explanation of where to place the example files (the <code>nuirun</code> folder).</p>
+<ol>
+<li>Download the <a href="http://dalihub.github.io/NUIsetup/animation-hello-world-tutorial.cs">Animation example source code</a>.</li>
+<li>Copy this file to your <code>nuirun</code> folder (or <code>../nuirun/tutorials</code>):
+<pre class="prettyprint">
+cp animation-hello-world.cs ~/DALiNUI/nuirun/tutorials
+</pre>
+</li>
+</ol>
+<h2 id="animationclassmethods">Animation Class Methods</h2>
+<p>The <code>Animation</code> class provides various overloaded methods for property animation:</p>
+<ul>
+<li><code>AnimateBy()</code> animates a property value by a relative amount.
+<pre class="prettyprint">
+public void AnimateBy(View target, string property, object relativeValue, AlphaFunction alphaFunction = null)
+
+public void AnimateBy(View target, string property, object relativeValue, int startTime, int endTime, AlphaFunction alphaFunction = null)
+</pre>
+<p>The following table describes the <code>AnimateBy()</code> method parameters.</p>
+<p align="center" class="Table"><strong>Table: <code>AnimateBy()</code> method parameters</strong></p>
+<table>
+<thead><tr>
+    <th>Parameter</th>
+    <th>Description</th>
+</tr></thead>
+<tbody>
+<tr>
+    <td><code>target</code></td>
+    <td>The target object to animate.</td>
+</tr>
+<tr>
+    <td><code>property</code></td>
+    <td>The target property to animate, which can be an enumerator or string.</td>
+</tr>
+<tr>
+    <td><code>relativeValue</code></td>
+    <td>The amount by which to change the property value.</td>
+</tr>
+<tr>
+    <td><code>alphaFunction</code></td>
+    <td>The alpha function to apply.</td>
+</tr>
+<tr>
+    <td><code>startTime</code></td>
+    <td>The animation start time.</td>
+</tr>
+<tr>
+    <td><code>endTime</code></td>
+    <td>The animation end time.</td>
+</tr>
+</tbody>
+</table>
+</li>
+<li><code>AnimateTo()</code> animates a property to a destination value.
+<pre class="prettyprint">
+public void AnimateTo(View target, string property, object destinationValue, AlphaFunction alphaFunction = null)
+
+public void AnimateTo(View target, string property, object destinationValue, int startTime, int endTime, AlphaFunction alphaFunction = null)
+</pre>
+</li>
+<li><code>AnimateBetween()</code> animates a property between <a href="#animationtypes">key frames</a>.
+<pre class="prettyprint">
+public void AnimateBetween(View target, string property, KeyFrames keyFrames, Interpolation interpolation = Interpolation.Linear, AlphaFunction alphaFunction = null)
+
+public void AnimateBetween(View target, string property, KeyFrames keyFrames)
+</pre>
+<p>The following table describes the <code>AnimateTo()</code> method parameters.</p>
+<p align="center" class="Table"><strong>Table: <code>AnimateTo()</code> method parameters</strong></p>
+<table>
+<thead><tr>
+    <th>Parameter</th>
+    <th>Description</th>
+</tr></thead>
+<tbody>
+<tr>
+    <td><code>keyFrames</code></td>
+    <td>The set of time/value pairs between which to animate.</td>
+</tr>
+<tr>
+    <td><code>interpolation</code></td>
+    <td>The method used to interpolate between values.</td>
+</tr>
+</tbody>
+</table>
+</li>
+<li><code>AnimatePath()</code> animates a view's position and orientation through a predefined path.
+<pre class="prettyprint">
+public void AnimatePath(View view, Path path, Vector3 forward, AlphaFunction alphaFunction = null)
+</pre>
+<p>The following table describes the <code>AnimatePath()</code> method parameters.</p>
+<p align="center" class="Table"><strong>Table: <code>AnimatePath()</code> method parameters</strong></p>
+<table>
+<thead><tr>
+    <th>Parameter</th>
+    <th>Description</th>
+</tr></thead>
+<tbody>
+<tr>
+    <td><code>path</code></td>
+    <td>The position and orientation.</td>
+</tr>
+<tr>
+    <td><code>forward</code></td>
+    <td>The vector (in local space coordinate system) oriented with the path's tangent direction.</td>
+</tr>
+</tbody>
+</table>
+</li>
+</ul>
+<h2 id="animationclassproperties">Animation Class Properties</h2>
+<p>The following table lists the <code>Animation</code> class properties.</p>
+<table>
+<thead><tr>
+    <th>Property</th>
+    <th>Type</th>
+    <th>Description</th>
+</tr></thead>
+<tbody>
+<tr>
+    <td><code>Duration</code></td>
+    <td><code>int</code></td>
+    <td>Gets/sets the animation duration in milliseconds.</td>
+</tr>
+<tr>
+    <td><code>DefaultAlphaFunction</code></td>
+    <td><code>AlphaFunction</code></td>
+    <td>Gets/sets the default alpha function for the animation.</td>
+</tr>
+<tr>
+    <td><code>State</code></td>
+    <td><code>States</code></td>
+    <td>Queries the animation state (<code>Stopped</code>, <code>Playing</code>, or <code>Paused</code>).</td>
+</tr>
+<tr>
+    <td><code>LoopCount</code></td>
+    <td><code>int</code></td>
+    <td>Set: Defines the number of times to loop the animation. A value of 0 is the same as setting <code>Looping = true</code>, looping continuously.
+    <p>Get: Gets the loop count.</p></td>
+</tr>
+<tr>
+    <td><code>Looping</code></td>
+    <td><code>bool</code></td>
+    <td>Gets/sets whether the animation loops, which resets the loop count. The loop count is initially 1 for a single play.</td>
+</tr>
+<tr>
+    <td><code>EndAction</code></td>
+    <td><code>EndActions</code></td>
+    <td>Gets/sets the animation end action. The action is performed when the animation ends, or if it is stopped.</td>
+</tr>
+<tr>
+    <td><code>CurrentLoop</code></td>
+    <td><code>int</code></td>
+    <td>Gets the current loop count.</td>
+</tr>
+<tr>
+    <td><code>DisconnectAction</code></td>
+    <td><code>EndAction</code></td>
+    <td>Gets/sets the disconnect action.</td>
+</tr>
+<tr>
+    <td><code>CurrentProgress</code></td>
+    <td><code>float</code></td>
+    <td>Gets/sets the animation progress.</td>
+</tr>
+<tr>
+    <td><code>SpeedFactor</code></td>
+    <td><code>float</code></td>
+    <td>Gets/sets a speed factor for the animation.</td>
+</tr>
+<tr>
+    <td><code>PlayRange</code></td>
+    <td><code>RelativeVector2</code></td>
+    <td>Defines the values between which the animation plays. Both values (<code>range.x</code> and <code>range.y</code>) must be between 0 and 1.</td>
+</tr>
+<tr>
+    <td><code>ProgressNotification</code></td>
+    <td><code>float</code></td>
+    <td>Gets/sets the progress notification marker that triggers the <code>ProgressReached</code> event. The value must be between 0 and 1.</td>
+</tr>
+</tbody>
+</table>
+
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
diff --git a/nui/button.htm b/nui/button.htm
new file mode 100644 (file)
index 0000000..2aeca6a
--- /dev/null
@@ -0,0 +1,378 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+<title>Button</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#creation">Creating a Button</a></li>
+            <li><a href="#states">Button States</a></li>
+            <li><a href="#events">Button Events</a></li>
+            <li><a href="#visuals">Button Visuals</a></li>
+            <li><a href="#tooltips">Tooltips</a></li>
+            <li><a href="#properties">Button Properties</a></li>
+
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>Button</h1>
+<p>The NUI button controls include various button types:</p>
+<ul>
+       <li><code>PushButton</code> changes its appearance when pressed, and returns to its original appearance when released.</li>
+       <li><code>Checkbox</code> can be checked or unchecked.</li>
+       <li><code>Radio</code> button has 2 states, selected and unselected. Usually radio buttons are grouped, and only 1 radio button in a group can be selected at a given time.</li>
+       <li><code>Toggle</code> button allows the user to switch a feature on or off. Toggle buttons also support tooltips.</li>
+</ul>
+<p>The <code>Button</code> class is the base class for the button UI components.</p>
+
+<h2 id="creation">Creating a Button</h2>
+<p>To create a button:</p>
+
+<ul>
+       <li>Create a push button.
+       <p>In the following example, the button is added to a Table View UI component:</p>
+<pre class="prettyprint">
+private TableView _contentContainer;
+
+_window = Window.Instance;
+_contentContainer = new TableView(6, 5);
+
+// Other UI components
+
+PushButton button = new PushButton();
+button.LabelText = "Process";
+button.ParentOrigin = ParentOrigin.BottomLeft;
+
+_contentContainer.AddChild(button, new TableView.CellPosition(....);
+_window.Add(_contentContainer);
+</pre>
+
+       </li>
+       <li>Create a checkbox:
+<pre class="prettyprint">
+CheckBoxButton checkBoxbutton = new CheckBoxButton();
+checkBoxbutton.LabelText = "Yes";
+checkBoxbutton.BackgroundColor = Color.White;
+</pre>
+       </li>
+       <li>Create a group of radio buttons:
+<pre class="prettyprint">
+View radioGroup = new View();
+radioGroup.SetParentOrigin.Centre;
+
+RadioButton button1 = new RadioButton();
+button1.LabelText = "Yes";
+button1.Selected = true;
+radioGroup.Add(button1);
+
+RadioButton button2 = new RadioButton();
+button2.LabelText = "No";
+radioGroup.Add(button2);
+</pre>
+       </li>
+       <li>Create a toggle button:
+<pre class="prettyprint">
+ToggleButton toggleButton = new ToggleButton();
+</pre>
+       </li>
+</ul>
+
+<h2 id="states">Button States</h2>
+<p>Each button can be in the <code>selectable</code>, <code>disabled</code>, and <code>togglable</code> states.</p>
+<p>The <code>Button</code> class provides the <code>Toggable</code> and <code>Selected</code> properties. The <code>View</code> class provides the <code>Disabled</code> property.</p>
+
+<h2 id="events">Button Events</h2>
+<p>There are 4 events associated with the <code>Button</code> class:</p>
+<ul>
+       <li><code>Clicked</code>: The button is touched, and the touch point does not leave the boundary of the button.
+       <li><code>Pressed</code>: The button is touched.</li>
+       <li><code>Released</code>: The button is touched, and the touch point leaves the boundary of the button.</li>
+       <li><code>StateChanged</code>: The button state is changed.</li>
+</ul>
+
+<p>For example, to add an event handler to the <code>Clicked</code> event of a push button:</p>
+<pre class="prettyprint">
+pushButton.Clicked += (obj, e) =&gt;
+{
+    PushButton sender = obj as PushButton;
+    sender.LabelText = "Click Me";
+
+    return true;
+};
+</pre>
+<p>Events do not trigger if the <code>Disabled</code> property of the button is set to <code>true</code>.</p>
+<p>The <code>Button</code> class provides the following properties which modify the triggered events:</p>
+
+<ul>
+       <li>If the <code>AutoRepeating</code> property is set to <code>true</code>, the <code>Pressed</code>, <code>Released</code>, and <code>Clicked</code> events are fired at regular intervals while the button is touched.
+       <p>The interval times can be modified with the <code>InitialAutoRepeatingDelay</code> and <code>NextAutoRepeatingDelay</code> properties.</p>
+       <p>A togglable button cannot be autorepeated. If the <code>AutoRepeating</code> property is set to <code>true</code>, the <code>Togglable</code> property is set to <code>false</code> but no event is fired.</p>
+       </li>
+       <li>If the <code>Togglable</code> property is set to <code>true</code>, a <code>StateChanged</code> event is fired with the selected state.</li>
+</ul>
+
+<p>For a checkbox, all 4 events are available, though usually only the <code>StateChanged</code> event is used to notify when the button changes its state to selected or unselected.</p>
+<p>For a radio button, use the <code>StateChanged</code> event to check when the radio button is selected.</p>
+
+<h2 id="visuals">Button Visuals</h2>
+
+<p>Visuals provide reusable rendering logic which can be used by all controls. Images and icons are added to buttons using visuals.</p>
+<p>The button's appearance can be modified by setting properties for the various state visuals. A control has 3 states: <code>NORMAL</code>, <code>FOCUSED</code>, and <code>DISABLED</code>. Buttons have substates: <code>SELECTED</code> and <code>UNSELECTED</code>. Each state and substate needs to have a visual defined for it. A visual can be shared between states.</p>
+<p>When the button pressed, the <code>unselected</code> visuals are replaced by the <code>selected</code> visuals. The text label is always placed on the top of all images.</p>
+<p>When the button is disabled, the background, button, and selected visuals are replaced by their <code>disabled</code> counterparts.</p>
+
+<p>The following example illustrates the toggle button <code>StateVisuals</code> property, which has visuals for each state:</p>
+<pre class="prettyprint">
+ToggleButton toggleButton = new ToggleButton();
+
+PropertyArray array = new PropertyArray();
+array.Add(new PropertyValue("./images/star-highlight.png"));
+array.Add(new PropertyValue("./images/star-mod.png"));
+array.Add(new PropertyValue("./images/star-dim.png"));
+toggleButton.StateVisuals = array;
+
+PropertyArray tooltips = new Dali.PropertyArray();
+tooltips.Add(new PropertyValue("State A"));
+tooltips.Add(new PropertyValue("State B"));
+tooltips.Add(new PropertyValue("State C"));
+toggleButton.Tooltips = tooltips;
+
+toggleButton.WidthResizePolicy  = ResizePolicyType.FillToParent;
+toggleButton.HeightResizePolicy = ResizePolicyType.FillToParent;
+</pre>
+<p>For more information on button styling with visuals, see <a href="styling_controls_with_JSON.htm">Styling Controls with JSON</a>.</p>
+
+<h2 id="tooltips">Tooltips</h2>
+<p>There are various methods of adding tooltips to a button:</p>
+<ul>
+       <li>Use the <code>TooltipText</code> property, which is inherited from the <code>View</code> class:
+<pre class="prettyprint">
+PushButton button = new PushButton();
+
+// Add a simple text-only tooltip
+button.TooltipText = "Simple Tooltip";
+</pre>
+       </li>
+       <li>Use a property array, as shown in the example in <a href="#visuals">Button Visuals</a>.</li>
+       <li>Property maps
+       <p>In the following example, an array of property maps is created for a tooltip with 1 icon and 1 text visual:</p>
+<pre class="prettyprint">
+PushButton button = new PushButton();
+
+// Create a property map for a tooltip with 1 icon and 1 text
+PropertyArray iconTooltipContent = new Property.Array();
+
+// Icon
+PropertyMap iconVisual = new PropertyMap();
+iconVisual.Add(Dali.Constants.Visual.Property.Type, new PropertyValue((int)Dali.Constants.Visual.Type.Image))
+          .Add(Dali.Constants.ImageVisualProperty.URL, new PropertyValue("./images/star-highlight.png"));
+
+iconTooltipContent.Add(new PropertyValue(iconVisual));
+
+// Text
+PropertyMap textVisual = new PropertyMap();
+textVisual.Add(Dali.Constants.Visual.Property.Type, new PropertyValue((int)Dali.Constants.Visual.Type.Text))
+          .Add(Dali.Constants.TextVisualProperty.Text, new PropertyValue("Tooltip with Icon"));
+
+iconTooltipContent.Add(new PropertyValue(textVisual));
+
+// Icon tooltip
+PropertyMap iconTooltip = new PropertyMap();
+iconTooltip.Add(Dali.Constants.Tooltip.Property.Content, new Property.Value(iconTooltipContent))
+           .Add(Dali.Constants.Tooltip.Property.Tail, new PropertyValue(true));
+
+// Add the tooltip with icon and text to the push button
+button.Tooltip = iconTooltip;
+</pre>
+       <p>The <code>Tooltip</code> property is inherited from the <em>View</em> class.</p>
+       </li>
+</ul>
+
+<h2 id="properties">Button Properties</h2>
+<p>The <code>Button</code> class has the following properties:</p>
+<table class="table table-striped table-bordered">
+<thead>
+<tr>
+<th>Property</th>
+<th>Type</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>UnselectedVisual</code></td>
+<td><code>Map</code></td>
+<td>Map describing a visual, changes depending on the button state</td>
+</tr>
+<tr>
+<td><code>SelectedVisual</code></td>
+<td><code>Map</code></td>
+<td>Map describing a visual, changes depending on the button state</td>
+</tr>
+<tr>
+<td><code>DisabledUnselectedVisual</code></td>
+<td><code>Map</code></td>
+<td>Map describing a visual, changes depending on the button state</td>
+</tr>
+<tr>
+<td><code>DisabledSelectedVisual</code></td>
+<td><code>Map</code></td>
+<td>Map describing a visual, changes depending on the button state</td>
+</tr>
+<tr>
+<td><code>UnselectedBackgroundVisual</code></td>
+<td><code>Map</code></td>
+<td>Map describing a visual, changes depending on the button state</td>
+</tr>
+<tr>
+<td><code>SelectedBackgroundVisual</code></td>
+<td><code>Map</code></td>
+<td>Map describing a visual, changes depending on the button state</td>
+</tr>
+<tr>
+<td><code>DisabledUnselectedBackgroundVisual</code></td>
+<td><code>Map</code></td>
+<td>Map describing a visual, changes depending on the button state</td>
+</tr>
+<tr>
+<td><code>DisabledSelectedBackgroundVisual</code></td>
+<td><code>Map</code></td>
+<td>Map describing a visual, changes depending on the button state</td>
+</tr>
+<tr>
+<td><code>LabelRelativeAlignment</code></td>
+<td><code>Align</code></td>
+<td>Position of the text label in relation to foreground/icon when both are present</td>
+</tr>
+<tr>
+<td><code>LabelPadding</code></td>
+<td><code>Vector4</code></td>
+<td>Padding area around the label (if present)</td>
+</tr>
+<tr>
+<td><code>ForegroundVisualPadding</code></td>
+<td><code>Vector4</code></td>
+<td>Padding area around the foreground/icon visual (if present)</td>
+</tr>
+<tr>
+<td><code>AutoRepeating</code></td>
+<td><code>bool</code></td>
+<td>Toggles the autorepeating state. For more information, see <a href="#events">Button Events</a>.</td>
+</tr>
+<tr>
+<td><code>InitialAutoRepeatingDelay</code></td>
+<td><code>float</code></td>
+<td>Initial autorepeating delay in seconds (default: 0.15 s)</td>
+</tr>
+<tr>
+<td><code>NextAutoRepeatingDelay</code></td>
+<td><code>float</code></td>
+<td>Continuous autorepeating delay in seconds (default: 0.05 s)</td>
+</tr>
+<tr>
+<td><code>Togglable</code></td>
+<td><code>bool</code></td>
+<td>If the <code>Togglable</code> property is set to <code>true</code>, the <code>AutoRepeating</code> property is set to <code>false</code>.</td>
+</tr>
+<tr>
+<td><code>Selected</code></td>
+<td><code>bool</code></td>
+<td>Sets a togglable button as either selected or unselected</td>
+</tr>
+<tr>
+<td><code>UnselectedColor</code></td>
+<td><code>Color</code></td>
+<td>Gets/sets the unselected color</td>
+</tr>
+<tr>
+<td><code>SelectedColor</code></td>
+<td><code>Color</code></td>
+<td>Gets/sets the selected color</td>
+</tr>
+<tr>
+<td><code>Label</code></td>
+<td><code>Map</code></td>
+<td>Button text label</td>
+</tr>
+<tr>
+<td><code>LabelText</code></td>
+<td><code>string</code></td>
+<td>Button text label</td>
+</tr>
+</tbody>
+</table>
+
+<div class="note">
+<strong>Note</strong>
+If the <code>AutoRepeating</code> property is set to <code>true</code>, the <code>Togglable</code> property is set to <code>false</code>.
+</div>
+
+<p>The <strong>ToggleButton</strong> class has the following additional properties:</p>
+
+<table>
+<thead>
+<tr>
+<th>Property</th>
+<th>Type</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>StateVisuals</code></td>
+<td><code>Array</code></td>
+<td>Array of property-maps, or a property array of strings. The property maps expect a description of a visual, and the strings represent image URLs.</td>
+</tr>
+<tr>
+<td><code>Tooltips</code></td>
+<td><code>Array</code></td>
+<td>Array of toggle state tooltip strings. Each tooltip string must match a toggle state</td>
+</tr>
+<tr>
+<td><code>CurrentStateIndex</code></td>
+<td><code>int</code></td>
+<td>Current state</td>
+</tr>
+</tbody>
+</table>
+
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/nui/creating_custom_view_controls.htm b/nui/creating_custom_view_controls.htm
new file mode 100644 (file)
index 0000000..0c0a906
--- /dev/null
@@ -0,0 +1,608 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>Custom View Controls</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#existingcustomview">CustomView Class</a></li>
+            <li><a href="#creation">Creating a Custom View</a></li>
+            <li><a href="#rendering">Rendering Content</a></li>
+            <li><a href="#stylable">Styling Custom Views</a></li>
+            <li><a href="#typeregistration">Type Registration</a></li>
+            <li><a href="#properties">Properties in Custom Views</a></li>
+            <li><a href="#enableproperties">Property Registration</a></li>
+            <li><a href="#creatingtransitions">Creating Transitions</a></li>
+            <li><a href="#viewbehaviour">Setting View Behavior</a></li>
+            <li><a href="#events">View Events</a></li>
+            <li><a href="#gestures">Gestures</a></li>
+            <li><a href="#accessibility">Accessibility</a></li>
+            <li><a href="#defaultwindowconnection">Window Connection</a></li>
+            <li><a href="#sizenegotiation">Size Negotiation</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>Custom View Controls</h1>
+
+<p>NUI provides the ability to create custom views.</p>
+
+<p>The following general guidelines apply to creating a custom view:</p>
+<ul>
+       <li>Derive your view from the <code>CustomView</code> class.</li>
+       <li>Use <strong>properties</strong> as much as possible, as views must be data-driven.
+    <p>These views are used through JavaScript and JSON files.</p></li>
+       <li>The view can be updated when the properties (such as styles) change
+    <p>Ensure the view deals with these property changes gracefully, on both first and subsequent times they are set.</p></li>
+       <li>Use visuals rather than creating several child views.
+    <p>This makes the rendering pipeline more efficient.</p></li>
+       <li>Accessibility actions must be considered when designing the view.</li>
+       <li>Use events if the application needs to react to changes in the view state.</li>
+       <li>Use of gestures is preferred over analyzing raw touch events.</li>
+</ul>
+
+<h2 id="existingcustomview">CustomView Class</h2>
+<p>The NUI <code>CustomView</code> class provides common functionality required by all views. The <code>CustomView</code> class is derived from the <code>ViewWrapper</code> class:</p>
+<pre class="prettyprint">
+public class CustomView : ViewWrapper
+</pre>
+<p>The <code>ViewWrapper</code> class in turn is derived from <code>View</code> class:</p>
+<pre class="prettyprint">
+public class ViewWrapper : View
+</pre>
+<p>There are several controls derived from <code>CustomView</code> objects already existing in NUI, including:</p>
+<ul>
+       <li><strong>Spin</strong> control, which is used for continuously changing values when the user can easily predict a set of values.</li>
+       <li><strong>ContactView</strong>, which consists of 4 visuals (<code>Image</code>, <code>Primitive</code>, <code>Text</code>, and <code>Color</code>), to display contact information.
+       <p>All of these visuals can be configured through properties: <code>ImageURL</code> (<code>Image</code>), <code>Shape</code> (<code>Primitive</code>), <code>Name</code> (<code>Text</code>), and <code>Color</code>.</p>
+       <p>The tap gesture is enabled on the <code>ContactView</code>, changing the color visual to a random color when the <code>ContactView</code> is tapped.</p>
+       <p align="center"><strong>Figure: ContactView</strong></p>
+<p align="center"><img src="images/ContactView.png" alt="ContactView" /></p>
+<p>The contact view screenshot shows 5 contacts, each with the 4 visuals.</p>
+       </li>
+       <li><strong>VisualView</strong> control, which enables you to add any visual. For more information, see <a href="visuals.htm#visualview">Visual View Class</a>.</li>
+       <li><strong>StarRating</strong> custom control, which is used for star rating of images (draggable to change the rating).</li>
+</ul>
+
+<h3>CustomView Methods</h3>
+<p>The following table lists the key <code>CustomView</code> methods.</p>
+
+<table>
+<thead>
+       <tr>
+       <th>Name</th>
+       <th>Description</th>
+       </tr>
+</thead>
+<tbody>
+       <tr>
+       <td><code>OnInitialize()</code></td>
+       <td>Called after the view has been initialized.</td>
+       </tr>
+       <tr>
+       <td><code>SetBackground()</code></td>
+       <td>Sets the background with a property map.</td>
+       </tr>
+       <tr>
+       <td><code>EnableGestureDetection()</code></td>
+       <td>Allows deriving classes to enable any of the gesture detectors that are available.</td>
+       </tr>
+       <tr>
+       <td><code>RegisterVisual()</code></td>
+       <td>Registers a visual by a property index, linking a view to a visual when required.</td>
+       </tr>
+       <tr>
+       <td><code>CreateTransition()</code></td>
+       <td>Creates a transition effect on the view for animations.</td>
+       </tr>
+       <tr>
+       <td><code>RelayoutRequest()</code></td>
+       <td>Requests a re-layout, which means performing a size negotiation on this view, its parent, and children (and potentially whole scene).</td>
+       </tr>
+       <tr>
+       <td><code>OnStageConnection()</code></td>
+       <td>Called after the view has been connected to the stage default window.</td>
+       </tr>
+</tbody>
+</table>
+
+<h2 id="creation">Creating a Custom View</h2>
+
+<p>A view is created with the <code>new</code> operator:</p>
+<pre class="prettyprint">
+contactView = new ContactView();
+</pre>
+
+<p>Each custom C# View must have its static constructor called before any JSON file is loaded. Static constructors for a class are only run once (they are run per view, not per instance). The View must register its type inside the static constructor. The <code>ViewRegistry.Instance.Register()</code> method registers the views and any scriptable properties they have with the Type Registry:</p>
+<pre class="prettyprint">
+static ContactView()
+{
+    ViewRegistry.Instance.Register(CreateInstance, typeof(ContactView));
+}
+</pre>
+
+<p>In addition, the custom view must provide a <code>CreateInstance()</code> method, which gets passed to the <code>ViewRegistry.Instance.Register()</code> method. The <code>CreateInstance()</code> method is called if the view is in a JSON file:</p>
+<pre class="prettyprint">
+static CustomView CreateInstance()
+{
+    return new ContactView();
+}
+</pre>
+<p>Override the<code>OnInitialize</code> method if necessary:</p>
+<pre class="prettyprint">
+public override void OnInitialize()
+{
+    // Create a container for the star images
+    _container = new FlexContainer();
+
+    _container.FlexDirection = FlexContainer.FlexDirectionType.Row;
+    _container.WidthResizePolicy = ResizePolicyType.FillToParent;
+    _container.HeightResizePolicy = ResizePolicyType.FillToParent;
+
+    this.Add(_container);
+}
+</pre>
+
+<h2 id="rendering">Rendering Content</h2>
+<p>To render content, the required views can be created and added to the control itself as its children. However, this solution is not fully optimized and means extra views are added, requiring additional processing.</p>
+<p>It is recommended to use or reuse visuals to create the required content. For more information, see <a href="visuals.htm">Visuals</a>.</p>
+<p>The following example shows the creation and registration of an image visual in <code>ContactView.cs</code>:</p>
+
+<pre class="prettyprint">
+private VisualBase _imageVisual;
+
+[ScriptableProperty()]
+public string ImageURL
+{
+    get
+    {
+        return _imageURL;
+    }
+    set
+    {
+        _imageURL = value;
+
+        // Create and register an image visual
+        PropertyMap imageVisual = new PropertyMap();
+        imageVisual.Add( Visual.Property.Type, new PropertyValue( (int)Visual.Type.Image ))
+                   .Add( ImageVisualProperty.URL, new PropertyValue( _imageURL ) )
+                   .Add( ImageVisualProperty.AlphaMaskURL, new PropertyValue( _maskURL ));
+       _imageVisual =  VisualFactory.Get().CreateVisual( imageVisual );
+
+        RegisterVisual( GetPropertyIndex("ImageURL"), _imageVisual );
+
+        // Set the depth index for the image visual
+       _imageVisual.DepthIndex = ImageVisualPropertyIndex;
+    }
+}
+</pre>
+
+<div class="note">
+       <strong>Note</strong>
+       The <code>ImageURL</code> property is a <a href="#enableproperties">ScriptableProperty</a>, which automatically generates indices.
+<p><code>RegisterVisual()</code> registers a visual by a property index, linking a view to a visual when required.</p>
+<p><code>GetPropertyIndex()</code> gets the generated index corresponding to the property name.</p>
+<p>A range of property indices are provided for <code>ImageVisualPropertyIndex</code>, 0 by default.</p>
+<p>For more information on the property maps that can be used for each visual type, see <a href="visuals.htm">Visuals</a>.</p>
+</div>
+
+
+<h2 id="stylable">Styling Custom Views</h2>
+<p>The NUI property system allows custom views to be easily styled. The JSON syntax is used in the stylesheets:</p>
+
+<h3>Current JSON Styling Format</h3>
+<p>This is an example of the current (as of July 2017) JSON stylesheet format. This example includes a visual.</p>
+<pre class="prettyprint">
+"styles":
+{
+  "TextField":
+  {
+    "pointSize":18,
+    "primaryCursorColor":[0.0,0.72,0.9,1.0],
+    "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+    "cursorWidth":3,
+    "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+    "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+    "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+    "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" },
+    "enableSelection":true
+  },
+
+  "TextFieldFontSize0":
+  {
+    "pointSize":10
+  },
+
+  "TextSelectionPopup":
+  {
+    "popupMaxSize":[656,72],
+    "optionDividerSize":[2,0],
+    "popupDividerColor":[0.23,0.72,0.8,0.11],
+    "popupIconColor":[1.0,1.0,1.0,1.0],
+    "popupPressedColor":[0.24,0.72,0.8,0.11],
+    "background":
+       {
+      "visualType": "IMAGE",
+      "url": "{DALI_IMAGE_DIR}selection-popup-background.9.png"
+    },
+    "backgroundBorder":
+       {
+      "visualType": "IMAGE",
+      "url": "{DALI_IMAGE_DIR}selection-popup-border.9.png",
+      "mixColor":[0.24,0.72,0.8,1.0]
+    },
+    "popupFadeInDuration":0.25,
+    "popupFadeOutDuration":0.25
+  }
+}
+</pre>
+
+<h3>New JSON Styling Format</h3>
+<p>This is an example of the new stylesheet format, currently under development. This example also includes a visual.</p>
+<pre class="prettyprint">
+"states":
+{
+  "NORMAL":
+  {
+    "states":
+    {
+      "UNSELECTED":
+      {
+        "visuals":
+        {
+          "backgroundVisual":
+           {
+            "visualType":"IMAGE",
+            "url":"backgroundUnSelected.png"
+           }
+        }
+      },
+      "SELECTED":
+      {
+        "visuals":
+        {
+          "backgroundVisual":
+           {
+            "visualType":"IMAGE",
+            "url":"backgroundSelected.png"
+           }
+        }
+      }
+    }
+  }
+}
+</pre>
+<p>Styling gives the UI designer the ability to change the look and feel of the View without any code changes.</p>
+
+<table>
+<thead>
+<tr>
+<th>Normal Style</th>
+<th>Customized Style</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><p align="center"><img src="images/popup-normal.png" alt="Popup window, normal style" /></p></td>
+<td><p align="center"><img src="images/popup-styled.png" alt="Popup window, custom style" /></p></td>
+</tr>
+</tbody>
+</table>
+
+<p>For more information on building up visuals for the button states using JSON stylesheets
+and transitioning between the various button states, see <a href="styling_controls_with_JSON.htm">Styling Controls with JSON</a>.</p>
+
+<h2 id="typeregistration">Type Registration</h2>
+<p>The Type Registry is used to register your custom view. Type registration allows the creation of the view through a JSON file, as well as registering properties, signals, actions, transitions, and animation effects.</p>
+<p>Type registration is performed by the <code>ViewRegistry</code> method. For more information, see <a href="#creation">Creating a Custom View</a>.</p>
+
+<h2 id="properties">Properties in Custom Views</h2>
+
+<p>Properties can be animatable or non-animatable. Examples of animatable <code>View</code> class properties are <code>Position</code>, <code>Orientation</code>, <code>Scale</code>, and <code>Color</code>.</p>
+<p>For more information on the NUI animation framework, see <a href="animation.htm">Animation</a>.</p>
+<p>Properties can be accessed through a unique index. The index can be set manually in code (hard-coded), or calculated automatically. <code>ContactView.cs</code> contains examples of both indexing methods; fixed for depth index, and automatic for registering visuals. The NUI code base is currently been modified (as of July 2017) to utilize property registration based solely on automatic generation of indices.</p>
+
+<h2 id="enableproperties">Property Registration</h2>
+
+<p>The <code>ScriptableProperty</code> class enables a property to be registered with the type registry. Add <code>ScriptableProperty</code> to any view-related property that you want to be scriptable from JSON.</p>
+
+<pre class="prettyprint">
+internal class ScriptableProperty : System.Attribute
+</pre>
+
+<p>Property indices are generated automatically in the <code>ScriptableProperty</code> class. A unique index for each property can be obtained by the <code>GetPropertyIndex()</code> method, with the name of the property as a parameter.</p>
+
+<p><a href="#rendering">Rendering</a> has an example of the use of a scriptable property, with <code>GetPropertyIndex</code>.</p>
+
+<h2 id="creatingtransitions">Creating Transitions</h2>
+
+<p>Controls, such as buttons, change between states from user interaction. All controls can move between the <code>NORMAL</code>, <code>FOCUSED</code>, and <code>DISABLED</code> states. Whilst in those states, a button has the <code>SELECTED</code> and <code>UNSELECTED</code> substates.</p>
+<p>To move between states and substates, transition animations can be defined. Each state and substate can have an entry and exit transition.</p>
+<p>To make defining common transitions easier, an effect can be used with a "from state" and a "to state". One such effect is <code>CROSSFADE</code>, which animates the opacity of visuals fading in and out to give a nice transition.</p>
+<p>Transition effects can be read from stylesheets, or created directly with the <code>CreateTransition</code> API.</p>
+
+<h3>CreateTransition API</h3>
+<p>Its possible to animate scriptable properties by using the <code>CreateTransition</code> API from <code>CustomView</code>-derived classes.</p>
+<p>The <code>CreateTransition()</code> method creates a transition effect on the view. The <code>transitionData</code> parameter describes the effect to create, and the return value is a handle to an animation defined with the given effect, or an empty handle if no properties match.</p>
+<pre class="prettyprint">
+protected Animation CreateTransition(TransitionData transitionData)
+</pre>
+
+<p>The following example code is taken from the <code>AnimateVisual()</code> method in <code>VisualView</code>, which is a <code>CustomView</code>-derived class.</p>
+<pre class="prettyprint">
+_alphaFunction = "EASE_IN_OUT_SINE";
+
+PropertyMap _animator = new PropertyMap();
+if ( _alphaFunction != null)
+{
+    _animator.Add("alphaFunction", new PropertyValue(_alphaFunction));
+}
+
+PropertyMap _timePeriod = new PropertyMap();
+_timePeriod.Add("duration", new PropertyValue((endTime - startTime) / 1000.0f));
+_timePeriod.Add("delay", new PropertyValue(startTime / 1000.0f));
+_animator.Add("timePeriod", new PropertyValue(_timePeriod));
+
+string _str1 = property.Substring(0, 1);
+string _str2 = property.Substring(1);
+string _str = _str1.ToLower() + _str2;
+if (_str == "position") {_str = "offset";}
+
+PropertyValue destVal = PropertyValue.CreateFromObject(destinationValue);
+
+PropertyMap _transition = new PropertyMap();
+_transition.Add("target", new PropertyValue(target.Name));
+_transition.Add("property", new PropertyValue(_str));
+if (initialValue != null)
+{
+    PropertyValue initVal = PropertyValue.CreateFromObject(initialValue);
+    _transition.Add("initialValue", new PropertyValue(initVal));
+}
+
+_transition.Add("targetValue", destVal);
+_transition.Add("animator", new PropertyValue(_animator));
+
+TransitionData _transitionData = new TransitionData(_transition);
+return this.CreateTransition(_transitionData);
+</pre>
+
+<h3>Transition Values in a Stylesheet</h3>
+<p>The following example uses the <code>CROSSFADE</code> effect:</p>
+<pre class="prettyprint">
+"transitions":
+[
+  {
+    "from":"UNSELECTED",
+    "to":"SELECTED",
+    "visualName":"*",
+    "effect":"CROSSFADE",
+    "animator":
+    {
+      "alphaFunction":"EASE_OUT",
+      "duration":"0.2,
+      "delay":0
+    }
+  }
+]
+</pre>
+
+<h2 id="viewbehaviour">Setting View Behavior</h2>
+<p>The <code>CustomViewBehaviour</code> enumeration specifies the following behavior:</p>
+<table>
+<thead>
+<tr>
+       <th>Behavior</th>
+       <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code>ViewBehaviourDefault</code></td>
+<td>Default behavior (size negotiation is on, style changes are monitored, event callbacks are not called)</td>
+</tr>
+<tr>
+<td><code>DisableSizeNegotiation</code></td>
+<td>View does not need size negotiation and is skipped by the size negotiation algorithm</td>
+</tr>
+<tr>
+<td><code>DisableStyleChangeSignals</code></td>
+<td>View does not need to monitor style change signals, such as theme or font changes</td>
+</tr>
+<tr>
+<td><code>RequiresKeyboardNavigationSupport</code></td>
+<td>View needs to support keyboard navigation</td>
+</tr>
+<tr>
+<td><code>LastViewBehaviour</code></td>
+<td>-</td>
+</tr>
+</tbody>
+</table>
+
+<p><code>CustomViewBehaviour</code> is used during object construction. For example:</p>
+
+<pre class="prettyprint">
+public VisualView() : base(typeof(VisualView).Name, CustomViewBehaviour.ViewBehaviourDefault)
+{
+}
+
+public ContactView() : base(typeof(ContactView).Name, CustomViewBehaviour.RequiresKeyboardNavigationSupport)
+{
+}
+</pre>
+
+<h2 id="events">View Events</h2>
+<p>The <code>View</code> class contains the following events:</p>
+
+<ul>
+<li><code>TouchEvent</code> is triggered when any touch occurs within the bounds of the custom view.</li>
+<li><code>HoverEvent</code> is triggered when a pointer moves within the bounds of a custom view (for example, mouse pointer or hover pointer).</li>
+<li><code>WheelEvent</code> is triggered when the mouse wheel (or similar) is moved while hovering over a view (through a mouse pointer or hover pointer).</li>
+</ul>
+
+<h2 id="gestures">Gestures</h2>
+<p>NUI has a gesture system which analyses a stream of touch events and attempts to determine the intention of the user. The following gesture detectors are provided:</p>
+<ul>
+       <li><strong>Pan:</strong> When the user starts panning (or dragging) 1 or more fingers.
+       <p>The panning must start from within the bounds of the view.</p></li>
+       <li><strong>Pinch:</strong> Detects when 2 touch points move towards or away from each other.
+       <p>The center point of the pinch must be within the bounds of the view.</p></li>
+       <li><strong>Tap:</strong> When the user taps within the bounds of the view.</li>
+       <li><strong>LongPress:</strong> When the user presses and holds on a certain point within the bounds of a view.</li>
+</ul>
+
+<p>Gesture detectors can be specified in the <code>OnInitialize()</code> method.</p>
+<p>The following example is taken from the <code>ContactView</code> custom view:</p>
+<pre class="prettyprint">
+public override void OnInitialize()
+{
+   // Enable the Tap gesture on ContactView
+   EnableGestureDetection(Gesture.GestureType.Tap);
+}
+</pre>
+<p>The <code>EnableGestureDetection()</code> method allows deriving classes to enable any of the gesture detectors that are available. The above code snippet only enables the default gesture detection for each type. If customization of the gesture detection is required, the gesture detector can be retrieved and set up accordingly in the same method:</p>
+<pre class="prettyprint">
+PanGestureDetector panGestureDetector = GetPanGestureDetector();
+panGestureDetector.AddDirection(PanGestureDetector.DIRECTION_VERTICAL);
+</pre>
+<p>Finally, the appropriate method must be overridden:</p>
+<pre class="prettyprint">
+OnPan(PanGesture&amp; pan) // Handle the pan gesture
+OnPinch(PinchGesture&amp; pinch ) // Handle the pinch gesture
+OnTap(TapGesture&amp; tap) // Handle the tap gesture
+OnLongPress(LongPressGesture&amp; longPress) // Handle the long-press gesture
+</pre>
+<p>The following example shows the <code>OnTap()</code> method from the <code>ContactView</code> class:</p>
+<pre class="prettyprint">
+public override void OnTap(TapGesture tap)
+{
+    // Change the color visual of ContactView with a random color
+    Random random = new Random();
+    float nextRed   = (random.Next(0, 256) / 255.0f);
+    float nextGreen = (random.Next(0, 256) / 255.0f);
+    float nextBlue  = (random.Next(0, 256) / 255.0f);
+    Animation anim = AnimateBackgroundColor( new Color( nextRed, nextGreen, nextBlue, 1.0f), 0, 2000 );
+    anim.Play();
+}
+</pre>
+
+<h2 id="accessibility">Accessibility</h2>
+<p>Accessibility is functionality that has been designed to aid usage by the visually impaired. Accessibility behavior can be customized in the view by overriding certain virtual methods, for example, <code>OnAccessibilityTouch()</code>. Touch events are delivered differently in the accessibility mode. The <code>OnAccessibilityTouch()</code> method needs to be overridden if a special behavior is required when these touch events are received.</p>
+
+<h2 id="defaultwindowconnection">Window Connection</h2>
+<p>If a notification is required when a custom view is connected to or disconnected from a window, override the <code>OnStageConnection()</code> and <code>OnStageDisconnection()</code> methods in the <code>CustomView</code> class.</p>
+
+
+<h2 id="sizenegotiation">Size Negotiation</h2>
+<p>Size negotiation controls the view sizes in a container. It is implemented with the values of the <code>ResizePolicyType</code> enumeration.</p>
+
+<p>The following table contains the values of the <code>ResizePolicyType</code> enumeration.</p>
+
+<p align="center" class="Table"><strong>Table: Resize policy types</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Name</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Fixed</code></td>
+    <td>Size is fixed, set by <code>SetSize()</code> (default)</td>
+</tr>
+<tr>
+    <td><code>UseNaturalSize</code></td>
+    <td>Use the views's natural size, meaning the dimensions of the image, or the size of the text</td>
+</tr>
+<tr>
+    <td><code>FillToParent</code></td>
+    <td>Fill up to the bounds of the view's parent. Aspect ratio is not maintained.</td>
+</tr>
+<tr>
+    <td><code>SizeRelativeToParent</code></td>
+    <td>Fill up to the bounds of the parent with a relative scale. Use <code>SetSizeModeFactor()</code> to specify the ratio.</td>
+</tr>
+<tr>
+    <td><code>SizeFixedOffsetFromParent</code></td>
+    <td>Fill up to the bounds of the view's parent, and add a fixed offset using <code>SetSizeModeFactor()</code>.</td>
+</tr>
+<tr>
+    <td><code>FitToChildren</code></td>
+    <td>Size adjusts to wrap around all the children of the view. For example, a popup's height can be adjusted to fit around its contents.</td>
+</tr>
+<tr>
+    <td><code>DimensionDependency</code></td>
+    <td>One dimension is dependent on the other</td>
+</tr>
+</tbody>
+</table>
+
+<div class="note">
+<strong>Note</strong>
+<code>UseAssignedSize</code>, which makes the view use a size assigned to it, is not a resize policy, but more of an implementation detail.
+</div>
+
+<ul>
+<li><code>UseNaturalSize</code>: Use this option for objects, such as images or text, to get their natural size, meaning the dimensions of an image or the size of the text without wrapping. Also use this on a <code>TableView</code> when the size of the table depends on its children.</li>
+<li><code>FillToParent</code>: Size fills up to the size of its parent, taking a size factor into account to allow for proportionate filling.</li>
+<li><code>FitToChildren</code>: Size scales around the size of the view's children. For example, a popup's height can be adjusted to fit around its content.</li>
+<li><code>DimensionDependency</code>: This covers rules, such as width-for-height and height-for-width. You specify that 1 dimension depends on another.</li>
+</ul>
+
+<p>An example of setting a resize policy for a custom view:</p>
+<pre class="prettyprint">
+contactView = new ContactView();
+contactView.WidthResizePolicy  = ResizePolicyType.FillToParent;
+contactView.HeightResizePolicy = ResizePolicyType.FillToParent;
+</pre>
+<p>Relayout requests are put in automatically when a property is changed on a view, or a change to the stage hierarchy is made and manual requests are usually not necessary. The <code>RelayoutRequest()</code> method is available for deriving views to call when they would like themselves to be relaid out.</p>
+<p>The following overridable methods provide customization points for the size negotiation algorithm:</p>
+<ul>
+<li><code>GetNaturalSize()</code> returns the natural size of the view.</li>
+<li><code>GetHeightForWidth()</code> returns the height for a given width. Invoked by the size negotiation algorithm if using a fixed width.</li>
+<li><code>GetWidthForHeight()</code> returns the width for a given height. Invoked by the size negotiation algorithm if using a fixed height.</li>
+<li>Override the <code>OnRelayout()</code> method to position and resize. The method is called during the relayout process at the end of the frame immediately after the new size has been set on the view, meaning after size negotiation is complete.</li>
+<li><code>OnSetResizePolicy()</code> is called when the resize policy is set on a view, and it allows deriving views to respond to changes in resize policy. The method can be overridden to receive notice that the resize policy has changed on the view and action can be taken.</li>
+</ul>
+<p>Size negotiation is enabled on views by default. To disable size negotiation, simply pass the <code>DisableSizeNegotiation</code> behavior flag into the view constructor. For more information, see <a href="#viewbehaviour">Setting View Behavior</a>.</p>
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/nui/css/snippet.css b/nui/css/snippet.css
new file mode 100644 (file)
index 0000000..f880409
--- /dev/null
@@ -0,0 +1,52 @@
+/* Pretty printing styles. Used with prettify.js. */
+
+/* SPAN elements with the classes below are added by prettyprint. */
+.pln { color: #000 }  /* plain text */
+
+@media screen {
+  .str { color: #793AFF }  /* string content */
+  .kwd { color: #7F0055 }  /* a keyword */
+  .com { color: green}  /* a comment */
+  .typ { color: #1C1C1C }  /* a type name */
+  .lit { color: black }  /* a literal value */
+  /* punctuation, lisp open bracket, lisp close bracket */
+  .pun, .opn, .clo { color: #1C1C1C}
+  .tag { color: #008 }  /* a markup tag name */
+  .atn { color: #606 }  /* a markup attribute name */
+  .atv { color: #080 }  /* a markup attribute value */
+  .dec, .var { color: #606 }  /* a declaration; a variable name */
+  .fun { color: red }  /* a function name */
+}
+
+/* Use higher contrast and text-weight for printable form. */
+@media print, projection {
+  .str { color: #060 }
+  .kwd { color: #006; font-weight: bold }
+  .com { color: #600; font-style: italic }
+  .typ { color: #404; font-weight: bold }
+  .lit { color: #044 }
+  .pun, .opn, .clo { color: #440 }
+  .tag { color: #006; font-weight: bold }
+  .atn { color: #404 }
+  .atv { color: #060 }
+}
+
+/* Put a border around prettyprinted code snippets. */
+pre.prettyprint { overflow: auto; padding: 2px; border: 1px solid #888 }
+
+/* Specify class=linenums on a pre to get line numbering */
+ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */
+li.L0,
+li.L1,
+li.L2,
+li.L3,
+li.L5,
+li.L6,
+li.L7,
+li.L8 { list-style-type: none }
+/* Alternate shading for lines */
+li.L1,
+li.L3,
+li.L5,
+li.L7,
+li.L9 { background: #eee }
diff --git a/nui/css/styles.css b/nui/css/styles.css
new file mode 100644 (file)
index 0000000..9ed4f63
--- /dev/null
@@ -0,0 +1,300 @@
+@charset "utf-8";
+
+body {
+       background: white;
+       color: #1C1C1C;
+       margin-right: 20px;
+       margin-left: 20px;
+       font-size: 9pt;
+       font-weight: normal;
+       font-family: Arial, Helvetica, sans-serif;
+}
+
+h1, h2, h3, h4, h5, h6, p, table, td, caption, th,  ol, dl, dd, footer {
+       font-family: Arial, Verdana, Helvetica, sans-serif
+       }
+
+/*     Set default font to 9 pt        */
+table, div, p, dl, td, caption, th, ul, ol, li, dd, pre, code {
+       font-size: 9pt;
+}
+       
+pre, code { 
+       font-family: "Courier New", Courier, monospace;
+       margin: 6px 1.5px;
+       padding: 1px 1px 1px 1px;
+       font-weight: normal;
+       font-style: normal;
+}
+
+h1 {font-size: 24pt; color: #0E437D;}
+h2 {font-size: 18pt; color: #0E437D;}
+h3 {font-size: 14pt; color: #1C1C1C;}
+h4 {font-size: 12pt; color: #1C1C1C;}
+h5 {font-size: 10pt; color: #1C1C1C;}
+       
+h1, h2, h3, h4, h5 {
+       font-weight: bold;
+       font-style: normal; 
+       line-height: normal; 
+       margin-top: 16pt;
+}
+
+caption { 
+       font-size: 9pt;
+       color: #1C1C1C;
+       font-weight: bold;
+       text-align: left;
+       margin-top: 20px;
+       margin-bottom: 0px;
+}
+
+ol  {
+       margin-bottom: 20px;
+}
+
+ul ul , ol ul, ul ol, ol ol{
+       margin-top: 10px;
+}
+
+ul li, ol li {
+       margin-bottom: 10px;
+}
+
+ol li p, ul li p {
+       font-size: 9pt;
+       font-weight: normal;
+       margin-bottom: 2px;
+       margin-top: 2px;
+}
+
+ol ol {
+       font-size: 9pt;
+       font-weight: normal;
+       list-style-type: lower-alpha;
+       color: #1C1C1C; 
+       border-style: none;
+       margin-top: 10px; 
+}
+
+ol ol li, ol ul li {
+       border-style: none;
+       margin-top: 5px;
+       font-size: 9pt;
+}
+
+ul {
+       font-size: 9pt;
+       font-weight: normal;
+       color: #1C1C1C;
+}
+
+
+/*     End of font face declarations   */
+
+/*     Set table borders and heading row background    */
+table {
+       border: 0px;
+       border-collapse: collapse;
+       width: 100%;
+       margin-top: 20px;
+       margin-bottom: 20px;
+       background: white;
+}
+
+th {
+       border-top: 2px solid #719cc7;
+       border-right: 1px solid #c6d9f1;
+       border-left: 1px solid #c6d9f1;
+       background-color: #f3f7fb;
+       padding: 4px;
+       color: #719cc7;
+       font-size: 9pt;
+       font-weight: bold;
+}      
+       
+td {
+       border: 1px solid #c6d9f1;
+       vertical-align:top;
+       padding: 3px 20px 5px 20px;
+       }
+       
+/*     Notes stand out using a light top & bottom borders with yellow background       */
+
+div.note {
+    background-color: #eeece1;
+    border: medium none;
+    color: #1c1c1c;
+    margin-bottom: 12px;
+    margin-top: 12px;
+    padding: 5px;
+}
+
+div.note > strong:first-child {
+    background-color: #ddd9c3;
+    border-bottom: 1px solid #719cc7;
+    border-right: medium none;
+    border-top: 2px solid #719cc7;
+    text-align: left;
+    color: #719cc7;
+    font-size: 9pt;
+    font-weight: bold;
+       margin: -4px -4px 4px -4px;  
+       padding: 4px 0px 4px 4px;
+       display: block; 
+       width: auto;
+}
+
+div.note * strong:after {
+       content: "\a ";
+    white-space: pre-line;
+}
+
+
+#toc-navigation {width: 20%; position: fixed; right: 17px; top: 0; bottom: 51px; /* overflow: auto; *//* min-width: 200px; *//* background: white; */z-index: 100;padding-top: 10px;/* padding-bottom: 88px; */margin-bottom: 89px;}
+#toc {padding: 0px 20px 5px 20px; /* border: 2px solid #567a9c; */ border-radius: 15px;position: absolute;top: 78px;bottom: 9px;overflow: auto;/* margin-bottom: 5px; */padding-bottom: 5px;border-bottom: 3px transparent solid;margin-left: 5px;}
+#main {width: 75%; height: 90%;}
+#container {width:100%;}
+#container #contents {padding:0px 0 20px; overflow: auto;position: fixed;top: 0;bottom: 0;margin-bottom: 64px;right: 200px;left: 20px;}
+body.no-toc #container #contents {right: 0;padding-right:30px;}
+body.no-toc #toc-navigation {width: auto;}
+body.no-toc .top {right: 19px; /* float:none; */ width: 28px;}
+body.no-toc #profile {float: right;right: -32px;}
+body.no-toc #profile p {padding: 0; margin: 0;}
+#container #contents:after {content: "."; display: block; height: 20px; clear: both; visibility: hidden;}
+       #container #contents>.content {/* width:75%; */min-width: 600px;/* right: 300px; *//* position: fixed; */padding-right: 5px;}
+       #container #contents>.content>.cont { margin-bottom:80px; padding-bottom:80px; }
+
+.devicespecs-util {float:right; margin-top:25px;}
+       .devicespecs-util ul.dutil {margin:0; padding-bottom:0; height: 11px; list-style-type:none;}
+       .devicespecs-util ul.dutil:after {content: "."; display: block; height: 0px; clear: both; visibility: hidden;}
+       .devicespecs-util ul.dutil li {float:left; margin-right:8px; padding-right:8px; background:url('../images/bg_util_bar.gif') no-repeat right center; color:#666;}
+       .devicespecs-util ul.dutil li.none {margin-right:0; padding-right:0; background-image:none;}
+       .devicespecs-util ul.dutil li a { font-size:11px; color:#666; line-height: 11px;}
+       .devicespecs-util ul.dutil li a:hover { color:#222; }
+       .devicespecs-util ul.dutil li a:active { color:#222; }
+
+ul.devicespecifications {clear:both; width:100%; margin:0; padding: 0;}
+ul.devicespecifications > li { width:100%; margin-top:0; padding-left:0; list-style-type:none; border:1px solid #799cd3; padding: 5px 0px 5px 0px;}
+ul.devicespecifications li div.devicespec-con {width:90%; margin:10px 0 20px 0; padding:0 14px; font-size: 13px;}
+ul.devicespecifications li div.devicespec-tit {/*height:22px;*/ padding-right: 71px; background-color:#ffffff; position: relative;}
+       ul.devicespecifications li div.devicespec-tit .items-tit { /*float:left;*/ margin:0 0 0 14px; padding:0; color:#567a9c; line-height: 22px; font-size: 14px; font-style:normal; font-weight: bold;}
+
+       ul.devicespecifications li div.devicespec-tit .items-tit-h2 { /*float:left;*/ margin: 0px 0px 0px 14px; padding:0; line-height: 22px; font-size: 18pt; color: #0E437D; font-style:normal; font-weight: bold;}
+       ul.devicespecifications li div.devicespec-tit .items-tit-h3 { /*float:left;*/ margin:0 0 0 14px; padding:0; line-height: 22px; font-size: 14pt; color: #1C1C1C; font-style:normal; font-weight: bold;}
+       ul.devicespecifications li div.devicespec-tit .items-tit-h4 { /*float:left;*/ margin:0 0 0 14px; padding:0; line-height: 22px; font-size: 12pt; color: #1C1C1C; font-style:normal; font-weight: bold;}
+
+       ul.devicespecifications li div.devicespec-tit > span {position: absolute; top: 0; right:0;background:#416cbb; display:block; height:22px; margin-right:0; border-left: solid 1px #7a9bd4; }
+       ul.devicespecifications li div.devicespec-tit > span a.bt-arr   {display:block; width: 55px; height:15px; margin-left:0; padding-top:5px; padding-left: 14px; text-align:left; background: url('../images/ico_arr_hidden.gif') 46px 9px no-repeat;}
+       ul.devicespecifications li div.devicespec-tit > span a.bt-arr em        {display:inline-block; height: 14px; line-height:11px; font-size:11px; color:#fff; font-style:normal; margin-right: 8px;}
+       ul.devicespecifications li div.devicespec-tit > span * {vertical-align:middle;}
+
+       ul.devicespecifications li div.devicespec-con ul.con-list { width:100%;  }
+       ul.devicespecifications li div.devicespec-con ul.con-list li {line-height: 18px; margin:0; padding:0 0 0 7px; background: url("../images/ico_bullet_2_7.gif") 0 8px no-repeat; }
+
+       
+.top {text-align: right;}
+.toc, ul.toc{
+       margin: 10px 0px 0px 0px;
+       padding-left: 13px;
+       list-style: disc;
+       font-size: 9pt;
+       line-height: 115%; 
+       }
+       
+.toc-title {
+       font-size: 12pt;
+       color: #0E437D; 
+       font-weight: bold;
+       font-style: normal; 
+       line-height: normal; 
+       margin-top: 16pt;
+}
+       
+a.top {
+       display:block; 
+       float: right; 
+       position:fixed;
+       width: 28px; 
+       height:89px; 
+       bottom:50px;
+       z-index: 101;
+       right: 19%;
+       }
+
+a img {border: 0;}
+       
+/*     Footer includes space and a gray line above             */
+#footer {
+       position: fixed;
+       /* width: 100%; */
+    bottom: 0px;
+       text-align: center;
+       border-top: 1px solid #CCCCCC;
+       background-color: #FFFFFF;      
+       left: 21px;  right: 21px;
+}
+
+.footer {font-size: 8pt;}
+
+p.Table {
+       text-align: center;
+       margin-top: 40px;
+       margin-bottom: -19px;
+       padding: 0;
+}
+       
+p.Table strong {
+       font-family: Arial, Verdana, Helvetica, sans-serif;
+       font-size: 9pt;
+       color: #1C1C1C;
+       font-weight: bold;
+}
+
+caption { 
+       font-size: 9pt;
+       color: #1C1C1C;
+       font-weight: bold;
+       text-align: center;
+       margin-top: 20px;
+       margin-bottom: 0px;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memitem {
+       padding: 0;
+}
+
+/* @end */
+
+.highlight {
+       background-color:#E2E2FF;
+}
+
+/* //Layout fixing */
+
+div#profile {
+    position: relative;
+}
+#profile p {
+       text-align: right;
+}
+
+div#toc_border {
+    border: 2px solid rgb(86, 122, 156);  border-top-left-radius: 15px;  border-top-right-radius: 15px;  border-bottom-right-radius: 15px;  border-bottom-left-radius: 15px;  height: 565px;
+}
+
+#contents li {
+       padding-top: 3px;
+       margin-top: 5px;
+       /* overflow: auto; */
+}
+
+p {
+       /* overflow: auto; */
+}
diff --git a/nui/flexcontainer.htm b/nui/flexcontainer.htm
new file mode 100644 (file)
index 0000000..868ca5b
--- /dev/null
@@ -0,0 +1,535 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>Flex Container</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#content-direction">ContentDirection</a></li>
+            <li><a href="#flex-direction">FlexDirection</a></li>
+            <li><a href="#flex-wrap">FlexWrap</a></li>
+            <li><a href="#justify-content">JustifyContent</a></li>
+            <li><a href="#align-items">AlignItems</a></li>
+            <li><a href="#align-content">AlignContent</a></li>
+            <li><a href="#custom-properties">Custom Properties Supported by Flex Items</a></li>
+            <li><a href="#layoutexample">FlexContainer Usage Example</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>Flex Container</h1>
+<p>A flex container contains items, such as buttons, text labels, and images.</p>
+
+<p><code>Flexbox</code> is a CSS3 Web layout model which allows responsive elements within a container, automatically arranged to different size screens or devices. The <code>FlexContainer</code> class implements a subset of the W3C <a href="https://www.w3.org/TR/css-flexbox-1/" target="_blank">CSS Flexible Box Layout Module Level 1</a> specification.</p>
+<p>The flex container has the ability to alter the width and/or height of its children (flex items), to optimally fill the available space on any display device. The container expands items to fill available free space, or shrinks them to prevent overflow.</p>
+<p>The following figure illustrates of the various directions and terms as applied to a flex container with the <code>FlexDirection</code> defined as <code>row</code>.</p>
+
+<p align="center"><strong>Figure: Flex container diagram</strong></p>
+<p align="center"><img src="images/flex-container.jpg" alt="Flex container diagram" /></p>
+
+<p>NUI supports the following subset of <code>Flexbox</code> properties:</p>
+<ul>
+<li><a href="#content-direction">ContentDirection</a></li>
+<li><a href="#flex-direction">FlexDirection</a></li>
+<li><a href="#flex-wrap">FlexWrap</a></li>
+<li><a href="#justify-content">JustifyContent</a></li>
+<li><a href="#align-items">AlignItems</a></li>
+<li><a href="#align-content">AlignContent</a></li>
+</ul>
+
+<h2 id="content-direction">ContentDirection</h2>
+<p>The <code>ContentDirection</code> property specifies the primary direction in which content is ordered on a line.</p>
+
+<p align="center" class="Table"><strong>Table: ContentDirection values</strong></p>
+<table>
+<thead>
+<tr>
+    <th>LTR (left-to-right)</th>
+    <th>RTL (right-to-left)</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><img src="images/content-direction-ltr.jpg" alt="ContentDirection LTR" /></td>
+    <td><img src="images/content-direction-rtl.jpg" alt="ContentDirection RTL" /></td>
+</tr>
+</tbody>
+</table>
+<p>The possible values for this property are:</p>
+<table>
+<thead>
+<tr>
+    <th>Property value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Inherit</code></td>
+    <td>Inherits the direction from the parent</td>
+</tr>
+<tr>
+    <td><code>LTR</code></td>
+    <td>From left to right</td>
+</tr>
+<tr>
+    <td><code>RTL</code></td>
+    <td>From right to left</td>
+</tr>
+</tbody>
+</table>
+<h3>Usage</h3>
+<pre class="prettyprint">
+FlexContainer flexContainer = new FlexContainer();
+flexContainer.ContentDirection = FlexContainer.ContentDirectionType.RTL;
+</pre>
+
+<h2 id="flex-direction">FlexDirection</h2>
+<p>The <code>FlexDirection</code> property specifies the direction of the main axis which determines the direction in which flex items are laid out.</p>
+<p align="center"><strong>Figure: FlexDirection values</strong></p>
+<p align="center"><img src="images/flex-direction.jpg" alt="FlexDirection values" /></p>
+<p>The possible values for this property are:</p>
+<table>
+<thead>
+<tr>
+    <th>Property value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Column</code></td>
+    <td>Flex items are laid out vertically as a column</td>
+</tr>
+<tr>
+    <td><code>ColumnReverse</code></td>
+    <td>Flex items are laid out vertically as a column, but in reverse order</td>
+</tr>
+<tr>
+    <td><code>Row</code></td>
+    <td>Flex items are laid out horizontally as a row</td>
+</tr>
+<tr>
+    <td><code>RowReverse</code></td>
+    <td>Flex items are laid out horizontally as a row, but in reverse order</td>
+</tr>
+</tbody>
+</table>
+<h3>Usage</h3>
+<pre class="prettyprint">
+FlexContainer flexContainer = new FlexContainer();
+flexContainer.FlexDirection = FlexContainer.FlexDirectionType.RowReverse;
+</pre>
+
+<h2 id="flex-wrap">FlexWrap</h2>
+<p>The <code>FlexWrap</code> property specifies whether the flex items must wrap if there is not enough room for them on one flex line.</p>
+<p align="center"><strong>Figure: FlexWrap values</strong></p>
+<p align="center"><img src="images/flex-wrap.jpg" alt="FlexWrap values" /></p>
+<p>The possible values for this property are:</p>
+<table>
+<thead>
+<tr>
+    <th>Property value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>NoWrap</code></td>
+    <td>Flex items are laid out in single line (shrunk to fit the flex container along the main axis)</td>
+</tr>
+<tr>
+    <td><code>Wrap</code></td>
+    <td>Flex items are laid out in multiple lines if needed</td>
+</tr>
+</tbody>
+</table>
+<h3>Usage</h3>
+<pre class="prettyprint">
+FlexContainer flexContainer = new FlexContainer();
+flexContainer.FlexWrap = FlexContainer.WrapType.NoWrap;
+</pre>
+
+<h2 id="justify-content">JustifyContent</h2>
+<p>The <code>JustifyContent</code> property specifies the alignment of flex items when they do not use all available space on the main axis.</p>
+<p align="center"><strong>Figure: JustifyContent values</strong></p>
+<p align="center"><img src="images/justify-content.jpg" alt="JustifyContent values" /></p>
+<p>The possible values for this property are:</p>
+<table>
+<thead>
+<tr>
+    <th>Property value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>JustifyFlexStart</code></td>
+    <td>Flex items are positioned at the beginning of the container</td>
+</tr>
+<tr>
+    <td><code>JustifyCenter</code></td>
+    <td>Flex items are positioned at the center of the container</td>
+</tr>
+<tr>
+    <td><code>JustifyFlexEnd</code></td>
+    <td>Flex items are positioned at the end of the container</td>
+</tr>
+<tr>
+    <td><code>JustifySpaceBetween</code></td>
+    <td>Flex items are positioned with equal space between the lines</td>
+</tr>
+<tr>
+    <td><code>JustifySpaceAround</code></td>
+    <td>Flex items are positioned with equal space before, between, and after the lines</td>
+</tr>
+    </tbody>
+</table>
+<h3>Usage</h3>
+<pre class="prettyprint">
+FlexContainer flexContainer = new FlexContainer();
+flexContainer.JustifyContent = FlexContainer.Justification.JustifySpaceBetween;
+</pre>
+
+<h2 id="align-items">AlignItems</h2>
+<p>The <code>AlignItems</code> property specifies the alignment of flex items when they do not use all available space on the cross axis.</p>
+<p align="center"><strong>Figure: AlignItems values</strong></p>
+<p align="center"><img src="images/align-items.jpg" alt="AlignItems values" /></p>
+<p>The possible values for this property are:</p>
+<table>
+<thead>
+<tr>
+    <th>Property value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>AlignAuto</code></td>
+    <td>Inherits the alignment from the parent (only valid for the <a href="#align-self">AlignSelf</a> property)</td>
+</tr>
+<tr>
+    <td><code>AlignFlexStart</code></td>
+    <td>Items are aligned at the beginning of the container</td>
+</tr>
+<tr>
+    <td><code>AlignCenter</code></td>
+    <td>Items are aligned at the center of the container</td>
+</tr>
+<tr>
+    <td><code>AlignFlexEnd</code></td>
+    <td>Items are aligned at the end of the container</td>
+</tr>
+<tr>
+    <td><code>AlignStretch</code></td>
+    <td>Items are stretched to fit the container</td>
+</tr>
+</tbody>
+</table>
+<h3>Usage</h3>
+<pre class="prettyprint">
+FlexContainer flexContainer = new FlexContainer();
+flexContainer.AlignItems = FlexContainer.Alignment.AlignFlexStart;
+</pre>
+
+<h2 id="align-content">AlignContent</h2>
+<p>The <code>AlignContent</code> property specifies the alignment of flex lines when they do not use all available space on the cross axis. It works when there are multiple lines.</p>
+<p align="center"><strong>Figure: AlignContent values</strong></p>
+<p align="center"><img src="images/align-content.jpg" alt="AlignContent values" /></p>
+<p>The possible values for this property are:</p>
+<table>
+<thead>
+<tr>
+    <th>Property value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>AlignAuto</code></td>
+    <td>Inherits the alignment from the parent (only valid for the <a href="#align-self">AlignSelf</a> property)</td>
+</tr>
+<tr>
+    <td><code>AlignFlexStart</code></td>
+    <td>Items are aligned at the beginning of the container</td>
+</tr>
+<tr>
+    <td><code>AlignCenter</code></td>
+    <td>Items are aligned at the center of the container</td>
+</tr>
+<tr>
+    <td><code>AlignFlexEnd</code></td>
+    <td>Items are aligned at the end of the container</td>
+</tr>
+<tr>
+    <td><code>AlignStretch</code></td>
+    <td>Items are stretched to fit the container</td>
+</tr>
+</tbody>
+</table>
+<h3>Usage</h3>
+<pre class="prettyprint">
+FlexContainer flexContainer = new FlexContainer();
+flexContainer.AlignContent = FlexContainer.Alignment.AlignFlexEnd;
+</pre>
+
+<h2 id="custom-properties">Custom Properties Supported by Flex Items</h2>
+<ul>
+<li><a href="#flex">Flex</a></li>
+<li><a href="#align-self">AlignSelf</a></li>
+<li><a href="#flex-margin">FlexMargin</a></li>
+</ul>
+
+<p>These non-animatable properties are registered dynamically to each child which is to be added to the flex container, and once added their values cannot be changed.</p>
+<p>When a view is added to the flex container, these properties are checked to decide how to lay out the view inside the flex container.</p>
+
+<h3 id="flex">Flex</h3>
+<p>By default, the items in the flex container are not flexible. Setting the <code>Flex</code> property makes the item flexible, which means the item can alter its width/height in order to receive the specified proportion of the free space in the flex container. If all items in the flex container use this pattern, their sizes are proportional to the specified flex factor. Flex items do not shrink below their minimum size (if set using the <code>View</code> <code>MinimumSize()</code> method).</p>
+<p align="center"><strong>Figure: Flex property</strong></p>
+<p align="center"><img src="images/flex.jpg" alt="Flex property" /></p>
+<h4>Usage</h4>
+<p>Here is the example code for items to achieve the proportion of free space as illustrated above.</p>
+<pre class="prettyprint">
+// Create the flex container
+FlexContainer flexContainer = new FlexContainer();
+
+// Set the flex direction to lay out the items horizontally
+flexContainer.FlexDirection = FlexContainer.FlexDirectionType.Row;
+
+// Create flex items and set the proportion
+View item1 = new View();
+item1.Flex = 1.0f;
+flexContainer.Add(item1);
+
+View item2 = new View();
+item2.Flex = 3.0f;
+flexContainer.Add(item2);
+
+View item3 = new View();
+item3.Flex = 1.0f;
+flexContainer.Add(item3);
+
+View item4 = new View();
+item4.Flex = 2.0f;
+flexContainer.Add(item4);
+
+View item5 = new View();
+item5.Flex = 1.0f;
+flexContainer.Add(item5);
+</pre>
+
+<h3 id="align-self">AlignSelf</h3>
+<p>The <code>AlignSelf</code> property specifies how the item aligns along the cross axis. If set, this property overrides the default alignment for all items defined by the container’s <a href="#align-items">AlignItems</a> property.</p>
+<p align="center"><strong>Figure: AlignSelf property</strong></p>
+<p align="center"><img src="images/align-self.jpg" alt="AlignSelf property" /></p>
+<h4>Usage</h4>
+<p>Below is the example code for the items to achieve the alignment on the cross axis as illustrated above.</p>
+<pre class="prettyprint">
+// Create the flex container
+FlexContainer flexContainer = new FlexContainer();
+
+// Set the flex direction to lay out the items horizontally
+flexContainer.FlexDirection = FlexContainer.FlexDirectionType.Row;
+
+// Set the items to be aligned at the beginning of the container on the cross axis by default
+flexContainer.AlignItems = FlexContainer.Alignment.AlignFlexStart;
+
+// Create flex items and add them to the flex container
+View item1 = new View();
+item1.AlignSelf = FlexContainer.Alignment.AlignCenter; // Align item1 at the center of the container
+flexContainer.Add(item1);
+
+View item2 = new View();
+flexContainer.Add(item2); // item2 is aligned at the beginning of the container
+
+View item3 = new View();
+item3.AlignSelf = FlexContainer.Alignment.AlignFlexEnd); // Align item3 at the bottom of the container
+flexContainer.Add(item3);
+
+View item4 = new View();
+flexContainer.Add(item4); // item4 is aligned at the beginning of the container
+</pre>
+
+<h2 id="flex-margin">FlexMargin</h2>
+<p>Each flex item inside the flex container is treated as a box (in CSS terms) made up of:</p>
+<ul>
+<li>Content: The content of the item.</li>
+<li>Padding: The space around the content (inside the border) of the item.</li>
+<li>Border: The border that goes around the padding and the content of the item.</li>
+<li>Margin: The space outside the border.</li>
+</ul>
+
+<p align="center"><strong>Figure: Flex item inside a container</strong></p>
+<p align="center"><img src="images/flex-margin.jpg" alt="Flex item inside a container" /></p>
+<p>In NUI, the size of the flex item = content size + padding + border.</p>
+<p>The <code>FlexMargin</code> property specifies the space around the flex item.</p>
+<h3>Usage</h3>
+<pre class="prettyprint">
+// Create the flex container
+FlexContainer flexContainer = new FlexContainer();
+
+// Create flex item
+View item = new View();
+
+// Add the margin around the item
+item.FlexMargin = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
+
+// Add the item to the container
+flexContainer.Add(item);
+</pre>
+
+<h2 id="layoutexample">FlexContainer Usage Example</h2>
+<p>This example creates a Gallery-like layout (as shown in the following figure) using <code>FlexContainer</code>.</p>
+<p align="center"><strong>Figure: FlexContainer usage example</strong></p>
+<p><img src="images/flexbox-demo.jpg" alt="FlexContainer usage example" /></p>
+<ol>
+<li>Create a flex container as the whole view, and set its resize policy to <code>FillToParent</code> (the parent is the <code>Window</code>):
+<pre class="prettyprint">
+// Create the main flex container
+FlexContainer flexContainer = new FlexContainer();
+flexContainer.ParentOrigin = ParentOrigin.TopLeft;
+flexContainer.PivotPoint = PivotPoint.TopLeft;
+flexContainer.WidthResizePolicy = ResizePolicyType.FillToParent;
+flexContainer.HeightResizePolicy = ResizePolicyType.FillToParent;
+flexContainer.BackgroundColor = Color.White; // Set the background color to be white
+
+// Add the flex container to the window
+Window.Instance.Add(flexContainer);
+</pre></li>
+
+<li>Set the flex direction of this main container to <code>Column</code>, to display the toolbar and content vertically:
+<pre class="prettyprint">
+// Display toolbar and content vertically
+flexContainer.FlexDirection = FlexContainer.FlexDirectionType.Column;
+</pre>
+</li>
+
+<li>Create a flex container for the toolbar and add it to the main container. Because the flex direction in the main container is <code>Column</code>, the toolbar is arranged on the top of the main container.
+<pre class="prettyprint">
+// Create the toolbar
+FlexContainer toolBar = new FlexContainer();
+toolBar.ParentOrigin = ParentOrigin.TopLeft );
+toolBar.PivotPoint = PivotPoint.TopLeft;
+toolBar.BackgroundColor = Color.Cyan; // Set the background color for the toolbar
+
+// Add the toolbar to the main container
+flexContainer.Add(toolBar);
+</pre>
+</li>
+<li>To display the buttons and title horizontally, and align them vertically to the center of the toolbar, set the toolbar flex direction to <code>Row</code>, and set its <code>alignItems</code> property to <code>Center</code>. To have the toolbar occupy 10 percent of the whole vertical space, and the content to occupy the rest, set the <code>Flex</code> property accordingly:
+<pre class="prettyprint">
+toolBar.FlexDirection = FlexContainer.FlexDirectionType.Row; // Display toolbar items horizontally
+toolBar.AlignItems = FlexContainer.Alignment.AlignCenter; // Center toolbar items vertically
+toolBar.Flex = 0.1f; // 10 percent of available space in the cross axis
+</pre>
+</li>
+<li>Create a third flex container as the content area in the bottom of the main container, to display the image. Items inside it are horizontally and vertically centered to align the image in the center of the content area.
+<pre class="prettyprint">
+// Create the content area
+FlexContainer content = new FlexContainer();
+content.ParentOrigin = ParentOrigin.TopLeft;
+content.PivotPoint = PivotPoint.TopLeft;
+content.FlexDirection = FlexContainer.FlexDirectionType.Row // Display items horizontally
+content.JustifyContent = FlexContainer.Justification.JustifyCenter; // Center toolbar items horizontally
+content.AlignItems = FlexContainer.Alignment.AlignCenter; // Center toolbar items vertically
+content.Flex = 0.9f; // 90 percent of available space in the cross axis
+
+// Add the content area to the main container
+flexContainer.Add(content);
+</pre>
+</li>
+<li>Add items to the toolbar. The toolbar has 1 button on the left, 1 button on the right, and a title always in the center (regardless of the screen size). To achieve that, make the title flexible so that it automatically takes all the available horizontal space left. Also add some space around the items with the <code>FlexMargin</code> property, so that the layout looks nicer.
+<pre class="prettyprint">
+// Add a button to the left of the toolbar
+PushButton prevButton = new PushButton();
+prevButton.ParentOrigin = ParentOrigin.TopLeft;
+prevButton.PivotPoint = PivotPoint.TopLeft;
+prevButton.MinimumSize = new Vector2( 100.0f, 60.0f ); // This is the minimum size the button should keep
+prevButton.FlexMargin = new Vector4(10.0f, 10.0f, 10.0f, 10.0f); // Set 10 pixel margin around the button
+toolBar.Add(prevButton);
+
+// Set the button text
+PropertyMap labelMap = new PropertyMap();
+labelMap.Add("text", new PropertyValue("Prev"));
+labelMap.Add("textColor", new PropertyValue(Color.Black));
+prevButton.Label = labelMap;
+
+// Add a title to the center of the toolbar
+TextLabel title = new TextLabel( "Gallery" );
+title.ParentOrigin = ParentOrigin.TopLeft;
+title.PivotPoint = PivotPoint.TopLeft;
+title.WidthResizePolicy = ResizePolicyType.UseNaturalSize;
+title.HeightResizePolicy = ResizePolicyType.UseNaturalSize;
+title.HorizontalAlignment = HorizontalAlignment.Center;
+title.VerticalAlignment = VerticalAlignment.Center;
+title.Flex = 1.0f; // Take all the available space left apart from the two buttons
+title.FlexMargin = new Vector4(10.0f, 10.0f, 10.0f, 10.0f); // Set 10 pixel margin around the title
+toolBar.Add(title);
+
+// Add a button to the right of the toolbar
+PushButton nextButton = new PushButton();
+nextButton.ParentOrigin = ParentOrigin.TopLeft;
+nextButton.PivotPoint = PivotPoint.TopLeft;
+nextButton.MinimumSize = new Vector2( 100.0f, 60.0f ); // This is the minimum size the button should keep
+nextButton.FlexMargin = new Vector4(10.0f, 10.0f, 10.0f, 10.0f); // Set 10 pixel margin around the button
+toolBar.Add(nextButton);
+
+// Set the button text
+PropertyMap labelMap2 = new PropertyMap();
+labelMap2.Add("text", new PropertyValue("Next"));
+labelMap2.Add("textColor", new PropertyValue(Color.Black));
+nextButton.Label = labelMap2;
+</pre>
+<p>The above settings enable the application to run on different-sized devices, or when changing the screen orientation. The toolbar does not expand or shrink based on the available space and the title is always in the center, therefore the layout of the toolbar remains the same.</p>
+</li>
+
+<li>Finally, add the image to the content area:
+<pre class="prettyprint">
+// Add an image to the center of the content area
+ImageView imageView = new ImageView( "image.jpg" );
+imageView.ParentOrigin = ParentOrigin.TopLeft;
+imageView.PivotPoint = PivotPoint.TopLeft;
+content.Add(imageView);
+</pre>
+</li>
+</ol>
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
diff --git a/nui/hello_world.htm b/nui/hello_world.htm
new file mode 100644 (file)
index 0000000..f0acf1d
--- /dev/null
@@ -0,0 +1,258 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>NUI Hello World Tutorial</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#tutorial">Tutorial Details</a></li>
+            <li><a href="#fullcode">Full Example Source Code</a></li>
+            <li><a href="#output">Example Output</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>NUI Hello World Tutorial</h1>
+<p>The tutorial shows how to create and display "Hello World" using a text label.</p>
+<p>For an introduction to NUI, see the <a href="NUIoverview.htm">NUI Overview</a>.</p>
+
+<h2 id="tutorial">Tutorial Details</h2>
+<p>The following steps are required to display text:</p>
+<ol>
+<li>Initialize the NUI library.</li>
+<li>Create a view with a text label.</li>
+<li>Add the text label to the application main window.</li>
+</ol>
+
+<p>This tutorial also demonstrates the triggering of the <code>Touch</code> window application event.</p>
+
+<h3>Namespaces</h3>
+<p>The required system and NUI namespaces are imported through the following <code>using</code> declarations:</p>
+<pre class="prettyprint">
+using System;
+using System.Runtime.InteropServices;
+using Tizen.NUI;
+using Tizen.NUI.UIComponents;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Constants;
+</pre>
+<p>This application is scoped to the <code>HelloTest</code> namespace.</p>
+
+<h3>Main Method</h3>
+<p>The <code>Main()</code> method consists of 2 steps:</p>
+<ol>
+<li>Create the application through the default constructor:
+<pre class="prettyprint">
+Example example = new Example();
+</pre>
+<p>The application is derived from the <code>NUIApplication</code> class:</p>
+<pre class="prettyprint">
+class Example : NUIApplication
+</pre>
+<p>The <code>NUIApplication</code> class also includes constructors enabling application creation with stylesheets and window modes.</p>
+</li>
+<li>Start the application main loop.
+<p>The main loop must be started to run the application. This ensures that images are displayed, and that events and signals are dispatched and captured.</p>
+<pre class="prettyprint">
+example.Run(args);
+</pre>
+<p>In this simple tutorial, the <code>Main()</code> method resides within the class. For significant application development, the <code>Main()</code> method must be placed in a separate <code>.cs</code> file.</p>
+</li>
+</ol>
+
+<h3>Creation Method - OnCreate()</h3>
+<p>The <code>OnCreate</code> method of the Hello World application overrides the NUIApplication <code>OnCreate</code> method: </p>
+<pre class="prettyprint">
+protected override void OnCreate()
+{
+    base.OnCreate();
+    Initialize();
+}
+</pre>
+<p>Hence you can incorporate the required initialization behavior in your application.</p>
+
+<div class="note">
+<strong>Note</strong>
+Calling <code>base.OnCreate()</code> is necessary, to invoke the <code>Created</code> event.
+</div>
+
+<h3>Initialization Method - Initialize()</h3>
+<p>The initialization code contains the following simple steps:</p>
+<ol>
+<li>Create the text label member variable:
+<pre class="prettyprint">
+_text = new TextLabel("Hello World");
+</pre>
+</li>
+<li>Position the text in the centre of the application window. The <code>ParentOrigin</code> property defines a point within the parent view area. If the text label size is not specified, the text label is at least as wide as the screen.
+<pre class="prettyprint">
+_text.ParentOrigin = ParentOrigin.CenterLeft;
+</pre>
+</li>
+<li>Align the text horizontally to the center of the available area:
+<pre class="prettyprint">
+_text.HorizontalAlignment = HorizontalAlignment.Center;
+</pre>
+</li>
+<li>Set the label background color to illustrate the label width:
+<pre class="prettyprint">
+_text.BackgroundColor = Color.Red;
+</pre>
+</li>
+<li>Set the text size (the size of the font is given in points):
+<pre class="prettyprint">
+_text.PointSize = 32.0f;
+</pre>
+<p>For more information on key properties of the <code>TextLabel</code> class, see <a href="textlabel.htm">TextLabel</a>.</p>
+</li>
+<li>Add the <code>TouchEvent</code> event handler to the main application window. This event handler is invoked on any click in the application window.
+<pre class="prettyprint">
+Window window = Window.Instance;
+window.TouchEvent += WindowTouched;
+</pre>
+<p>Alternatively, you can add the event handler using the lambda expression syntax:</p>
+<pre class="prettyprint">
+window.TouchEvent += (object src, Window.TouchEventArgs args) =&gt;
+{
+    _text.Text = "I have been touched!";
+};
+</pre>
+</li>
+<li>Add the text label to the root layer:
+<pre class="prettyprint">
+window.Add(_text);
+</pre>
+<p>The window adds the view to the root layer.</p>
+</li>
+</ol>
+
+<h3>TouchEvent event handler</h3>
+<p>The user can click anywhere in the application window to change the text in the label:</p>
+<pre class="prettyprint">
+private void WindowTouched(object sender, Window.TouchEventArgs e)
+{
+    _text.Text = "I have been touched!";
+}
+</pre>
+
+<h3>Closing the Application - OnTerminate()</h3>
+<p><code>OnTerminate</code> is invoked when the application is about to terminate and when the window close button is clicked.</p>
+<pre class="prettyprint">
+protected override void OnTerminate()
+{
+    base.OnTerminate();
+    _text = null;
+}
+</pre>
+
+<div class="note">
+<strong>Note</strong>
+Calling <code>base.OnTerminate()</code> is necessary to invoke the <code>Deleted</code> event.
+</div>
+
+<h3>Building and Running the Application</h3>
+<p>To build and run the application, use Visual Studio on a Windows platform, and Visual Studio Code on Linux.</p>
+<p>The <a href="setup_ubuntu.htm">NUI development setup guide</a> describes setting up the NUI development environment on Ubuntu, using this tutorial as an example project.</p>
+
+<h2 id="fullcode">Full Example Source Code</h2>
+<pre class="prettyprint">
+using System;
+using System.Runtime.InteropServices;
+using Tizen.NUI;
+using Tizen.NUI.UIComponents;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Constants;
+
+namespace HelloTest
+{
+    class Example : NUIApplication
+    {
+        TextLabel _text;
+
+        protected override void OnCreate()
+        {
+            base.OnCreate();
+            Initialize();
+        }
+
+        private void Initialize()
+        {
+            // Add a simple text label to the main window
+            _text = new TextLabel("Hello World");
+            _text.ParentOrigin = ParentOrigin.CenterLeft;
+            _text.HorizontalAlignment = HorizontalAlignment.Center;
+           _text.BackgroundColor = Color.Red;
+            _text.PointSize = 32.0f;
+
+            // Connect the signal callback for a touch signal
+            Window window = Window.Instance;
+            window.TouchEvent += WindowTouched;
+
+            window.Add(_text);
+        }
+
+        // Callback for main window touched signal handling
+        private void WindowTouched(object sender, Window.TouchEventArgs e)
+        {
+            _text.Text = "I have been touched!";
+        }
+
+        protected override void OnTerminate()
+        {
+            base.OnTerminate();
+            _text = null;
+        }
+
+        static void Main(string[] args)
+        {
+            Example example = new Example();
+            example.Run(args);
+        }
+    }
+}
+</pre>
+
+<h2 id="output">Example Output</h2>
+<p>After running the example, the following output should appear:</p>
+<p><img alt="Hello world" src="images/hello-world.png"/></p>
+
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
diff --git a/nui/images/ArabicBegin.png b/nui/images/ArabicBegin.png
new file mode 100644 (file)
index 0000000..56dcec1
Binary files /dev/null and b/nui/images/ArabicBegin.png differ
diff --git a/nui/images/ArabicCenter.png b/nui/images/ArabicCenter.png
new file mode 100644 (file)
index 0000000..cbc77d3
Binary files /dev/null and b/nui/images/ArabicCenter.png differ
diff --git a/nui/images/ArabicEnd.png b/nui/images/ArabicEnd.png
new file mode 100644 (file)
index 0000000..e35e1a8
Binary files /dev/null and b/nui/images/ArabicEnd.png differ
diff --git a/nui/images/AutoScroll.gif b/nui/images/AutoScroll.gif
new file mode 100644 (file)
index 0000000..663cd3b
Binary files /dev/null and b/nui/images/AutoScroll.gif differ
diff --git a/nui/images/ContactView.png b/nui/images/ContactView.png
new file mode 100644 (file)
index 0000000..b585197
Binary files /dev/null and b/nui/images/ContactView.png differ
diff --git a/nui/images/HelloWorld.png b/nui/images/HelloWorld.png
new file mode 100644 (file)
index 0000000..aa40f20
Binary files /dev/null and b/nui/images/HelloWorld.png differ
diff --git a/nui/images/ImageView.png b/nui/images/ImageView.png
new file mode 100644 (file)
index 0000000..ca78f3a
Binary files /dev/null and b/nui/images/ImageView.png differ
diff --git a/nui/images/LatinBegin.png b/nui/images/LatinBegin.png
new file mode 100644 (file)
index 0000000..bec2507
Binary files /dev/null and b/nui/images/LatinBegin.png differ
diff --git a/nui/images/LatinCenter.png b/nui/images/LatinCenter.png
new file mode 100644 (file)
index 0000000..ef5aa57
Binary files /dev/null and b/nui/images/LatinCenter.png differ
diff --git a/nui/images/LatinEnd.png b/nui/images/LatinEnd.png
new file mode 100644 (file)
index 0000000..4e22cbc
Binary files /dev/null and b/nui/images/LatinEnd.png differ
diff --git a/nui/images/NUI_Class_Hierarchy.png b/nui/images/NUI_Class_Hierarchy.png
new file mode 100644 (file)
index 0000000..53bf356
Binary files /dev/null and b/nui/images/NUI_Class_Hierarchy.png differ
diff --git a/nui/images/RedText.png b/nui/images/RedText.png
new file mode 100644 (file)
index 0000000..f2fe9fe
Binary files /dev/null and b/nui/images/RedText.png differ
diff --git a/nui/images/SystemProxySettings.png b/nui/images/SystemProxySettings.png
new file mode 100644 (file)
index 0000000..3f338d4
Binary files /dev/null and b/nui/images/SystemProxySettings.png differ
diff --git a/nui/images/TextLabelTopLeft.png b/nui/images/TextLabelTopLeft.png
new file mode 100644 (file)
index 0000000..ad8f492
Binary files /dev/null and b/nui/images/TextLabelTopLeft.png differ
diff --git a/nui/images/TextWith1pxUnderline.png b/nui/images/TextWith1pxUnderline.png
new file mode 100644 (file)
index 0000000..082d19e
Binary files /dev/null and b/nui/images/TextWith1pxUnderline.png differ
diff --git a/nui/images/TextWithBiggerShadow.png b/nui/images/TextWithBiggerShadow.png
new file mode 100644 (file)
index 0000000..921f745
Binary files /dev/null and b/nui/images/TextWithBiggerShadow.png differ
diff --git a/nui/images/TextWithColorShadow.png b/nui/images/TextWithColorShadow.png
new file mode 100644 (file)
index 0000000..a82635d
Binary files /dev/null and b/nui/images/TextWithColorShadow.png differ
diff --git a/nui/images/TextWithColorUnderline.png b/nui/images/TextWithColorUnderline.png
new file mode 100644 (file)
index 0000000..42ec4ff
Binary files /dev/null and b/nui/images/TextWithColorUnderline.png differ
diff --git a/nui/images/TextWithShadow.png b/nui/images/TextWithShadow.png
new file mode 100644 (file)
index 0000000..1cde8d2
Binary files /dev/null and b/nui/images/TextWithShadow.png differ
diff --git a/nui/images/TextWithUnderline.png b/nui/images/TextWithUnderline.png
new file mode 100644 (file)
index 0000000..530920a
Binary files /dev/null and b/nui/images/TextWithUnderline.png differ
diff --git a/nui/images/VSC.png b/nui/images/VSC.png
new file mode 100644 (file)
index 0000000..58246e9
Binary files /dev/null and b/nui/images/VSC.png differ
diff --git a/nui/images/VSC_ExtandSettings.png b/nui/images/VSC_ExtandSettings.png
new file mode 100644 (file)
index 0000000..a0d1b44
Binary files /dev/null and b/nui/images/VSC_ExtandSettings.png differ
diff --git a/nui/images/align-content.jpg b/nui/images/align-content.jpg
new file mode 100644 (file)
index 0000000..6f99507
Binary files /dev/null and b/nui/images/align-content.jpg differ
diff --git a/nui/images/align-items.jpg b/nui/images/align-items.jpg
new file mode 100644 (file)
index 0000000..a9ccb17
Binary files /dev/null and b/nui/images/align-items.jpg differ
diff --git a/nui/images/align-self.jpg b/nui/images/align-self.jpg
new file mode 100644 (file)
index 0000000..ea29610
Binary files /dev/null and b/nui/images/align-self.jpg differ
diff --git a/nui/images/animated-image-visual.gif b/nui/images/animated-image-visual.gif
new file mode 100644 (file)
index 0000000..ddc3312
Binary files /dev/null and b/nui/images/animated-image-visual.gif differ
diff --git a/nui/images/animated-path.png b/nui/images/animated-path.png
new file mode 100644 (file)
index 0000000..04ae2a6
Binary files /dev/null and b/nui/images/animated-path.png differ
diff --git a/nui/images/bevelled-cube-high.png b/nui/images/bevelled-cube-high.png
new file mode 100644 (file)
index 0000000..d6676db
Binary files /dev/null and b/nui/images/bevelled-cube-high.png differ
diff --git a/nui/images/bevelled-cube-low.png b/nui/images/bevelled-cube-low.png
new file mode 100644 (file)
index 0000000..d76c836
Binary files /dev/null and b/nui/images/bevelled-cube-low.png differ
diff --git a/nui/images/border-visual.png b/nui/images/border-visual.png
new file mode 100644 (file)
index 0000000..05834f7
Binary files /dev/null and b/nui/images/border-visual.png differ
diff --git a/nui/images/btn_top.gif b/nui/images/btn_top.gif
new file mode 100644 (file)
index 0000000..d35e824
Binary files /dev/null and b/nui/images/btn_top.gif differ
diff --git a/nui/images/color-visual.png b/nui/images/color-visual.png
new file mode 100644 (file)
index 0000000..2bfe28f
Binary files /dev/null and b/nui/images/color-visual.png differ
diff --git a/nui/images/cone.png b/nui/images/cone.png
new file mode 100644 (file)
index 0000000..6437a0e
Binary files /dev/null and b/nui/images/cone.png differ
diff --git a/nui/images/conical-frustrum.png b/nui/images/conical-frustrum.png
new file mode 100644 (file)
index 0000000..000c74b
Binary files /dev/null and b/nui/images/conical-frustrum.png differ
diff --git a/nui/images/content-direction-ltr.jpg b/nui/images/content-direction-ltr.jpg
new file mode 100644 (file)
index 0000000..2758670
Binary files /dev/null and b/nui/images/content-direction-ltr.jpg differ
diff --git a/nui/images/content-direction-rtl.jpg b/nui/images/content-direction-rtl.jpg
new file mode 100644 (file)
index 0000000..1dd4856
Binary files /dev/null and b/nui/images/content-direction-rtl.jpg differ
diff --git a/nui/images/cube.png b/nui/images/cube.png
new file mode 100644 (file)
index 0000000..af04b30
Binary files /dev/null and b/nui/images/cube.png differ
diff --git a/nui/images/cylinder.png b/nui/images/cylinder.png
new file mode 100644 (file)
index 0000000..d4efd00
Binary files /dev/null and b/nui/images/cylinder.png differ
diff --git a/nui/images/flex-container.jpg b/nui/images/flex-container.jpg
new file mode 100644 (file)
index 0000000..55eb4aa
Binary files /dev/null and b/nui/images/flex-container.jpg differ
diff --git a/nui/images/flex-direction.jpg b/nui/images/flex-direction.jpg
new file mode 100644 (file)
index 0000000..bd7541c
Binary files /dev/null and b/nui/images/flex-direction.jpg differ
diff --git a/nui/images/flex-margin.jpg b/nui/images/flex-margin.jpg
new file mode 100644 (file)
index 0000000..2430513
Binary files /dev/null and b/nui/images/flex-margin.jpg differ
diff --git a/nui/images/flex-wrap.jpg b/nui/images/flex-wrap.jpg
new file mode 100644 (file)
index 0000000..aca0f40
Binary files /dev/null and b/nui/images/flex-wrap.jpg differ
diff --git a/nui/images/flex.jpg b/nui/images/flex.jpg
new file mode 100644 (file)
index 0000000..bd5574f
Binary files /dev/null and b/nui/images/flex.jpg differ
diff --git a/nui/images/flexbox-demo.jpg b/nui/images/flexbox-demo.jpg
new file mode 100644 (file)
index 0000000..bfe9545
Binary files /dev/null and b/nui/images/flexbox-demo.jpg differ
diff --git a/nui/images/hello-world.png b/nui/images/hello-world.png
new file mode 100644 (file)
index 0000000..d26c75e
Binary files /dev/null and b/nui/images/hello-world.png differ
diff --git a/nui/images/image-visual.png b/nui/images/image-visual.png
new file mode 100644 (file)
index 0000000..a09f92b
Binary files /dev/null and b/nui/images/image-visual.png differ
diff --git a/nui/images/justify-content.jpg b/nui/images/justify-content.jpg
new file mode 100644 (file)
index 0000000..db0e76b
Binary files /dev/null and b/nui/images/justify-content.jpg differ
diff --git a/nui/images/linear-gradient-visual.png b/nui/images/linear-gradient-visual.png
new file mode 100644 (file)
index 0000000..1d8074a
Binary files /dev/null and b/nui/images/linear-gradient-visual.png differ
diff --git a/nui/images/mesh-visual.png b/nui/images/mesh-visual.png
new file mode 100644 (file)
index 0000000..d5e8ca0
Binary files /dev/null and b/nui/images/mesh-visual.png differ
diff --git a/nui/images/multi-threaded-animation-2.png b/nui/images/multi-threaded-animation-2.png
new file mode 100644 (file)
index 0000000..2d481f1
Binary files /dev/null and b/nui/images/multi-threaded-animation-2.png differ
diff --git a/nui/images/multi-threaded-animation.png b/nui/images/multi-threaded-animation.png
new file mode 100644 (file)
index 0000000..ebe0bef
Binary files /dev/null and b/nui/images/multi-threaded-animation.png differ
diff --git a/nui/images/n-patch-visual.png b/nui/images/n-patch-visual.png
new file mode 100644 (file)
index 0000000..530efd3
Binary files /dev/null and b/nui/images/n-patch-visual.png differ
diff --git a/nui/images/octahedron.png b/nui/images/octahedron.png
new file mode 100644 (file)
index 0000000..9ad5704
Binary files /dev/null and b/nui/images/octahedron.png differ
diff --git a/nui/images/popup-normal.png b/nui/images/popup-normal.png
new file mode 100644 (file)
index 0000000..ce06133
Binary files /dev/null and b/nui/images/popup-normal.png differ
diff --git a/nui/images/popup-styled.png b/nui/images/popup-styled.png
new file mode 100644 (file)
index 0000000..831950a
Binary files /dev/null and b/nui/images/popup-styled.png differ
diff --git a/nui/images/radial-gradient-visual.png b/nui/images/radial-gradient-visual.png
new file mode 100644 (file)
index 0000000..5b7ac5e
Binary files /dev/null and b/nui/images/radial-gradient-visual.png differ
diff --git a/nui/images/slices.png b/nui/images/slices.png
new file mode 100644 (file)
index 0000000..8747577
Binary files /dev/null and b/nui/images/slices.png differ
diff --git a/nui/images/sphere.png b/nui/images/sphere.png
new file mode 100644 (file)
index 0000000..3efd4a0
Binary files /dev/null and b/nui/images/sphere.png differ
diff --git a/nui/images/stacks.png b/nui/images/stacks.png
new file mode 100644 (file)
index 0000000..fb3cb84
Binary files /dev/null and b/nui/images/stacks.png differ
diff --git a/nui/images/svg-visual.svg b/nui/images/svg-visual.svg
new file mode 100644 (file)
index 0000000..b7d5476
--- /dev/null
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 306.90988 416.79828"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="Kid1.svg"><metadata
+     id="metadata185"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs183" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="640"
+     inkscape:window-height="480"
+     id="namedview181"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="0.28032166"
+     inkscape:cx="152.20465"
+     inkscape:cy="184.87264"
+     inkscape:window-x="75"
+     inkscape:window-y="34"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Layer_1" /><path
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 192.28065,343.14765 c 0,0 -4.5,75.5 37.5,71 42,-4.5 11.5,-75.5 11.5,-75.5 l -49,4.5 z"
+     id="path3"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#666666;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 229.78065,414.14765 c 24.024,-2.574 24.325,-26.903 20.184,-47.259 l -56.117,5.805 c 3.172,20.614 12.003,44.018 35.933,41.454 z"
+     id="path5"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 113.60765,343.14765 c 0,0 -23.087995,69 14,73 37.088,4 48,-73 48,-73 h -62 z"
+     id="path7"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#666666;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 169.15465,370.76265 -60.625,-7.118 c -3.745,20.685 -4.689,49.94 19.078,52.503 21.993,2.372 34.78,-23.738 41.547,-45.385 z"
+     id="path9"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 117.10565,371.73465 39.895,2.68 c 0,0 -7.065,27.803 -23.798,24.788 -16.733,-3.015 -16.097,-27.468 -16.097,-27.468 z"
+     id="path11"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 206.27865,381.65765 35.399,-5.164 c 0,0 2.531,26.234 -10.49,26.241 -18.543,0.011 -24.909,-21.077 -24.909,-21.077 z"
+     id="path13"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 121.49165,210.92765 c -24.560995,5.263 -52.631995,5.263 -52.631995,5.263 l 5.354,60.772 25.859995,-5.032 c 0,0 64.328,-18.197 62.574,-34.16 -2.104,-19.138 -16.595,-32.106 -41.156,-26.843 z"
+     id="path15"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#c1272d;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 231.14065,228.64765 c -10.143,-34.251 -65.789,-51.053 -65.789,-51.053 0,0 -19.298,28.07 -43.86,33.333 -1.209,0.259 -2.428,0.502 -3.65,0.736 l -20.035995,60.709 2.267995,-0.441 -16.300995,80.54 184.714995,-4.731 c 0,10e-4 -25.566,-79.313 -37.347,-119.093 z"
+     id="path17"
+     inkscape:connector-curvature="0" /><line
+     style="fill:#666666;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="110.72466"
+     y1="311.29565"
+     x2="104.40065"
+     y2="352.30963"
+     id="line19" /><polygon
+     style="fill:#666666;stroke:#000000;stroke-miterlimit:10"
+     points="390.823,464.081 392.798,470.374 237.225,476.667 237.225,468.729 "
+     id="polygon21"
+     transform="translate(-145.43535,-189.01935)" /><linearGradient
+     id="SVGID_1_"
+     gradientUnits="userSpaceOnUse"
+     x1="317.35651"
+     y1="383.66669"
+     x2="317.35651"
+     y2="199.5519"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0"
+       style="stop-color:#402A04"
+       id="stop24" /><stop
+       offset="1"
+       style="stop-color:#7F5100"
+       id="stop26" /></linearGradient><path
+     style="fill:url(#SVGID_1_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="M 172.97165,196.01565 H 63.267655 c 0,0 -54.6040005,-192.1050008 109.704995,-188.5960008 164.309,3.5089998 106.414,188.5960008 106.414,188.5960008 h -106.415 z"
+     id="path28"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_2_"
+     gradientUnits="userSpaceOnUse"
+     x1="317.6879"
+     y1="298.16669"
+     x2="317.6879"
+     y2="399.66791"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0.0019"
+       style="stop-color:#FFCA94"
+       id="stop31" /><stop
+       offset="1"
+       style="stop-color:#E2A380"
+       id="stop33" /></linearGradient><path
+     style="fill:url(#SVGID_2_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 93.798655,65.647649 c 0,0 -48.605,145.281001 77.692995,145.281001 126.298,0 80.202,-145.281001 80.202,-145.281001 H 93.798655 z"
+     id="path35"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_3_"
+     gradientUnits="userSpaceOnUse"
+     x1="316.33801"
+     y1="383.66669"
+     x2="316.33801"
+     y2="199.5519"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0"
+       style="stop-color:#402A04"
+       id="stop38" /><stop
+       offset="1"
+       style="stop-color:#7F5100"
+       id="stop40" /></linearGradient><path
+     style="fill:url(#SVGID_3_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 108.82665,29.573649 c 0,0 -37.535995,22.859 -34.316995,82.359001 h 62.920995 c 0,0 7.255,-35.965001 7.255,-31.786001 0,4.179 3.509,31.786001 3.509,31.786001 h 48.246 V 87.833649 l 8.772,24.099001 h 62.281 c 0,0 0,-53.553001 -28.63,-82.359001 -28.072,0.877 -130.037,0 -130.037,0 z"
+     id="path42"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_4_"
+     gradientUnits="userSpaceOnUse"
+     x1="195.0862"
+     y1="372.3811"
+     x2="217.894"
+     y2="516.99213"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0"
+       style="stop-color:#006178"
+       id="stop45" /><stop
+       offset="1"
+       style="stop-color:#00495C"
+       id="stop47" /></linearGradient><path
+     style="fill:url(#SVGID_4_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 111.64765,331.69965 -70.387995,13.196 c -6.487,1.216 -12.79,-3.096 -14.006,-9.583 L 1.8536545,199.83065 c -1.21599995,-6.487 3.096,-12.79 9.5830005,-14.006 l 70.388,-13.196 c 6.487,-1.216 12.79,3.096 14.006,9.583 l 25.399995,135.482 c 1.217,6.487 -3.096,12.79 -9.583,14.006 z"
+     id="path49"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_5_"
+     gradientUnits="userSpaceOnUse"
+     x1="197.17931"
+     y1="393.6586"
+     x2="218.5313"
+     y2="505.75641"><stop
+       offset="0"
+       style="stop-color:#6BBBD0"
+       id="stop52" /><stop
+       offset="1"
+       style="stop-color:#ACCCD4"
+       id="stop54" /></linearGradient><polygon
+     style="fill:url(#SVGID_5_);stroke:#000000;stroke-miterlimit:10"
+     points="179.836,514.167 159.336,399.948 236.336,387.667 254.336,498.167 "
+     id="polygon56"
+     transform="translate(-145.43535,-189.01935)" /><linearGradient
+     id="SVGID_6_"
+     gradientUnits="userSpaceOnUse"
+     x1="207.9456"
+     y1="466.41"
+     x2="201.4173"
+     y2="399.4946"><stop
+       offset="0"
+       style="stop-color:#FBCA51"
+       id="stop59" /><stop
+       offset="1"
+       style="stop-color:#FFECBF"
+       id="stop61" /></linearGradient><ellipse
+     style="fill:url(#SVGID_6_);stroke:#000000;stroke-miterlimit:10"
+     cx="205.43201"
+     cy="440.64801"
+     rx="28.959"
+     ry="28.080999"
+     id="ellipse63"
+     sodipodi:cx="205.43201"
+     sodipodi:cy="440.64801"
+     sodipodi:rx="28.959"
+     sodipodi:ry="28.080999"
+     transform="translate(-145.43535,-189.01935)" /><linearGradient
+     id="SVGID_7_"
+     gradientUnits="userSpaceOnUse"
+     x1="190.9269"
+     y1="427.96649"
+     x2="192.52139"
+     y2="436.33749"><stop
+       offset="0"
+       style="stop-color:#6BBBD0"
+       id="stop66" /><stop
+       offset="1"
+       style="stop-color:#ACCCD4"
+       id="stop68" /></linearGradient><line
+     style="fill:url(#SVGID_7_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="44.983662"
+     y1="238.97565"
+     x2="47.595661"
+     y2="247.29865"
+     id="line70" /><linearGradient
+     id="SVGID_8_"
+     gradientUnits="userSpaceOnUse"
+     x1="211.39799"
+     y1="423.5397"
+     x2="213.01559"
+     y2="432.0325"><stop
+       offset="0"
+       style="stop-color:#6BBBD0"
+       id="stop73" /><stop
+       offset="1"
+       style="stop-color:#ACCCD4"
+       id="stop75" /></linearGradient><line
+     style="fill:url(#SVGID_8_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="66.200653"
+     y1="234.40564"
+     x2="67.343658"
+     y2="243.13666"
+     id="line77" /><path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 47.595655,260.51865 c 0,0 0.653,13.22 15.831,9.14 15.178,-4.08 11.229,-15.994 11.229,-15.994"
+     id="path79"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_9_"
+     gradientUnits="userSpaceOnUse"
+     x1="247.2587"
+     y1="416.16669"
+     x2="247.2587"
+     y2="464.19009"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0.0019"
+       style="stop-color:#FFCA94"
+       id="stop82" /><stop
+       offset="1"
+       style="stop-color:#E2A380"
+       id="stop84" /></linearGradient><path
+     style="fill:url(#SVGID_9_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 125.03565,225.81865 c 0,0 -54.844995,-4.046 -54.589995,5.391 0.255,9.437 21.359,3.668 20.849,8.259 -0.51,4.591 -10.173,3.424 -8.763,9.166 1.335,5.436 9.891,0.337 10.485,4.399 0.594,4.062 -7.944,4.738 -7.2,9.587 0.744,4.849 9.437,1.275 9.947,4.081 0.51,2.806 -5.959,4.099 -3.664,7.415 2.296,3.316 25.481995,4.532 36.820995,-0.784 11.531,-5.406 -3.885,-47.514 -3.885,-47.514 z"
+     id="path86"
+     inkscape:connector-curvature="0" /><path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 108.82665,147.75265 c 0,0 0.464,-21.64 21.464,-21.14 21,0.5 22,21.14 22,21.14"
+     id="path88"
+     inkscape:connector-curvature="0" /><path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 194.78965,147.75265 c 0,0 5.5,-23.64 25,-23.64 19.5,0 21.571,21 21.571,21"
+     id="path90"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="M 154.28965,177.59465"
+     id="path92"
+     inkscape:connector-curvature="0" /><path
+     style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 154.28965,177.59465 c 0,0 0.715,18.789 16.607,18.421 15.893,-0.368 12.893,-18.421 12.893,-18.421"
+     id="path94"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 228.94765,254.13365 c -2.38,6.629 -9.604,20.319 -44.933,26.513 -37.922,6.649 -56.122,-3.11 -56.122,-3.11 l -10.787,-59.329 c 0,0 37.312,5.696 53.792,4.439 16.48,-1.257 33.346,-5.764 33.346,-5.764 0,0 18.324,-4.366 23.904,8.074 5.579,12.439 3.538,21.552 0.8,29.177 z"
+     id="path96"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_10_"
+     gradientUnits="userSpaceOnUse"
+     x1="316.32571"
+     y1="383.66669"
+     x2="316.32571"
+     y2="199.5519"><stop
+       offset="0"
+       style="stop-color:#402A04"
+       id="stop99" /><stop
+       offset="1"
+       style="stop-color:#7F5100"
+       id="stop101" /></linearGradient><polygon
+     style="fill:url(#SVGID_10_)"
+     points="408.426,250.667 394.198,218.593 358.725,207.167 262.541,210.167 237.725,225.136 224.225,247.667 "
+     id="polygon103"
+     transform="translate(-145.43535,-189.01935)" /><polygon
+     style="fill:#c1272d;stroke:#000000;stroke-miterlimit:10"
+     points="399.167,290.713 428.616,269.855 394.694,225.136 365.225,225.136 354.191,247.667 404.225,254.667 "
+     id="polygon105"
+     transform="translate(-145.43535,-189.01935)" /><path
+     style="fill:#c1272d;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 245.96865,0.64764917 c -6.811,-2.50199997 -41.178,27.49999983 -36.678,36.49999983 4.5,9 39,21.5 39,21.5 l 13.209,-17.558 c -10e-4,0 -4.031,-36.2179998 -15.531,-40.44199983 z"
+     id="path107"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#c1272d;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 272.19765,55.502649 -13.408,15.144 c 0,0 9,36.500001 17.5,35.500001 8.5,-1 32,-21.720001 30,-31.408001 -2,-9.688 -34.092,-19.236 -34.092,-19.236 z"
+     id="path109"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#c1272d;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 243.78965,58.647649 c 0,0 13.418,-23.5 17.709,-22.5 4.291,1 15.093,16.043 15.791,19.356 0.698,3.313 -13,20.644 -18.5,19.144 -5.5,-1.5 -12.5,-10 -15,-16 z"
+     id="path111"
+     inkscape:connector-curvature="0" /><line
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="215.78966"
+     y1="36.11665"
+     x2="245.96864"
+     y2="54.967648"
+     id="line113" /><line
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="262.99066"
+     y1="73.483643"
+     x2="277.31567"
+     y2="96.647644"
+     id="line115" /><circle
+     style="opacity:0.2;fill:#d86d44"
+     cx="262.54099"
+     cy="357.16699"
+     r="19.249001"
+     id="circle117"
+     sodipodi:cx="262.54099"
+     sodipodi:cy="357.16699"
+     sodipodi:rx="19.249001"
+     sodipodi:ry="19.249001"
+     transform="translate(-145.43535,-189.01935)" /><circle
+     style="opacity:0.2;fill:#d86d44"
+     cx="372.72501"
+     cy="357.16699"
+     r="19.249001"
+     id="circle119"
+     sodipodi:cx="372.72501"
+     sodipodi:cy="357.16699"
+     sodipodi:rx="19.249001"
+     sodipodi:ry="19.249001"
+     transform="translate(-145.43535,-189.01935)" /><path
+     style="fill:#c1272d;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="M 231.14065,228.64765"
+     id="path121"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_11_"
+     gradientUnits="userSpaceOnUse"
+     x1="218.8582"
+     y1="511.4505"
+     x2="220.60651"
+     y2="520.62927"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0"
+       style="stop-color:#006178"
+       id="stop124" /><stop
+       offset="1"
+       style="stop-color:#00495C"
+       id="stop126" /></linearGradient><path
+     style="fill:url(#SVGID_11_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 61.249655,330.25265 c 0.7,3.23 4.623,2.704 4.623,2.704 0,0 14.196,-2.268 16.856,-2.704 2.66,-0.436 5.413,-2.183 4.802,-5.501 -0.611,-3.318 -2.578,-4.334 -4.977,-4.104 -2.143,0.206 -17.811,4.016 -17.811,4.016 0,0 -4.628,0.35 -3.493,5.589 z"
+     id="path128"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_12_"
+     gradientUnits="userSpaceOnUse"
+     x1="196.34351"
+     y1="377.0275"
+     x2="197.17529"
+     y2="381.39441"><stop
+       offset="0"
+       style="stop-color:#006178"
+       id="stop131" /><stop
+       offset="1"
+       style="stop-color:#00495C"
+       id="stop133" /></linearGradient><polygon
+     style="fill:url(#SVGID_12_);stroke:#000000;stroke-miterlimit:10"
+     points="186.437,382.911 186.437,379.506 206.978,374.966 207.302,379.506 "
+     id="polygon135"
+     transform="translate(-145.43535,-189.01935)" /><linearGradient
+     id="SVGID_13_"
+     gradientUnits="userSpaceOnUse"
+     x1="152.85809"
+     y1="432.1676"
+     x2="155.30721"
+     y2="445.02539"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0.0019"
+       style="stop-color:#FFCA94"
+       id="stop138" /><stop
+       offset="1"
+       style="stop-color:#E2A380"
+       id="stop140" /></linearGradient><path
+     style="fill:url(#SVGID_13_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 2.5626545,251.52265 c 0.949,7.344 13.9770005,5.843 12.4400005,-2.53 -1.537,-8.373 -13.8540005,-8.404 -12.4400005,2.53 z"
+     id="path142"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_14_"
+     gradientUnits="userSpaceOnUse"
+     x1="150.90849"
+     y1="418.1373"
+     x2="153.3576"
+     y2="430.99509"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0.0019"
+       style="stop-color:#FFCA94"
+       id="stop145" /><stop
+       offset="1"
+       style="stop-color:#E2A380"
+       id="stop147" /></linearGradient><path
+     style="fill:url(#SVGID_14_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 0.61265455,237.49265 c 0.94899995,7.344 13.97700045,5.843 12.44000045,-2.53 -1.537,-8.373 -13.85300045,-8.404 -12.44000045,2.53 z"
+     id="path149"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_15_"
+     gradientUnits="userSpaceOnUse"
+     x1="155.52521"
+     y1="446.19681"
+     x2="157.7338"
+     y2="457.79221"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0.0019"
+       style="stop-color:#FFCA94"
+       id="stop152" /><stop
+       offset="1"
+       style="stop-color:#E2A380"
+       id="stop154" /></linearGradient><path
+     style="fill:url(#SVGID_15_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 5.7066545,264.72965 c 0.856,6.623 12.6050005,5.269 11.2180005,-2.281 -1.387,-7.55 -12.4920005,-7.58 -11.2180005,2.281 z"
+     id="path156"
+     inkscape:connector-curvature="0" /><linearGradient
+     id="SVGID_16_"
+     gradientUnits="userSpaceOnUse"
+     x1="153.2876"
+     y1="459.8923"
+     x2="155.15581"
+     y2="469.70059"
+     gradientTransform="translate(-145.43535,-189.01935)"><stop
+       offset="0.0019"
+       style="stop-color:#FFCA94"
+       id="stop159" /><stop
+       offset="1"
+       style="stop-color:#E2A380"
+       id="stop161" /></linearGradient><path
+     style="fill:url(#SVGID_16_);stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     d="m 14.738655,269.81365 c 0,0 -14.45200045,0.644 -13.0900005,6.785 1.362,6.141 15.1240005,2.806 15.1240005,2.806 l -2.034,-9.591 z"
+     id="path163"
+     inkscape:connector-curvature="0" /><line
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="103.19666"
+     y1="134.52966"
+     x2="111.07164"
+     y2="138.28766"
+     id="line165" /><line
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="116.44066"
+     y1="121.91666"
+     x2="119.95366"
+     y2="128.63864"
+     id="line167" /><line
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="231.53465"
+     y1="117.39664"
+     x2="227.96065"
+     y2="125.27765"
+     id="line169" /><line
+     style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="249.61266"
+     y1="127.38266"
+     x2="237.84065"
+     y2="134.52966"
+     id="line171" /><line
+     style="fill:#666666;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="243.72664"
+     y1="311.64764"
+     x2="251.97566"
+     y2="348.16364"
+     id="line173" /><line
+     style="fill:#666666;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="184.01564"
+     y1="310.31366"
+     x2="184.01564"
+     y2="349.90466"
+     id="line175" /><line
+     style="fill:#666666;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="146.45665"
+     y1="311.64764"
+     x2="143.12267"
+     y2="350.95166"
+     id="line177" /><line
+     style="fill:#666666;stroke:#000000;stroke-width:1;stroke-miterlimit:10"
+     x1="218.07564"
+     y1="311.29565"
+     x2="222.05864"
+     y2="348.93066"
+     id="line179" /></svg>
diff --git a/nui/images/wireframe-visual.png b/nui/images/wireframe-visual.png
new file mode 100644 (file)
index 0000000..b22bd94
Binary files /dev/null and b/nui/images/wireframe-visual.png differ
diff --git a/nui/imageview.htm b/nui/imageview.htm
new file mode 100644 (file)
index 0000000..23280c0
--- /dev/null
@@ -0,0 +1,144 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>ImageView</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#usage">Creating an ImageView</a></li>
+            <li><a href="#properties">Image View Properties</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>ImageView</h1>
+
+<p>An <code>ImageView</code> is a NUI control that displays an image. The following figure shows an image displayed with an ImageView.</p>
+<p align="center"><strong>Figure: ImageView example</strong></p>
+<p align="center"><img src="images/ImageView.png" alt="ImageView example" /> </p>
+
+<h2 id="usage">Creating an ImageView</h2>
+<p>To create an <code>ImageView</code>:</p>
+<ol>
+       <li>Create an <code>ImageView</code> instance with a file path:
+<pre class="prettyprint">
+imageView = new ImageView(DirectoryInfo.Resource + "images/gallery-3.jpg");
+</pre>
+<p>You can also create an <code>ImageView</code> instance with the <code>ResourceUrl</code> property:</p>
+<pre class="prettyprint">
+imageView = new ImageView();
+imageView.ResourceUrl = DirectoryInfo.Resource + "images/gallery-3.jpg";
+</pre>
+       </li>
+       <li>To change the image later, use the <code>SetImage()</code> method:
+<pre class="prettyprint">
+imageView.SetImage(DirectoryInfo.Resource + "images/gallery-4.jpg");
+</pre>
+       </li>
+</ol>
+
+
+<h2 id="properties">Image View Properties</h2>
+<p>The following table defines the <code>ImageView</code> control properties.</p>
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th>Type</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>ResourceUrl</code></td>
+    <td><code>string</code></td>
+    <td>Path to image file.</td>
+</tr>
+<tr>
+    <td><code>ImageMap</code></td>
+    <td><code>Map</code></td>
+    <td>Map of properties associated with a given image.</td>
+</tr>
+<tr>
+    <td><code>PreMultipliedAlpha</code></td>
+    <td><code>bool</code></td>
+    <td>Opacity-adjusted image.
+<div class="note">
+<strong>Note</strong>
+If <code>PreMultipliedAlpha</code> equals <code>true</code>, the RGB components represent the color of the object or pixel adjusted for its opacity by multiplication. If <code>false</code>, the opacity is disregarded.
+</div></td>
+</tr>
+<tr>
+    <td><code>PixelArea</code></td>
+    <td><code>Vector4</code></td>
+    <td>Subarea of the image.
+<div class="note">
+<strong>Note</strong>
+<code>PixelArea</code> is a relative value, with the whole image area as [0.0, 0.0, 1.0, 1.0]. The <code>Vector4</code> area values are (<code>x</code>, <code>y</code>, <code>width</code>, <code>height</code>).
+<p>For example, on a 200 x 200 pixel image, the [0.25, 0.5, 0.5, 0.5] value represents a subarea of that image with the following coordinates:</p>
+<ul>
+    <li>Top left: 50,100</li>
+    <li>Top right: 150,100</li>
+    <li>Bottom left: 50,200</li>
+    <li>Bottom right: 150,200</li>
+</ul>
+</div></td>
+</tr>
+<tr>
+    <td><code>Border</code></td>
+    <td><code>Rectangle</code></td>
+    <td>Border of the image in the order of left, right, bottom, and top. For N-Patch images only.</td>
+</tr>
+<tr>
+    <td><code>BorderOnly</code></td>
+    <td><code>bool</code></td>
+    <td>Gets/sets whether to draw only the borders. For N-Patch images only.</td>
+</tr>
+<tr>
+    <td><code>SynchronousLoading</code></td>
+    <td><code>bool</code></td>
+    <td>Gets/sets whether the image is synchronous. For N-Patch images only.</td>
+</tr>
+</tbody>
+</table>
+
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
diff --git a/nui/scripts/common.js b/nui/scripts/common.js
new file mode 100644 (file)
index 0000000..60250b6
--- /dev/null
@@ -0,0 +1,1752 @@
+$(document).ready(function(){
+       $('#contents table').each(function(){
+               if (!$(this).parent().hasClass('table')) {
+                       $(this).wrap('<div class="table"></div>');
+               }
+       });
+
+       // Lnb Menu Initialize
+       if($('div#contents').find('.lnb').length){
+               if($("ul li.events_news").size() > 0) {
+                       $("ul.lnb").after("<p class=\"mt20\"><a href=\"/wearables\" target=\"_blank\"><img src=\"http://img-developer.samsung.com/images/common/img_sw_banner.gif\" alt=\"Samsung Wearables\"></a></p>");
+               }
+               initLnb();
+               initScript(staticURL + "/js/fixednavbar.js", function(){});
+       }
+
+       //family site
+       if($('div#footer').find('dl#familySlider').length){
+               fn_rollToEx('familySlider', 'sliderBanner', 1, true);
+       }
+
+       // Svn Commit Test
+       
+       // Language Selection
+       if($('div#header').find('.util').length){
+               var $lang = $('div#header').find('.util');
+               $lang.find('a.lang').toggle(function(){
+                               $(this).css('background-image', $(this).css('background-image').replace('.gif','_.gif')).next('ul.language').show();
+                       },function(){
+                               $(this).css('background-image', $(this).css('background-image').replace('_.gif','.gif')).next('ul.language').hide();
+                       });
+
+               $lang.bind('mouseleave',function(){
+                       $(this).find('ul.language').hide();
+                       $lang.find('a.lang').css('background-image', $lang.find('a.lang').css('background-image').replace('_.gif','.gif'));
+               });
+
+               $lang.find('ul.language').children().last().on("keydown", function(e) {
+                       if(e.which == 9 && e.shiftKey) {
+                               return true;
+                       }
+                       
+                       if(e.which == 9) {
+                               e.preventDefault();
+                               $lang.find('ul.language').hide();
+                               $lang.find('a.lang').css('background-image', $lang.find('a.lang').css('background-image').replace('_.gif','.gif'));
+                               setTimeout(function() {
+                                       $("#searchTop").focus();
+                               }, 1);
+                       }
+               });
+       }
+
+       // Open the Sitemap
+       var $open = $('div#header').find('.bt-open');
+       $open.bind('click',function(){
+               var $self = $(this);
+               var $sitemap = $('div#wrapper').find('div#sitemap');
+               //var source = $sitemap.is(':visible') ? $self.css('background-image').replace('_.gif','.gif') : $self.css('background-image').replace('.gif','_.gif');
+
+               if($sitemap.is(':visible')){
+                       var source = $self.css('background-image').replace('_.gif','.gif');
+                       //if($('body#main').length) $('#header .util').css('border-bottom','3px solid #e4e4e4');
+
+                       $self.attr('title','open sitemap');
+               }else{
+                       var source = $self.css('background-image').replace('.gif','_.gif');
+                       //if($('body#main').length) $('#header .util').css('border-bottom','3px solid #114196');
+
+                       $self.attr('title','close sitemap');
+               }
+               
+               $self.css('background-image',source);
+               $sitemap.slideToggle('fast');
+               
+               $sitemap.find('ul').filter(':last').children().filter(':last').focusout(function(){
+                       var source = $self.css('background-image').replace('_.gif','.gif');
+                       $self.css('background-image',source);
+                       $sitemap.slideToggle('fast');
+               });
+
+       });
+
+       // Search Auto Complete
+       var $search = $('div#header').find('fieldset.search');
+       var $searchList = $search.find('#topAutocomplete>ul');
+
+       if($search.length){
+               $search.find('> input').each(function(){
+                       $(this).bind({
+                               keydown : function(e){
+                       
+                                       if(e.type=='keydown'&& $(this).val().length!=0){
+                                               $search.find('#topAutocomplete').show();
+                                               var hei = $searchList.outerHeight();
+                                               if(hei>400){
+                                                       $searchList.css({'height':'400px','overflow-y':'auto'});
+                                               }
+                                       }
+                                       if(e.keyCode==9){
+                                               $search.unbind('focusout.search');
+                                       }
+                                       if(e.keyCode==40){
+                                               $search.find('#topAutocomplete>ul').children(':first').find('a').focus();
+                                               //window.scrollTo(0,0);
+                                       }
+                               },
+                               focusin : function(e){
+                                       if($(this).val()==='Search'){
+                                               $(this).val('');
+                                       }
+                               },
+                               focusout : function(e){
+                                       if($(this).val().length==0) $(this).val('Search');
+                               }
+                       });
+               });
+
+               //$('#topAutocomplete>ul').children().find('a').bind('focusin',function(e){
+               //      if(e.keyCode==40){
+               //              $(this).parent().next().css('border','1px solid red').find('a').focus();
+               //      }
+               //});
+
+               $search.find('#topAutocomplete').bind('mouseleave',function(e){
+                       if($search.find('> input').val().length==0){
+                               $search.find('> input').val('Search');
+                       }
+                       $search.find('#topAutocomplete').hide();
+               });
+
+               $search.find('#topAutocomplete>ul').children().last().focusout(function(){
+                       $search.find('> input').val('Search');
+                       $search.find('#topAutocomplete').hide();
+                       
+                       //$search.bind('focusout.search', function(){
+                       //      $(this).find('> input').val('Search');
+                       //      $(this).find('#topAutocomplete').hide();
+                       //});
+               });
+       }
+});
+
+// 비차단 동적 스크립트 로딩
+function initScript(url, callback){
+       var script = document.createElement("script");
+       script.type = "text/javascript";
+
+       if(script.readyState){ // 인터넷 익스플로러
+               script.onreadystatechange = function(){
+                       if(script.readyState=="loaded" || script.readyState=="complete"){
+                               script.onreadystatechange = null;
+                               callback();
+                       }
+               };
+       }else{  // 다른  브라우저
+               script.onload = function(){
+                       callback();
+               };
+       }
+
+       script.src = url;
+       document.getElementsByTagName("head")[0].appendChild(script);
+}
+
+
+// lnb
+function initLnb(){
+       var sMenu = $('.lnb');
+       var sItem = sMenu.find('>li');
+
+       sItem.each(function(){
+               if($(this).find('a').hasClass('more')){
+                       if($(this).find('ul').is(":visible")) {
+                               $('<button type="button" class="ico-arr">close submenu</button>').insertAfter($(this).find('a').eq(0)); 
+                       } else {
+                               $('<button type="button" class="ico-arr">open submenu</button>').insertAfter($(this).find('a').eq(0));
+                       }
+               }
+       });
+       
+       var setIcoArrText = function(obj) {
+               if(obj.next().is(":visible")) {
+                       obj.text("close submenu");
+               } else {
+                       obj.text("open submenu");
+               }
+       }
+       
+       sItem.find('.ico-arr').on("click", function() {
+               var $that = $(this);
+               var liBox = $that.parent();   
+               var ulBox = $that.next();
+               
+               sItem.not(liBox).not(".on").find("a.more").next().next().hide();
+               sItem.not(liBox).removeClass("active").find("a").removeClass("bov");
+               
+               if(liBox.hasClass("on")) {
+                       if(ulBox.is(":visible")) {
+                               ulBox.hide();
+                               $that.addClass("ico-on");
+                       } else {
+                               ulBox.show();
+                               $that.removeClass("ico-on");
+                       }
+                       setIcoArrText($that);
+                       return true;
+               }
+               
+               if(liBox.hasClass("active")) {
+                       liBox.removeClass("active").find("a").eq(0).removeClass("bov");
+                       ulBox.hide();
+               } else {
+                       liBox.addClass("active").find("a").eq(0).addClass("bov");
+                       ulBox.show();
+               }
+               setIcoArrText($that);
+       });
+
+       sItem.hover(function(){
+               if($(this).hasClass('on')||$(this).hasClass('active')) return false;
+               $(this).find("a").eq(0).addClass("bov");
+       },function(){
+               if($(this).hasClass('on')||$(this).hasClass('active')) return false;
+                $(this).find("a").eq(0).removeClass("bov");
+
+       });
+}
+
+//footer rolling banner
+function fn_rollToEx(container,objectId,step,auto){
+
+       // 롤링할 객체를 변수에 담아둔다.
+       var el = $('#'+container).find('#'+objectId);
+       var lastChild;
+       var speed = 3000;
+       var timer = 0;
+       var autoplay = false;
+
+       el.data('prev', $('#'+container).find('.prev'));        //이전버튼을 data()메서드를 사용하여 저장한다.
+       el.data('next', $('#'+container).find('.next'));        //다음버튼을 data()메서드를 사용하여 저장한다.
+       el.data('size', el.children().outerWidth());            //롤링객체의 자식요소의 넓이를 저장한다.
+       el.data('len', el.children().length);                           //롤링객체의 전체요소 개수
+       el.data('animating',false);
+       el.data('step', step);                                                          //매개변수로 받은 step을 저장한다.
+       el.data('autoStart', false);                                                            //매개변수로 받은 step을 저장한다.
+
+       el.css('width',el.data('size')*el.data('len'));         //롤링객체의 전체넓이 지정한다.
+
+       if(arguments.length==4){
+               el.data('autoStart', auto);
+       }
+
+       if(el.data('autoStart')){
+               if(timer==0){
+                       timer = setInterval(moveNextSlide, speed);
+                       autoplay = true;
+               }
+       }
+
+       el.bind({
+               mouseenter:function(){
+                       if(!autoplay) return false;
+
+                       if(timer!=0 && el.data('autoStart')){
+                               clearInterval(timer);
+                               timer=0;
+                       }
+               },
+               mouseleave:function(){
+                       if(!autoplay) return false;
+
+                       if(timer==0 && el.data('autoStart')){
+                               timer = setInterval(moveNextSlide, speed);
+                       }
+               }
+       });
+
+
+       //el에 첨부된 prev 데이타를 클릭이벤트에 바인드한다.
+       el.data('prev').bind({
+               click:function(e){
+                       e.preventDefault();
+                       movePrevSlide();
+               },
+               mouseenter:function(){
+
+                       $(this).find('img').addClass('btnOn');
+
+                       if(!autoplay) return false;
+
+                       if(timer!=0 && el.data('autoStart')){
+                               clearInterval(timer);
+                               timer=0;
+                       }
+               },
+               mouseleave:function(){
+
+                       $(this).find('img').removeClass('btnOn');
+
+                       if(!autoplay) return false;
+
+                       if(timer==0 && el.data('autoStart')){
+                               timer = setInterval(moveNextSlide, speed);
+                       }
+               }
+       });
+
+       //el에 첨부된 next 데이타를 클릭이벤트에 바인드한다.
+       el.data('next').bind({
+               click:function(e){
+                       e.preventDefault();
+                       moveNextSlide();
+               },
+               mouseenter:function(){
+
+                       $(this).find('img').addClass('btnOn');
+
+                       if(!autoplay) return false;
+
+                       if(timer!=0 && el.data('autoStart')){
+                               clearInterval(timer);
+                               timer=0;
+                       }
+               },
+               mouseleave:function(){
+
+                       $(this).find('img').removeClass('btnOn');
+
+                       if(!autoplay) return false;
+
+                       if(timer==0 && el.data('autoStart')){
+                               timer = setInterval(moveNextSlide, speed);
+                       }
+               }
+       });
+
+       function movePrevSlide(){
+               if(!el.data('animating')){
+                       //전달된 step개수 만큼 롤링객체의 끝에서 요소를 선택하여 복사한후 변수에 저장한다.
+                       var lastItem = el.children().eq(-(el.data('step')+1)).nextAll().clone(true);
+                       lastItem.prependTo(el);         //복사된 요소를 롤링객체의 앞에 붙여놓는다.
+                       el.children().eq(-(el.data('step')+1)).nextAll().remove();      //step개수만큼 선택된 요소를 끝에서 제거한다
+                       el.css('left','-'+(el.data('size')*el.data('step'))+'px');      //롤링객체의 left위치값을 재설정한다.
+               
+                       el.data('animating',true);      //애니메이션 중복을 막기 위해 첨부된 animating 데이타를 true로 설정한다.
+
+                       el.animate({'left': '0px'},'normal',function(){         //롤링객체를 left:0만큼 애니메이션 시킨다.
+                               el.data('animating',false);
+                       });
+               }
+               return false;
+       }
+
+    function moveNextSlide(){
+               if(!el.data('animating')){
+                       el.data('animating',true);
+
+                       el.animate({'left':'-'+(el.data('size')*el.data('step'))+'px'},'normal',function(){     //롤링객체를 첨부된 size와 step을 곱한 만큼 애니메이션 시킨다.
+                               //전달된 step개수 만큼 롤링객체의 앞에서 요소를 선택하여 복사한후 변수에 저장한다.
+                               var firstChild = el.children().filter(':lt('+el.data('step')+')').clone(true);
+                               firstChild.appendTo(el);        //복사된 요소를 롤링객체의 끝에 붙여놓는다.
+                               el.children().filter(':lt('+el.data('step')+')').remove();      //step개수만큼 선택된 요소를 앞에서 제거한다
+                               el.css('left','0px');   ////롤링객체의 left위치값을 재설정한다.
+
+                               el.data('animating',false);
+                       });
+               }
+               return false;
+       }
+
+}
+
+function fn_slide(options){
+
+       var opts = jQuery.extend({},options);
+
+       var $bt = $('#'+opts.container).find('#'+opts.bt).children();                                   //롤링버튼에 대한 선택자
+       var $obj = $('#'+opts.container).find('#'+opts.obj);                                                            //objectId를 id로 갖는 롤링객체의 선택자
+       var $prev = $('#'+opts.container).find('#'+opts.prev).hide();                                   //이전버튼에 대한 선택자
+       var $next = $('#'+opts.container).find('#'+opts.next);                                                  //다음버튼에 대한 선택자
+       var size = $obj.children().outerWidth();                                //롤링객체의 각 이미지 넓이값
+       var len = $obj.children().length;                                               //롤링객체의 이미지 갯수
+       var effect = false;                                                                             //슬라이드효과를 위한 boolean변수
+       var auto = false;
+       var current = 0;                                                                                //현재 보여지는 이미지의 인덱스값을 저장하기 위한 변수
+       var time;
+
+
+       $obj.css('width',size*len);                                                             //롤링객체의 전체넓이 지정
+       effect = opts.effect;
+       auto = opts.auto;
+
+       if(auto){
+               time = setTimeout('slideShow()',3000);
+       }
+
+       slideShow = function(){
+
+               if(current < len-1){
+                       current++;
+               }else{
+                       current=0;
+               }
+
+               controllStatus();
+
+               moveControl('next');
+
+               time = setTimeout('slideShow()',3000);
+       }
+
+       controllStatus = function(){
+               //이미지의 인덱스값에 따라 이전,다음 버튼 활성여부 지정
+               if(current>0||current<len-1){                           
+                       $prev.show();
+                       $next.show();
+               }
+               if(current==0){
+                       $prev.hide();
+                       $next.show();
+               }
+               if(current>=len-1){
+                       $prev.show();
+                       $next.hide();
+               }
+       }
+
+       moveControl = function(msg){
+               if(opts.bt!=null){
+                       msg=='next'? $bt.eq(current-1).find('img').attr('src', $bt.eq(current-1).find('img').attr('src').replace('_.png','.png'))
+                                                       :$bt.eq(current+1).find('img').attr('src', $bt.eq(current-1).find('img').attr('src').replace('_.png','.png'));  //이전에 활성화된 롤링버튼을 비활성화
+                       $bt.eq(current).find('img').attr('src', $bt.eq(current).find('img').attr('src').replace('.png','_.png'));               //현재 인덱스값을 가지는 롤링버튼을 활성화
+               }
+
+               if(effect!=true){                               //action변수가 true가 아닐경우 슬라이드 효과없이 현재의 인덱스값을 갖는 이미지를 보여줌.
+                       $obj.children().hide();
+                       $obj.children().eq(current).show();
+               }else{                                                  //action변수가 true일 경우 현재의 인덱스값을 갖는 이미지로 슬라이드됨
+                       $obj.animate({'left':'-'+size*current},'slow');
+               }
+       }
+
+       $obj.bind({
+               mouseenter:function(){
+                       if(!auto) return false;
+                       clearTimeout(time);
+               },
+               mouseleave:function(){
+                       if(!auto) return false;
+                       time = setTimeout('slideShow()',3000);
+               }
+       });
+
+       //롤링 버튼 클릭시
+       $bt.bind({
+               mouseenter:function(){
+                       if(!auto) return false;
+                       clearTimeout(time);
+               },
+               mouseleave:function(){
+                       if(!auto) return false;
+                       time = setTimeout('slideShow()',3000);
+               },
+               click:function(){
+                       var idx = $bt.index(this);                                      //클릭한 롤링버튼의 인덱스값 저장
+
+                       current = idx;                                                          //롤링버튼의 인덱스값을 이미지의 인덱스값으로 지정
+
+                       controllStatus();
+
+                       if(effect!=true){                               //action변수가 true가 아닐경우 슬라이드 효과없이 현재의 인덱스값을 갖는 이미지를 보여줌.
+                               $obj.children().hide();
+                               $obj.children().eq(current).show();
+                       }else{                                                  //action변수가 true일 경우 현재의 인덱스값을 갖는 이미지로 슬라이드됨
+                               $obj.animate({'left':'-'+size*current},'slow');
+                       }
+
+                       // 모든 롤링 버튼을 비활성화
+                       $bt.each(function(){
+                               var source = $(this).find('img').attr('src').replace('_.png','.png');
+                                $(this).find('img').attr('src',source);
+                       });
+
+                       // 선택한 롤링버튼을 활성화
+                       var source = $(this).find('img').attr('src').replace('.png','_.png');
+                       $(this).find('img').attr('src',source);
+
+                       return false;
+               }
+       });
+
+       //이전 버튼 클릭시
+       $prev.bind({
+               mouseenter:function(){
+                       var source = $(this).find('img').attr('src').replace('.png','_.png');
+                       $(this).find('img').attr('src',source);
+                       if(!auto) return false;
+                       clearTimeout(time);
+               },
+               mouseleave:function(){
+                       var source = $(this).find('img').attr('src').replace('_.png','.png');
+                       $(this).find('img').attr('src',source);
+                       if(!auto) return false;
+                       time = setTimeout('slideShow()',3000);
+               },
+               click:function(){
+                       if(current==len-1) $next.show();        //이미지 인덱스값이 마지막이 아닐경우 비활성화된 다음버튼을 활성화 
+                       current--;                                                      //이미지 인덱스값 1씩 감소
+
+                       moveControl('prev');
+
+                       if(current==0) $(this).hide();  //이미지 인덱스값이 0일 경우, 즉 현재 첫번째 이미지가 활성화될 경우 이전버튼을 비활성화
+
+                       return false;
+               }
+       });
+
+       //다음 버튼 클릭시
+       $next.bind({
+               mouseenter:function(){
+                       var source = $(this).find('img').attr('src').replace('.png','_.png');
+                       $(this).find('img').attr('src',source);
+                       if(!auto) return false;
+                       clearTimeout(time);
+               },
+               mouseleave:function(){
+                       var source = $(this).find('img').attr('src').replace('_.png','.png');
+                       $(this).find('img').attr('src',source);
+                       if(!auto) return false;
+                       time = setTimeout('slideShow()',3000);
+               },
+               click:function(){
+                       current++;                                                      //이미지 인덱스값 1씩 증가
+                       
+                       moveControl('next');
+
+                       if(current>=len-1) $(this).hide();      //이미지인덱스값이 마지막일 경우, 즉 현재 마지막 이미지가 활성화될 경우 다음버튼을 비활성화
+                       if(current>0) $prev.show();                     //이미지인덱스값이 0이 아닌경우 이전버튼 활성화
+
+                       return false;
+               }
+       });
+
+}
+
+// main rolling banner
+function slideMotion1(){
+       var $banner = $('#rolling .motionview'),
+               //$nav = $('#rolling ul.nav'),
+               banner = {prev:null, next:null},
+               size = $banner.children().length;
+               index = 1,
+               speed = 3000,
+               timer = null,
+               auto = true,
+               width = parseInt(100/size),
+               rest = parseInt(100%size);
+
+       var $nav = $('<ul class="nav">').insertAfter($banner);
+
+       $banner.children().each(function(index){
+               index++;
+               (index==1) ? $('<li style="width:'+width+'%;"><a href="'+ $(this).attr("href") +'" class="sel">'+index+'</a></li>').appendTo($nav) : $('<li style="width:'+width+'%;"><a href="'+ $(this).attr("href") +'">'+index+'</a></li>').appendTo($nav);
+               if(index==size){
+                       $nav.children().eq(-1).find('a').css('background-image','none');
+               }
+       });
+
+       if(rest>0){
+               width+=rest;
+               $nav.children().eq(-1).css('width',width+'%');
+       }
+
+       $nav.delegate("li",'click',function(){
+               var idx = $nav.children().index(this);
+               index = idx;
+               banner.prev = $banner.find('a.active');
+               banner.next = $banner.find('a').eq(index);
+
+               clearInterval(timer);
+               auto = false;
+               
+               $nav.trigger('change.banner',banner)
+                       .trigger('change.tab',index);
+
+               return false;
+       });
+
+       $nav.bind('change.banner',function(event, banner){
+               aniMotion();
+       });
+
+       $nav.bind('change.tab',function(event, index){
+               $nav.children().find('a').removeClass('sel');
+               $nav.children().eq(index).find('a').addClass('sel');
+       });
+
+       timer = setInterval(autoMotion, speed);
+
+       function autoMotion(){
+               if(index > size-1) index = 0;
+
+               aniMotion();
+       }
+
+       function aniMotion(){
+               if(auto){
+                       banner.prev = $banner.find('a.active');
+                       banner.next = $banner.find('a').eq(index);
+
+                       $nav.children().find('a').removeClass('sel');
+                       $nav.children().eq(index).find('a').addClass('sel');
+               }
+               banner.prev.addClass('last-active');
+               banner.next.css({'opacity':0.0})
+                       .addClass('active')
+                       .animate({'opacity':1.0}, 1000, function(){
+                               banner.prev.removeClass('active last-active');
+
+                               if(auto){
+                                       index++;
+                               }else{
+                                       index++;
+                                       timer = setInterval(autoMotion, speed*1.5);
+                                       auto = true;
+                               }
+                       });
+       }
+}
+
+// forum list show or hide function
+function toggleFunc(){
+       
+       var defaulNum = [2];
+
+       $('.forum-tit').each(function(){
+               var self = $(this);
+
+               var idx = $('.forum-tit').index(this);
+
+               for(i=0;i<=defaulNum.length;i++){
+                       if(idx==defaulNum[i]){
+                               var source = self.find('a.toggle').css('background-image').replace('.gif','_.gif');
+                               self.find('a.toggle').css('background-image',source);
+
+                               self.find('a.toggle').text('Show');
+                               self.addClass('mb35').next().hide();
+                       }
+               }
+
+               self.find('a.toggle').click(function(){
+                       
+                       if(self.next().is(':visible')){
+                               var source = $(this).css('background-image').replace('.gif','_.gif');
+                               $(this).css('background-image',source);
+
+                               $(this).text('Show');
+                               self.addClass('mb35').next().hide();
+                       }else{
+                               var source = $(this).css('background-image').replace('_.gif','.gif');
+                               $(this).css('background-image',source);
+
+                               $(this).text('Hide');
+                               self.removeClass('mb35').next().show();
+                       }
+
+                       return false;
+
+               });
+
+       });
+}
+
+// 파일 업로드
+function fileUpload( width ){
+       //var $img = $('.attach input[type=image]');
+       //var width = $img.attr('width');
+
+       // 2012-08-08 추가 : 파일 input 너비영역 셋팅
+       var w = width == null || width == undefined || isNaN( width ) ? "230px" : width + "px";
+
+       var $file = $('.attach input.upload').css({
+               "position": "absolute",
+               "top": "0px",
+               "right": "0px",
+               "width": w,
+               "cursor": "pointer",
+               "opacity": "0.0",
+               "height": "23px"
+       });
+       $file.off('change');
+       $file.on('change',function(e){
+               if(this.files != undefined && this.files.length == 0) { //chrome file 선택 취소시 파일 칸이 지워짐. 방지코드
+                       return;
+               }
+               var idx = $file.index(this);
+               var localeCode = $("#localeCode").val() == undefined ? "en" : $("#localeCode").val();
+               var fileErrMsg = {
+                               limit_ko : "최대 3개의 파일까지 업로드되며 200MB를 넘을수 없습니다"
+                           ,limit_zh : "最多允许附加 3 个文件附件,并且其大小不能超过 200MB。"
+                           ,limit_en : "Up to 3 file attachments are allowed and its size cannot exceed 200MB"
+                           ,ext_ko : "지원하지 않는 확장자 입니다."
+                           ,ext_zh : "不允许上传具有该扩展名的文件。"
+                           ,ext_en : "File extention not allowed for upload."
+               };
+               var initFileInput = function(obj) {
+                       $(obj).parent().find('input.file').val("");
+                       if($.browser.msie && $.browser.msie && $.browser.version < 10.0  ) $(obj).replaceWith( $(obj).clone(true) );
+                       else $(obj).val("");
+               };
+               
+               var filename = $(this).val();
+               
+               //CHK File ext
+               var imgExts = [ "txt", "xls", "xlsx", "doc", "docx"
+                                     , "ppt", "pptx", "pdf", "bmp", "gif", "jpeg"
+                                     , "jpg", "png", "zip"];
+               var fileExt  = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
+               var findFlag = false;
+               for(var i = 0; i < imgExts.length; i++) {
+                       if(imgExts[i] == fileExt) {
+                               findFlag = true;
+                               break;
+                       }
+               }
+       
+               if(findFlag == false) {
+                       alert( fileErrMsg["ext_" + localeCode] );
+                       initFileInput(this);
+//                     setTab(localeCode); //thread_write에도 있는데 실제로 본체가 없음.
+                       return;
+               }
+               
+               //CHK File Size
+               if(
+                               ($.browser.msie && $.browser.version >= 10.0 ) //msie
+                               || $.browser.mozilla //FF
+                               || $.browser.safari //Chrome
+               )
+               {
+                       var filesize = parseInt(this.files[0].size/1024/1024); //MB;
+                       if( filesize > 200 ) {
+                               alert( fileErrMsg["limit_" + localeCode] );
+                               initFileInput(this);
+                               return;
+                       }
+               }
+               
+               $(this).parent().find('input.file').attr("disablesd","disabled").val(filename);
+       });
+};
+
+
+// Show or Hide Toggle
+function showToEx(args){
+
+       if(!arguments.length) return false;
+       
+       var bt = $('#'+args.bt);
+       var obj = $('#'+args.obj);
+
+       var source = bt.css('background-image');
+       
+       if(obj.is(':visible')){
+               obj.hide();
+       }
+
+       bt.toggle(function(){
+               var src = source.replace('.gif','_.gif');
+               bt.css('background-image', src);
+               obj.show();
+               
+               return false;
+       },function(){
+               var src = source.replace('_.gif','.gif');
+               bt.css('background-image', src);
+               obj.hide();
+
+               return false;
+       });
+
+}
+
+
+// FAQ 20131016
+function faqToEx(){
+
+ var $question = $('#contents').find('.question');
+ var $answer = $('#contents').find('.answer');
+
+ // All Answer Rows Hide
+ $answer.hide().find('.conts').hide();
+
+ $question.each(function(){
+  var $self = $(this);
+  $self.append("<div style='display: none'>" + $self.find("a").html() + "</div>");
+  
+  $self.find('a').bind('click',function(){
+   $("#selArea ul").hide();
+   /*
+   if($(this).parents('tr').next().find('.answer').is(':visible')) return false;
+
+   $answer.hide().find('.conts').hide();
+   $(this).parents('tr').next().find('.answer').show().find('.conts').slideDown('normal');
+   */
+
+   /* 20120822 hjh modify*/
+   /* if ( this open )?  close : all close, e.target open */
+   var cutTtl  = $(this).parent().children("div").html();
+   var ttl     = $(this).parent().parent().children("td.real_question").html();
+   
+   if($(this).parents('tr').next().find('.answer').is(':visible')){
+    $(this).html(cutTtl);
+    $(this).parents('tr').next().find('.answer').find('.conts').slideUp('fast',function(){
+     $answer.hide();
+    });
+   }else{
+    titleInit();
+    $(this).html(ttl);
+    $answer.hide().find('.conts').hide();
+    //$answer.slideUp('normal').find('.conts').hide();
+    $(this).parents('tr').next().find('.answer').show().find('.conts').slideDown('slow'); 
+   }   
+
+   return false;
+  });
+ });
+
+ $answer.each(function(){
+  var $self = $(this);
+
+  $(this).find('a.bt-close-faq').bind('click',function(){
+   var question_td = $(this).parent().parent().parent().prev().children("td.question");
+   var cutTtl      = question_td.children("div").html();
+   question_td.children("a").html(cutTtl);
+   
+   $self.find('.conts').slideUp('fast',function(){
+    $self.hide();
+   });
+
+   return false;
+  });
+ });
+ var titleInit = function() {
+  $question.each(function(i) {
+   $(this).find("a").html($(this).find("div").html());
+  });
+ }
+}
+
+
+
+/**
+ *  쓰기페이지 Tab 영역 컨트롤
+ *  @param     selector        텝을 선택했을 때 교체할 레이어 선택자 ex) '.bbs-write:not(#opt)'
+ */
+function setSwitchTab( selector ) {
+       var tabs = $('.tab-list').find("li");
+       var elements = $( selector );
+
+       $( elements ).each( function( i ) {
+               if( i != 0 )
+               {
+                       $(this).hide();
+               }
+       })
+
+       // Control Tabs
+       $( tabs ).each( function( i ) {
+               $( this ).click( function(){
+                       resetClass();
+
+                       $( this ).find( 'a' ).addClass( "sel" );
+                       $( elements[i] ).show();
+
+                       return false;
+               });
+       });
+
+       // Class 리셋
+       function resetClass()
+       {
+               $( tabs ).each( function( i ) {
+                       $( this ).find( 'a' ).removeClass( 'sel' );
+               });
+
+               $( elements ).each( function( i ) {
+                       $( this ).hide();
+               });
+       }
+}
+
+var SET_ATTACH_LIMIT;
+var SET_ATTACH_WIDTH;
+var SET_ATTACH_BTNNAME;
+
+var firstAddAction = function(obj, limit, w, btnName) {
+ var bn            = btnName || 'File';
+ var fileAttachStr = "<li class='clfix no-first'>";
+ fileAttachStr += '<div class="attach">';
+ fileAttachStr += '<input readonly="readonly" disabled="disabled" type="text" class="ipt-txt file" />';
+ fileAttachStr += '<span class="fbtn" style="margin-left: 4px;">' + bn + '</span>';
+ fileAttachStr += '<input type="file" name="file" class="upload" title="File upload" />';
+ fileAttachStr += '</div>';
+ fileAttachStr += '<a href="#none" class="remove-btn fl" style="margin-left: 3px;">remove file</a>';
+ fileAttachStr += '</li>';
+ obj.on("keydown", function(e) {
+  if(e.which == 9 && e.shiftKey) {
+   e.preventDefault();
+   setTimeout(function() {
+    $("a.remove-btn").eq(0).focus();
+   }, 1);
+  }
+ });
+ obj.click( function()
+ {
+  var ul = $( this ).parentsUntil( $("td"), ".file-att-form" );
+  
+  if( $( ul ).find( "li" ).length >= limit )
+  {
+   alert( "Only " + limit + " files are allowed" );
+   return;
+  }
+  //$( fileAttachStr ).find( ".ipt-txt" ).css("width", w + "px" );
+  $( ul ).append( fileAttachStr );
+  var removeBtns = $( ul ).find( ".remove-btn" ).last();
+  $( removeBtns ).bind( "click", onBtnFileDetachClick );
+  
+  
+  removeBtns.on("keydown", function(e) {
+   var that = $(this);
+   if(e.which == 9 && e.shiftKey) {
+    e.preventDefault();
+    setTimeout(function() {
+     that.prev().find("input[type=file]").focus();
+    }, 1);
+   }
+  });
+  
+  var addInputFile = $("ul.file-att-form input[type=file]").last(); 
+  
+  addInputFile.on("keydown", function(e) {
+   var that = $(this);
+   if(e.which == 9 && e.shiftKey) {
+    return true;
+   }
+   
+   if(e.which === 9) {
+    e.preventDefault();
+    setTimeout(function() {
+     that.parent().parent().find("a.remove-btn").eq(0).focus();
+    }, 1);
+   }
+  }).on("focusin", function(e) {
+   $(this).parent().css("outline", "1px dotted #2d2d2d");
+  }).on("focusout", function(e) {
+   $(this).parent().css("outline", "");
+  });
+
+  fileUpload( w + 50 );
+  updateFileField();
+  return false;
+ });
+ function onBtnFileDetachClick()
+ {
+  var that = $(this);
+  $( this ).unbind( "click", onBtnFileDetachClick );
+   var a = that.parent().prev().children("a").eq(0);
+   setTimeout(function() {
+   that.parents(".no-first").remove();
+  }, 1);
+  
+  setTimeout(function() {
+   a.focus();
+  }, 300);
+  return false;
+ }
+ function updateFileField()
+ {
+  var ul = $( ".file-att-form" );
+  $( ul ).find( ".ipt-txt" ).css( "width", w + "px" );
+ }
+}
+
+var firstRemoveAction = function(id) {
+ var obj = $("#" + id);
+ var compFile    = $("input[type=file]");
+ var compFileCnt = compFile.size();
+ var ulObj       = compFile.eq(0).parent().parent().parent();
+ if(compFileCnt <= 1) {
+  var firstCompFile = compFile.eq(0);
+  firstCompFile.prev().prev().val("");
+  if ($.browser.msie) {
+               $(obj).parent().find('input.file').val("");
+               firstCompFile.replaceWith( firstCompFile.clone(true) );
+       } else {
+               firstCompFile.val("");
+               firstCompFile.prev().prev().val("");
+  }
+ } else {
+  obj.parent().remove();
+  ulObj.find("a.remove-btn").eq(0).after("<a href=\"JAVA-SCRIPT:;\" class=\"add-btn fl\" style=\"margin-left: 3px;\">add file</a>");
+  
+  //add-btn event..
+  firstAddAction($("a.add-btn"), SET_ATTACH_LIMIT, SET_ATTACH_WIDTH, SET_ATTACH_BTNNAME);
+ }
+ ulObj
+ .find("li")
+ .eq(0)
+ .removeClass("no-first")
+ .find("a.remove-btn")
+ .attr("id", id)
+ .unbind("click");
+ setTimeout(function() {
+  $("#" + id).focus();
+ }, 100);
+ $("#" + id).on("keydown", function(e) {
+  if(e.which == 9 && e.shiftKey) {
+   e.preventDefault();
+   var that = $(this);
+   setTimeout(function() {
+    that.prev().focus();
+   }, 1);
+  }
+ });
+ $("#" + id).on("click", function(e) {
+  firstRemoveAction($(this).attr("id"));
+ });
+}
+
+/** 
+ * File 첨부컨트롤
+ * @param limit 최대 파일 첨부 갯수
+ * @param width 파일 업로드 필드의 너비 <- 2012-08-08 추가
+ */
+function setAttachFile( limit, width, btnName, removeBtnId )
+{
+ var w = width == null || width == undefined  || isNaN( width ) ? 180 : width;
+ var btnFileAttach = $( 'ul.file-att-form' ).find( 'a.add-btn' );
+ var inputFile     = $( 'ul.file-att-form input[type=file]' );
+ SET_ATTACH_LIMIT = limit;
+ SET_ATTACH_WIDTH = w;
+ SET_ATTACH_BTNNAME = btnName;
+ inputFile.on("keydown", function(e) {
+  var that = $(this);
+  
+  if(e.which == 9 && e.shiftKey) {
+   return true;
+  }
+  
+  if(e.which === 9) {
+   e.preventDefault();
+   setTimeout(function() {
+    that.parent().parent().find("#" + removeBtnId).eq(0).focus();
+   }, 1);
+  }
+ });
+ inputFile.on("focusin", function(e) {
+  $(this).parent().css("outline", "1px dotted #2d2d2d");
+ }).on("focusout", function(e) {
+  $(this).parent().css("outline", "");
+ });
+ firstAddAction(btnFileAttach, limit, w, btnName);
+ /*
+ btnFileAttach.on("keydown", function(e) {
+  if(e.which == 9 && e.shiftKey) {
+   e.preventDefault();
+   setTimeout(function() {
+    inputFile.focus();
+   }, 1);
+  }
+ });
+ btnFileAttach.click( function()
+ {
+  var ul = $( this ).parentsUntil( $("td"), ".file-att-form" );
+  
+  if( $( ul ).find( "li" ).length >= limit )
+  {
+   alert( "Only " + limit + " files are allowed" );
+   return;
+  }
+  //$( fileAttachStr ).find( ".ipt-txt" ).css("width", w + "px" );
+  $( ul ).append( fileAttachStr );
+  var removeBtns = $( ul ).find( ".remove-btn" ).last();
+  $( removeBtns ).bind( "click", onBtnFileDetachClick );
+  
+  
+  removeBtns.on("keydown", function(e) {
+   var that = $(this);
+   if(e.which == 9 && e.shiftKey) {
+    e.preventDefault();
+    setTimeout(function() {
+     that.prev().find("input[type=file]").focus();
+    }, 1);
+   }
+  });
+  
+  var addInputFile = $("ul.file-att-form input[type=file]").last(); 
+  
+  addInputFile.on("keydown", function(e) {
+   var that = $(this);
+   if(e.which == 9 && e.shiftKey) {
+    return true;
+   }
+   
+   if(e.which === 9) {
+    e.preventDefault();
+    setTimeout(function() {
+     that.parent().parent().find("a.remove-btn").eq(0).focus();
+    }, 1);
+   }
+  }).on("focusin", function(e) {
+   $(this).parent().css("outline", "1px dotted #2d2d2d");
+  }).on("focusout", function(e) {
+   $(this).parent().css("outline", "");
+  });
+
+  fileUpload( w + 50 );
+  updateFileField();
+  return false;
+ });
+
+ // File 제거 버튼
+ function onBtnFileDetachClick()
+ {
+  var that = $(this);
+  $( this ).unbind( "click", onBtnFileDetachClick );
+   var a = that.parent().prev().children("a").eq(0);
+   setTimeout(function() {
+   that.parents(".no-first").remove();
+  }, 1);
+  
+  setTimeout(function() {
+   a.focus();
+  }, 300);
+  return false;
+ }
+ */
+ /**
+  *  2012-08-08 전종호 추가
+  *  파일 Input Text 영역 너비를 잡아주는 메서드
+  */
+ function updateFileField()
+ {
+  var ul = $( ".file-att-form" );
+  $( ul ).find( ".ipt-txt" ).css( "width", w + "px" );
+ }
+
+ updateFileField();
+ fileUpload( w + 50 );
+ $("#" + removeBtnId).on("click", function(e) {
+  firstRemoveAction($(this).attr("id"));
+ });
+}
+
+
+
+/** 
+ * [PAGE] device speces list page
+ * date : 20120808
+ * id : hjh
+ */
+function initDevicespecsList (){
+       var isCompareView=false;
+       $("#devicespecs-list > li").each( 
+               function(i){ 
+                       $(".info", this).bind("click", devicespecsListInfoToggle);
+                       $(".xx", this).bind("click", devicespecsListInfoToggle);
+                       
+                       //detail info layer toggle function
+                       function devicespecsListInfoToggle (){
+                               $("#devicespecs-list li:nth-child("+(i+1)+") .info-detail").toggle();
+                               return false;
+                       }
+       });
+
+
+       /* DEVICE COMPARE 열리는 부분
+       - defualt : close. 
+       - 최초 한번만 열림 
+       - 현재는 compare 버튼에 공통으로 함수 바인딩
+       */
+       function devicespecsCompareOnOff (){
+               if ( isCompareView ) return;
+               var ww = ( isCompareView ) ? "30px":"207px";
+               $("#devicespecs-compare").animate({
+                   height: ww }, 300, "linear", function(){ });
+
+               isCompareView = ( isCompareView ) ? false:true;
+               return false;
+       }
+
+       //compare 버튼 공통으로 클릭 이벤트 걸림 
+       $(".compare").bind("click", function (){ devicespecsCompareOnOff() });
+}
+
+/** 
+ * [PAGE] device speces view page
+ * date : 20120808
+ * id : hjh
+ */
+ function initDevicespecsView (){
+       var isImgView = false;
+       var isView = 0;
+       
+       //thumbnail overevent bind
+       $("#img-viewer-thumbnail > li").each( function(i){ $(this).bind("mouseover focusin",function(){focusDeviceDetail(i+1);}); } );
+       focusDeviceDetail (1);
+       
+       $("#img-viewer-thumbnail li").last().on("keydown keyup", function(e) {
+               if(e.which == 9 && e.shiftKey) {
+                       return true;
+               }
+               
+               if(e.type === "keydown" && e.which == 9) {
+                       setTimeout(function() {
+                               $("#img-viewer-handle a").eq(0).focus();        
+                       }, 1);
+               }
+       });
+       
+       //thumbnail viewarea controll handler bind
+       $("#img-viewer-handle").click(function () {
+               var ww;
+               var src = $("#img-viewer-handle img").attr("src");
+               if ( isImgView ){
+                       ww = "300px";
+                       src = src.replace(".gif", "_.gif");
+                       $("#img-viewer-thumbnail").hide();
+                       $("#device-info").show();
+               }else{
+                       ww = "730px";
+                       src = src.replace("_.gif", ".gif");
+                       $("#img-viewer-thumbnail").show();
+                       $("#device-info").hide();
+                       focusDeviceDetail(1);
+               }
+               
+               $("#img-viewer-handle img").attr("src", src);
+       $("#img-viewer").animate({
+                   width: ww
+                       }, 300, "linear", function(){
+                       if($.browser.msie)
+                               $("#img-inner").css("width", ww);
+               });
+               
+       isImgView = ( isImgView ) ? false:true;
+    });
+
+       //thumbnail overevent function (update date 2012.09.05 kangki)
+       function focusDeviceDetail ( id ) {
+               if ( isView == id ) return;
+
+               $("#img-viewer-thumbnail li:nth-child("+isView+")").removeClass ("on");
+               var imgSrc = $("#img-viewer-thumbnail li:nth-child("+id+")").addClass ("on").find('img').attr('src');
+
+               $( "#img-viewer-bic > img").attr("src", imgSrc);
+               isView = (id);          
+       }
+
+       /*toggle devicespecs List*/
+       if($('div#contents').find('.devicespec-tit').length){
+               
+               $('.devicespec-tit').each(function(){
+                       var self = $(this);
+                       $('a', self).bind ("click", fnToggle);
+
+                       function fnToggle(){
+
+                               if ( $(this).parent().parent().next().is(':visible') ){
+                                       $(this).css('background-image', $(this).css('background-image').replace('.gif','_.gif'));
+
+                                       self.find('em').text('Show');
+                                       self.next().hide();
+
+                                       return false;
+                               }else{
+                                       $(this).css('background-image', $(this).css('background-image').replace('_.gif','.gif'));
+                                       self.find('em').text('Hide');
+                                       self.next().show();
+
+                                       return false;
+                               }
+                       }
+                                                       
+               });
+       }
+
+       /*all Show Hide devicespecs List*/
+       if($('div#contents').find('.devicespecs-util').length){
+               var self = $('div#contents').find('.devicespecs-util');
+
+               $('.showA', self).bind ("click", function (){
+                       $('.devicespec-tit').each(function(){
+
+                               var me = $(this);
+                               if ( !me.next().is(':visible') ){
+                                       me.find("a").css('background-image', me.find("a").css('background-image').replace('_.gif','.gif'));
+                                       me.find('em').text('Hide');
+                                       me.next().show();
+                               }
+                       });
+                       return false;
+               })
+               $('.hideA', self).bind ("click", function (){
+                       
+                       $('.devicespec-tit').each(function(){
+
+                               var me = $(this);
+                               if ( me.next().is(':visible') ){
+                                       me.find("a").css('background-image', me.find("a").css('background-image').replace('.gif','_.gif'));
+                                       me.find('em').text('Show');
+                                       me.next().hide();
+                               }
+                                                               
+                       });
+                       return false;
+               })
+       }       
+}
+
+/** 
+ * [PAGE] Search Result
+ * date : 20120810
+ * author : 전종호
+function searchInit()
+{
+       var focusTarget = "input";
+
+       $("#searchInput").bind("keydown", checkSearchText);
+       $("#searchInput").focusout(function() {
+               if( focusTarget == "dropdown" )
+               {
+                       return false;
+               }
+               else
+               {
+                       //toggleClass( false );
+               }
+       });
+       
+       $( "#searchInput" ).focusin( function() {
+               focusTarget = "input";
+       });
+
+       $("#btnDropdown").mousedown( function(){
+               focusTarget = "dropdown";
+       });
+
+       $(".autocomplete ul li").focusin( function() {
+               //
+       });
+
+       $(".autocomplete ul li:last-child").focusout( function() {
+               toggleClass( false );
+       })
+
+       $(".autocomplete").mouseleave(function(){
+               toggleClass( false );
+       });
+       
+       $("#btnDropdown").click( function(){
+               //alert("btn click");
+               if( $("#searchInput").val().length == 0 ){ 
+                       return false;
+               }
+               else{
+                       if( $("#btnDropdown").hasClass("dropdown") ){
+                               toggleClass( true );
+                       }
+                       else{
+                               toggleClass( false );
+                       }
+               }
+
+               return false;
+       });
+
+       function checkSearchText(){
+               setTimeout(function(){
+                       var txt = $("#searchInput").val();
+
+                       if( txt.length > 0 ){
+                               toggleClass( true );
+                       }
+                       else{
+                               toggleClass( false );   
+                       }
+               }, 1);
+       }
+
+       function toggleClass( bo ){
+               if( bo ){
+                       $(".autocomplete").css("visibility", "visible");
+
+                       $("#btnDropdown").removeClass("dropdown");
+                       $("#btnDropdown").addClass("dropdownoff");
+
+                       var hei = $(".autocomplete").find('>ul').outerHeight();
+                       if(hei>400){
+                               $(".autocomplete").css({'height':'400px','overflow-y':'auto'});
+                       }
+               }
+               else{
+                       $(".autocomplete").css("visibility", "hidden");
+                       
+                       $("#btnDropdown").removeClass("dropdownoff");
+                       $("#btnDropdown").addClass("dropdown");
+               }
+       }
+}
+ */
+
+function setTopScroll(selector) {
+       if ( !selector ) return false;
+       var btn = $( selector );
+       var w = $( window );
+       btn.css( "position", "absolute" );
+
+
+       btn.click( function(){ w.scrollTop( 0 ) } );
+
+       var wheight = w.innerHeight();
+       
+       $(window).resize( function() {
+               wheight = w.innerHeight();
+               redraw();
+       });
+
+       $(window).scroll( function() {
+               redraw();
+       })
+
+       /**
+        *      Top 버튼의 재정렬 메서드
+        */
+       function redraw()
+       {
+               var t = w.scrollTop() + wheight - 289;
+
+               if( t < wheight / 2 && w.scrollTop() == 0 )     {
+                       t = wheight / 2;
+               }
+               
+               btn.clearQueue();
+
+               btn.animate({
+           top: t
+               }, 500, function() {
+           // Animation complete.
+               });
+               //btn.css( "top", t );
+               //console.log( "target : " + t );
+       }
+
+       redraw();
+       /*
+       obj.initTop = position;
+       obj.topLimit = topLimit;
+       obj.bottomLimit = Math.max( document.documentElement.scrollHeight, document.body.scrollHeight ) - btmLimit - obj.offsetHeight;
+
+       obj.style.position = "absolute";
+       obj.top = obj.initTop;
+       // obj.left = obj.initLeft;
+
+       if ( typeof( window.pageYOffset ) === "number" ) {      //WebKit
+               obj.getTop = function() {
+                       return window.pageYOffset;
+               }
+       } else if ( typeof( document.documentElement.scrollTop ) === "number" ) {
+               obj.getTop = function() {
+                       return Math.max( document.documentElement.scrollTop, document.body.scrollTop );
+               }
+       } else {
+               obj.getTop = function() {
+                       return 0;
+               }
+       }
+
+       if ( self.innerHeight ) {       //WebKit
+               obj.getHeight = function() {
+                       return self.innerHeight;
+               }
+       } else if( document.documentElement.clientHeight ) {
+               obj.getHeight = function() {
+                       return document.documentElement.clientHeight;
+               }
+       } else {
+               obj.getHeight = function() {
+                       return 500;
+               }
+       }
+
+       obj.move = setInterval( function() {
+               if ( obj.initTop > 0 ) {
+                       pos = obj.getTop() + obj.initTop;
+               } else {
+                       pos = obj.getTop() + obj.getHeight() + obj.initTop;
+               }
+
+               if ( pos > obj.bottomLimit ) pos = obj.bottomLimit;
+               if ( pos < obj.topLimit ) pos = obj.topLimit;
+
+               interval = obj.top - pos;
+               obj.top = obj.top - interval / 3;
+               obj.style.top = obj.top + "px";
+       }, 30 )
+       */
+}
+
+
+//popup
+function pop(url,name,w,h){window.open(url,name,'width='+w+',height='+h+',scrollbars=no')} //Popup(스크롤바없음)
+function pops(url,name,w,h){ window.open(url,name,'width='+w+',height='+h+',scrollbars=yes') } //Popup(스크롤바있음)
+
+//popup 중앙에 띄우기
+function pop_center(){ 
+       var x,y; 
+       if (window.innerHeight) { // IE 외 모든 브라우저 
+               x = (screen.availWidth - self.innerWidth) / 2; 
+               y = (screen.availHeight - self.innerHeight) / 2; 
+       }else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict 모드 
+               x = (screen.availWidth - document.documentElement.clientWidth) / 2; 
+               y = (screen.availHeight - document.documentElement.clientHeight) / 2; 
+       }else if (document.body) { // 다른 IE 브라우저( IE &lt; 6) 
+               x = (screen.availWidth - document.body.clientWidth) / 2; 
+               y = (screen.availHeight - document.body.clientHeight) / 2; 
+       } 
+       window.moveTo(x,y); 
+}
+
+// Layer Popup Open
+function layer_open(el){
+       var temp = $('#' + el);
+
+       if(!temp.hasClass('sty2')){
+               $('.layer').fadeIn();
+       }
+
+       if (temp.outerHeight() < $(document).height() ) temp.css('margin-top', '-'+temp.outerHeight()/2+'px');
+       else temp.css('top', '0px');
+       if (temp.outerWidth() < $(document).width() ) temp.css('margin-left', '-'+temp.outerWidth()/2+'px');
+       else temp.css('left', '0px');
+
+       if(temp.hasClass('sty2')){
+               temp.fadeIn();
+
+               temp.find('a.cbtn').click(function(e){
+                       temp.fadeOut();
+               });
+               temp.find('a.gbtn').click(function(e){
+                       temp.fadeOut();
+               });
+
+               return false;
+       }
+       // 닫는 버튼 gbtn-c 추가 20130627
+       $('.layer .bg, .pop-header .close, .gbtn-c').click(function(){
+               $('.layer').fadeOut();
+               return false;
+       });
+}
+
+// background dim - 2013-05-31
+function layer_open2(el){
+       var temp = $('#' + el);
+       $('input').attr('disabled', 'disabled');
+       $('.layerPop').fadeIn();
+       
+
+       if (temp.outerHeight() < $(document).height() ) temp.css('margin-top', '-'+temp.outerHeight()/2+'px');
+       else temp.css('top', '0px');
+       if (temp.outerWidth() < $(document).width() ) temp.css('margin-left', '-'+temp.outerWidth()/2+'px');
+       else temp.css('left', '0px');
+
+       $('.layerPop .bg, .pop-header .close, .gbtn, .cbtn').click(function(){
+               $('.layerPop').fadeOut();
+               $('input').removeAttr('disabled');
+               return false;
+       });
+}
+
+
+function pop_account(url){
+       window.open(url,'account','width=619,height=591,scrollbars=yes')
+}
+
+function pop_loadDoc(url){
+       window.open(url,'online','width=850,height=600,scrollbars=yes')
+}
+
+/** 
+ *  [PAGE] Tags
+ *  date : 20120820
+ *  author : 전종호
+ */
+function initTags()
+{
+       // Tag리스트의 각 엘리먼트 뒤에 "," 리터럴 추가.
+       // 마지막 아이템은 제외
+       var eleArr = $(".tag-list").find("li");
+
+       $( eleArr ).each( function( i ) {
+               if( i < eleArr.length - 1 )
+               {
+                       var target = $(this).find("a")[0];
+                       var content = $( target ).html();
+
+                       $( target ).html( content + "," );
+               }
+       })
+}
+
+$(document).ready(function(){
+       $(".tip_info").css("cursor","pointer");
+       $(".tip_info > img").mouseover(function(){
+               $(".tip_cont").css("display","block");
+       });
+       $(".tip_info > img").mouseout(function(){
+               $(".tip_cont").css("display","none");
+       });
+});
+
+// new layer popup script by ygh 2013.11.14
+
+var isPopup = false ;
+
+function popupLayerView(id){
+
+       var $L = $("#" + id) ;
+       var $D  = $("#" + id + "down") ;
+
+       $T = $("#" + id) ;
+
+       $L.show();
+       isPopup = true ;
+
+       $('html, body').animate({ scrollTop: $L.offset().top }, 500);
+
+       $("#" + id + "agree").focus() ;
+
+       jQuery(":focusable").focusin(function(e){
+               if (isPopup) {
+                       e.stopPropagation() ;
+                       if ($L.find(jQuery(this)).length > 0) {
+                       } else {
+                               jQuery(this).blur() ;
+                               jQuery("#" + id + " :focusable:first").focus() ;
+                       }
+               }
+       }) ;
+
+       $L.find('.close').click(function(){
+               resetPopup(id) ;
+       });
+
+       $("#" + id + "agree").click(function() { $(this).is(':checked') ? $D.show() : $D.hide() ; });
+}
+
+function resetPopup(T) {
+       $("#" + T + "down").hide();
+       $("#" + T + "agree").attr("checked", false) ;
+       isPopup = false ;
+       $("#" + T).hide() ;
+       $("#" + T + "Btn").focus() ;
+}
+
+function getDownload(T, F, I) {
+       if ($("#" + T + "agree").is(':checked')) {
+               commonDownloadLog(F, I) ;
+               resetPopup(T) ;
+       }
+}
+
+function focusable( element, isTabIndexNotNaN ) {
+       var map, mapName, img, nodeName = element.nodeName.toLowerCase() ;
+       if ( "area" === nodeName ) {
+               map = element.parentNode;
+               mapName = map.name;
+               if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { return false ; }
+               img = $( "img[usemap=#" + mapName + "]" )[0];
+               return !!img && visible( img );
+       }
+       return ( /input|select|textarea|button|object/.test( nodeName ) ? !element.disabled : "a" === nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN) && // the element and all of its ancestors must be visible
+                       visible( element ) ;
+}
+
+function visible( element ) {
+       return $.expr.filters.visible( element ) && !$( element ).parents().addBack().filter(function() {
+               return $.css( this, "visibility" ) === "hidden";
+       }).length;
+}
+if ( !$.fn.addBack ) { $.fn.addBack = function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter( selector ) ); }; }
+
+$.extend( $.expr[ ":" ], {
+       data: $.expr.createPseudo ? $.expr.createPseudo(function( dataName ) { return function( elem ) { return !!$.data( elem, dataName ); }; }) : function( elem, i, match ) { return !!$.data( elem, match[ 3 ] ); },
+       focusable: function( element ) { return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); },
+       tabbable: function( element ) { var tabIndex = $.attr( element, "tabindex" ), isTabIndexNaN = isNaN( tabIndex ); return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); }
+});
+// new layer popup script by ygh 2013.11.14
+
+// 2013-11-15 타이젠 썸네일 추가
+$(document).ready(function() {
+       $('.view_device1').hide();
+       
+       $('#thumb_view_btn').hover(function() {
+               $('.view_device1').show();
+       },function() {
+               $('.view_device1').hide();
+       });
+               
+});
+
+// 2014-04-22 타이젠 썸네일 추가
+$(document).ready(function() {
+       $('.view_device2').hide();
+       
+       $('#thumb_view_btn2').hover(function() {
+               $('.view_device2').show();
+       },function() {
+               $('.view_device2').hide();
+       });
+               
+});
+
+
+function beforePopupLayerView(popId, popId2, popContinue){
+       var $L = $("#" + popId) ;
+       $L.show(100);
+       $('html, body').animate({ scrollTop: $L.offset().top }, 500);
+       $L.find('.close').click(function(){
+               $L.hide();
+       });
+       $L.find("." + popContinue).click(function() { $L.hide(); popupLayerView(popId2); });
+}
diff --git a/nui/scripts/core.js b/nui/scripts/core.js
new file mode 100644 (file)
index 0000000..68dea4c
--- /dev/null
@@ -0,0 +1,899 @@
+// /////////////////////////////////////////////////////////////////////////////////////////////////
+// # com.samsung.devloper common core javascript #
+// # Create Date : 2012.07.10. 
+// # Create By : kangki
+;(function ($) {
+/**
+ * Samsung Developer Common JavaScript
+ */
+$.SD = {};
+
+/*
+ * Method Common
+ */
+$.SD.message = function (msg) { if (msg) alert(msg); };
+$.SD.replaceAll = function (str, from, to) { return str.split(from).join(to); }
+$.SD.typeOf = function (data) { var func = func || Object.prototype.toString; return func.call(data); };
+$.SD.typeTest = function (data, datatype) {
+       if (datatype === "String" || datatype === "string") return /String/.test($.SD.typeOf(data));
+       if (datatype === "Number" || datatype === "number") return /Number/.test($.SD.typeOf(data));
+       if (datatype === "Array" || datatype === "array") return /Array/.test($.SD.typeOf(data));
+       if (datatype === "Boolean" || datatype === "boolean") return /Boolean/.test($.SD.typeOf(data));
+       if (datatype === "Function" || datatype === "function") return /Function/.test($.SD.typeOf(data));
+       if (datatype === "Date" || datatype === "date") return /Date/.test($.SD.typeOf(data));
+       if (datatype === "Object" || datatype === "object") return /Object/.test($.SD.typeOf(data));
+
+       return (new RegExp("/" + datatype + "/")).test($.SD.typeOf(data));
+};
+
+$.SD.toDate = function (date, seperator) {
+       if (!seperator) seperator = '-';
+
+       date = $.SD.replaceAll(date, seperator, '');
+       date = $.SD.replaceAll(date, '/', '');
+
+       if (date.length !== 8) return null;
+       
+       date = new Date(date.substring(0,4) + '/' + date.substring(4,6) + '/' + date.substring(6,8));
+
+       if (date.valueOf().toString() === 'NaN') return null;
+
+       return date;
+};
+
+$.SD.toDateString = function (date, seperator) {
+       if (!seperator) seperator = '/';
+       if (/String/.test(Object.prototype.toString.call(date))) date = $.SD.toDate(date);
+       if (/Date/.test(Object.prototype.toString.call(date)) === false) return "";
+
+       var str, dateString = date.getFullYear();
+
+       str             = "0" + (date.getMonth()+1);
+       dateString      = dateString + seperator + str.substring(str.length-2, str.length);
+       str             = "0" + date.getDate();
+       dateString      = dateString + seperator + str.substring(str.length-2, str.length);
+
+       return dateString;
+};
+
+$.SD.addYear = function (date, number) { date.setYear(date.getFullYear() + number); return date; };
+$.SD.addMonth = function (date, number) { date.setMonth(date.getMonth() + number); return date; };
+$.SD.addDate = function (date, number) { date.setDate(date.getDate() + number); return date; };
+
+$.SD.insertComma = function(num) {
+       var tnum    = num + "";
+       var tarr    = new Array();
+       var dot     = "";
+       var idxDot  = tnum.indexOf(".");
+       var sign    = "";
+       var tinx    = 0;
+       var fnum    = tnum;
+        
+       
+       if(idxDot > -1) {
+               fnum = tnum.substring(0, idxDot);
+               dot  = tnum.substring(idxDot);
+               tnum = fnum;
+       } 
+       
+       if(tnum.indexOf("-") > -1) {
+               fnum = tnum.substring(1);
+               sign = tnum.substring(0, 1);
+       }
+       
+       for(var inx = fnum.length; inx > 0; ) {
+               tarr[tinx++] = fnum.substring(inx, inx - 3);
+               inx = inx - 3;
+       }
+       
+       return sign + tarr.reverse().join(",") + dot;
+}
+
+/**
+ * Method Ajax
+ */
+$.SD.ajax = {
+       doAjax : function (json) {
+               var param = {
+                       async : json.async,
+                       type : json.type,
+                       dataType : json.dataType,
+                       cache: json.cache,
+                       timeout : json.timeout,
+                       success : json.success,
+                       error : json.error
+               };
+
+               if (param.dataType === 'jsonp') {
+                       param.url = json.url + '?' + $.param(json.data) + '&callback=?';
+               } else {
+                       param.url = json.url;
+                       param.data = json.data;
+               }
+               $.ajax(param);
+       },
+       
+       get : function (json) {
+               $.SD.ajax.doAjax({ 
+                       url:json.url,
+                       cache:json.cache != null ? json.cache : false,
+                       async:json.async != null ? json.async : true,
+                       type:'get', 
+                       dataType:'json',
+                       data:json.data != null ? json.data : {}, 
+                       timeout:10000, success:json.success, 
+                       error: function(){ if(json.error != null)json.error(); }
+               });
+       },
+       
+       post : function (json) {
+               $.SD.ajax.doAjax({ url:json.url,
+                       cache: json.cache != null ? json.cache : false,
+                       async:json.async != null ? json.async : true,
+                       type:'post', dataType:'json',
+                       data:json.data != null ? json.data : {}, 
+                       timeout:10000, success:json.success, 
+                       error: function(){ if(json.error != null)json.error(); }
+               });
+       }
+};
+
+/**
+ * SD20 password check
+ */
+
+$.SD.isSD20Pwd = function(pwd) {
+       
+       if(/[a-zA-Z]{1,}/.test(pwd) == false) {
+               return false;
+       }
+       
+       if(/[0-9]{1,}/.test(pwd) == false) {
+               return false;
+       }
+       
+       if(/^[0-9a-zA-Z]{6,16}$/.test(pwd) == false) {
+               return false;
+       }
+       
+       return true;
+};
+
+$.SD.popupCenter = function(popObj) {
+       var scrollbars  = "no";
+       var resizeable  = "no";
+       
+       if(popObj.scrollbars) {
+               scrollbars = popObj.scrollbars; 
+       }
+       
+       if(popObj.resizeable) {
+               resizeable = popObj.resizeable;
+       }
+       
+       var width  = screen.width;
+       var height = screen.height;
+
+       var x = ( width / 2 ) - ( popObj.width / 2 );
+       var y = ( height / 2 ) - ( popObj.height / 2 );
+
+       var opt = "left=" + x +
+                 ",top=" + y +
+                 ",width=" + popObj.width +
+                 ",height=" + popObj.height +
+                 ",toolbar=no,location=no,directories=no,status=no,menubar=no" +
+                 ",scrollbars=" + scrollbars +
+                 ",resizable=" + resizeable;
+       var pop = window.open(popObj.url, popObj.target, opt);
+       if(pop) {
+               pop.focus();
+       }
+}
+
+$.SD.isValidDate = function(val) {
+       if(val.length != 8) {
+               return false;
+       }
+       
+       var yyyy = Number(val.substring(0, 4)); 
+       var mm   = Number(val.substring(4, 6));
+       var dd   = Number(val.substring(6));
+       
+       if( mm < 1 || mm > 12 ) {
+               return false;
+       }
+       
+       var endDay  = 0;
+       
+       if( mm == 2 ) {
+               if(yyyy % 4 == 0 && yyyy % 100 != 0 || yyyy % 400 == 0) {
+                       endDay = 29;
+               } else {
+                       endDay = 28;
+               }
+               
+       } else {
+               var endDays = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
+               endDay = endDays[mm - 1];
+       }
+       
+       if( dd <= 0 || dd > endDay ) {
+               return false;
+       } 
+       
+       return true;
+       
+}
+
+$.SD.boardDownload = function(option, func) {
+       var jsonData = {
+               url: "/board/ajaxDwnldProc.do",
+               async: false,
+               data: {ctgy1: option.ctgy1, ctgy2: option.ctgy2, ctgyId: option.ctgyId, bdId: option.bdId, attachId: option.attachId},
+               success: function(data) {
+                       if(data.existFileYn == "Y") {
+                               location.href = "/board/download.do?bdId=" + option.bdId + "&attachId=" + option.attachId;
+                               //location.href = $(obj).attr("href");
+                               if(func) {
+                                       func(data);
+                               }       
+                       } else {
+                               alert("File does not exist.");
+                       }
+               }
+       }
+       
+       $.SD.ajax.get(jsonData);
+}
+
+$.SD.commonDownload = function(fileName, categoryId, func) {
+       var jsonData = {
+               url: "/common/ajaxCommonDwnldProc.do",
+               async: false,
+               data: {fileName: fileName, categoryId: categoryId},
+               success: function(data) {
+                       if(data.existFileYn == "Y") {
+                               location.href = "/common/commonDownload.do?fileName=" + fileName + "&categoryId=" + categoryId;
+                               if(func) {
+                                       func(data);
+                               }       
+                       } else {
+                               alert("File does not exist.");
+                       }
+               }
+       }
+       
+       $.SD.ajax.get(jsonData); 
+}
+
+$.SD.commonDownloadLog = function(fileFullPath, categoryId, func) {
+       var jsonData = {
+               url: "/common/ajaxCommonDownloadLogProc.do",
+               async: false,
+               data: {fileFullPath: fileFullPath, categoryId: categoryId},
+               success: function(data) {
+                       if(data.existFileYn == "Y") {
+                               //location.href = "/common/commonDownload.do?fileName=" + fileName + "&categoryId=" + categoryId;
+                               location.href = fileFullPath;
+                               if(func) {
+                                       func(data);
+                               }       
+                       } else {
+                               alert("File does not exist.");
+                       }
+               }
+       }
+       
+       $.SD.ajax.get(jsonData); 
+}
+
+$.SD.commonDownloadLogTarget = function(fileFullPath, categoryId, target, func) {
+       var jsonData = {
+               url: "/common/ajaxCommonDownloadLogProc.do",
+               async: false,
+               data: {fileFullPath: fileFullPath, categoryId: categoryId},
+               success: function(data) {
+                       if(data.existFileYn == "Y") {
+                               //location.href = "/common/commonDownload.do?fileName=" + fileName + "&categoryId=" + categoryId;
+                               if(target == 'new'){
+                                       window.open(fileFullPath, '');
+                               }else{
+                                       location.href = fileFullPath;
+                               }
+                               
+                               if(func) {
+                                       func(data);
+                               }       
+                       } else {
+                               alert("File does not exist.");
+                       }
+               }
+       }
+       
+       $.SD.ajax.get(jsonData); 
+}
+
+$.SD.commonAllShareClickCount = function(fileFullPath, categoryId, func) {
+       var jsonData = {
+               url: "/common/ajaxCommonAllShareClickCountProc.do",
+               async: false,
+               data: {fileFullPath: fileFullPath, categoryId: categoryId},
+               success: function(data) {}
+       }
+       
+       $.SD.ajax.get(jsonData); 
+}
+
+$.SD.commonClickCount = function(categoryName, categoryId) {
+       var jsonData = {
+               url: "/common/ajaxCommonClickCountProc.do",
+               data: {categoryName: categoryName, categoryId: categoryId},
+               success: function(data) {}
+       }
+       
+       $.SD.ajax.get(jsonData);
+}
+
+$.SD.getByteLen = function(str) {
+       var resultSize = 0;
+       if(str == null){
+               return 0;
+       }
+       for(var i=0; i<str.length; i++){
+         var c = escape(str.charAt(i));
+         if(c.length == 1){
+                 resultSize ++;
+         }     else if(c.indexOf("%u") != -1) {
+                 resultSize += 2;
+         }     else if(c.indexOf("%") != -1) {
+                 resultSize += c.length/3;
+         }
+       }
+       return resultSize;
+}
+
+$.SD.cutByte = function(str, limit) {
+       var tempStr = new String(str);
+       var len = 0;
+       for ( var i = 0; i < str.length; i++) {
+               var c = escape(str.charAt(i));
+               if (c.length == 1)
+                       len++;
+               else if (c.indexOf("%u") != -1)
+                       len += 2;
+               else if (c.indexOf("%") != -1)
+                       len += c.length / 3;
+               if (len > limit) {
+                       tempStr = tempStr.substring(0, i);
+                       break;
+               }
+       }
+       return tempStr;
+}
+
+$.SD.pagination = {alt:{first:"",prev:"",next:"",last:""}};
+
+/* ---------------- ADD JQUERY CUSTOM METHOD -------------------------------- */
+
+/** 
+ * Method pagination 
+ * */
+$.fn.frontPagination = function (pageInfo, func) {
+       var info = {
+                        prev : 1
+                       ,first : 1
+                       ,begin : pageInfo.begin - 0
+                       ,current : pageInfo.current - 0
+                       ,end : pageInfo.end - 0
+                       ,last : pageInfo.last - 0
+                       ,next : 1
+               },
+               target  = this, 
+               page    = $('<span class="page"></span>'),
+               prev    = "", 
+               next    = "", 
+               i               = 0, 
+               n               = 0;
+
+       info.begin       = info.begin < 1 ? 1 : info.begin;
+       info.current = info.current < 1 ? 1 : info.current;
+       info.end         = info.end < 1 ? 1 : info.end;
+       info.last        = info.last < 1 ? 1 : info.last;
+
+       info.prev = info.current - 1;
+       info.next = info.current + 1;
+
+       target.addClass("pageNumber");
+       target.addClass("mt20");
+       target.children().remove();
+
+       if (info.first < info.begin) {
+               target.append($('<a href="#" class="first"><img src="/images/common/ico/ico_arr_first.gif" alt="'+$.SD.pagination.alt.first+'" /></a>').bind('click', function(e) {
+                       e.preventDefault();
+                       func(info.first);
+               }));
+       }
+
+       if (info.prev >= info.first) {
+               target.append($('<a href="#" class="prev"><img src="/images/common/ico/ico_arr_prev.gif" alt="'+$.SD.pagination.alt.prev+'"/></a>').bind('click', function(e) {
+                       e.preventDefault();
+                       func(info.prev);
+               }));
+       }
+
+       i = info.begin;
+       n = info.end;
+       for(; i <= n; i++) {
+               if (i === info.current) {
+                       page.append('<strong>'+i+'</strong>');
+               } else {
+                       (function(index){
+                               page.append($('<a href="#">'+index+'</a>').bind('click', function(e){
+                                       e.preventDefault();
+                                       func(index);
+                               }));
+                       })(i);
+               }
+       }
+
+       target.append(page);
+
+       if (info.next <= info.last) {
+               target.append($('<a href="#" class="next"><img src="/images/common/ico/ico_arr_next.gif" alt="'+$.SD.pagination.alt.next+'" /></a>').bind('click', function(e) {
+                       e.preventDefault();
+                       func(info.next);
+               }));
+       }
+       
+       if (info.last > info.end) {
+               target.append($('<a href="#" class="last"><img src="/images/common/ico/ico_arr_last.gif" alt="'+$.SD.pagination.alt.last+'" /></a>').bind('click', function(e) {
+                       e.preventDefault();
+                       func(info.last);
+               }));
+       }       
+};
+
+/**
+ *  Method : popup Show Hide 
+ */
+$.fn.popupShow = function(options) {
+       var opts = $.extend({}, $.fn.popupShow.defaults, options);
+       
+       if($("body div#" + opts.maskId).size() == 0) {
+               $("body").append("<div id='" + opts.maskId + "'></div>");
+               $("#" + opts.maskId).css({
+                       "position" : "absolute",
+                       "left"     : "0",
+                       "top"      : "0",
+                       "z-index"  : "9000",
+                       "background-color" : "#000",
+                       "display"  : "none"
+               });
+       }
+       
+       var mask_layer  = $("#" + opts.maskId);
+       var popup_layer = $(this);
+       
+       popup_layer.css("z-index", "9999");
+       
+       var maskHeight = $(document).height();
+       var maskWidth = $(window).width();
+       
+       mask_layer.css({'width':maskWidth,'height':maskHeight});
+       
+       mask_layer.fadeIn(opts.fadeSec);
+       mask_layer.fadeTo(opts.speed, opts.fadeLow);
+       
+       var winH = $(window).height();
+       var winW = $(window).width();
+       
+       popup_layer.css('top',  $(window).scrollTop() + winH/2 - popup_layer.height()/2);
+       popup_layer.css('left', $(window).scrollLeft()  + winW/2 - popup_layer.width()/2);
+       
+       popup_layer.fadeIn(opts.fadeSec);
+       
+       var init_num = 0;
+       
+       if(init_num == 0) {
+               mask_layer.click(function() {
+                       $(this).hide();
+                       popup_layer.hide();
+               });
+               
+               
+               $("#" + opts.closeId).click( function(e) {
+                       e.preventDefault();
+                       popup_layer.popupHidden(opts.maskId);
+               });
+               
+               
+               $(window).resize( function() {
+                       var maskHeight = $(document).height();
+                       var maskWidth  = $(window).width();
+                       var winH       = $(window).height();
+                       var winW       = $(window).width();
+                       
+                       mask_layer.css({'width':maskWidth,'height':maskHeight});
+                       
+                       popup_layer.css('top',  $(window).scrollTop() + winH/2 - popup_layer.height()/2);
+                       popup_layer.css('left', $(window).scrollLeft()  + winW/2 - popup_layer.width()/2);
+               });
+               
+               init_num++;
+       }
+};
+
+$.fn.popupHidden = function(maskId) {
+       var id = "#";
+       
+       if(maskId) {
+               id = id + maskId;
+       } else {
+               id = id + $.fn.popupShow.defaults.maskId; 
+       }
+       
+       $(id).hide();
+       $(this).hide();
+};
+
+
+$.fn.popupShow.defaults = {
+       speed : "slow",
+       fadeLow : 0.8,
+       fadeSec : 100,
+       maskId  : "mask",
+       popupId : "layer-pop",
+       closeId : "layer-pop-close"
+};
+
+/**
+ *  Method : validate File Ext
+ */
+$.fn.isNotValidateFileExt = function(imgExts) {
+       imgExts = imgExts || {txt:true, xls:true, xlsx:true, doc:true, docx:true, ppt:true, pptx:true, pdf:true, bmp:true,gif:true, jpeg:true, jpg:true, png:true, zip:true, swf:true};
+       var that = this;
+       var target = null;
+
+       that.each(function (i, item) {
+               var filePath = $(item).attr('type') === 'file' ? $(item).val() : '';
+               if (filePath != "") {
+                       var fileExt  = filePath.substring(filePath.lastIndexOf(".") + 1).toLowerCase();
+                       if (!imgExts[fileExt]) {
+                               target = item;
+                               return false;
+                       }
+               }
+       });
+
+       return target;
+}      
+
+/**
+ *  Method : validate SD20 Password
+ */
+$.validator.addMethod("isSD20Pwd", function(value, element) {
+       return this.optional(element) 
+              || $.SD.isSD20Pwd(value);
+}, "비밀번호를 다시 입력해 주세요.");
+
+$.SD.alterParent = function(options, event) {
+    var label = $(this).data('label');
+    
+    /*
+    if (event && event.type === 'focusin') {
+      label.hide();
+    } else if (event && event.type === 'focusout') {
+      label.css('opacity', options.placeholderOpacity);
+    }
+    */
+    
+    if (event && event.type !== 'keydown') {
+      toggleLabel(this, label);
+    } else {
+      // Use timeout to catch val() just after the key is pressed
+      // Using keyup is too slow.   
+      (function(input) {
+        setTimeout(function() {
+          toggleLabel(input, label);
+        }, 0);
+      })(this);
+    }
+    
+    if (event && event.type === 'focusin') {
+       label.hide();
+    }
+  };
+  
+  var toggleLabel = function(input, label) {
+    if ($(input).val()) {
+      label.hide();
+    } else {
+      label.show();
+    }
+  };
+
+  $.fn.stickyPlaceholders = function(options) {
+    var defaults = {
+      wrapperClass: 'sticky-placeholder-wrapper',
+      wrapperDisplay: 'block',
+      labelClass: 'sticky-placeholder-label',
+      placeholderAttr: 'placeholder',
+      dataAttr: 'data-sticky-placeholder',
+      placeholderColor: '#000',
+      placeholderOpacity: 0.5,
+      placeholderFocusOpacity: 0.25
+    };
+    options = $.extend(defaults, options);
+
+    return this.each(function() {
+      var input       = $(this),
+          placeholder = input.attr(options.placeholderAttr),
+          wrapper     = $(this).wrap('<span class="' + options.wrapperClass + '" />').parent().css({'position':'relative', 'display':options.wrapperDisplay}),
+          label       = $('<label class="' + options.labelClass + '" for="' + input.attr('id') + '">' + placeholder + '</label>').appendTo(wrapper),
+          labelStyle;
+
+      // store a reference to each input's label
+      input.data('label', label);
+
+      // remove the placeholder attribute to avoid conflcits
+      input.removeAttr('placeholder');
+      
+      // If the dataAttr is set and it's not equal to the placeholderAttr
+      if ( options.dataAttr && options.placeholderAttr !== options.dataAttr ) {
+        input.attr('data-sticky-placeholder', placeholder);
+      }
+
+      labelStyle = {
+        'color': options.placeholderColor,
+        'cursor': 'text',
+        'font-family': input.css('font-family'),
+        'font-weight': input.css('font-weight'),
+        'font-size': input.css('font-size'),
+        'left': parseInt(input.css('border-left-width'), 10) + parseInt(input.css('margin-left'), 10),
+        'line-height': this.currentStyle ? this.currentStyle.lineHeight : input.css('line-height'),
+        // fix for an IE/jQuery bug returning 1px when the line-height doesn't have a unit: http://bugs.jquery.com/ticket/2671
+        'opacity': options.placeholderOpacity,
+        'padding-left': input.css('padding-left'),
+        'padding-top': input.css('padding-top'),
+        'position': 'absolute',
+        'text-transform': input.css('text-transform'),
+        'top': parseInt(input.css('border-top-width'), 10) + parseInt(input.css('margin-top'), 10)
+      };
+      label.css(labelStyle);
+      
+      // hide the placeholder if the input already has a value
+      if (input.val()) {
+        label.hide();
+      }
+
+      $(this).bind('keydown input focusin focusout', function(event) {
+        $.SD.alterParent.call(this, options, event);
+      });
+        
+      // prevent click/dblclick from selecting the label text
+      label.bind('mousedown', function(e) {
+        e.preventDefault();
+      });
+      
+      // call alterParent initially without an event to set up the wrapper elements
+      $.SD.alterParent.call(this, options);
+    });
+  };
+$.SD.setInputFileKeyEvent = function(file_id, after_id) {
+       $("#" + file_id).on("keydown", function(e) {
+               var that = $(this);
+               if(e.which == 9 && e.shiftKey) {
+                       return true;
+               }
+               
+               if(e.which === 9) {
+                       e.preventDefault();
+                       setTimeout(function() {
+                               $("#" + after_id).focus();
+                       }, 1);
+               }
+       });
+       
+       $("#" + after_id).on("keydown", function(e) {
+               if(e.which == 9 && e.shiftKey) {
+                       e.preventDefault();
+                       setTimeout(function() {
+                               $("#" + file_id).focus();
+                       }, 1);
+               }
+       });
+}  
+
+$.SD.closeWP = function() {
+       var Browser = navigator.appName;
+       var indexB = Browser.indexOf('Explorer');
+       if (indexB > 0) {
+           var indexV = navigator.userAgent.indexOf('MSIE') + 5;
+           var Version = navigator.userAgent.substring(indexV, indexV + 1);
+           window.opener.focus();
+           if (Version >= 7) {
+               window.open('', '_self', '');
+               window.close();
+           }
+           else if (Version == 6) {
+               window.opener = null;
+               window.close();
+           }
+           else {
+               window.opener = '';
+               window.close();
+           }
+       }
+       else {
+           window.close();
+       }
+}
+
+$.SD.profileFacebook = function() {
+       location.replace("http://facebook.com/profile.php");
+}
+
+/* ------------------------------ END --------------------------------------- */
+window.$SD = $.SD;
+
+})(jQuery);
+
+
+$(document).ready(function(){
+//document rady Start #########################################
+
+// Top menu action Start
+var onClickChangeEn            = function(e){ e.preventDefault(); $("#langCode").val("en"); $("#chLanguage").submit(); };
+var onClickChangeZh            = function(e){ e.preventDefault(); $("#langCode").val("zh"); $("#chLanguage").submit(); };
+var onClickChangeKo            = function(e){ e.preventDefault(); $("#langCode").val("ko"); $("#chLanguage").submit(); };
+var onClickSignOut                     = function(e){ e.preventDefault(); $("#signForm").attr("action", "/sa/mbr.logout.do"); $("#signForm").submit(); };
+var onClickSignUp                      = function(e){ e.preventDefault(); $("#signForm").attr("action", "/signup"); $("#signForm").submit(); };
+var onClickSignIn                      = function(e){ e.preventDefault(); $("#signForm").attr("action", "/sa/signIn.do"); $("#signForm").submit(); };
+var onClickUserInfoUpdate      = function(e){ e.preventDefault(); $("#signForm").attr("action", "/mypage/myforum/list.do"); $("#signForm").submit(); };
+var onClickSignOff                     = function(e){ e.preventDefault(); $("#signForm").attr("action", "/sa/signOff.do"); $("#signForm").submit(); }; 
+var onClickMyProfileUpdate     = function(e){ e.preventDefault(); $("#signForm").attr("action", "/sa/update.profile.do"); $("#signForm").submit(); };
+var onClickDeleteAccount       = function(e){ e.preventDefault(); $("#signForm").attr("action", "/sa/signOff.do"); $("#signForm").submit(); };
+
+$("#wrapper").on('click', 'a', function(e) {
+        switch($(this).attr('id')) {
+        case 'changeEn': onClickChangeEn(e);  break;
+        case 'changeZh': onClickChangeZh(e); break;
+        case 'changeKo': onClickChangeKo(e); break;
+        case 'signOut': onClickSignOut(e); break;
+        case 'signUp': onClickSignUp(e); break;
+        case 'signIn': onClickSignIn(e); break;
+        case 'userInfoUpdate': onClickUserInfoUpdate(e); break;
+        case 'signOff': onClickSignOff(e); break;
+        case 'myProfileUpdate' : onClickMyProfileUpdate(e); break;
+        case 'deleteAccount' : onClickDeleteAccount(e); break;
+        }
+});
+//Top menu action End
+
+
+$("#sendFacebook, #sendTwitter").click(function(e) {
+       e.preventDefault();
+       var $this = $(this);
+       
+       if(typeof(copyUrl) != "undefined" && typeof(boardTitle) != "undefined") {
+               var sns = $this.attr("id").substring(4).toLowerCase();
+               switch(sns) {
+               case "facebook" :
+                       var imgUrl = "http://img-developer.samsung.com/images/common/logo_200x200.gif";
+                       $("div.content img").each(function() {
+                               var that = $(this);
+                               if(that.width() > 200 && that.height() > 200) {
+                                       imgUrl = that.attr("src");
+                                       return false;
+                               }
+                       });
+                       
+                       var data = {
+                               app_id : $("#sd_appId").text(),
+                               link : copyUrl,
+                               picture : imgUrl,
+                               name : $("title").text(),
+                               caption : "developer.samsung.com",
+                               description : $("div.content p").eq(0).text(),
+                               redirectUri : "http://" + location.host + "/board/sns.do"
+                       };
+                       var url = "https://www.facebook.com/dialog/feed?" ;
+                       url += "app_id=" + data.app_id + "&" ;
+                       url += "link=" + data.link + "&" ;
+                       url += "picture=" + data.picture + "&" ;
+                       url += "name=" + encodeURIComponent(data.name) + "&" ;
+                       url += "caption=" + encodeURIComponent(data.caption) + "&" ;
+                       url += "description=" + encodeURIComponent(data.description) + "&" ;
+                       url += "redirect_uri=" + data.redirectUri ;
+                       sendSNS(sns, url, 850, 600);
+                       break;
+               case "twitter" :
+                       sendSNS(sns, "http://twitter.com/home?status=" + encodeURIComponent(boardTitle) + " " + encodeURIComponent(copyUrl), 600, 400);
+                       break;
+               }
+       }
+       
+       function sendSNS(sns, url, iWidth, iHeight) {
+               var popObj = { url : url
+                                    , width : iWidth
+                                    , height: iHeight
+                                    , target: sns
+                                    , scrollbars: "yes"
+                                    , resizeable: "yes"};
+       
+               $SD.popupCenter(popObj);
+       }
+})
+//document rady End #########################################
+ });
+
+;(function(){
+       window.deviceImageError = function(el) {
+               var noImage = noImage || '/images/common/device_details_noimage.gif';
+               if (el.src === noImage) 
+                       return;
+               el.src = noImage;
+       };
+})();
+
+function commonDownload(fileName, categoryId){
+       if (fileName == "" || categoryId == ""){
+               alert("필요한 인자값을 확인해주세요!!!!")
+               return;
+       }else{
+               $SD.commonDownload(fileName, categoryId, function(data) {
+               });
+       }
+}
+
+function commonDownloadLog(fileFullPath, categoryId){
+       if (fileFullPath == "" || categoryId == ""){
+               alert("필요한 인자값을 확인해주세요!!")
+               return;
+       }else{
+               $SD.commonDownloadLog(fileFullPath, categoryId, function(data) {
+               });
+       }
+}
+
+function commonDownloadLogTarget(fileFullPath, categoryId, target){
+       if (fileFullPath == "" || categoryId == ""){
+               alert("필요한 인자값을 확인해주세요!!")
+               return;
+       }else{
+               $SD.commonDownloadLogTarget(fileFullPath, categoryId, target, function(data) {
+               });
+       }
+}
+
+function commonAllShareClickCount(fileFullPath, categoryId){
+       if (fileFullPath == "" || categoryId == ""){
+               alert("필요한 인자값을 확인해주세요!!")
+               return;
+       }else{
+               $SD.commonAllShareClickCount(fileFullPath, categoryId, function(data) {
+               });
+       }
+}
+
+/*
+function layer_view(id){
+
+       var $layer = $('#'+id);
+       var $down  = $('.license-layer').find('a#down');
+
+       $layer.show();
+       $layer.find('.close, #down').click(function(){
+               $layer.hide();
+       });
+
+       function countChecked() {
+               $(":checkbox").is(':checked') ? $down.show() : $down.hide()
+       }
+
+       $(":checkbox").click(countChecked);
+}
+*/
diff --git a/nui/scripts/jquery.util.js b/nui/scripts/jquery.util.js
new file mode 100644 (file)
index 0000000..3fc3ad0
--- /dev/null
@@ -0,0 +1,1441 @@
+/* org: 'http://www.JSON.org', copyright: '(c)2005 JSON.org', license: 'http://www.crockford.com/JSON/license.html' */
+(function (wn) {var JSON={stringify:function stringify(c){var a,d,f,b='',e;switch(typeof c){case'object':if(c){if(c.constructor==Array){for(d=0;d<c.length;++d){e=stringify(c[d]);if(b){b+=','}b+=e}return'['+b+']'}else if(typeof c.toString!='undefined'){for(d in c){e=stringify(c[d]);if(typeof e!='function'){if(b){b+=','}b+=stringify(d)+':'+e}}return'{'+b+'}'}}return'null';case'number':return isFinite(c)?String(c):'null';case'string':f=c.length;b='"';for(d=0;d<f;d+=1){a=c.charAt(d);if(a>=' '){if(a=='\\'||a=='"'){b+='\\'}b+=a}else{switch(a){case'\b':b+='\\b';break;case'\f':b+='\\f';break;case'\n':b+='\\n';break;case'\r':b+='\\r';break;case'\t':b+='\\t';break;default:a=a.charCodeAt();b+='\\u00'+Math.floor(a/16).toString(16)+(a%16).toString(16)}}}return b+'"';case'boolean':return String(c);case'function':return c.toString();default:return'null'}},parse:function(c){var a=c;if(a.substr(0,9)=="while(1);"){a=a.substr(9)}if(a.substr(0,2)=="/*"){a=a.substr(2,a.length-4)}return eval('('+a+')')}};wn.JSON = wn.JSON || JSON ;})(window);
+
+
+/*! jQuery v1.7.1 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
+f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
+{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
+
+/*
+ * Metadata - jQuery plugin for parsing metadata from elements
+ *
+ * Copyright (c) 2006 John Resig, Yehuda Katz, J�örn Zaefferer, Paul McLanahan
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+ * Revision: $Id: jquery.metadata.js 4187 2007-12-16 17:15:27Z joern.zaefferer $
+ *
+ */
+
+/**
+ * Sets the type of metadata to use. Metadata is encoded in JSON, and each property
+ * in the JSON will become a property of the element itself.
+ *
+ * There are three supported types of metadata storage:
+ *
+ *   attr:  Inside an attribute. The name parameter indicates *which* attribute.
+ *          
+ *   class: Inside the class attribute, wrapped in curly braces: { }
+ *   
+ *   elem:  Inside a child element (e.g. a script tag). The
+ *          name parameter indicates *which* element.
+ *          
+ * The metadata for an element is loaded the first time the element is accessed via jQuery.
+ *
+ * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
+ * matched by expr, then redefine the metadata type and run another $(expr) for other elements.
+ * 
+ * @name $.metadata.setType
+ *
+ * @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
+ * @before $.metadata.setType("class")
+ * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
+ * @desc Reads metadata from the class attribute
+ * 
+ * @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
+ * @before $.metadata.setType("attr", "data")
+ * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
+ * @desc Reads metadata from a "data" attribute
+ * 
+ * @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
+ * @before $.metadata.setType("elem", "script")
+ * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
+ * @desc Reads metadata from a nested script element
+ * 
+ * @param String type The encoding type
+ * @param String name The name of the attribute to be used to get metadata (optional)
+ * @cat Plugins/Metadata
+ * @descr Sets the type of encoding to be used when loading metadata for the first time
+ * @type undefined
+ * @see metadata()
+ */
+
+(function($) {
+
+$.extend({
+       metadata : {
+               defaults : {
+                       type: 'class',
+                       name: 'metadata',
+                       cre: /({.*})/,
+                       single: 'metadata'
+               },
+               setType: function( type, name ){
+                       this.defaults.type = type;
+                       this.defaults.name = name;
+               },
+               get: function( elem, opts ){
+                       var settings = $.extend({},this.defaults,opts);
+                       // check for empty string in single property
+                       if ( !settings.single.length ) settings.single = 'metadata';
+                       
+                       var data = $.data(elem, settings.single);
+                       // returned cached data if it already exists
+                       if ( data ) return data;
+                       
+                       data = "{}";
+                       
+                       if ( settings.type == "class" ) {
+                               var m = settings.cre.exec( elem.className );
+                               if ( m )
+                                       data = m[1];
+                       } else if ( settings.type == "elem" ) {
+                               if( !elem.getElementsByTagName )
+                                       return undefined;
+                               var e = elem.getElementsByTagName(settings.name);
+                               if ( e.length )
+                                       data = $.trim(e[0].innerHTML);
+                       } else if ( elem.getAttribute != undefined ) {
+                               var attr = elem.getAttribute( settings.name );
+                               if ( attr )
+                                       data = attr;
+                       }
+                       
+                       if ( data.indexOf( '{' ) <0 )
+                       data = "{" + data + "}";
+                       
+                       data = eval("(" + data + ")");
+                       
+                       $.data( elem, settings.single, data );
+                       return data;
+               }
+       }
+});
+
+/**
+ * Returns the metadata object for the first member of the jQuery object.
+ *
+ * @name metadata
+ * @descr Returns element's metadata object
+ * @param Object opts An object contianing settings to override the defaults
+ * @type jQuery
+ * @cat Plugins/Metadata
+ */
+$.fn.metadata = function( opts ){
+       return $.metadata.get( this[0], opts );
+};
+
+})(jQuery);
+
+
+/**
+ * jQuery Validation Plugin 1.9.0
+
+ *
+ * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
+ * http://docs.jquery.com/Plugins/Validation
+ *
+ * Copyright (c) 2006 - 2011 J철rn Zaefferer
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ */
+
+/**
+ * 353 line 변경 - jquery.validate.js 버전을 업그레이드 할 경우에는 확인 요망
+ */
+
+(function($) {
+
+$.extend($.fn, {
+       // http://docs.jquery.com/Plugins/Validation/validate
+       validate: function( options ) {
+
+               // if nothing is selected, return nothing; can't chain anyway
+               if (!this.length) {
+                       options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
+                       return;
+               }
+
+               // check if a validator for this form was already created
+               var validator = $.data(this[0], 'validator');
+               if ( validator ) {
+                       return validator;
+               }
+
+               // Add novalidate tag if HTML5.
+               this.attr('novalidate', 'novalidate');
+
+               validator = new $.validator( options, this[0] );
+               $.data(this[0], 'validator', validator);
+
+               if ( validator.settings.onsubmit ) {
+
+                       var inputsAndButtons = this.find("input, button");
+
+                       // allow suppresing validation by adding a cancel class to the submit button
+                       inputsAndButtons.filter(".cancel").click(function () {
+                               validator.cancelSubmit = true;
+                       });
+
+                       // when a submitHandler is used, capture the submitting button
+                       if (validator.settings.submitHandler) {
+                               inputsAndButtons.filter(":submit").click(function () {
+                                       validator.submitButton = this;
+                               });
+                       }
+
+                       // validate the form on submit
+                       this.submit( function( event ) {
+                               if ( validator.settings.debug )
+                                       // prevent form submit to be able to see console output
+                                       event.preventDefault();
+
+                               function handle() {
+                                       if ( validator.settings.submitHandler ) {
+                                               if (validator.submitButton) {
+                                                       // insert a hidden input as a replacement for the missing submit button
+                                                       var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
+                                               }
+                                               validator.settings.submitHandler.call( validator, validator.currentForm );
+                                               if (validator.submitButton) {
+                                                       // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
+                                                       hidden.remove();
+                                               }
+                                               return false;
+                                       }
+                                       return true;
+                               }
+
+                               // prevent submit for invalid forms or custom submit handlers
+                               if ( validator.cancelSubmit ) {
+                                       validator.cancelSubmit = false;
+                                       return handle();
+                               }
+                               if ( validator.form() ) {
+                                       if ( validator.pendingRequest ) {
+                                               validator.formSubmitted = true;
+                                               return false;
+                                       }
+                                       return handle();
+                               } else {
+                                       validator.focusInvalid();
+                                       return false;
+                               }
+                       });
+               }
+
+               return validator;
+       },
+       // http://docs.jquery.com/Plugins/Validation/valid
+       valid: function() {
+        if ( $(this[0]).is('form')) {
+            return this.validate().form();
+        } else {
+            var valid = true;
+            var validator = $(this[0].form).validate();
+            this.each(function() {
+                               valid &= validator.element(this);
+            });
+            return valid;
+        }
+    },
+       // attributes: space seperated list of attributes to retrieve and remove
+       removeAttrs: function(attributes) {
+               var result = {},
+                       $element = this;
+               $.each(attributes.split(/\s/), function(index, value) {
+                       result[value] = $element.attr(value);
+                       $element.removeAttr(value);
+               });
+               return result;
+       },
+       // http://docs.jquery.com/Plugins/Validation/rules
+       rules: function(command, argument) {
+               var element = this[0];
+
+               if (command) {
+                       var settings = $.data(element.form, 'validator').settings;
+                       var staticRules = settings.rules;
+                       var existingRules = $.validator.staticRules(element);
+                       switch(command) {
+                       case "add":
+                               $.extend(existingRules, $.validator.normalizeRule(argument));
+                               staticRules[element.name] = existingRules;
+                               if (argument.messages)
+                                       settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
+                               break;
+                       case "remove":
+                               if (!argument) {
+                                       delete staticRules[element.name];
+                                       return existingRules;
+                               }
+                               var filtered = {};
+                               $.each(argument.split(/\s/), function(index, method) {
+                                       filtered[method] = existingRules[method];
+                                       delete existingRules[method];
+                               });
+                               return filtered;
+                       }
+               }
+
+               var data = $.validator.normalizeRules(
+               $.extend(
+                       {},
+                       $.validator.metadataRules(element),
+                       $.validator.classRules(element),
+                       $.validator.attributeRules(element),
+                       $.validator.staticRules(element)
+               ), element);
+
+               // make sure required is at front
+               if (data.required) {
+                       var param = data.required;
+                       delete data.required;
+                       data = $.extend({required: param}, data);
+               }
+
+               return data;
+       }
+});
+
+// Custom selectors
+$.extend($.expr[":"], {
+       // http://docs.jquery.com/Plugins/Validation/blank
+       blank: function(a) {return !$.trim("" + a.value);},
+       // http://docs.jquery.com/Plugins/Validation/filled
+       filled: function(a) {return !!$.trim("" + a.value);},
+       // http://docs.jquery.com/Plugins/Validation/unchecked
+       unchecked: function(a) {return !a.checked;}
+});
+
+// constructor for validator
+$.validator = function( options, form ) {
+       this.settings = $.extend( true, {}, $.validator.defaults, options );
+       this.currentForm = form;
+       this.init();
+};
+
+$.validator.format = function(source, params) {
+       if ( arguments.length == 1 )
+               return function() {
+                       var args = $.makeArray(arguments);
+                       args.unshift(source);
+                       return $.validator.format.apply( this, args );
+               };
+       if ( arguments.length > 2 && params.constructor != Array  ) {
+               params = $.makeArray(arguments).slice(1);
+       }
+       if ( params.constructor != Array ) {
+               params = [ params ];
+       }
+       $.each(params, function(i, n) {
+               source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
+       });
+       return source;
+};
+
+$.extend($.validator, {
+
+       defaults: {
+               messages: {},
+               groups: {},
+               rules: {},
+               errorClass: "error",
+               validClass: "valid",
+               errorElement: "label",
+               focusInvalid: true,
+               errorContainer: $( [] ),
+               errorLabelContainer: $( [] ),
+               onsubmit: true,
+               ignore: ":hidden",
+               ignoreTitle: false,
+               onfocusin: function(element, event) {
+                       this.lastActive = element;
+
+                       // hide error label and remove error class on focus if enabled
+                       if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
+                               this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
+                               this.addWrapper(this.errorsFor(element)).hide();
+                       }
+               },
+               onfocusout: function(element, event) {
+                       if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
+                               this.element(element);
+                       }
+               },
+               onkeyup: function(element, event) {
+                       if ( element.name in this.submitted || element == this.lastElement ) {
+                               this.element(element);
+                       }
+               },
+               onclick: function(element, event) {
+                       // click on selects, radiobuttons and checkboxes
+                       if ( element.name in this.submitted )
+                               this.element(element);
+                       // or option elements, check parent select in that case
+                       else if (element.parentNode.name in this.submitted)
+                               this.element(element.parentNode);
+               },
+               highlight: function(element, errorClass, validClass) {
+                       if (element.type === 'radio') {
+                               this.findByName(element.name).addClass(errorClass).removeClass(validClass);
+                       } else {
+                               $(element).addClass(errorClass).removeClass(validClass);
+                       }
+               },
+               unhighlight: function(element, errorClass, validClass) {
+                       if (element.type === 'radio') {
+                               this.findByName(element.name).removeClass(errorClass).addClass(validClass);
+                       } else {
+                               $(element).removeClass(errorClass).addClass(validClass);
+                       }
+               }
+       },
+
+       // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
+       setDefaults: function(settings) {
+               $.extend( $.validator.defaults, settings );
+       },
+
+       messages: {
+               required: "This field is required.",
+               remote: "Please fix this field.",
+               email: "Please enter a valid email address.",
+               url: "Please enter a valid URL.",
+               date: "Please enter a valid date.",
+               dateISO: "Please enter a valid date (ISO).",
+               number: "Please enter a valid number.",
+               digits: "Please enter only digits.",
+               creditcard: "Please enter a valid credit card number.",
+               equalTo: "Please enter the same value again.",
+               accept: "Please enter a value with a valid extension.",
+               maxlength: $.validator.format("Please enter no more than {0} characters."),
+               minlength: $.validator.format("Please enter at least {0} characters."),
+               rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
+               range: $.validator.format("Please enter a value between {0} and {1}."),
+               max: $.validator.format("Please enter a value less than or equal to {0}."),
+               min: $.validator.format("Please enter a value greater than or equal to {0}.")
+       },
+
+       autoCreateRanges: false,
+
+       prototype: {
+
+               init: function() {
+                       this.labelContainer = $(this.settings.errorLabelContainer);
+                       this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
+                       this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
+                       this.submitted = {};
+                       this.valueCache = {};
+                       this.pendingRequest = 0;
+                       this.pending = {};
+                       this.invalid = {};
+                       this.reset();
+
+                       var groups = (this.groups = {});
+                       $.each(this.settings.groups, function(key, value) {
+                               $.each(value.split(/\s/), function(index, name) {
+                                       groups[name] = key;
+                               });
+                       });
+                       var rules = this.settings.rules;
+                       $.each(rules, function(key, value) {
+                               rules[key] = $.validator.normalizeRule(value);
+                       });
+
+                       function delegate(event) {
+                               var validator = $.data(this[0].form, "validator"),
+                                       eventType = "on" + event.type.replace(/^validate/, "");
+                               validator.settings[eventType] && validator.settings[eventType].call(validator, this[0], event);
+                       }
+                       $(this.currentForm)
+                              .validateDelegate("[type='text'], [type='password'], [type='file'], select, textarea, " +
+                                               "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
+                                               "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
+                                               "[type='week'], [type='time'], [type='datetime-local'], " +
+                                               "[type='range'], [type='color'] ",
+                                               "focusin focusout keyup", delegate)
+                               .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);
+
+                       if (this.settings.invalidHandler)
+                               $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Validator/form
+               form: function() {
+                       this.checkForm();
+                       $.extend(this.submitted, this.errorMap);
+                       this.invalid = $.extend({}, this.errorMap);
+                       if (!this.valid())
+                               $(this.currentForm).triggerHandler("invalid-form", [this]);
+                       this.showErrors();
+                       return this.valid();
+               },
+
+               // 원본소스
+               /*
+               checkForm: function() {
+                       this.prepareForm();
+                       for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
+                               this.check( elements[i] );
+                       }
+                       return this.valid();
+               },
+               */
+
+               // 수정소스 : 동일한 name 속성의 개체 array에 대해서도 validation을 하도록 변경
+               checkForm: function() {
+                       this.prepareForm();
+                       for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
+                               if (this.findByName( elements[i].name ).length != undefined && this.findByName( elements[i].name ).length > 1) {
+                                       for (var cnt = 0; cnt < this.findByName( elements[i].name ).length; cnt++) {
+                                               this.check( this.findByName( elements[i].name )[cnt] );
+                                       }
+                               } else {
+                                       this.check( elements[i] );
+                               }
+                       }
+                       return this.valid();
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Validator/element
+               element: function( element ) {
+                       element = this.validationTargetFor( this.clean( element ) );
+                       this.lastElement = element;
+                       this.prepareElement( element );
+                       this.currentElements = $(element);
+                       var result = this.check( element );
+                       if ( result ) {
+                               delete this.invalid[element.name];
+                       } else {
+                               this.invalid[element.name] = true;
+                       }
+                       if ( !this.numberOfInvalids() ) {
+                               // Hide error containers on last error
+                               this.toHide = this.toHide.add( this.containers );
+                       }
+                       this.showErrors();
+                       return result;
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
+               showErrors: function(errors) {
+                       if(errors) {
+                               // add items to error list and map
+                               $.extend( this.errorMap, errors );
+                               this.errorList = [];
+                               for ( var name in errors ) {
+                                       this.errorList.push({
+                                               message: errors[name],
+                                               element: this.findByName(name)[0]
+                                       });
+                               }
+                               // remove items from success list
+                               this.successList = $.grep( this.successList, function(element) {
+                                       return !(element.name in errors);
+                               });
+                       }
+                       this.settings.showErrors
+                               ? this.settings.showErrors.call( this, this.errorMap, this.errorList )
+                               : this.defaultShowErrors();
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
+               resetForm: function() {
+                       if ( $.fn.resetForm )
+                               $( this.currentForm ).resetForm();
+                       this.submitted = {};
+                       this.lastElement = null;
+                       this.prepareForm();
+                       this.hideErrors();
+                       this.elements().removeClass( this.settings.errorClass );
+               },
+
+               numberOfInvalids: function() {
+                       return this.objectLength(this.invalid);
+               },
+
+               objectLength: function( obj ) {
+                       var count = 0;
+                       for ( var i in obj )
+                               count++;
+                       return count;
+               },
+
+               hideErrors: function() {
+                       this.addWrapper( this.toHide ).hide();
+               },
+
+               valid: function() {
+                       return this.size() == 0;
+               },
+
+               size: function() {
+                       return this.errorList.length;
+               },
+
+               focusInvalid: function() {
+                       if( this.settings.focusInvalid ) {
+                               try {
+                                       $(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
+                                       .filter(":visible")
+                                       .focus()
+                                       // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
+                                       .trigger("focusin");
+                               } catch(e) {
+                                       // ignore IE throwing errors when focusing hidden elements
+                               }
+                       }
+               },
+
+               findLastActive: function() {
+                       var lastActive = this.lastActive;
+                       return lastActive && $.grep(this.errorList, function(n) {
+                               return n.element.name == lastActive.name;
+                       }).length == 1 && lastActive;
+               },
+
+               elements: function() {
+                       var validator = this,
+                               rulesCache = {};
+
+                       // select all valid inputs inside the form (no submit or reset buttons)
+                       return $(this.currentForm)
+                       .find("input, select, textarea")
+                       .not(":submit, :reset, :image, [disabled]")
+                       .not( this.settings.ignore )
+                       .filter(function() {
+                               !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);
+
+                               // select only the first element for each name, and only those with rules specified
+                               if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
+                                       return false;
+
+                               rulesCache[this.name] = true;
+                               return true;
+                       });
+               },
+
+               clean: function( selector ) {
+                       return $( selector )[0];
+               },
+
+               errors: function() {
+                       return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
+               },
+
+               reset: function() {
+                       this.successList = [];
+                       this.errorList = [];
+                       this.errorMap = {};
+                       this.toShow = $([]);
+                       this.toHide = $([]);
+                       this.currentElements = $([]);
+               },
+
+               prepareForm: function() {
+                       this.reset();
+                       this.toHide = this.errors().add( this.containers );
+               },
+
+               prepareElement: function( element ) {
+                       this.reset();
+                       this.toHide = this.errorsFor(element);
+               },
+
+               check: function( element ) {
+                       element = this.validationTargetFor( this.clean( element ) );
+
+                       var rules = $(element).rules();
+                       var dependencyMismatch = false;
+                       for (var method in rules ) {
+                               var rule = { method: method, parameters: rules[method] };
+                               try {
+                                       var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );
+
+                                       // if a method indicates that the field is optional and therefore valid,
+                                       // don't mark it as valid when there are no other rules
+                                       if ( result == "dependency-mismatch" ) {
+                                               dependencyMismatch = true;
+                                               continue;
+                                       }
+                                       dependencyMismatch = false;
+
+                                       if ( result == "pending" ) {
+                                               this.toHide = this.toHide.not( this.errorsFor(element) );
+                                               return;
+                                       }
+
+                                       if( !result ) {
+                                               this.formatAndAdd( element, rule );
+                                               return false;
+                                       }
+                               } catch(e) {
+                                       this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
+                                                + ", check the '" + rule.method + "' method", e);
+                                       throw e;
+                               }
+                       }
+                       if (dependencyMismatch)
+                               return;
+                       if ( this.objectLength(rules) )
+                               this.successList.push(element);
+                       return true;
+               },
+
+               // return the custom message for the given element and validation method
+               // specified in the element's "messages" metadata
+               customMetaMessage: function(element, method) {
+                       if (!$.metadata)
+                               return;
+
+                       var meta = this.settings.meta
+                               ? $(element).metadata()[this.settings.meta]
+                               : $(element).metadata();
+
+                       return meta && meta.messages && meta.messages[method];
+               },
+
+               // return the custom message for the given element name and validation method
+               customMessage: function( name, method ) {
+                       var m = this.settings.messages[name];
+                       return m && (m.constructor == String
+                               ? m
+                               : m[method]);
+               },
+
+               // return the first defined argument, allowing empty strings
+               findDefined: function() {
+                       for(var i = 0; i < arguments.length; i++) {
+                               if (arguments[i] !== undefined)
+                                       return arguments[i];
+                       }
+                       return undefined;
+               },
+
+               defaultMessage: function( element, method) {
+                       return this.findDefined(
+                               this.customMessage( element.name, method ),
+                               this.customMetaMessage( element, method ),
+                               // title is never undefined, so handle empty string as undefined
+                               !this.settings.ignoreTitle && element.title || undefined,
+                               $.validator.messages[method],
+                               "<strong>Warning: No message defined for " + element.name + "</strong>"
+                       );
+               },
+
+               formatAndAdd: function( element, rule ) {
+                       var message = this.defaultMessage( element, rule.method ),
+                               theregex = /\$?\{(\d+)\}/g;
+                       if ( typeof message == "function" ) {
+                               message = message.call(this, rule.parameters, element);
+                       } else if (theregex.test(message)) {
+                               message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
+                       }
+                       this.errorList.push({
+                               message: message,
+                               element: element
+                       });
+
+                       this.errorMap[element.name] = message;
+                       this.submitted[element.name] = message;
+               },
+
+               addWrapper: function(toToggle) {
+                       if ( this.settings.wrapper )
+                               toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
+                       return toToggle;
+               },
+
+               defaultShowErrors: function() {
+                       for ( var i = 0; this.errorList[i]; i++ ) {
+                               var error = this.errorList[i];
+                               this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
+                               this.showLabel( error.element, error.message );
+                       }
+                       if( this.errorList.length ) {
+                               this.toShow = this.toShow.add( this.containers );
+                       }
+                       if (this.settings.success) {
+                               for ( var i = 0; this.successList[i]; i++ ) {
+                                       this.showLabel( this.successList[i] );
+                               }
+                       }
+                       if (this.settings.unhighlight) {
+                               for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
+                                       this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
+                               }
+                       }
+                       this.toHide = this.toHide.not( this.toShow );
+                       this.hideErrors();
+                       this.addWrapper( this.toShow ).show();
+               },
+
+               validElements: function() {
+                       return this.currentElements.not(this.invalidElements());
+               },
+
+               invalidElements: function() {
+                       return $(this.errorList).map(function() {
+                               return this.element;
+                       });
+               },
+
+               showLabel: function(element, message) {
+                       var label = this.errorsFor( element );
+                       if ( label.length ) {
+                               // refresh error/success class
+                               label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
+
+                               // check if we have a generated label, replace the message then
+                               label.attr("generated") && label.html(message);
+                       } else {
+                               // create label
+                               label = $("<" + this.settings.errorElement + "/>")
+                                       .attr({"for":  this.idOrName(element), generated: true})
+                                       .addClass(this.settings.errorClass)
+                                       .html(message || "");
+                               if ( this.settings.wrapper ) {
+                                       // make sure the element is visible, even in IE
+                                       // actually showing the wrapped element is handled elsewhere
+                                       label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
+                               }
+                               if ( !this.labelContainer.append(label).length )
+                                       this.settings.errorPlacement
+                                               ? this.settings.errorPlacement(label, $(element) )
+                                               : label.insertAfter(element);
+                       }
+                       if ( !message && this.settings.success ) {
+                               label.text("");
+                               typeof this.settings.success == "string"
+                                       ? label.addClass( this.settings.success )
+                                       : this.settings.success( label );
+                       }
+                       this.toShow = this.toShow.add(label);
+               },
+
+               errorsFor: function(element) {
+                       var name = this.idOrName(element);
+               return this.errors().filter(function() {
+                               return $(this).attr('for') == name;
+                       });
+               },
+
+               idOrName: function(element) {
+                       return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
+               },
+
+               validationTargetFor: function(element) {
+                       // if radio/checkbox, validate first element in group instead
+                       if (this.checkable(element)) {
+                               element = this.findByName( element.name ).not(this.settings.ignore)[0];
+                       }
+                       return element;
+               },
+
+               checkable: function( element ) {
+                       return /radio|checkbox/i.test(element.type);
+               },
+
+               findByName: function( name ) {
+                       // select by name and filter by form for performance over form.find("[name=...]")
+                       var form = this.currentForm;
+                       return $(document.getElementsByName(name)).map(function(index, element) {
+                               return element.form == form && element.name == name && element  || null;
+                       });
+               },
+
+               getLength: function(value, element) {
+                       switch( element.nodeName.toLowerCase() ) {
+                       case 'select':
+                               return $("option:selected", element).length;
+                       case 'input':
+                               if( this.checkable( element) )
+                                       return this.findByName(element.name).filter(':checked').length;
+                       }
+                       return value.length;
+               },
+
+               depend: function(param, element) {
+                       return this.dependTypes[typeof param]
+                               ? this.dependTypes[typeof param](param, element)
+                               : true;
+               },
+
+               dependTypes: {
+                       "boolean": function(param, element) {
+                               return param;
+                       },
+                       "string": function(param, element) {
+                               return !!$(param, element.form).length;
+                       },
+                       "function": function(param, element) {
+                               return param(element);
+                       }
+               },
+
+               optional: function(element) {
+                       return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
+               },
+
+               startRequest: function(element) {
+                       if (!this.pending[element.name]) {
+                               this.pendingRequest++;
+                               this.pending[element.name] = true;
+                       }
+               },
+
+               stopRequest: function(element, valid) {
+                       this.pendingRequest--;
+                       // sometimes synchronization fails, make sure pendingRequest is never < 0
+                       if (this.pendingRequest < 0)
+                               this.pendingRequest = 0;
+                       delete this.pending[element.name];
+                       if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
+                               $(this.currentForm).submit();
+                               this.formSubmitted = false;
+                       } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
+                               $(this.currentForm).triggerHandler("invalid-form", [this]);
+                               this.formSubmitted = false;
+                       }
+               },
+
+               previousValue: function(element) {
+                       return $.data(element, "previousValue") || $.data(element, "previousValue", {
+                               old: null,
+                               valid: true,
+                               message: this.defaultMessage( element, "remote" )
+                       });
+               }
+
+       },
+
+       classRuleSettings: {
+               required: {required: true},
+               email: {email: true},
+               url: {url: true},
+               date: {date: true},
+               dateISO: {dateISO: true},
+               dateDE: {dateDE: true},
+               number: {number: true},
+               numberDE: {numberDE: true},
+               digits: {digits: true},
+               creditcard: {creditcard: true}
+       },
+
+       addClassRules: function(className, rules) {
+               className.constructor == String ?
+                       this.classRuleSettings[className] = rules :
+                       $.extend(this.classRuleSettings, className);
+       },
+
+       classRules: function(element) {
+               var rules = {};
+               var classes = $(element).attr('class');
+               classes && $.each(classes.split(' '), function() {
+                       if (this in $.validator.classRuleSettings) {
+                               $.extend(rules, $.validator.classRuleSettings[this]);
+                       }
+               });
+               return rules;
+       },
+
+       attributeRules: function(element) {
+               var rules = {};
+               var $element = $(element);
+
+               for (var method in $.validator.methods) {
+                       var value;
+                       // If .prop exists (jQuery >= 1.6), use it to get true/false for required
+                       if (method === 'required' && typeof $.fn.prop === 'function') {
+                               value = $element.prop(method);
+                       } else {
+                               value = $element.attr(method);
+                       }
+                       if (value) {
+                               rules[method] = value;
+                       } else if ($element[0].getAttribute("type") === method) {
+                               rules[method] = true;
+                       }
+               }
+
+               // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
+               if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
+                       delete rules.maxlength;
+               }
+
+               return rules;
+       },
+
+       metadataRules: function(element) {
+               if (!$.metadata) return {};
+
+               var meta = $.data(element.form, 'validator').settings.meta;
+               return meta ?
+                       $(element).metadata()[meta] :
+                       $(element).metadata();
+       },
+
+       staticRules: function(element) {
+               var rules = {};
+               var validator = $.data(element.form, 'validator');
+               if (validator.settings.rules) {
+                       rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
+               }
+               return rules;
+       },
+
+       normalizeRules: function(rules, element) {
+               // handle dependency check
+               $.each(rules, function(prop, val) {
+                       // ignore rule when param is explicitly false, eg. required:false
+                       if (val === false) {
+                               delete rules[prop];
+                               return;
+                       }
+                       if (val.param || val.depends) {
+                               var keepRule = true;
+                               switch (typeof val.depends) {
+                                       case "string":
+                                               keepRule = !!$(val.depends, element.form).length;
+                                               break;
+                                       case "function":
+                                               keepRule = val.depends.call(element, element);
+                                               break;
+                               }
+                               if (keepRule) {
+                                       rules[prop] = val.param !== undefined ? val.param : true;
+                               } else {
+                                       delete rules[prop];
+                               }
+                       }
+               });
+
+               // evaluate parameters
+               $.each(rules, function(rule, parameter) {
+                       rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
+               });
+
+               // clean number parameters
+               $.each(['minlength', 'maxlength', 'min', 'max'], function() {
+                       if (rules[this]) {
+                               rules[this] = Number(rules[this]);
+                       }
+               });
+               $.each(['rangelength', 'range'], function() {
+                       if (rules[this]) {
+                               rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
+                       }
+               });
+
+               if ($.validator.autoCreateRanges) {
+                       // auto-create ranges
+                       if (rules.min && rules.max) {
+                               rules.range = [rules.min, rules.max];
+                               delete rules.min;
+                               delete rules.max;
+                       }
+                       if (rules.minlength && rules.maxlength) {
+                               rules.rangelength = [rules.minlength, rules.maxlength];
+                               delete rules.minlength;
+                               delete rules.maxlength;
+                       }
+               }
+
+               // To support custom messages in metadata ignore rule methods titled "messages"
+               if (rules.messages) {
+                       delete rules.messages;
+               }
+
+               return rules;
+       },
+
+       // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
+       normalizeRule: function(data) {
+               if( typeof data == "string" ) {
+                       var transformed = {};
+                       $.each(data.split(/\s/), function() {
+                               transformed[this] = true;
+                       });
+                       data = transformed;
+               }
+               return data;
+       },
+
+       // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
+       addMethod: function(name, method, message) {
+               $.validator.methods[name] = method;
+               $.validator.messages[name] = message != undefined ? message : $.validator.messages[name];
+               if (method.length < 3) {
+                       $.validator.addClassRules(name, $.validator.normalizeRule(name));
+               }
+       },
+
+       methods: {
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/required
+               required: function(value, element, param) {
+                       // check if dependency is met
+                       if ( !this.depend(param, element) )
+                               return "dependency-mismatch";
+                       switch( element.nodeName.toLowerCase() ) {
+                       case 'select':
+                               // could be an array for select-multiple or a string, both are fine this way
+                               var val = $(element).val();
+                               return val && val.length > 0;
+                       case 'input':
+                               if ( this.checkable(element) )
+                                       return this.getLength(value, element) > 0;
+                       default:
+                               return $.trim(value).length > 0;
+                       }
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/remote
+               remote: function(value, element, param) {
+                       if ( this.optional(element) )
+                               return "dependency-mismatch";
+
+                       var previous = this.previousValue(element);
+                       if (!this.settings.messages[element.name] )
+                               this.settings.messages[element.name] = {};
+                       previous.originalMessage = this.settings.messages[element.name].remote;
+                       this.settings.messages[element.name].remote = previous.message;
+
+                       param = typeof param == "string" && {url:param} || param;
+
+                       if ( this.pending[element.name] ) {
+                               return "pending";
+                       }
+                       if ( previous.old === value ) {
+                               return previous.valid;
+                       }
+
+                       previous.old = value;
+                       var validator = this;
+                       this.startRequest(element);
+                       var data = {};
+                       data[element.name] = value;
+                       $.ajax($.extend(true, {
+                               url: param,
+                               mode: "abort",
+                               port: "validate" + element.name,
+                               dataType: "json",
+                               data: data,
+                               success: function(response) {
+                                       validator.settings.messages[element.name].remote = previous.originalMessage;
+                                       var valid = response === true;
+                                       if ( valid ) {
+                                               var submitted = validator.formSubmitted;
+                                               validator.prepareElement(element);
+                                               validator.formSubmitted = submitted;
+                                               validator.successList.push(element);
+                                               validator.showErrors();
+                                       } else {
+                                               var errors = {};
+                                               var message = response || validator.defaultMessage( element, "remote" );
+                                               errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
+                                               validator.showErrors(errors);
+                                       }
+                                       previous.valid = valid;
+                                       validator.stopRequest(element, valid);
+                               }
+                       }, param));
+                       return "pending";
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/minlength
+               minlength: function(value, element, param) {
+                       return this.optional(element) || this.getLength($.trim(value), element) >= param;
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
+               maxlength: function(value, element, param) {
+                       return this.optional(element) || this.getLength($.trim(value), element) <= param;
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
+               rangelength: function(value, element, param) {
+                       var length = this.getLength($.trim(value), element);
+                       return this.optional(element) || ( length >= param[0] && length <= param[1] );
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/min
+               min: function( value, element, param ) {
+                       return this.optional(element) || value >= param;
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/max
+               max: function( value, element, param ) {
+                       return this.optional(element) || value <= param;
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/range
+               range: function( value, element, param ) {
+                       return this.optional(element) || ( value >= param[0] && value <= param[1] );
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/email
+               email: function(value, element) {
+                       // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
+                       return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/url
+               url: function(value, element) {
+                       // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
+                       return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/date
+               date: function(value, element) {
+                       return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
+               dateISO: function(value, element) {
+                       return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/number
+               number: function(value, element) {
+                       return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/digits
+               digits: function(value, element) {
+                       return this.optional(element) || /^\d+$/.test(value);
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
+               // based on http://en.wikipedia.org/wiki/Luhn
+               creditcard: function(value, element) {
+                       if ( this.optional(element) )
+                               return "dependency-mismatch";
+                       // accept only spaces, digits and dashes
+                       if (/[^0-9 -]+/.test(value))
+                               return false;
+                       var nCheck = 0,
+                               nDigit = 0,
+                               bEven = false;
+
+                       value = value.replace(/\D/g, "");
+
+                       for (var n = value.length - 1; n >= 0; n--) {
+                               var cDigit = value.charAt(n);
+                               var nDigit = parseInt(cDigit, 10);
+                               if (bEven) {
+                                       if ((nDigit *= 2) > 9)
+                                               nDigit -= 9;
+                               }
+                               nCheck += nDigit;
+                               bEven = !bEven;
+                       }
+
+                       return (nCheck % 10) == 0;
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/accept
+               accept: function(value, element, param) {
+                       param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
+                       return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
+               },
+
+               // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
+               equalTo: function(value, element, param) {
+                       // bind to the blur event of the target in order to revalidate whenever the target field is updated
+                       // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
+                       var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
+                               $(element).valid();
+                       });
+                       return value == target.val();
+               }
+
+       }
+
+});
+
+// deprecated, use $.validator.format instead
+$.format = $.validator.format;
+
+})(jQuery);
+
+// ajax mode: abort
+// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
+// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
+;(function($) {
+       var pendingRequests = {};
+       // Use a prefilter if available (1.5+)
+       if ( $.ajaxPrefilter ) {
+               $.ajaxPrefilter(function(settings, _, xhr) {
+                       var port = settings.port;
+                       if (settings.mode == "abort") {
+                               if ( pendingRequests[port] ) {
+                                       pendingRequests[port].abort();
+                               }
+                               pendingRequests[port] = xhr;
+                       }
+               });
+       } else {
+               // Proxy ajax
+               var ajax = $.ajax;
+               $.ajax = function(settings) {
+                       var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
+                               port = ( "port" in settings ? settings : $.ajaxSettings ).port;
+                       if (mode == "abort") {
+                               if ( pendingRequests[port] ) {
+                                       pendingRequests[port].abort();
+                               }
+                               return (pendingRequests[port] = ajax.apply(this, arguments));
+                       }
+                       return ajax.apply(this, arguments);
+               };
+       }
+})(jQuery);
+
+// provides cross-browser focusin and focusout events
+// IE has native support, in other browsers, use event caputuring (neither bubbles)
+
+// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
+// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
+;(function($) {
+       // only implement if not provided by jQuery core (since 1.4)
+       // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
+       if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {
+               $.each({
+                       focus: 'focusin',
+                       blur: 'focusout'
+               }, function( original, fix ){
+                       $.event.special[fix] = {
+                               setup:function() {
+                                       this.addEventListener( original, handler, true );
+                               },
+                               teardown:function() {
+                                       this.removeEventListener( original, handler, true );
+                               },
+                               handler: function(e) {
+                                       arguments[0] = $.event.fix(e);
+                                       arguments[0].type = fix;
+                                       return $.event.handle.apply(this, arguments);
+                               }
+                       };
+                       function handler(e) {
+                               e = $.event.fix(e);
+                               e.type = fix;
+                               return $.event.handle.call(this, e);
+                       }
+               });
+       };
+       $.extend($.fn, {
+               validateDelegate: function(delegate, type, handler) {
+                       return this.bind(type, function(event) {
+                               var target = $(event.target);
+                               if (target.is(delegate)) {
+                                       return handler.apply(target, arguments);
+                               }
+                       });
+               }
+       });
+})(jQuery);
+
+/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
+ * Licensed under the MIT License (LICENSE.txt).
+ *
+ * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
+ * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
+ * Thanks to: Seamus Leahy for adding deltaX and deltaY
+ *
+ * Version: 3.0.6
+ * 
+ * Requires: 1.2.2+
+ */
+
+(function($) {
+
+var types = ['DOMMouseScroll', 'mousewheel'];
+
+if ($.event.fixHooks) {
+    for ( var i=types.length; i; ) {
+        $.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
+    }
+}
+
+$.event.special.mousewheel = {
+    setup: function() {
+        if ( this.addEventListener ) {
+            for ( var i=types.length; i; ) {
+                this.addEventListener( types[--i], handler, false );
+            }
+        } else {
+            this.onmousewheel = handler;
+        }
+    },
+    
+    teardown: function() {
+        if ( this.removeEventListener ) {
+            for ( var i=types.length; i; ) {
+                this.removeEventListener( types[--i], handler, false );
+            }
+        } else {
+            this.onmousewheel = null;
+        }
+    }
+};
+
+$.fn.extend({
+    mousewheel: function(fn) {
+        return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
+    },
+    
+    unmousewheel: function(fn) {
+        return this.unbind("mousewheel", fn);
+    }
+});
+
+
+function handler(event) {
+    var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
+    event = $.event.fix(orgEvent);
+    event.type = "mousewheel";
+    
+    // Old school scrollwheel delta
+    if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
+    if ( orgEvent.detail     ) { delta = -orgEvent.detail/3; }
+    
+    // New school multidimensional scroll (touchpads) deltas
+    deltaY = delta;
+    
+    // Gecko
+    if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
+        deltaY = 0;
+        deltaX = -1*delta;
+    }
+    
+    // Webkit
+    if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
+    if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
+    
+    // Add event and delta to the front of the arguments
+    args.unshift(event, delta, deltaX, deltaY);
+    
+    return ($.event.dispatch || $.event.handle).apply(this, args);
+}
+
+})(jQuery);
+
+/*
+ * jScrollPane - v2.0.0beta12 - 2012-07-24
+ * http://jscrollpane.kelvinluck.com/
+ *
+ * Copyright (c) 2010 Kelvin Luck
+ * Dual licensed under the MIT and GPL licenses.
+ */
+(function(b,a,c){b.fn.jScrollPane=function(e){function d(D,O){var ay,Q=this,Y,aj,v,al,T,Z,y,q,az,aE,au,i,I,h,j,aa,U,ap,X,t,A,aq,af,am,G,l,at,ax,x,av,aH,f,L,ai=true,P=true,aG=false,k=false,ao=D.clone(false,false).empty(),ac=b.fn.mwheelIntent?"mwheelIntent.jsp":"mousewheel.jsp";aH=D.css("paddingTop")+" "+D.css("paddingRight")+" "+D.css("paddingBottom")+" "+D.css("paddingLeft");f=(parseInt(D.css("paddingLeft"),10)||0)+(parseInt(D.css("paddingRight"),10)||0);function ar(aQ){var aL,aN,aM,aJ,aI,aP,aO=false,aK=false;ay=aQ;if(Y===c){aI=D.scrollTop();aP=D.scrollLeft();D.css({overflow:"hidden",padding:0});aj=D.innerWidth()+f;v=D.innerHeight();D.width(aj);Y=b('<div class="jspPane" />').css("padding",aH).append(D.children());al=b('<div class="jspContainer" />').css({width:aj+"px",height:v+"px"}).append(Y).appendTo(D)}else{D.css("width","");aO=ay.stickToBottom&&K();aK=ay.stickToRight&&B();aJ=D.innerWidth()+f!=aj||D.outerHeight()!=v;if(aJ){aj=D.innerWidth()+f;v=D.innerHeight();al.css({width:aj+"px",height:v+"px"})}if(!aJ&&L==T&&Y.outerHeight()==Z){D.width(aj);return}L=T;Y.css("width","");D.width(aj);al.find(">.jspVerticalBar,>.jspHorizontalBar").remove().end()}Y.css("overflow","auto");if(aQ.contentWidth){T=aQ.contentWidth}else{T=Y[0].scrollWidth}Z=Y[0].scrollHeight;Y.css("overflow","");y=T/aj;q=Z/v;az=q>1;aE=y>1;if(!(aE||az)){D.removeClass("jspScrollable");Y.css({top:0,width:al.width()-f});n();E();R();w()}else{D.addClass("jspScrollable");aL=ay.maintainPosition&&(I||aa);if(aL){aN=aC();aM=aA()}aF();z();F();if(aL){N(aK?(T-aj):aN,false);M(aO?(Z-v):aM,false)}J();ag();an();if(ay.enableKeyboardNavigation){S()}if(ay.clickOnTrack){p()}C();if(ay.hijackInternalLinks){m()}}if(ay.autoReinitialise&&!av){av=setInterval(function(){ar(ay)},ay.autoReinitialiseDelay)}else{if(!ay.autoReinitialise&&av){clearInterval(av)}}aI&&D.scrollTop(0)&&M(aI,false);aP&&D.scrollLeft(0)&&N(aP,false);D.trigger("jsp-initialised",[aE||az])}function aF(){if(az){al.append(b('<div class="jspVerticalBar" />').append(b('<div class="jspCap jspCapTop" />'),b('<div class="jspTrack" />').append(b('<div class="jspDrag" />').append(b('<div class="jspDragTop" />'),b('<div class="jspDragBottom" />'))),b('<div class="jspCap jspCapBottom" />')));U=al.find(">.jspVerticalBar");ap=U.find(">.jspTrack");au=ap.find(">.jspDrag");if(ay.showArrows){aq=b('<a class="jspArrow jspArrowUp" />').bind("mousedown.jsp",aD(0,-1)).bind("click.jsp",aB);af=b('<a class="jspArrow jspArrowDown" />').bind("mousedown.jsp",aD(0,1)).bind("click.jsp",aB);if(ay.arrowScrollOnHover){aq.bind("mouseover.jsp",aD(0,-1,aq));af.bind("mouseover.jsp",aD(0,1,af))}ak(ap,ay.verticalArrowPositions,aq,af)}t=v;al.find(">.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow").each(function(){t-=b(this).outerHeight()});au.hover(function(){au.addClass("jspHover")},function(){au.removeClass("jspHover")}).bind("mousedown.jsp",function(aI){b("html").bind("dragstart.jsp selectstart.jsp",aB);au.addClass("jspActive");var s=aI.pageY-au.position().top;b("html").bind("mousemove.jsp",function(aJ){V(aJ.pageY-s,false)}).bind("mouseup.jsp mouseleave.jsp",aw);return false});o()}}function o(){ap.height(t+"px");I=0;X=ay.verticalGutter+ap.outerWidth();Y.width(aj-X-f);try{if(U.position().left===0){Y.css("margin-left",X+"px")}}catch(s){}}function z(){if(aE){al.append(b('<div class="jspHorizontalBar" />').append(b('<div class="jspCap jspCapLeft" />'),b('<div class="jspTrack" />').append(b('<div class="jspDrag" />').append(b('<div class="jspDragLeft" />'),b('<div class="jspDragRight" />'))),b('<div class="jspCap jspCapRight" />')));am=al.find(">.jspHorizontalBar");G=am.find(">.jspTrack");h=G.find(">.jspDrag");if(ay.showArrows){ax=b('<a class="jspArrow jspArrowLeft" />').bind("mousedown.jsp",aD(-1,0)).bind("click.jsp",aB);x=b('<a class="jspArrow jspArrowRight" />').bind("mousedown.jsp",aD(1,0)).bind("click.jsp",aB);
+if(ay.arrowScrollOnHover){ax.bind("mouseover.jsp",aD(-1,0,ax));x.bind("mouseover.jsp",aD(1,0,x))}ak(G,ay.horizontalArrowPositions,ax,x)}h.hover(function(){h.addClass("jspHover")},function(){h.removeClass("jspHover")}).bind("mousedown.jsp",function(aI){b("html").bind("dragstart.jsp selectstart.jsp",aB);h.addClass("jspActive");var s=aI.pageX-h.position().left;b("html").bind("mousemove.jsp",function(aJ){W(aJ.pageX-s,false)}).bind("mouseup.jsp mouseleave.jsp",aw);return false});l=al.innerWidth();ah()}}function ah(){al.find(">.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow").each(function(){l-=b(this).outerWidth()});G.width(l+"px");aa=0}function F(){if(aE&&az){var aI=G.outerHeight(),s=ap.outerWidth();t-=aI;b(am).find(">.jspCap:visible,>.jspArrow").each(function(){l+=b(this).outerWidth()});l-=s;v-=s;aj-=aI;G.parent().append(b('<div class="jspCorner" />').css("width",aI+"px"));o();ah()}if(aE){Y.width((al.outerWidth()-f)+"px")}Z=Y.outerHeight();q=Z/v;if(aE){at=Math.ceil(1/y*l);if(at>ay.horizontalDragMaxWidth){at=ay.horizontalDragMaxWidth}else{if(at<ay.horizontalDragMinWidth){at=ay.horizontalDragMinWidth}}h.width(at+"px");j=l-at;ae(aa)}if(az){A=Math.ceil(1/q*t);if(A>ay.verticalDragMaxHeight){A=ay.verticalDragMaxHeight}else{if(A<ay.verticalDragMinHeight){A=ay.verticalDragMinHeight}}au.height(A+"px");i=t-A;ad(I)}}function ak(aJ,aL,aI,s){var aN="before",aK="after",aM;if(aL=="os"){aL=/Mac/.test(navigator.platform)?"after":"split"}if(aL==aN){aK=aL}else{if(aL==aK){aN=aL;aM=aI;aI=s;s=aM}}aJ[aN](aI)[aK](s)}function aD(aI,s,aJ){return function(){H(aI,s,this,aJ);this.blur();return false}}function H(aL,aK,aO,aN){aO=b(aO).addClass("jspActive");var aM,aJ,aI=true,s=function(){if(aL!==0){Q.scrollByX(aL*ay.arrowButtonSpeed)}if(aK!==0){Q.scrollByY(aK*ay.arrowButtonSpeed)}aJ=setTimeout(s,aI?ay.initialDelay:ay.arrowRepeatFreq);aI=false};s();aM=aN?"mouseout.jsp":"mouseup.jsp";aN=aN||b("html");aN.bind(aM,function(){aO.removeClass("jspActive");aJ&&clearTimeout(aJ);aJ=null;aN.unbind(aM)})}function p(){w();if(az){ap.bind("mousedown.jsp",function(aN){if(aN.originalTarget===c||aN.originalTarget==aN.currentTarget){var aL=b(this),aO=aL.offset(),aM=aN.pageY-aO.top-I,aJ,aI=true,s=function(){var aR=aL.offset(),aS=aN.pageY-aR.top-A/2,aP=v*ay.scrollPagePercent,aQ=i*aP/(Z-v);if(aM<0){if(I-aQ>aS){Q.scrollByY(-aP)}else{V(aS)}}else{if(aM>0){if(I+aQ<aS){Q.scrollByY(aP)}else{V(aS)}}else{aK();return}}aJ=setTimeout(s,aI?ay.initialDelay:ay.trackClickRepeatFreq);aI=false},aK=function(){aJ&&clearTimeout(aJ);aJ=null;b(document).unbind("mouseup.jsp",aK)};s();b(document).bind("mouseup.jsp",aK);return false}})}if(aE){G.bind("mousedown.jsp",function(aN){if(aN.originalTarget===c||aN.originalTarget==aN.currentTarget){var aL=b(this),aO=aL.offset(),aM=aN.pageX-aO.left-aa,aJ,aI=true,s=function(){var aR=aL.offset(),aS=aN.pageX-aR.left-at/2,aP=aj*ay.scrollPagePercent,aQ=j*aP/(T-aj);if(aM<0){if(aa-aQ>aS){Q.scrollByX(-aP)}else{W(aS)}}else{if(aM>0){if(aa+aQ<aS){Q.scrollByX(aP)}else{W(aS)}}else{aK();return}}aJ=setTimeout(s,aI?ay.initialDelay:ay.trackClickRepeatFreq);aI=false},aK=function(){aJ&&clearTimeout(aJ);aJ=null;b(document).unbind("mouseup.jsp",aK)};s();b(document).bind("mouseup.jsp",aK);return false}})}}function w(){if(G){G.unbind("mousedown.jsp")}if(ap){ap.unbind("mousedown.jsp")}}function aw(){b("html").unbind("dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp");if(au){au.removeClass("jspActive")}if(h){h.removeClass("jspActive")}}function V(s,aI){if(!az){return}if(s<0){s=0}else{if(s>i){s=i}}if(aI===c){aI=ay.animateScroll}if(aI){Q.animate(au,"top",s,ad)}else{au.css("top",s);ad(s)}}function ad(aI){if(aI===c){aI=au.position().top}al.scrollTop(0);I=aI;var aL=I===0,aJ=I==i,aK=aI/i,s=-aK*(Z-v);if(ai!=aL||aG!=aJ){ai=aL;aG=aJ;D.trigger("jsp-arrow-change",[ai,aG,P,k])}u(aL,aJ);Y.css("top",s);D.trigger("jsp-scroll-y",[-s,aL,aJ]).trigger("scroll")}function W(aI,s){if(!aE){return}if(aI<0){aI=0}else{if(aI>j){aI=j}}if(s===c){s=ay.animateScroll}if(s){Q.animate(h,"left",aI,ae)
+}else{h.css("left",aI);ae(aI)}}function ae(aI){if(aI===c){aI=h.position().left}al.scrollTop(0);aa=aI;var aL=aa===0,aK=aa==j,aJ=aI/j,s=-aJ*(T-aj);if(P!=aL||k!=aK){P=aL;k=aK;D.trigger("jsp-arrow-change",[ai,aG,P,k])}r(aL,aK);Y.css("left",s);D.trigger("jsp-scroll-x",[-s,aL,aK]).trigger("scroll")}function u(aI,s){if(ay.showArrows){aq[aI?"addClass":"removeClass"]("jspDisabled");af[s?"addClass":"removeClass"]("jspDisabled")}}function r(aI,s){if(ay.showArrows){ax[aI?"addClass":"removeClass"]("jspDisabled");x[s?"addClass":"removeClass"]("jspDisabled")}}function M(s,aI){var aJ=s/(Z-v);V(aJ*i,aI)}function N(aI,s){var aJ=aI/(T-aj);W(aJ*j,s)}function ab(aV,aQ,aJ){var aN,aK,aL,s=0,aU=0,aI,aP,aO,aS,aR,aT;try{aN=b(aV)}catch(aM){return}aK=aN.outerHeight();aL=aN.outerWidth();al.scrollTop(0);al.scrollLeft(0);while(!aN.is(".jspPane")){s+=aN.position().top;aU+=aN.position().left;aN=aN.offsetParent();if(/^body|html$/i.test(aN[0].nodeName)){return}}aI=aA();aO=aI+v;if(s<aI||aQ){aR=s-ay.verticalGutter}else{if(s+aK>aO){aR=s-v+aK+ay.verticalGutter}}if(aR){M(aR,aJ)}aP=aC();aS=aP+aj;if(aU<aP||aQ){aT=aU-ay.horizontalGutter}else{if(aU+aL>aS){aT=aU-aj+aL+ay.horizontalGutter}}if(aT){N(aT,aJ)}}function aC(){return -Y.position().left}function aA(){return -Y.position().top}function K(){var s=Z-v;return(s>20)&&(s-aA()<10)}function B(){var s=T-aj;return(s>20)&&(s-aC()<10)}function ag(){al.unbind(ac).bind(ac,function(aL,aM,aK,aI){var aJ=aa,s=I;Q.scrollBy(aK*ay.mouseWheelSpeed,-aI*ay.mouseWheelSpeed,false);return aJ==aa&&s==I})}function n(){al.unbind(ac)}function aB(){return false}function J(){Y.find(":input,a").unbind("focus.jsp").bind("focus.jsp",function(s){ab(s.target,false)})}function E(){Y.find(":input,a").unbind("focus.jsp")}function S(){var s,aI,aK=[];aE&&aK.push(am[0]);az&&aK.push(U[0]);Y.focus(function(){D.focus()});D.attr("tabindex",0).unbind("keydown.jsp keypress.jsp").bind("keydown.jsp",function(aN){if(aN.target!==this&&!(aK.length&&b(aN.target).closest(aK).length)){return}var aM=aa,aL=I;switch(aN.keyCode){case 40:case 38:case 34:case 32:case 33:case 39:case 37:s=aN.keyCode;aJ();break;case 35:M(Z-v);s=null;break;case 36:M(0);s=null;break}aI=aN.keyCode==s&&aM!=aa||aL!=I;return !aI}).bind("keypress.jsp",function(aL){if(aL.keyCode==s){aJ()}return !aI});if(ay.hideFocus){D.css("outline","none");if("hideFocus" in al[0]){D.attr("hideFocus",true)}}else{D.css("outline","");if("hideFocus" in al[0]){D.attr("hideFocus",false)}}function aJ(){var aM=aa,aL=I;switch(s){case 40:Q.scrollByY(ay.keyboardSpeed,false);break;case 38:Q.scrollByY(-ay.keyboardSpeed,false);break;case 34:case 32:Q.scrollByY(v*ay.scrollPagePercent,false);break;case 33:Q.scrollByY(-v*ay.scrollPagePercent,false);break;case 39:Q.scrollByX(ay.keyboardSpeed,false);break;case 37:Q.scrollByX(-ay.keyboardSpeed,false);break}aI=aM!=aa||aL!=I;return aI}}function R(){D.attr("tabindex","-1").removeAttr("tabindex").unbind("keydown.jsp keypress.jsp")}function C(){if(location.hash&&location.hash.length>1){var aK,aI,aJ=escape(location.hash.substr(1));try{aK=b("#"+aJ+', a[name="'+aJ+'"]')}catch(s){return}if(aK.length&&Y.find(aJ)){if(al.scrollTop()===0){aI=setInterval(function(){if(al.scrollTop()>0){ab(aK,true);b(document).scrollTop(al.position().top);clearInterval(aI)}},50)}else{ab(aK,true);b(document).scrollTop(al.position().top)}}}}function m(){if(b(document.body).data("jspHijack")){return}b(document.body).data("jspHijack",true);b(document.body).delegate("a[href*=#]","click",function(s){var aI=this.href.substr(0,this.href.indexOf("#")),aK=location.href,aO,aP,aJ,aM,aL,aN;if(location.href.indexOf("#")!==-1){aK=location.href.substr(0,location.href.indexOf("#"))}if(aI!==aK){return}aO=escape(this.href.substr(this.href.indexOf("#")+1));aP;try{aP=b("#"+aO+', a[name="'+aO+'"]')}catch(aQ){return}if(!aP.length){return}aJ=aP.closest(".jspScrollable");aM=aJ.data("jsp");aM.scrollToElement(aP,true);if(aJ[0].scrollIntoView){aL=b(a).scrollTop();aN=aP.offset().top;if(aN<aL||aN>aL+b(a).height()){aJ[0].scrollIntoView()}}s.preventDefault()
+})}function an(){var aJ,aI,aL,aK,aM,s=false;al.unbind("touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick").bind("touchstart.jsp",function(aN){var aO=aN.originalEvent.touches[0];aJ=aC();aI=aA();aL=aO.pageX;aK=aO.pageY;aM=false;s=true}).bind("touchmove.jsp",function(aQ){if(!s){return}var aP=aQ.originalEvent.touches[0],aO=aa,aN=I;Q.scrollTo(aJ+aL-aP.pageX,aI+aK-aP.pageY);aM=aM||Math.abs(aL-aP.pageX)>5||Math.abs(aK-aP.pageY)>5;return aO==aa&&aN==I}).bind("touchend.jsp",function(aN){s=false}).bind("click.jsp-touchclick",function(aN){if(aM){aM=false;return false}})}function g(){var s=aA(),aI=aC();D.removeClass("jspScrollable").unbind(".jsp");D.replaceWith(ao.append(Y.children()));ao.scrollTop(s);ao.scrollLeft(aI);if(av){clearInterval(av)}}b.extend(Q,{reinitialise:function(aI){aI=b.extend({},ay,aI);ar(aI)},scrollToElement:function(aJ,aI,s){ab(aJ,aI,s)},scrollTo:function(aJ,s,aI){N(aJ,aI);M(s,aI)},scrollToX:function(aI,s){N(aI,s)},scrollToY:function(s,aI){M(s,aI)},scrollToPercentX:function(aI,s){N(aI*(T-aj),s)},scrollToPercentY:function(aI,s){M(aI*(Z-v),s)},scrollBy:function(aI,s,aJ){Q.scrollByX(aI,aJ);Q.scrollByY(s,aJ)},scrollByX:function(s,aJ){var aI=aC()+Math[s<0?"floor":"ceil"](s),aK=aI/(T-aj);W(aK*j,aJ)},scrollByY:function(s,aJ){var aI=aA()+Math[s<0?"floor":"ceil"](s),aK=aI/(Z-v);V(aK*i,aJ)},positionDragX:function(s,aI){W(s,aI)},positionDragY:function(aI,s){V(aI,s)},animate:function(aI,aL,s,aK){var aJ={};aJ[aL]=s;aI.animate(aJ,{duration:ay.animateDuration,easing:ay.animateEase,queue:false,step:aK})},getContentPositionX:function(){return aC()},getContentPositionY:function(){return aA()},getContentWidth:function(){return T},getContentHeight:function(){return Z},getPercentScrolledX:function(){return aC()/(T-aj)},getPercentScrolledY:function(){return aA()/(Z-v)},getIsScrollableH:function(){return aE},getIsScrollableV:function(){return az},getContentPane:function(){return Y},scrollToBottom:function(s){V(i,s)},hijackInternalLinks:b.noop,destroy:function(){g()}});ar(O)}e=b.extend({},b.fn.jScrollPane.defaults,e);b.each(["mouseWheelSpeed","arrowButtonSpeed","trackClickSpeed","keyboardSpeed"],function(){e[this]=e[this]||e.speed});return this.each(function(){var f=b(this),g=f.data("jsp");if(g){g.reinitialise(e)}else{b("script",f).filter('[type="text/javascript"],not([type])').remove();g=new d(f,e);f.data("jsp",g)}})};b.fn.jScrollPane.defaults={showArrows:false,maintainPosition:true,stickToBottom:false,stickToRight:false,clickOnTrack:true,autoReinitialise:false,autoReinitialiseDelay:500,verticalDragMinHeight:0,verticalDragMaxHeight:99999,horizontalDragMinWidth:0,horizontalDragMaxWidth:99999,contentWidth:c,animateScroll:false,animateDuration:300,animateEase:"linear",hijackInternalLinks:false,verticalGutter:4,horizontalGutter:4,mouseWheelSpeed:0,arrowButtonSpeed:0,arrowRepeatFreq:50,arrowScrollOnHover:false,trackClickSpeed:0,trackClickRepeatFreq:70,verticalArrowPositions:"split",horizontalArrowPositions:"split",enableKeyboardNavigation:true,hideFocus:false,keyboardSpeed:0,initialDelay:300,speed:30,scrollPagePercent:0.8}})(jQuery,this);
\ No newline at end of file
diff --git a/nui/scripts/jquery.zclip.min.js b/nui/scripts/jquery.zclip.min.js
new file mode 100644 (file)
index 0000000..51471a1
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * zClip :: jQuery ZeroClipboard v1.1.1
+ * http://steamdev.com/zclip
+ *
+ * Copyright 2011, SteamDev
+ * Released under the MIT license.
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Date: Wed Jun 01, 2011
+ */
+
+(function(a){a.fn.zclip=function(c){if(typeof c=="object"&&!c.length){var b=a.extend({path:"ZeroClipboard.swf",copy:null,beforeCopy:null,afterCopy:null,clickAfter:true,setHandCursor:true,setCSSEffects:true},c);return this.each(function(){var e=a(this);if(e.is(":visible")&&(typeof b.copy=="string"||a.isFunction(b.copy))){ZeroClipboard.setMoviePath(b.path);var d=new ZeroClipboard.Client();if(a.isFunction(b.copy)){e.bind("zClip_copy",b.copy)}if(a.isFunction(b.beforeCopy)){e.bind("zClip_beforeCopy",b.beforeCopy)}if(a.isFunction(b.afterCopy)){e.bind("zClip_afterCopy",b.afterCopy)}d.setHandCursor(b.setHandCursor);d.setCSSEffects(b.setCSSEffects);d.addEventListener("mouseOver",function(f){e.trigger("mouseenter")});d.addEventListener("mouseOut",function(f){e.trigger("mouseleave")});d.addEventListener("mouseDown",function(f){e.trigger("mousedown");if(!a.isFunction(b.copy)){d.setText(b.copy)}else{d.setText(e.triggerHandler("zClip_copy"))}if(a.isFunction(b.beforeCopy)){e.trigger("zClip_beforeCopy")}});d.addEventListener("complete",function(f,g){if(a.isFunction(b.afterCopy)){e.trigger("zClip_afterCopy")}else{if(g.length>500){g=g.substr(0,500)+"...\n\n("+(g.length-500)+" characters not shown)"}e.removeClass("hover");alert("Copied text to clipboard:\n\n "+g)}if(b.clickAfter){e.trigger("click")}});d.glue(e[0],e.parent()[0]);a(window).bind("load resize",function(){d.reposition()})}})}else{if(typeof c=="string"){return this.each(function(){var f=a(this);c=c.toLowerCase();var e=f.data("zclipId");var d=a("#"+e+".zclip");if(c=="remove"){d.remove();f.removeClass("active hover")}else{if(c=="hide"){d.hide();f.removeClass("active hover")}else{if(c=="show"){d.show()}}}})}}}})(jQuery);var ZeroClipboard={version:"1.0.7",clients:{},moviePath:"ZeroClipboard.swf",nextId:1,$:function(a){if(typeof(a)=="string"){a=document.getElementById(a)}if(!a.addClass){a.hide=function(){this.style.display="none"};a.show=function(){this.style.display=""};a.addClass=function(b){this.removeClass(b);this.className+=" "+b};a.removeClass=function(d){var e=this.className.split(/\s+/);var b=-1;for(var c=0;c<e.length;c++){if(e[c]==d){b=c;c=e.length}}if(b>-1){e.splice(b,1);this.className=e.join(" ")}return this};a.hasClass=function(b){return !!this.className.match(new RegExp("\\s*"+b+"\\s*"))}}return a},setMoviePath:function(a){this.moviePath=a},dispatch:function(d,b,c){var a=this.clients[d];if(a){a.receiveEvent(b,c)}},register:function(b,a){this.clients[b]=a},getDOMObjectPosition:function(c,a){var b={left:0,top:0,width:c.width?c.width:c.offsetWidth,height:c.height?c.height:c.offsetHeight};if(c&&(c!=a)){b.left+=c.offsetLeft;b.top+=c.offsetTop}return b},Client:function(a){this.handlers={};this.id=ZeroClipboard.nextId++;this.movieId="ZeroClipboardMovie_"+this.id;ZeroClipboard.register(this.id,this);if(a){this.glue(a)}}};ZeroClipboard.Client.prototype={id:0,ready:false,movie:null,clipText:"",handCursorEnabled:true,cssEffects:true,handlers:null,glue:function(d,b,e){this.domElement=ZeroClipboard.$(d);var f=99;if(this.domElement.style.zIndex){f=parseInt(this.domElement.style.zIndex,10)+1}if(typeof(b)=="string"){b=ZeroClipboard.$(b)}else{if(typeof(b)=="undefined"){b=document.getElementsByTagName("body")[0]}}var c=ZeroClipboard.getDOMObjectPosition(this.domElement,b);this.div=document.createElement("div");this.div.className="zclip";this.div.id="zclip-"+this.movieId;$(this.domElement).data("zclipId","zclip-"+this.movieId);var a=this.div.style;a.position="absolute";a.left=""+c.left+"px";a.top=""+c.top+"px";a.width=""+c.width+"px";a.height=""+c.height+"px";a.zIndex=f;if(typeof(e)=="object"){for(addedStyle in e){a[addedStyle]=e[addedStyle]}}b.appendChild(this.div);this.div.innerHTML=this.getHTML(c.width,c.height)},getHTML:function(d,a){var c="";var b="id="+this.id+"&width="+d+"&height="+a;if(navigator.userAgent.match(/MSIE/)){var e=location.href.match(/^https/i)?"https://":"http://";c+='<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+e+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+d+'" height="'+a+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+b+'"/><param name="wmode" value="transparent"/></object>'}else{c+='<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+d+'" height="'+a+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+b+'" wmode="transparent" />'}return c},hide:function(){if(this.div){this.div.style.left="-2000px"}},show:function(){this.reposition()},destroy:function(){if(this.domElement&&this.div){this.hide();this.div.innerHTML="";var a=document.getElementsByTagName("body")[0];try{a.removeChild(this.div)}catch(b){}this.domElement=null;this.div=null}},reposition:function(c){if(c){this.domElement=ZeroClipboard.$(c);if(!this.domElement){this.hide()}}if(this.domElement&&this.div){var b=ZeroClipboard.getDOMObjectPosition(this.domElement);var a=this.div.style;a.left=""+b.left+"px";a.top=""+b.top+"px"}},setText:function(a){this.clipText=a;if(this.ready){this.movie.setText(a)}},addEventListener:function(a,b){a=a.toString().toLowerCase().replace(/^on/,"");if(!this.handlers[a]){this.handlers[a]=[]}this.handlers[a].push(b)},setHandCursor:function(a){this.handCursorEnabled=a;if(this.ready){this.movie.setHandCursor(a)}},setCSSEffects:function(a){this.cssEffects=!!a},receiveEvent:function(d,f){d=d.toString().toLowerCase().replace(/^on/,"");switch(d){case"load":this.movie=document.getElementById(this.movieId);if(!this.movie){var c=this;setTimeout(function(){c.receiveEvent("load",null)},1);return}if(!this.ready&&navigator.userAgent.match(/Firefox/)&&navigator.userAgent.match(/Windows/)){var c=this;setTimeout(function(){c.receiveEvent("load",null)},100);this.ready=true;return}this.ready=true;try{this.movie.setText(this.clipText)}catch(h){}try{this.movie.setHandCursor(this.handCursorEnabled)}catch(h){}break;case"mouseover":if(this.domElement&&this.cssEffects){this.domElement.addClass("hover");if(this.recoverActive){this.domElement.addClass("active")}}break;case"mouseout":if(this.domElement&&this.cssEffects){this.recoverActive=false;if(this.domElement.hasClass("active")){this.domElement.removeClass("active");this.recoverActive=true}this.domElement.removeClass("hover")}break;case"mousedown":if(this.domElement&&this.cssEffects){this.domElement.addClass("active")}break;case"mouseup":if(this.domElement&&this.cssEffects){this.domElement.removeClass("active");this.recoverActive=false}break}if(this.handlers[d]){for(var b=0,a=this.handlers[d].length;b<a;b++){var g=this.handlers[d][b];if(typeof(g)=="function"){g(this,f)}else{if((typeof(g)=="object")&&(g.length==2)){g[0][g[1]](this,f)}else{if(typeof(g)=="string"){window[g](this,f)}}}}}}};
\ No newline at end of file
diff --git a/nui/scripts/navi.js b/nui/scripts/navi.js
new file mode 100644 (file)
index 0000000..badc738
--- /dev/null
@@ -0,0 +1,192 @@
+//<![CDATA[
+    var staticURL = "http://img-developer.samsung.com";
+       var sslCall = "";
+
+       if('' !== 'N') {
+               var locationStr = location.href;
+               if(locationStr.indexOf("https://") > -1) {
+                       location.href = "http://" + locationStr.substring(8);
+               }     
+    }
+
+//     if( typeof($) === function ) {
+               //https? ??? $SD? ??? ??? https ???? http? js ???? ???? ???.
+               //? ??? ?? ?? ??? ?? ?? ???.
+//     }
+    $SD.pagination.alt = {
+               first:"go first",
+               prev:"go prev",
+               next:"go next",
+               last:"go last"
+    };
+    $(document).ready(function(){
+       var myVar;
+           topSearchInit();//top search ??
+           $('#searchTop').attr("autocomplete","off");
+           var searchingBoolean = false;
+           
+           var topSearchChange = function(){
+               
+               if (searchingBoolean) return;
+               
+                       var searchInput = $('#searchTop').val();
+                       
+                       if($('#searchTop').val() != ""){
+                               $("#topAutocomplete").hide();
+                               searchingBoolean = true;
+                               
+                               var jsonData = {
+                                               url : "/search/autoComplete.do;jsessionid=hphlTh5pL0pypqhNXb18Tnhbxwzk2hBC6KxnThCvysc2Hz2WG1y2!1103778492",
+                                               async : true,
+                                               data : { searchInput : searchInput},
+                                               success : function(data){
+                                                       if (searchInput == $('#searchTop').val()){
+                                                               var autoComplete = data.kwdNm;
+                                                               var tmpHtml = "";
+                                                               
+                                                               if (autoComplete.length > 0){
+                                                                       $('#topAutocomplete').children().remove();
+                                                                       $('#topAutocomplete').append($('<ul id="topAutocompleteList"><\/ul>'));
+                                                                       $.each(autoComplete, function(i, item){
+                                                                               var a = $("<a href='javascript:;'><em>"+data.searchInput+"<\/em>"+item.kwdNmSub+"<\/a>");
+                                                                               a.data('keyword', item.kwdNm);
+                                                                               $('#topAutocompleteList').append($('<li><\/li>').html(a));
+                                                                       });
+                                                                       $("#topAutocompleteList").find("li").last().on("keydown", function(e) {
+                                                                               if(e.which == 9 && e.shiftKey) {
+                                                                                       return true;
+                                                                               }
+                                                                               
+                                                                               if(e.which == 9) {
+                                                                                       e.preventDefault();
+                                                                                       $('#topAutocomplete').hide();   
+                                                                                       setTimeout(function() {
+                                                                                               $("#searchTopBtn").focus();
+                                                                                       }, 1);
+                                                                               }
+                                                                               
+                                                                       });
+                                                                       $("#searchTopBtn").off("focusout", function(e) {});
+                                                                   $("#searchTopBtn").on("focusout", function(e) {
+                                                                               $('#topAutocomplete').hide();
+                                                                       });
+                                                               }else{
+                                                                       $('#topAutocomplete').children().remove();
+                                                               }
+                                                               if($('#searchTop').val() == ""){
+                                                                       $("#topAutocomplete").hide();
+                                                                       searchingBoolean = false;
+                                                                       return;
+                                                               }else{
+                                                                       if (searchInput == $('#searchTop').val()){
+                                                                               searchingBoolean = false;
+                                                                       }else{
+                                                                               searchingBoolean = false;
+                                                                               topSearchChange();
+                                                                       }
+                                                               }
+                                                               if (autoComplete.length == 0){
+                                                                       $("#topAutocomplete").hide();
+                                                               }else{
+                                                                       if (searchInput == $('#searchTop').val()){
+                                                                               $("#topAutocomplete").show();
+                                                                               var $searchList = $("#topAutocomplete").find('ul');
+                                                                               var hei = $searchList.outerHeight();
+                                                                               if(hei>180){
+                                                                                       $searchList.css({'height':'180px','overflow-y':'auto'});
+                                                                               }
+                                                                       }else{
+                                                                               searchingBoolean = false;
+                                                                               topSearchChange();
+                                                                       }
+                                                               }
+                                                       }else{
+                                                               searchingBoolean = false;
+                                                               topSearchChange();
+                                                       }
+                                               },
+                                               error : function() {searchingBoolean = false;}
+                                               
+                               };
+                               //setTimeout(function(){$SD.ajax.get(jsonData);},100);
+                               $SD.ajax.get(jsonData);
+                               searchingBoolean = false;
+                       }
+                       
+                       //console.log("/search/autoComplete.do end");
+                       //console.groupEnd();
+               };
+               
+               $('#searchTop').keyup(function(e){
+                       if($('#searchTop').val() == ""){
+                               $('#topAutocomplete').children().remove();
+                               $("#topAutocomplete").hide();
+                       }else{
+                               if(e.which == 13){
+                                       search();
+                               }else{
+                                       topSearchChange();
+                               }
+                       }
+               });
+               
+               var search = function(){
+                       if($.trim($('#searchTop').val()) == ""){
+                               alert('Search keyword is required.');
+                       }else{
+                               $('#topSearchForm').submit();
+                       }
+               };
+               $("#topAutocomplete").on('mousedown','ul li a', function(e){
+                       e.preventDefault();
+                       var keyword = $(this).data('keyword');
+                       $("#searchTop").val(keyword);
+                       $('#topSearchForm').submit();
+               });
+               
+               $("#topAutocomplete").on('keydown keypress','ul li a', function(e){
+                       if(e.which == 13) {
+                               e.preventDefault();
+                               var keyword = $(this).data('keyword');
+                               $("#searchTop").val(keyword);
+                               $('#topSearchForm').submit();                   
+                       }
+               });
+               
+               $('#searchTopBtn').click(function(e){
+                       search();       
+               });  
+    });
+    
+    function topSearchEnter(){
+       if($.trim($('#searchTop').val()) == "" || $.trim($('#searchTop').val()) == "Search"){
+               alert('Search keyword is required.');
+               return false;
+       }else{
+               return true;
+       }
+    }
+
+/* Tracking Code TOTAL */
+               var _gaq = _gaq || [];
+               var pluginUrl = '//www.google-analytics.com/plugins/ga/inpage_linkid.js';
+               _gaq.push(['_require', 'inpage_linkid', pluginUrl]);
+               _gaq.push(['_setAccount', 'UA-6892706-3']);
+               _gaq.push(['_setDomainName', 'samsung.com']);
+               _gaq.push(['_setAllowLinker', true]);
+               _gaq.push(['_trackPageview']);
+               (function() {
+                 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+                 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+                 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+               })();
+       
+               <!--// Tracking Code 1 -->
+                       var _gaq = _gaq || [];
+                       _gaq.push(['_setAccount', 'UA-6892706-4']);
+                       _gaq.push(['_trackPageview']);
+                       (function() {
+                         var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+                         ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+                         var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+                       })();
diff --git a/nui/scripts/search.js b/nui/scripts/search.js
new file mode 100644 (file)
index 0000000..d1ae5ad
--- /dev/null
@@ -0,0 +1,168 @@
+/** 
+ * [PAGE] Search Result
+ * date : 20120810
+ * author : 전종호
+ */
+function searchInit()
+{
+       var focusTarget = "input";
+
+       //$("#autocomplete").hide();
+
+       //$("#searchInput").bind("keydown", checkSearchText);
+       
+       $("#searchInput").focusout(function() {
+               if( focusTarget == "dropdown" )
+               {
+                       return false;
+               }
+               else
+               {
+                       //toggleClass( false );
+               }
+       });
+       
+       $( "#searchInput" ).focusin( function() {
+               focusTarget = "input";
+       });
+
+       $("#btnDropdown").mousedown( function(){
+               focusTarget = "dropdown";
+       });
+
+       $(".autocomplete ul li").focusin( function() {
+               //
+       });
+       
+       $("#autocomplete").bind("mouseleave",function(){
+               $(this).hide();
+               $("#btnDropdown").removeClass("dropdownoff");
+               $("#btnDropdown").addClass("dropdown");         
+       });
+
+       $(".autocomplete ul li:last-child").focusout( function() {
+               toggleClass( false );
+       });
+       
+       $("#btnDropdown").click( function(){
+               //alert("btn click");
+               if( $("#searchInput").val().length == 0 ){ 
+                       return false;
+               }
+               else{
+                       if( $("#btnDropdown").hasClass("dropdown") ){
+                               toggleClass( true );
+                       }
+                       else{
+                               toggleClass( false );
+                       }
+               }
+
+               return false;
+       });
+
+       function checkSearchText(){
+               setTimeout(function(){
+                       var txt = $("#searchInput").val();
+
+                       if( txt.length > 0 ){
+                               toggleClass( true );
+                       }
+                       else{
+                               toggleClass( false );   
+                       }
+               }, 1);
+       }
+
+       function toggleClass( bo ){
+               if( bo ){
+                       //$(".autocomplete").css("visibility", "visible");
+                       $("#autocomplete").show();
+                       
+                       $("#btnDropdown").removeClass("dropdown");
+                       $("#btnDropdown").addClass("dropdownoff");
+               }
+               else{
+                       //$(".autocomplete").css("visibility", "hidden");
+                       $("#autocomplete").hide();
+                       
+                       $("#btnDropdown").removeClass("dropdownoff");
+                       $("#btnDropdown").addClass("dropdown");
+               }
+       }
+}
+
+
+
+function topSearchInit()
+{
+       var focusTarget = "input";
+
+       //$("#searchTop").bind("keydown", checkSearchText);
+       
+       $("#searchTop").focusout(function() {
+               if( focusTarget == "dropdown" )
+               {
+                       return false;
+               }
+               else
+               {       
+                       //toggleClass( false );
+               }
+       });
+       
+       $( "#searchTop" ).focusin( function()   {
+               focusTarget = "input";
+       });
+
+       $("#btnDropdown").mousedown( function(){
+               focusTarget = "dropdown";
+       });
+
+       $(".autocomplete ul li").focusin( function() {
+               //
+       });
+       
+       $(".autocomplete ul li:last-child").focusout( function() {
+               toggleClass( false );
+       })
+       
+       $("#btnDropdown").click( function(){
+               //alert("btn click");
+               if( $("#searchInput").val().length == 0 ){ 
+                       return false;
+               }
+               else{
+                       if( $("#btnDropdown").hasClass("dropdown") ){
+                               toggleClass( true );
+                       }
+                       else{
+                               toggleClass( false );
+                       }
+               }
+
+               return false;
+       });
+
+       function checkSearchText(){
+               setTimeout(function(){
+                       var txt = $("#searchTop").val();
+
+                       if( txt.length > 0 ){
+                               toggleClass( true );
+                       }
+                       else{
+                               toggleClass( false );   
+                       }
+               }, 1);
+       }
+
+       function toggleClass( bo ){
+               if( bo ){
+                       $(".topAutocomplete").css("visibility", "visible");
+               }else{
+                       $(".topAutocomplete").css("visibility", "hidden");
+                       $("#topAutocomplete").hide();
+               }
+       }
+}
diff --git a/nui/scripts/showhide.js b/nui/scripts/showhide.js
new file mode 100644 (file)
index 0000000..2e85407
--- /dev/null
@@ -0,0 +1,204 @@
+/*all Show Hide devicespecs List*/
+if($('div#contents').find('.devicespecs-util').length){
+var self = $('div#contents').find('.devicespecs-util');
+
+$('.showA', self).bind ("click", function (){
+$(this).parents('.devicespecs-util').next().find('.devicespec-tit').each(function(){
+var me = $(this);
+var idx = $('.devicespecifications .devicespec-tit').index(this);
+
+if ( !me.next().is(':visible') ){
+       me.find("a").css('background-image', me.find("a").css('background-image').replace('_.gif','.gif'));
+       me.find('em').text('Hide');
+       me.next().show();
+}
+});
+return false;
+})
+$('.hideA', self).bind ("click", function (){
+$(this).parents('.devicespecs-util').next().find('.devicespec-tit').each(function(){
+
+       var me = $(this);
+       var idx = $('.devicespecifications .devicespec-tit').index(this);
+
+       if ( me.next().is(':visible') ){
+               me.find("a").css('background-image', me.find("a").css('background-image').replace('.gif','_.gif'));
+               me.find('em').text('Show');
+               me.next().hide();
+       }
+                                       
+});
+return false;
+})
+}      
+
+/*toggle devicespecs List*/
+if($('div#contents').find('.devicespec-tit').length){
+
+$('.devicespec-tit').each(function(){
+var self = $(this);
+$('a', self).bind ("click", function(){
+       var idx = $('.devicespec-tit a').index(this);
+
+       if ( $(this).parent().parent().next().is(':visible') ){
+               $(this).css('background-image', $(this).css('background-image').replace('.gif','_.gif'));
+
+               self.find('em').text('Show');
+               self.next().hide();
+
+               return false;
+       }else{
+               $(this).css('background-image', $(this).css('background-image').replace('_.gif','.gif'));
+               self.find('em').text('Hide');
+
+               self.next().show();
+
+               return false;
+       }
+
+});
+
+});
+}
+
+$('ul.devicespecifications li div.devicespec-con').hide();
+
+
+$('.devicespec-tit').each(function(){
+var self = $(this);
+var arrow =  $('a', self);
+
+if(self.next().is(':visible')){
+arrow.css('background-image', arrow.css('background-image').replace('_.gif','.gif'));
+self.find('em').text('Hide');
+}else{
+arrow.css('background-image', arrow.css('background-image').replace('.gif','_.gif'));
+self.find('em').text('Show');
+}
+
+});
+
+$(document).ready(function(){
+       var openheading = function(target) {
+               var origin = $(target);
+               target = origin.closest('.devicespec-con');
+               if (!(target.length > 0)) {
+                       target = origin.closest('.devicespec-tit');
+               }
+               if (target.length > 0) {
+                       if (!$('.devicespec-con', target.parent()).is(":visible")) {
+                               $("div.devicespec-tit a.bt-arr", target.parent()).click();
+                       }
+               }
+
+               $(window.location.hash)[0].scrollIntoView();
+       };
+
+       $(".opensection").click(function(){
+               var target = $($(this).attr("href"));//.closest('.devicespec-con');
+               openheading(target);
+       });
+
+       if (window.location.hash) {
+               var target = $(window.location.hash);
+               openheading(target);
+               //$(target).focus(); //uncomment if fail to work
+       }
+
+       var isScrolledIntoView = function(elem)
+       {
+               var docViewTop = $('#contents').scrollTop();
+               var docViewBottom = docViewTop + $('#contents').height();
+
+               var elemTop = $(elem).offset().top;
+               var elemBottom = elemTop + $(elem).height();
+
+               return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
+                 && (elemBottom <= docViewBottom) &&  (elemTop >= docViewTop) );
+       }
+
+       $('#contents').scroll();
+
+       var checkBreadCrumbs = function() {
+               if (!isScrolledIntoView($('#contents .content h1')))
+               {
+                       $('a.top.sms').show();
+                       $('.help_breadcrumbs').hide();
+               } else {
+                       $('a.top.sms').hide();
+                       $('.help_breadcrumbs').show();
+               }
+               $('#contents').css('padding-top', $('.help_breadcrumbs').outerHeight()*(7/6));
+       }       
+
+       var updateH = function(){
+               checkBreadCrumbs();
+               $('a.top').css('bottom', $('#footer').outerHeight());
+               $('a.top').css('left', $('#toc-navigation').position()['left'] + (($('#toc-navigation').outerWidth() - $('a.top').outerWidth())/2));
+
+               $('#toc').css('top', $('#toc_border').position()['top'] + 7);
+
+               if ($('a.top').is(':visible'))
+               {
+                       $('#toc').css('height', $(window).height()-$('#toc').position()['top']-($(window).height() - $('a.top').position()['top']) - 10);
+               } else {
+                       $('#toc').css('height', $(window).height()-$('#toc').position()['top']-$('#footer').outerHeight() - 20);
+               }
+               $('#toc').css('height', $('#toc').css('height') - 5);
+
+               $('#toc_border').height($('#toc').outerHeight() + 5);
+               $('#container #contents').css('margin-bottom', $('#footer').outerHeight());
+               //$('#toc').css('top', $('#toc_border').position()['top'] + 2);
+               $('#toc').css('top', $('#toc_border').position()['top'] + 7);
+               $('#contents').css('right', $(window).width() - $('#toc-navigation').position()['left'] + 5);
+               //$('#toc').css('width', $('#toc_border').width() - 40);
+               $('#toc').css('width', $('#toc_border').width() - 49);
+       };
+
+       var updateH_no_toc = function() {
+               checkBreadCrumbs();
+               if (!isScrolledIntoView($('#contents .content h1')))
+               {
+                       $('a.top.sms').show();
+               } else {
+                       $('a.top.sms').hide();
+               }
+               $('a.top').css('bottom', $('#footer').outerHeight());
+               
+               $('#container #contents').css('margin-bottom', $('#footer').outerHeight());
+       }
+
+       if ($('body').hasClass('no-toc')) {
+               updateH = updateH_no_toc;
+       }
+       $(window).resize(updateH);
+       $('#contents').scroll(updateH);
+       $(window).resize();
+       
+       $('a.top').click(function(){$('#contents').scrollTop(0)});
+
+       var hashchanged = function() {
+               if (window.location.hash.length) {
+                       openheading(window.location.hash);
+                       //$(window.location.hash).scrollTo();
+                       $(window.location.hash)[0].scrollIntoView();
+
+               } else 
+               {
+                       $('#contents').scrollTop(0);
+               }
+       };
+
+       if (("onhashchange" in window) && !($.browser.msie)) { 
+               $(window).bind( 'hashchange',hashchanged);
+       }
+       else { 
+               var prevHash = window.location.hash;
+               window.setInterval(function () {
+                       if (window.location.hash != prevHash) {
+                               hashchanged();
+                               prevHash = window.location.hash;
+                       }
+               }, 100);
+       }
+});
diff --git a/nui/scripts/snippet.js b/nui/scripts/snippet.js
new file mode 100644 (file)
index 0000000..777e9ae
--- /dev/null
@@ -0,0 +1,1478 @@
+// Copyright (C) 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/**
+ * @fileoverview
+ * some functions for browser-side pretty printing of code contained in html.
+ *
+ * <p>
+ * For a fairly comprehensive set of languages see the
+ * <a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html#langs">README</a>
+ * file that came with this source.  At a minimum, the lexer should work on a
+ * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
+ * XML, CSS, Javascript, and Makefiles.  It works passably on Ruby, PHP and Awk
+ * and a subset of Perl, but, because of commenting conventions, doesn't work on
+ * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
+ * <p>
+ * Usage: <ol>
+ * <li> include this source file in an html page via
+ *   {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
+ * <li> define style rules.  See the example page for examples.
+ * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
+ *    {@code class=prettyprint.}
+ *    You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
+ *    printer needs to do more substantial DOM manipulations to support that, so
+ *    some css styles may not be preserved.
+ * </ol>
+ * That's it.  I wanted to keep the API as simple as possible, so there's no
+ * need to specify which language the code is in, but if you wish, you can add
+ * another class to the {@code <pre>} or {@code <code>} element to specify the
+ * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
+ * starts with "lang-" followed by a file extension, specifies the file type.
+ * See the "lang-*.js" files in this directory for code that implements
+ * per-language file handlers.
+ * <p>
+ * Change log:<br>
+ * cbeust, 2006/08/22
+ * <blockquote>
+ *   Java annotations (start with "@") are now captured as literals ("lit")
+ * </blockquote>
+ * @requires console
+ */
+
+// JSLint declarations
+/*global console, document, navigator, setTimeout, window */
+
+/**
+ * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
+ * UI events.
+ * If set to {@code false}, {@code prettyPrint()} is synchronous.
+ */
+window['PR_SHOULD_USE_CONTINUATION'] = true;
+
+(function () {
+  // Keyword lists for various languages.
+  // We use things that coerce to strings to make them compact when minified
+  // and to defeat aggressive optimizers that fold large string constants.
+  var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
+  var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," + 
+      "double,enum,extern,float,goto,int,long,register,short,signed,sizeof," +
+      "static,struct,switch,typedef,union,unsigned,void,volatile"];
+  var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
+      "new,operator,private,protected,public,this,throw,true,try,typeof"];
+  var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
+      "concept,concept_map,const_cast,constexpr,decltype," +
+      "dynamic_cast,explicit,export,friend,inline,late_check," +
+      "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast," +
+      "template,typeid,typename,using,virtual,where"];
+  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
+      "abstract,boolean,extends,final,finally,implements,import," +
+      "instanceof,null,native,package,strictfp,super,synchronized,throws," +
+      "transient"];
+  var CSHARP_KEYWORDS = [JAVA_KEYWORDS,
+      "as,base,by,checked,decimal,delegate,descending,dynamic,event," +
+      "fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock," +
+      "object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed," +
+      "stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];
+  var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
+      "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
+      "true,try,unless,until,when,while,yes";
+  var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
+      "debugger,eval,export,function,get,null,set,undefined,var,with," +
+      "Infinity,NaN"];
+  var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
+      "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
+      "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
+  var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
+      "elif,except,exec,finally,from,global,import,in,is,lambda," +
+      "nonlocal,not,or,pass,print,raise,try,with,yield," +
+      "False,True,None"];
+  var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
+      "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
+      "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
+      "BEGIN,END"];
+  var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
+      "function,in,local,set,then,until"];
+  var ALL_KEYWORDS = [
+      CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS +
+      PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
+  var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;
+
+  // token style names.  correspond to css classes
+  /**
+   * token style for a string literal
+   * @const
+   */
+  var PR_STRING = 'str';
+  /**
+   * token style for a keyword
+   * @const
+   */
+  var PR_KEYWORD = 'kwd';
+  /**
+   * token style for a comment
+   * @const
+   */
+  var PR_COMMENT = 'com';
+  /**
+   * token style for a type
+   * @const
+   */
+  var PR_TYPE = 'typ';
+  /**
+   * token style for a literal value.  e.g. 1, null, true.
+   * @const
+   */
+  var PR_LITERAL = 'lit';
+  /**
+   * token style for a punctuation string.
+   * @const
+   */
+  var PR_PUNCTUATION = 'pun';
+  /**
+   * token style for a punctuation string.
+   * @const
+   */
+  var PR_PLAIN = 'pln';
+
+  /**
+   * token style for an sgml tag.
+   * @const
+   */
+  var PR_TAG = 'tag';
+  /**
+   * token style for a markup declaration such as a DOCTYPE.
+   * @const
+   */
+  var PR_DECLARATION = 'dec';
+  /**
+   * token style for embedded source.
+   * @const
+   */
+  var PR_SOURCE = 'src';
+  /**
+   * token style for an sgml attribute name.
+   * @const
+   */
+  var PR_ATTRIB_NAME = 'atn';
+  /**
+   * token style for an sgml attribute value.
+   * @const
+   */
+  var PR_ATTRIB_VALUE = 'atv';
+
+  /**
+   * A class that indicates a section of markup that is not code, e.g. to allow
+   * embedding of line numbers within code listings.
+   * @const
+   */
+  var PR_NOCODE = 'nocode';
+
+
+
+/**
+ * A set of tokens that can precede a regular expression literal in
+ * javascript
+ * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
+ * has the full list, but I've removed ones that might be problematic when
+ * seen in languages that don't support regular expression literals.
+ *
+ * <p>Specifically, I've removed any keywords that can't precede a regexp
+ * literal in a syntactically legal javascript program, and I've removed the
+ * "in" keyword since it's not a keyword in many languages, and might be used
+ * as a count of inches.
+ *
+ * <p>The link a above does not accurately describe EcmaScript rules since
+ * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
+ * very well in practice.
+ *
+ * @private
+ * @const
+ */
+var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
+
+// CAVEAT: this does not properly handle the case where a regular
+// expression immediately follows another since a regular expression may
+// have flags for case-sensitivity and the like.  Having regexp tokens
+// adjacent is not valid in any language I'm aware of, so I'm punting.
+// TODO: maybe style special characters inside a regexp as punctuation.
+
+
+  /**
+   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
+   * matches the union of the sets of strings matched by the input RegExp.
+   * Since it matches globally, if the input strings have a start-of-input
+   * anchor (/^.../), it is ignored for the purposes of unioning.
+   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
+   * @return {RegExp} a global regex.
+   */
+  function combinePrefixPatterns(regexs) {
+    var capturedGroupIndex = 0;
+  
+    var needToFoldCase = false;
+    var ignoreCase = false;
+    for (var i = 0, n = regexs.length; i < n; ++i) {
+      var regex = regexs[i];
+      if (regex.ignoreCase) {
+        ignoreCase = true;
+      } else if (/[a-z]/i.test(regex.source.replace(
+                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
+        needToFoldCase = true;
+        ignoreCase = false;
+        break;
+      }
+    }
+  
+    var escapeCharToCodeUnit = {
+      'b': 8,
+      't': 9,
+      'n': 0xa,
+      'v': 0xb,
+      'f': 0xc,
+      'r': 0xd
+    };
+  
+    function decodeEscape(charsetPart) {
+      var cc0 = charsetPart.charCodeAt(0);
+      if (cc0 !== 92 /* \\ */) {
+        return cc0;
+      }
+      var c1 = charsetPart.charAt(1);
+      cc0 = escapeCharToCodeUnit[c1];
+      if (cc0) {
+        return cc0;
+      } else if ('0' <= c1 && c1 <= '7') {
+        return parseInt(charsetPart.substring(1), 8);
+      } else if (c1 === 'u' || c1 === 'x') {
+        return parseInt(charsetPart.substring(2), 16);
+      } else {
+        return charsetPart.charCodeAt(1);
+      }
+    }
+  
+    function encodeEscape(charCode) {
+      if (charCode < 0x20) {
+        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
+      }
+      var ch = String.fromCharCode(charCode);
+      if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
+        ch = '\\' + ch;
+      }
+      return ch;
+    }
+  
+    function caseFoldCharset(charSet) {
+      var charsetParts = charSet.substring(1, charSet.length - 1).match(
+          new RegExp(
+              '\\\\u[0-9A-Fa-f]{4}'
+              + '|\\\\x[0-9A-Fa-f]{2}'
+              + '|\\\\[0-3][0-7]{0,2}'
+              + '|\\\\[0-7]{1,2}'
+              + '|\\\\[\\s\\S]'
+              + '|-'
+              + '|[^-\\\\]',
+              'g'));
+      var groups = [];
+      var ranges = [];
+      var inverse = charsetParts[0] === '^';
+      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
+        var p = charsetParts[i];
+        if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
+          groups.push(p);
+        } else {
+          var start = decodeEscape(p);
+          var end;
+          if (i + 2 < n && '-' === charsetParts[i + 1]) {
+            end = decodeEscape(charsetParts[i + 2]);
+            i += 2;
+          } else {
+            end = start;
+          }
+          ranges.push([start, end]);
+          // If the range might intersect letters, then expand it.
+          // This case handling is too simplistic.
+          // It does not deal with non-latin case folding.
+          // It works for latin source code identifiers though.
+          if (!(end < 65 || start > 122)) {
+            if (!(end < 65 || start > 90)) {
+              ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
+            }
+            if (!(end < 97 || start > 122)) {
+              ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
+            }
+          }
+        }
+      }
+  
+      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
+      // -> [[1, 12], [14, 14], [16, 17]]
+      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
+      var consolidatedRanges = [];
+      var lastRange = [NaN, NaN];
+      for (var i = 0; i < ranges.length; ++i) {
+        var range = ranges[i];
+        if (range[0] <= lastRange[1] + 1) {
+          lastRange[1] = Math.max(lastRange[1], range[1]);
+        } else {
+          consolidatedRanges.push(lastRange = range);
+        }
+      }
+  
+      var out = ['['];
+      if (inverse) { out.push('^'); }
+      out.push.apply(out, groups);
+      for (var i = 0; i < consolidatedRanges.length; ++i) {
+        var range = consolidatedRanges[i];
+        out.push(encodeEscape(range[0]));
+        if (range[1] > range[0]) {
+          if (range[1] + 1 > range[0]) { out.push('-'); }
+          out.push(encodeEscape(range[1]));
+        }
+      }
+      out.push(']');
+      return out.join('');
+    }
+  
+    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
+      // Split into character sets, escape sequences, punctuation strings
+      // like ('(', '(?:', ')', '^'), and runs of characters that do not
+      // include any of the above.
+      var parts = regex.source.match(
+          new RegExp(
+              '(?:'
+              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
+              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
+              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
+              + '|\\\\[0-9]+'  // a back-reference or octal escape
+              + '|\\\\[^ux0-9]'  // other escape sequence
+              + '|\\(\\?[:!=]'  // start of a non-capturing group
+              + '|[\\(\\)\\^]'  // start/emd of a group, or line start
+              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
+              + ')',
+              'g'));
+      var n = parts.length;
+  
+      // Maps captured group numbers to the number they will occupy in
+      // the output or to -1 if that has not been determined, or to
+      // undefined if they need not be capturing in the output.
+      var capturedGroups = [];
+  
+      // Walk over and identify back references to build the capturedGroups
+      // mapping.
+      for (var i = 0, groupIndex = 0; i < n; ++i) {
+        var p = parts[i];
+        if (p === '(') {
+          // groups are 1-indexed, so max group index is count of '('
+          ++groupIndex;
+        } else if ('\\' === p.charAt(0)) {
+          var decimalValue = +p.substring(1);
+          if (decimalValue && decimalValue <= groupIndex) {
+            capturedGroups[decimalValue] = -1;
+          }
+        }
+      }
+  
+      // Renumber groups and reduce capturing groups to non-capturing groups
+      // where possible.
+      for (var i = 1; i < capturedGroups.length; ++i) {
+        if (-1 === capturedGroups[i]) {
+          capturedGroups[i] = ++capturedGroupIndex;
+        }
+      }
+      for (var i = 0, groupIndex = 0; i < n; ++i) {
+        var p = parts[i];
+        if (p === '(') {
+          ++groupIndex;
+          if (capturedGroups[groupIndex] === undefined) {
+            parts[i] = '(?:';
+          }
+        } else if ('\\' === p.charAt(0)) {
+          var decimalValue = +p.substring(1);
+          if (decimalValue && decimalValue <= groupIndex) {
+            parts[i] = '\\' + capturedGroups[groupIndex];
+          }
+        }
+      }
+  
+      // Remove any prefix anchors so that the output will match anywhere.
+      // ^^ really does mean an anchored match though.
+      for (var i = 0, groupIndex = 0; i < n; ++i) {
+        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
+      }
+  
+      // Expand letters to groups to handle mixing of case-sensitive and
+      // case-insensitive patterns if necessary.
+      if (regex.ignoreCase && needToFoldCase) {
+        for (var i = 0; i < n; ++i) {
+          var p = parts[i];
+          var ch0 = p.charAt(0);
+          if (p.length >= 2 && ch0 === '[') {
+            parts[i] = caseFoldCharset(p);
+          } else if (ch0 !== '\\') {
+            // TODO: handle letters in numeric escapes.
+            parts[i] = p.replace(
+                /[a-zA-Z]/g,
+                function (ch) {
+                  var cc = ch.charCodeAt(0);
+                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
+                });
+          }
+        }
+      }
+  
+      return parts.join('');
+    }
+  
+    var rewritten = [];
+    for (var i = 0, n = regexs.length; i < n; ++i) {
+      var regex = regexs[i];
+      if (regex.global || regex.multiline) { throw new Error('' + regex); }
+      rewritten.push(
+          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
+    }
+  
+    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
+  }
+
+
+  /**
+   * Split markup into a string of source code and an array mapping ranges in
+   * that string to the text nodes in which they appear.
+   *
+   * <p>
+   * The HTML DOM structure:</p>
+   * <pre>
+   * (Element   "p"
+   *   (Element "b"
+   *     (Text  "print "))       ; #1
+   *   (Text    "'Hello '")      ; #2
+   *   (Element "br")            ; #3
+   *   (Text    "  + 'World';")) ; #4
+   * </pre>
+   * <p>
+   * corresponds to the HTML
+   * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
+   *
+   * <p>
+   * It will produce the output:</p>
+   * <pre>
+   * {
+   *   sourceCode: "print 'Hello '\n  + 'World';",
+   *   //                 1         2
+   *   //       012345678901234 5678901234567
+   *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
+   * }
+   * </pre>
+   * <p>
+   * where #1 is a reference to the {@code "print "} text node above, and so
+   * on for the other text nodes.
+   * </p>
+   *
+   * <p>
+   * The {@code} spans array is an array of pairs.  Even elements are the start
+   * indices of substrings, and odd elements are the text nodes (or BR elements)
+   * that contain the text for those substrings.
+   * Substrings continue until the next index or the end of the source.
+   * </p>
+   *
+   * @param {Node} node an HTML DOM subtree containing source-code.
+   * @return {Object} source code and the text nodes in which they occur.
+   */
+  function extractSourceSpans(node) {
+    var nocode = /(?:^|\s)nocode(?:\s|$)/;
+  
+    var chunks = [];
+    var length = 0;
+    var spans = [];
+    var k = 0;
+  
+    var whitespace;
+    if (node.currentStyle) {
+      whitespace = node.currentStyle.whiteSpace;
+    } else if (window.getComputedStyle) {
+      whitespace = document.defaultView.getComputedStyle(node, null)
+          .getPropertyValue('white-space');
+    }
+    var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);
+  
+    function walk(node) {
+      switch (node.nodeType) {
+        case 1:  // Element
+          if (nocode.test(node.className)) { return; }
+          for (var child = node.firstChild; child; child = child.nextSibling) {
+            walk(child);
+          }
+          var nodeName = node.nodeName;
+          if ('BR' === nodeName || 'LI' === nodeName) {
+            chunks[k] = '\n';
+            spans[k << 1] = length++;
+            spans[(k++ << 1) | 1] = node;
+          }
+          break;
+        case 3: case 4:  // Text
+          var text = node.nodeValue;
+          if (text.length) {
+            if (!isPreformatted) {
+              text = text.replace(/[ \t\r\n]+/g, ' ');
+            } else {
+              text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
+            }
+            // TODO: handle tabs here?
+            chunks[k] = text;
+            spans[k << 1] = length;
+            length += text.length;
+            spans[(k++ << 1) | 1] = node;
+          }
+          break;
+      }
+    }
+  
+    walk(node);
+  
+    return {
+      sourceCode: chunks.join('').replace(/\n$/, ''),
+      spans: spans
+    };
+  }
+
+
+  /**
+   * Apply the given language handler to sourceCode and add the resulting
+   * decorations to out.
+   * @param {number} basePos the index of sourceCode within the chunk of source
+   *    whose decorations are already present on out.
+   */
+  function appendDecorations(basePos, sourceCode, langHandler, out) {
+    if (!sourceCode) { return; }
+    var job = {
+      sourceCode: sourceCode,
+      basePos: basePos
+    };
+    langHandler(job);
+    out.push.apply(out, job.decorations);
+  }
+
+  var notWs = /\S/;
+
+  /**
+   * Given an element, if it contains only one child element and any text nodes
+   * it contains contain only space characters, return the sole child element.
+   * Otherwise returns undefined.
+   * <p>
+   * This is meant to return the CODE element in {@code <pre><code ...>} when
+   * there is a single child element that contains all the non-space textual
+   * content, but not to return anything where there are multiple child elements
+   * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
+   * is textual content.
+   */
+  function childContentWrapper(element) {
+    var wrapper = undefined;
+    for (var c = element.firstChild; c; c = c.nextSibling) {
+      var type = c.nodeType;
+      wrapper = (type === 1)  // Element Node
+          ? (wrapper ? element : c)
+          : (type === 3)  // Text Node
+          ? (notWs.test(c.nodeValue) ? element : wrapper)
+          : wrapper;
+    }
+    return wrapper === element ? undefined : wrapper;
+  }
+
+  /** Given triples of [style, pattern, context] returns a lexing function,
+    * The lexing function interprets the patterns to find token boundaries and
+    * returns a decoration list of the form
+    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
+    * where index_n is an index into the sourceCode, and style_n is a style
+    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
+    * all characters in sourceCode[index_n-1:index_n].
+    *
+    * The stylePatterns is a list whose elements have the form
+    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
+    *
+    * Style is a style constant like PR_PLAIN, or can be a string of the
+    * form 'lang-FOO', where FOO is a language extension describing the
+    * language of the portion of the token in $1 after pattern executes.
+    * E.g., if style is 'lang-lisp', and group 1 contains the text
+    * '(hello (world))', then that portion of the token will be passed to the
+    * registered lisp handler for formatting.
+    * The text before and after group 1 will be restyled using this decorator
+    * so decorators should take care that this doesn't result in infinite
+    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
+    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
+    * '<script>foo()<\/script>', which would cause the current decorator to
+    * be called with '<script>' which would not match the same rule since
+    * group 1 must not be empty, so it would be instead styled as PR_TAG by
+    * the generic tag rule.  The handler registered for the 'js' extension would
+    * then be called with 'foo()', and finally, the current decorator would
+    * be called with '<\/script>' which would not match the original rule and
+    * so the generic tag rule would identify it as a tag.
+    *
+    * Pattern must only match prefixes, and if it matches a prefix, then that
+    * match is considered a token with the same style.
+    *
+    * Context is applied to the last non-whitespace, non-comment token
+    * recognized.
+    *
+    * Shortcut is an optional string of characters, any of which, if the first
+    * character, gurantee that this pattern and only this pattern matches.
+    *
+    * @param {Array} shortcutStylePatterns patterns that always start with
+    *   a known character.  Must have a shortcut string.
+    * @param {Array} fallthroughStylePatterns patterns that will be tried in
+    *   order if the shortcut ones fail.  May have shortcuts.
+    *
+    * @return {function (Object)} a
+    *   function that takes source code and returns a list of decorations.
+    */
+  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
+    var shortcuts = {};
+    var tokenizer;
+    (function () {
+      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
+      var allRegexs = [];
+      var regexKeys = {};
+      for (var i = 0, n = allPatterns.length; i < n; ++i) {
+        var patternParts = allPatterns[i];
+        var shortcutChars = patternParts[3];
+        if (shortcutChars) {
+          for (var c = shortcutChars.length; --c >= 0;) {
+            shortcuts[shortcutChars.charAt(c)] = patternParts;
+          }
+        }
+        var regex = patternParts[1];
+        var k = '' + regex;
+        if (!regexKeys.hasOwnProperty(k)) {
+          allRegexs.push(regex);
+          regexKeys[k] = null;
+        }
+      }
+      allRegexs.push(/[\0-\uffff]/);
+      tokenizer = combinePrefixPatterns(allRegexs);
+    })();
+
+    var nPatterns = fallthroughStylePatterns.length;
+
+    /**
+     * Lexes job.sourceCode and produces an output array job.decorations of
+     * style classes preceded by the position at which they start in
+     * job.sourceCode in order.
+     *
+     * @param {Object} job an object like <pre>{
+     *    sourceCode: {string} sourceText plain text,
+     *    basePos: {int} position of job.sourceCode in the larger chunk of
+     *        sourceCode.
+     * }</pre>
+     */
+    var decorate = function (job) {
+      var sourceCode = job.sourceCode, basePos = job.basePos;
+      /** Even entries are positions in source in ascending order.  Odd enties
+        * are style markers (e.g., PR_COMMENT) that run from that position until
+        * the end.
+        * @type {Array.<number|string>}
+        */
+      var decorations = [basePos, PR_PLAIN];
+      var pos = 0;  // index into sourceCode
+      var tokens = sourceCode.match(tokenizer) || [];
+      var styleCache = {};
+
+      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
+        var token = tokens[ti];
+        var style = styleCache[token];
+        var match = void 0;
+
+        var isEmbedded;
+        if (typeof style === 'string') {
+          isEmbedded = false;
+        } else {
+          var patternParts = shortcuts[token.charAt(0)];
+          if (patternParts) {
+            match = token.match(patternParts[1]);
+            style = patternParts[0];
+          } else {
+            for (var i = 0; i < nPatterns; ++i) {
+              patternParts = fallthroughStylePatterns[i];
+              match = token.match(patternParts[1]);
+              if (match) {
+                style = patternParts[0];
+                break;
+              }
+            }
+
+            if (!match) {  // make sure that we make progress
+              style = PR_PLAIN;
+            }
+          }
+
+          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
+          if (isEmbedded && !(match && typeof match[1] === 'string')) {
+            isEmbedded = false;
+            style = PR_SOURCE;
+          }
+
+          if (!isEmbedded) { styleCache[token] = style; }
+        }
+
+        var tokenStart = pos;
+        pos += token.length;
+
+        if (!isEmbedded) {
+          decorations.push(basePos + tokenStart, style);
+        } else {  // Treat group 1 as an embedded block of source code.
+          var embeddedSource = match[1];
+          var embeddedSourceStart = token.indexOf(embeddedSource);
+          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
+          if (match[2]) {
+            // If embeddedSource can be blank, then it would match at the
+            // beginning which would cause us to infinitely recurse on the
+            // entire token, so we catch the right context in match[2].
+            embeddedSourceEnd = token.length - match[2].length;
+            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
+          }
+          var lang = style.substring(5);
+          // Decorate the left of the embedded source
+          appendDecorations(
+              basePos + tokenStart,
+              token.substring(0, embeddedSourceStart),
+              decorate, decorations);
+          // Decorate the embedded source
+          appendDecorations(
+              basePos + tokenStart + embeddedSourceStart,
+              embeddedSource,
+              langHandlerForExtension(lang, embeddedSource),
+              decorations);
+          // Decorate the right of the embedded section
+          appendDecorations(
+              basePos + tokenStart + embeddedSourceEnd,
+              token.substring(embeddedSourceEnd),
+              decorate, decorations);
+        }
+      }
+      job.decorations = decorations;
+    };
+    return decorate;
+  }
+
+  /** returns a function that produces a list of decorations from source text.
+    *
+    * This code treats ", ', and ` as string delimiters, and \ as a string
+    * escape.  It does not recognize perl's qq() style strings.
+    * It has no special handling for double delimiter escapes as in basic, or
+    * the tripled delimiters used in python, but should work on those regardless
+    * although in those cases a single string literal may be broken up into
+    * multiple adjacent string literals.
+    *
+    * It recognizes C, C++, and shell style comments.
+    *
+    * @param {Object} options a set of optional parameters.
+    * @return {function (Object)} a function that examines the source code
+    *     in the input job and builds the decoration list.
+    */
+  function sourceDecorator(options) {
+    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
+    if (options['tripleQuotedStrings']) {
+      // '''multi-line-string''', 'single-line-string', and double-quoted
+      shortcutStylePatterns.push(
+          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
+           null, '\'"']);
+    } else if (options['multiLineStrings']) {
+      // 'multi-line-string', "multi-line-string"
+      shortcutStylePatterns.push(
+          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
+           null, '\'"`']);
+    } else {
+      // 'single-line-string', "single-line-string"
+      shortcutStylePatterns.push(
+          [PR_STRING,
+           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
+           null, '"\'']);
+    }
+    if (options['verbatimStrings']) {
+      // verbatim-string-literal production from the C# grammar.  See issue 93.
+      fallthroughStylePatterns.push(
+          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
+    }
+    var hc = options['hashComments'];
+    if (hc) {
+      if (options['cStyleComments']) {
+        if (hc > 1) {  // multiline hash comments
+          shortcutStylePatterns.push(
+              [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
+              
+        } else {
+          // Stop C preprocessor declarations at an unclosed open comment
+//          shortcutStylePatterns.push(
+//              [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
+//               null, '#']);
+        }
+        fallthroughStylePatterns.push(
+            [PR_STRING,
+             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
+             null]);
+      } else {
+        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
+      }
+    }
+    if (options['cStyleComments']) {
+      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
+      fallthroughStylePatterns.push(
+          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
+    }
+    if (options['regexLiterals']) {
+      /**
+       * @const
+       */
+      var REGEX_LITERAL = (
+          // A regular expression literal starts with a slash that is
+          // not followed by * or / so that it is not confused with
+          // comments.
+          '/(?=[^/*])'
+          // and then contains any number of raw characters,
+          + '(?:[^/\\x5B\\x5C]'
+          // escape sequences (\x5C),
+          +    '|\\x5C[\\s\\S]'
+          // or non-nesting character sets (\x5B\x5D);
+          +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
+          // finally closed by a /.
+          + '/');
+      fallthroughStylePatterns.push(
+          ['lang-regex',
+           new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
+           ]);
+    }
+
+    var types = options['types'];
+    if (types) {
+      fallthroughStylePatterns.push([PR_TYPE, types]);
+    }
+
+    var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
+    if (keywords.length) {
+      fallthroughStylePatterns.push(
+          [PR_KEYWORD,
+           new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
+           null]);
+    }
+
+    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
+    fallthroughStylePatterns.push(
+        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
+        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
+        [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
+        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
+        [PR_LITERAL,
+         new RegExp(
+             '^(?:'
+             // A hex number
+             + '0x[a-f0-9]+'
+             // or an octal or decimal number,
+             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
+             // possibly in scientific notation
+             + '(?:e[+\\-]?\\d+)?'
+             + ')'
+             // with an optional modifier like UL for unsigned long
+             + '[a-z]*', 'i'),
+         null, '0123456789'],
+        // Don't treat escaped quotes in bash as starting strings.  See issue 144.
+        [PR_PLAIN,       /^\\[\s\S]?/, null],
+        [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#\\]*/, null]);
+
+    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
+  }
+
+  var decorateSource = sourceDecorator({
+        'keywords': ALL_KEYWORDS,
+        'hashComments': true,
+        'cStyleComments': true,
+        'multiLineStrings': true,
+        'regexLiterals': true
+      });
+
+  /**
+   * Given a DOM subtree, wraps it in a list, and puts each line into its own
+   * list item.
+   *
+   * @param {Node} node modified in place.  Its content is pulled into an
+   *     HTMLOListElement, and each line is moved into a separate list item.
+   *     This requires cloning elements, so the input might not have unique
+   *     IDs after numbering.
+   */
+  function numberLines(node, opt_startLineNum) {
+    var nocode = /(?:^|\s)nocode(?:\s|$)/;
+    var lineBreak = /\r\n?|\n/;
+  
+    var document = node.ownerDocument;
+  
+    var whitespace;
+    if (node.currentStyle) {
+      whitespace = node.currentStyle.whiteSpace;
+    } else if (window.getComputedStyle) {
+      whitespace = document.defaultView.getComputedStyle(node, null)
+          .getPropertyValue('white-space');
+    }
+    // If it's preformatted, then we need to split lines on line breaks
+    // in addition to <BR>s.
+    var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);
+  
+    var li = document.createElement('LI');
+    while (node.firstChild) {
+      li.appendChild(node.firstChild);
+    }
+    // An array of lines.  We split below, so this is initialized to one
+    // un-split line.
+    var listItems = [li];
+  
+    function walk(node) {
+      switch (node.nodeType) {
+        case 1:  // Element
+          if (nocode.test(node.className)) { break; }
+          if ('BR' === node.nodeName) {
+            breakAfter(node);
+            // Discard the <BR> since it is now flush against a </LI>.
+            if (node.parentNode) {
+              node.parentNode.removeChild(node);
+            }
+          } else {
+            for (var child = node.firstChild; child; child = child.nextSibling) {
+              walk(child);
+            }
+          }
+          break;
+        case 3: case 4:  // Text
+          if (isPreformatted) {
+            var text = node.nodeValue;
+            var match = text.match(lineBreak);
+            if (match) {
+              var firstLine = text.substring(0, match.index);
+              node.nodeValue = firstLine;
+              var tail = text.substring(match.index + match[0].length);
+              if (tail) {
+                var parent = node.parentNode;
+                parent.insertBefore(
+                    document.createTextNode(tail), node.nextSibling);
+              }
+              breakAfter(node);
+              if (!firstLine) {
+                // Don't leave blank text nodes in the DOM.
+                node.parentNode.removeChild(node);
+              }
+            }
+          }
+          break;
+      }
+    }
+  
+    // Split a line after the given node.
+    function breakAfter(lineEndNode) {
+      // If there's nothing to the right, then we can skip ending the line
+      // here, and move root-wards since splitting just before an end-tag
+      // would require us to create a bunch of empty copies.
+      while (!lineEndNode.nextSibling) {
+        lineEndNode = lineEndNode.parentNode;
+        if (!lineEndNode) { return; }
+      }
+  
+      function breakLeftOf(limit, copy) {
+        // Clone shallowly if this node needs to be on both sides of the break.
+        var rightSide = copy ? limit.cloneNode(false) : limit;
+        var parent = limit.parentNode;
+        if (parent) {
+          // We clone the parent chain.
+          // This helps us resurrect important styling elements that cross lines.
+          // E.g. in <i>Foo<br>Bar</i>
+          // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
+          var parentClone = breakLeftOf(parent, 1);
+          // Move the clone and everything to the right of the original
+          // onto the cloned parent.
+          var next = limit.nextSibling;
+          parentClone.appendChild(rightSide);
+          for (var sibling = next; sibling; sibling = next) {
+            next = sibling.nextSibling;
+            parentClone.appendChild(sibling);
+          }
+        }
+        return rightSide;
+      }
+  
+      var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
+  
+      // Walk the parent chain until we reach an unattached LI.
+      for (var parent;
+           // Check nodeType since IE invents document fragments.
+           (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
+        copiedListItem = parent;
+      }
+      // Put it on the list of lines for later processing.
+      listItems.push(copiedListItem);
+    }
+  
+    // Split lines while there are lines left to split.
+    for (var i = 0;  // Number of lines that have been split so far.
+         i < listItems.length;  // length updated by breakAfter calls.
+         ++i) {
+      walk(listItems[i]);
+    }
+  
+    // Make sure numeric indices show correctly.
+    if (opt_startLineNum === (opt_startLineNum|0)) {
+      listItems[0].setAttribute('value', opt_startLineNum);
+    }
+  
+    var ol = document.createElement('OL');
+    ol.className = 'linenums';
+    var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
+    for (var i = 0, n = listItems.length; i < n; ++i) {
+      li = listItems[i];
+      // Stick a class on the LIs so that stylesheets can
+      // color odd/even rows, or any other row pattern that
+      // is co-prime with 10.
+      li.className = 'L' + ((i + offset) % 10);
+      if (!li.firstChild) {
+        li.appendChild(document.createTextNode('\xA0'));
+      }
+      ol.appendChild(li);
+    }
+  
+    node.appendChild(ol);
+  }
+
+  /**
+   * Breaks {@code job.sourceCode} around style boundaries in
+   * {@code job.decorations} and modifies {@code job.sourceNode} in place.
+   * @param {Object} job like <pre>{
+   *    sourceCode: {string} source as plain text,
+   *    spans: {Array.<number|Node>} alternating span start indices into source
+   *       and the text node or element (e.g. {@code <BR>}) corresponding to that
+   *       span.
+   *    decorations: {Array.<number|string} an array of style classes preceded
+   *       by the position at which they start in job.sourceCode in order
+   * }</pre>
+   * @private
+   */
+  function recombineTagsAndDecorations(job) {
+    var isIE = /\bMSIE\b/.test(navigator.userAgent);
+    var newlineRe = /\n/g;
+  
+    var source = job.sourceCode;
+    var sourceLength = source.length;
+    // Index into source after the last code-unit recombined.
+    var sourceIndex = 0;
+  
+    var spans = job.spans;
+    var nSpans = spans.length;
+    // Index into spans after the last span which ends at or before sourceIndex.
+    var spanIndex = 0;
+  
+    var decorations = job.decorations;
+    var nDecorations = decorations.length;
+    // Index into decorations after the last decoration which ends at or before
+    // sourceIndex.
+    var decorationIndex = 0;
+  
+    // Remove all zero-length decorations.
+    decorations[nDecorations] = sourceLength;
+    var decPos, i;
+    for (i = decPos = 0; i < nDecorations;) {
+      if (decorations[i] !== decorations[i + 2]) {
+        decorations[decPos++] = decorations[i++];
+        decorations[decPos++] = decorations[i++];
+      } else {
+        i += 2;
+      }
+    }
+    nDecorations = decPos;
+  
+    // Simplify decorations.
+    for (i = decPos = 0; i < nDecorations;) {
+      var startPos = decorations[i];
+      // Conflate all adjacent decorations that use the same style.
+      var startDec = decorations[i + 1];
+      var end = i + 2;
+      while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
+        end += 2;
+      }
+      decorations[decPos++] = startPos;
+      decorations[decPos++] = startDec;
+      i = end;
+    }
+  
+    nDecorations = decorations.length = decPos;
+  
+    var decoration = null;
+    while (spanIndex < nSpans) {
+      var spanStart = spans[spanIndex];
+      var spanEnd = spans[spanIndex + 2] || sourceLength;
+  
+      var decStart = decorations[decorationIndex];
+      var decEnd = decorations[decorationIndex + 2] || sourceLength;
+  
+      var end = Math.min(spanEnd, decEnd);
+  
+      var textNode = spans[spanIndex + 1];
+      var styledText;
+      if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
+          // Don't introduce spans around empty text nodes.
+          && (styledText = source.substring(sourceIndex, end))) {
+        // This may seem bizarre, and it is.  Emitting LF on IE causes the
+        // code to display with spaces instead of line breaks.
+        // Emitting Windows standard issue linebreaks (CRLF) causes a blank
+        // space to appear at the beginning of every line but the first.
+        // Emitting an old Mac OS 9 line separator makes everything spiffy.
+        if (isIE) { styledText = styledText.replace(newlineRe, '\r'); }
+        textNode.nodeValue = styledText;
+        var document = textNode.ownerDocument;
+        var span = document.createElement('SPAN');
+        span.className = decorations[decorationIndex + 1];
+        var parentNode = textNode.parentNode;
+        parentNode.replaceChild(span, textNode);
+        span.appendChild(textNode);
+        if (sourceIndex < spanEnd) {  // Split off a text node.
+          spans[spanIndex + 1] = textNode
+              // TODO: Possibly optimize by using '' if there's no flicker.
+              = document.createTextNode(source.substring(end, spanEnd));
+          parentNode.insertBefore(textNode, span.nextSibling);
+        }
+      }
+  
+      sourceIndex = end;
+  
+      if (sourceIndex >= spanEnd) {
+        spanIndex += 2;
+      }
+      if (sourceIndex >= decEnd) {
+        decorationIndex += 2;
+      }
+    }
+  }
+
+
+  /** Maps language-specific file extensions to handlers. */
+  var langHandlerRegistry = {};
+  /** Register a language handler for the given file extensions.
+    * @param {function (Object)} handler a function from source code to a list
+    *      of decorations.  Takes a single argument job which describes the
+    *      state of the computation.   The single parameter has the form
+    *      {@code {
+    *        sourceCode: {string} as plain text.
+    *        decorations: {Array.<number|string>} an array of style classes
+    *                     preceded by the position at which they start in
+    *                     job.sourceCode in order.
+    *                     The language handler should assigned this field.
+    *        basePos: {int} the position of source in the larger source chunk.
+    *                 All positions in the output decorations array are relative
+    *                 to the larger source chunk.
+    *      } }
+    * @param {Array.<string>} fileExtensions
+    */
+  function registerLangHandler(handler, fileExtensions) {
+    for (var i = fileExtensions.length; --i >= 0;) {
+      var ext = fileExtensions[i];
+      if (!langHandlerRegistry.hasOwnProperty(ext)) {
+        langHandlerRegistry[ext] = handler;
+      } else if (window['console']) {
+        console['warn']('cannot override language handler %s', ext);
+      }
+    }
+  }
+  function langHandlerForExtension(extension, source) {
+    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
+      // Treat it as markup if the first non whitespace character is a < and
+      // the last non-whitespace character is a >.
+      extension = /^\s*</.test(source)
+          ? 'default-markup'
+          : 'default-code';
+    }
+    return langHandlerRegistry[extension];
+  }
+  registerLangHandler(decorateSource, ['default-code']);
+  registerLangHandler(
+      createSimpleLexer(
+          [],
+          [
+           [PR_PLAIN,       /^[^<?]+/],
+           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
+           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
+           // Unescaped content in an unknown language
+           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
+           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
+           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
+           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
+           // Unescaped content in javascript.  (Or possibly vbscript).
+           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
+           // Contains unescaped stylesheet content
+           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
+           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
+          ]),
+      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
+  registerLangHandler(
+      createSimpleLexer(
+          [
+           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
+           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
+           ],
+          [
+           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
+           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
+           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
+           [PR_PUNCTUATION,  /^[=<>\/]+/],
+           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
+           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
+           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
+           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
+           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
+           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
+           ]),
+      ['in.tag']);
+  registerLangHandler(
+      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
+  registerLangHandler(sourceDecorator({
+          'keywords': CPP_KEYWORDS,
+          'hashComments': true,
+          'cStyleComments': true,
+          'types': C_TYPES
+        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
+  registerLangHandler(sourceDecorator({
+          'keywords': 'null,true,false'
+        }), ['json']);
+  registerLangHandler(sourceDecorator({
+          'keywords': CSHARP_KEYWORDS,
+          'hashComments': true,
+          'cStyleComments': true,
+          'verbatimStrings': true,
+          'types': C_TYPES
+        }), ['cs']);
+  registerLangHandler(sourceDecorator({
+          'keywords': JAVA_KEYWORDS,
+          'cStyleComments': true
+        }), ['java']);
+  registerLangHandler(sourceDecorator({
+          'keywords': SH_KEYWORDS,
+          'hashComments': true,
+          'multiLineStrings': true
+        }), ['bsh', 'csh', 'sh']);
+  registerLangHandler(sourceDecorator({
+          'keywords': PYTHON_KEYWORDS,
+          'hashComments': true,
+          'multiLineStrings': true,
+          'tripleQuotedStrings': true
+        }), ['cv', 'py']);
+  registerLangHandler(sourceDecorator({
+          'keywords': PERL_KEYWORDS,
+          'hashComments': true,
+          'multiLineStrings': true,
+          'regexLiterals': true
+        }), ['perl', 'pl', 'pm']);
+  registerLangHandler(sourceDecorator({
+          'keywords': RUBY_KEYWORDS,
+          'hashComments': true,
+          'multiLineStrings': true,
+          'regexLiterals': true
+        }), ['rb']);
+  registerLangHandler(sourceDecorator({
+          'keywords': JSCRIPT_KEYWORDS,
+          'cStyleComments': true,
+          'regexLiterals': true
+        }), ['js']);
+  registerLangHandler(sourceDecorator({
+          'keywords': COFFEE_KEYWORDS,
+          'hashComments': 3,  // ### style block comments
+          'cStyleComments': true,
+          'multilineStrings': true,
+          'tripleQuotedStrings': true,
+          'regexLiterals': true
+        }), ['coffee']);
+  registerLangHandler(createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
+
+  function applyDecorator(job) {
+    var opt_langExtension = job.langExtension;
+
+    try {
+      // Extract tags, and convert the source code to plain text.
+      var sourceAndSpans = extractSourceSpans(job.sourceNode);
+      /** Plain text. @type {string} */
+      var source = sourceAndSpans.sourceCode;
+      job.sourceCode = source;
+      job.spans = sourceAndSpans.spans;
+      job.basePos = 0;
+
+      // Apply the appropriate language handler
+      langHandlerForExtension(opt_langExtension, source)(job);
+
+      // Integrate the decorations and tags back into the source code,
+      // modifying the sourceNode in place.
+      recombineTagsAndDecorations(job);
+    } catch (e) {
+      if ('console' in window) {
+        console['log'](e && e['stack'] ? e['stack'] : e);
+      }
+    }
+  }
+
+  /**
+   * @param sourceCodeHtml {string} The HTML to pretty print.
+   * @param opt_langExtension {string} The language name to use.
+   *     Typically, a filename extension like 'cpp' or 'java'.
+   * @param opt_numberLines {number|boolean} True to number lines,
+   *     or the 1-indexed number of the first line in sourceCodeHtml.
+   */
+  function prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
+    var container = document.createElement('PRE');
+    // This could cause images to load and onload listeners to fire.
+    // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
+    // We assume that the inner HTML is from a trusted source.
+    container.innerHTML = sourceCodeHtml;
+    if (opt_numberLines) {
+      numberLines(container, opt_numberLines);
+    }
+
+    var job = {
+      langExtension: opt_langExtension,
+      numberLines: opt_numberLines,
+      sourceNode: container
+    };
+    applyDecorator(job);
+    return container.innerHTML;
+  }
+
+  function prettyPrint(opt_whenDone) {
+    function byTagName(tn) { return document.getElementsByTagName(tn); }
+    // fetch a list of nodes to rewrite
+    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
+    var elements = [];
+    for (var i = 0; i < codeSegments.length; ++i) {
+      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
+        elements.push(codeSegments[i][j]);
+      }
+    }
+    codeSegments = null;
+
+    var clock = Date;
+    if (!clock['now']) {
+      clock = { 'now': function () { return +(new Date); } };
+    }
+
+    // The loop is broken into a series of continuations to make sure that we
+    // don't make the browser unresponsive when rewriting a large page.
+    var k = 0;
+    var prettyPrintingJob;
+
+    var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
+    var prettyPrintRe = /\bprettyprint\b/;
+
+    function doWork() {
+      var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?
+                     clock['now']() + 250 /* ms */ :
+                     Infinity);
+      for (; k < elements.length && clock['now']() < endTime; k++) {
+        var cs = elements[k];
+        var className = cs.className;
+        if (className.indexOf('prettyprint') >= 0) {
+          // If the classes includes a language extensions, use it.
+          // Language extensions can be specified like
+          //     <pre class="prettyprint lang-cpp">
+          // the language extension "cpp" is used to find a language handler as
+          // passed to PR.registerLangHandler.
+          // HTML5 recommends that a language be specified using "language-"
+          // as the prefix instead.  Google Code Prettify supports both.
+          // http://dev.w3.org/html5/spec-author-view/the-code-element.html
+          var langExtension = className.match(langExtensionRe);
+          // Support <pre class="prettyprint"><code class="language-c">
+          var wrapper;
+          if (!langExtension && (wrapper = childContentWrapper(cs))
+              && "CODE" === wrapper.tagName) {
+            langExtension = wrapper.className.match(langExtensionRe);
+          }
+
+          if (langExtension) {
+            langExtension = langExtension[1];
+          }
+
+          // make sure this is not nested in an already prettified element
+          var nested = false;
+          for (var p = cs.parentNode; p; p = p.parentNode) {
+            if ((p.tagName === 'pre' || p.tagName === 'code' ||
+                 p.tagName === 'xmp') &&
+                p.className && p.className.indexOf('prettyprint') >= 0) {
+              nested = true;
+              break;
+            }
+          }
+          if (!nested) {
+            // Look for a class like linenums or linenums:<n> where <n> is the
+            // 1-indexed number of the first line.
+            var lineNums = cs.className.match(/\blinenums\b(?::(\d+))?/);
+            lineNums = lineNums
+                  ? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
+                  : false;
+            if (lineNums) { numberLines(cs, lineNums); }
+
+            // do the pretty printing
+            prettyPrintingJob = {
+              langExtension: langExtension,
+              sourceNode: cs,
+              numberLines: lineNums
+            };
+            applyDecorator(prettyPrintingJob);
+          }
+        }
+      }
+      if (k < elements.length) {
+        // finish up in a continuation
+        setTimeout(doWork, 250);
+      } else if (opt_whenDone) {
+        opt_whenDone();
+      }
+    }
+
+    doWork();
+  }
+
+   /**
+    * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
+    * {@code class=prettyprint} and prettify them.
+    *
+    * @param {Function?} opt_whenDone if specified, called when the last entry
+    *     has been finished.
+    */
+  window['prettyPrintOne'] = prettyPrintOne;
+   /**
+    * Pretty print a chunk of code.
+    *
+    * @param {string} sourceCodeHtml code as html
+    * @return {string} code as html, but prettier
+    */
+  window['prettyPrint'] = prettyPrint;
+   /**
+    * Contains functions for creating and registering new language handlers.
+    * @type {Object}
+    */
+  window['PR'] = {
+        'createSimpleLexer': createSimpleLexer,
+        'registerLangHandler': registerLangHandler,
+        'sourceDecorator': sourceDecorator,
+        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
+        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
+        'PR_COMMENT': PR_COMMENT,
+        'PR_DECLARATION': PR_DECLARATION,
+        'PR_KEYWORD': PR_KEYWORD,
+        'PR_LITERAL': PR_LITERAL,
+        'PR_NOCODE': PR_NOCODE,
+        'PR_PLAIN': PR_PLAIN,
+        'PR_PUNCTUATION': PR_PUNCTUATION,
+        'PR_SOURCE': PR_SOURCE,
+        'PR_STRING': PR_STRING,
+        'PR_TAG': PR_TAG,
+        'PR_TYPE': PR_TYPE
+      };
+})();
diff --git a/nui/setup_ubuntu.htm b/nui/setup_ubuntu.htm
new file mode 100644 (file)
index 0000000..79b2cd7
--- /dev/null
@@ -0,0 +1,360 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>Setting Up the NUI Development Environment on Ubuntu</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#install">Installing .NET Core and Visual Studio Code</a></li>
+            <li><a href="#getsrc">Getting the NUI Source Code</a></li>
+            <li><a href="#buildenv">Setting Up the NUI Build Environment</a></li>
+            <li><a href="#buildsrc">Building the NUI Source Code</a></li>
+            <li><a href="#buildrun">Building and Running the Hello World Tutorial</a></li>
+            <li><a href="#firewall">Configuring Firewall Proxy Settings</a></li>
+            <li><a href="#buildclean">Cleaning the Build</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>Setting Up the NUI Development Environment on Ubuntu</h1>
+
+<p>This topic explains how to setup, build, and run NUI (DALi C#) applications using Visual Studio Code (VSC). It assumes that the starting point is a completely 'clean' system, though that is not essential.</p>
+<p>VSC can be installed on Ubuntu 14.04 and onwards.</p>
+<p>The <a href="hello_world.htm">NUI Hello World tutorial</a> is used as an example. It provides an introduction into NUI application development, describing how to display text in a text label.</p>
+
+<h2 id="install">Installing .NET Core and Visual Studio Code</h2>
+<p>To install .NET Core and Visual Studio Core (VSC):</p>
+<ol>
+       <li><a href="https://www.microsoft.com/net/core#linuxubuntu">Install .NET Core for Ubuntu</a>.</li>
+       <li>Install the latest version of Visual Studio Code for Ubuntu:
+       <ol type="a">
+               <li>Download the Debian package from <a href="https://code.visualstudio.com" target="_blank">https://code.visualstudio.com</a>.</li>
+               <li>Install the package:
+<pre class="prettyprint">
+$ sudo dpkg -i code_1.10.2xXXXXXXXXXX_amd64.deb
+</pre>
+               </li>
+       </ol>
+       </li>
+
+       <li id="launch_vsc">Launch VSC:
+       <ul>
+               <li>Launching VSC through the icon:
+               <ol type="a">
+                       <li>In the desktop launcher, select <strong>Search your Computer &gt; Applications</strong> for the Visual Studio Code icon.</li>
+                       <li>Select the <strong>Launch</strong> button to open VSC.</li>
+                       <li>Optionally, copy the VSC icon to the launcher, so you can start VSC by double-clicking the icon in the launcher.</li>
+               </ol>
+               </li>
+               <li>Launching VSC from the terminal:
+<pre class="prettyprint">
+$ code // Launch VSC
+$ code  // Launch VSC in current directory
+$ code myfile // Open file in VSC
+</pre>
+               </li>
+       </ul>
+       </li>
+       <li>Set the firewall proxy settings.
+       <p>VSC requires installation of required packages and libraries. It can be necessary to <a href="#firewall">configure the firewall proxy settings</a> to enable HTTP download.</p>
+       </li>
+       <li>Install C# extension in the VSC <strong>Extensions</strong> view:
+       <ol type="a">
+               <li>Bring up the <strong>Extensions</strong> view by clicking the <strong>Extensions</strong> icon in the Activity Bar, or by pressing <strong>Ctrl + Shift + X</strong>. This brings up all the extensions in the VS code marketplace.</li>
+               <li>Type "C#" to filter the selection.</li>
+               <li>Click <strong>Install</strong> next to the C# extension. After a successful install, click <strong>Reload</strong> to restart VSC.</li>
+       </ol>
+       <p>Alternatively, you can install the C# extension through the <a href="https://marketplace.visualstudio.com" target="_blank">Visual Studio Marketplace</a>.</p></li>
+       <li>Familiarize yourself with VSC by building the "Hello World" application. For more information, see <a href="https://docs.microsoft.com/en-us/dotnet/csharp/getting-started/with-visual-studio-code" target="_blank">Get Started with C# and Visual Studio Code</a>.</li>
+</ol>
+
+<h2 id="getsrc">Getting the NUI Source Code</h2>
+
+<p>To get the NUI source code from Git:</p>
+<ol>
+<li><p>Create a NUI root folder for the source code. The following example uses <code>~/DALiNUI</code>.</p>
+<pre class="prettyprint">
+$ mkdir ~/DALiNUI
+$ cd ~/DALiNUI
+</pre>
+       </li>
+<li>Get the source code from GitHub:
+<pre class="prettyprint">
+$ git clone git@github.com:dalihub/dali-core
+$ git clone git@github.com:dalihub/dali-adaptor
+$ git clone git@github.com:dalihub/dali-csharp-binder
+$ git clone git@github.com:dalihub/dali-toolkit
+$ git clone git@github.com:dalihub/nui
+</pre>
+</li>
+<li>Switch to the <code>devel/master</code> branch for each required repository, for example, for <code>dali-core</code>:
+
+<pre class="prettyprint">
+$ cd ~/DALiNUI/dali-core
+$ git checkout devel/master
+</pre></li>
+</ol>
+
+<h2 id="buildenv">Setting Up the NUI Build Environment</h2>
+
+<p>To set up the NUI build environment and save the settings to a file:</p>
+
+<pre class="prettyprint">
+$ cd ~/DALiNUI
+$ dali-core/build/scripts/dali_env -c
+$ dali-env/opt/bin/dali_env -s &gt; setenv
+$ . setenv
+</pre>
+
+<p>The above process only needs to be done once.</p>
+<p>You must source your environment variables every time you open up a new terminal (or you can add them to <code>.bashrc</code>). You can do this by sourcing the <code>setenv</code> script you created above: </p>
+
+<pre class="prettyprint">
+$ . setenv
+</pre>
+
+<h2 id="buildsrc">Building the NUI Source Code</h2>
+
+<p>To build the NUI source code:</p>
+
+<ol>
+       <li>Build the DALi native repositories in the following order, following instructions in the <code>README</code> file in each repository folder:
+               <ol>
+                       <li>Build <code>dali-core</code>.</li>
+                       <li>Build <code>dali-adaptor</code>.</li>
+                       <li>Build <code>dali-toolkit</code>.</li>
+               </ol>
+       <p>The shared library files (<code>.so</code>) are built and installed into the <code>~/DALiNUI/dali-env/opt/lib</code> folder.</p>
+       </li>
+       <li>Optionally, run and test DALi Native (C++):
+               <ol>
+               <li>Get the code. This step requires the <code>dali_demo</code> repository.</li>
+               <li>Build from the README file (see the Building the Repository section).</li>
+               <li>Run <code>dali-demo</code>.</li>
+               </ol>
+<pre class="prettyprint">
+$ git clone git@github.com:dalihub/dali-demo
+$ cd ~/DALiNUI/dali-demo
+$ git checkout devel/master
+
+// Build from README
+
+$ cd ~/DALiNUI/dali-env/opt/bin
+$ dali-demo
+</pre>
+               <p>If the test is successful, the DALi demo window appears.</p>
+
+       </li>
+
+       <li>Change to the NUI C# bindings folder:
+
+<pre class="prettyprint">
+$ cd dali-csharp-binder
+</pre>
+       </li>
+       <li>Build the NUI C# bindings:
+
+<pre class="prettyprint">
+    $ autoreconf --install
+    $ ./configure --prefix=$DESKTOP_PREFIX
+    $ make install -j8
+</pre>
+       </li>
+       <li>Copy the <code>nui</code> source folder to a new <code>nuirun</code> subfolder (for subsequent overwriting of files):
+
+<pre class="prettyprint">
+    $ cd ~/DALiNUI
+    $ mkdir nuirun
+    $ cp -r nui/Tizen.NUI/src nuirun
+</pre>
+       </li>
+       <li>Copy/overwrite 2 NUI files in <code>~/DALiNUI/nuirun/src/public</code>:
+               <ol>
+               <li>Download <a href="http://dalihub.github.io/NUIsetup/CoreApplication.cs">CoreApplication.cs</a>.</li>
+               <li>Download <a href="http://dalihub.github.io/NUIsetup/NUIApplication.cs">NUIApplication.cs</a>.</li>
+               <li>Place the files in your <code>nuirun/src/public</code> folder (overwrite the existing <code>NUIApplication.cs</code> file).</li>
+               </ol>
+       <p>Replacing the above 2 files is necessary, as NUI in Ubuntu is not fully supported just yet (as of July 2017).</p>
+       </li>
+       <li>To subsequently clean the build (if required), see <a href="#buildclean">Cleaning the Build</a>.</li>
+</ol>
+
+<h2 id="buildrun">Building and Running the Hello World Tutorial</h2>
+
+<p>To build and run the Hello World (NUI) tutorial:</p>
+
+<ol>
+       <li><p>Create the tutorial file:</p>
+               <ol type="a">
+                       <li>Copy the example code from the <a href="hello_world.htm">NUI Hello World tutorial</a> to a new file, <code>hello-world.cs</code>.</li>
+                       <li>Create a <code>tutorials</code> folder.</li>
+                       <li>Copy <code>hello-world.cs</code> to the <code>nuirun/tutorials</code> folder:
+<pre class="prettyprint">
+$ mkdir tutorials
+$ cp hello-world.cs ~/DALiNUI/nuirun/tutorials
+</pre>
+                       </li>
+               </ol>
+       </li>
+       <li>Create a Hello World project in VSC:
+       <ol>
+               <li><a href="#launch_vsc">Launch VSC</a>.</li>
+               <li>Select <strong>File &gt; Open Folder</strong> in the main menu.</li>
+               <li>Select the <code>nuirun</code> folder in the File dialog.</li>
+               <li>Open the command prompt by pressing <strong>Ctrl + `</strong> (backtick).</li>
+               <li>In the VSC integrated terminal, enter the following commands:
+<pre class="prettyprint">
+$ cd ~/DALiNUI
+$ . setenv
+$ cd ~/DALiNUI/nuirun
+$ dotnet new console
+</pre>
+               <p>The <code>setenv</code> is not necessary, if <a href="#buildenv">the environment has been set up</a> in your <code>.bashrc</code>.</p>
+               <p>The <code>dotnet new console</code> line creates a project, with a project file <code>nuirun.csproj</code> and a <code>Program.cs</code> file.</p>
+               </li>
+               <li>Delete <code>Program.cs</code> in VSC Explorer, as it is not needed.</li>
+               <li>Modify the project file by editing <code>nuirun.csproj</code>, adding the following line inside the <code>PropertyGroup</code> element:
+<pre class="prettyprint">
+&lt;DefineConstants&gt;DOT_NET_CORE&lt;/DefineConstants&gt;
+</pre>
+               </li>
+       </ol>
+       </li>
+       <li>Restore the dependencies and tools of the project:
+<pre class="prettyprint">
+$ dotnet restore
+</pre>
+       <p>Running <code>dotnet restore</code> gives you access to the required .NET Core packages that are needed to build your project.</p>
+       </li>
+       <li>Configure VSC by creating a <code>tasks.json</code> file.
+       <p>Press <strong>Ctrl + Shift + P</strong> to open the command palette, type <code>ctr</code>, and select <strong>Configure Task runner &gt; NET core</strong>.</p>
+       <p>A <code>tasks.json</code> file is essential, to prevent "No task runner configured" or "Error Could not find the Pre Launch Task 'build'" errors from occurring when building.</p>
+       </li>
+       <li>Build the project:
+<pre class="prettyprint">
+$ dotnet build
+</pre>
+
+<div class="note">
+       <strong>Note</strong>
+       This step builds the <code>nui</code> library.
+</div>
+       <p align="center"><img src="images/VSC.png" alt="VSC Explorer after building"/></p>
+       <p>The screenshot shows the key files associated with the "Hello World" project in VSC Explorer.</p>
+       </li>
+       <li>Copy the shared library to the application runtime location (this step must be done after the build step, when the <code>bin</code> folder exists):
+<pre class="prettyprint">
+cp dali-env/opt/lib/libdali-csharp-binder.so ~/DALiNUI/nuirun/bin/Debug/netcoreapp1.1/
+</pre>
+       </li>
+       <li>Run the project:
+               <ul>
+                       <li>To run the full size application in the VSC integrated terminal:
+<pre class="prettyprint">
+$ dotnet run
+</pre></li>
+                       <li>To run the adjusted size application in the VSC integrated terminal:
+<pre class="prettyprint">
+$ DALI_WINDOW_WIDTH=600 DALI_WINDOW_HEIGHT=800 dotnet run
+</pre></li>
+               </ul>
+       </li>
+</ol>
+
+<h3>Modifying the Hello World Application Window Size</h3>
+<p>You can configure the application Launch profile.</p>
+<p>In VSC Explorer, open the <code>launch.json</code> file. In the <strong>Configurations</strong> section, add the required width and height to the environment variable:</p>
+<pre class="prettyprint">
+"name": ".NET Core Launch (console)",
+
+"env": {
+    "DALI_WINDOW_WIDTH":"600",
+    "DALI_WINDOW_HEIGHT":"800"
+},
+</pre>
+<p>These settings are picked up if the application is run with F5.</p>
+
+
+<h2 id="firewall">Configuring Firewall Proxy Settings</h2>
+
+<p>To configure the firewall proxy settings:</p>
+<ul>
+<li>To set up the system firewall proxy settings to enable installing the VSC C# extension package:
+<ol>
+       <li>On the desktop, select <strong>System Settings &gt; Network &gt; Network Proxy</strong>.</li>
+       <li>In the <strong>HTTP Proxy</strong> and <strong>HTTPS Proxy</strong> fields, enter the IP address, including the port number.</li>
+</ol>
+<p align="center"><img src="images/SystemProxySettings.png" alt="System proxy settings"/></p>
+</li>
+<li>To configure the VSC firewall proxy settings for installing library packages, such as mono runtime and .NET Core Debugger:
+               <ol>
+                       <li>Select <strong>File &gt; Preferences &gt; Settings &gt; Edit</strong>.</li>
+                       <li>Select <strong>HTTP</strong> in the middle pane.</li>
+                       <li>Select <strong>Edit &gt; Copy to settings</strong>.
+<p>The <code>http.proxy</code> is copied to the right hand pane. Add the proxy setting:</p>
+<pre class="prettyprint">
+{
+    "http.proxy": "http://xxx.xxx.xxx.xxx:xxxx
+}
+</pre>
+                       <p>The proxy settings are saved to the <code>settings.json</code> file.</p>
+                       <p><img src="images/VSC_ExtandSettings.png" alt="Installed C# extension package with proxy settings"/></p>
+                       <p>The screenshot shows the installed C# extension package, with the proxy settings for the library packages in the <code>settings.json</code> file.</p>
+                       </li>
+               </ol>
+<p>Alternatively, you can set the <code>http_proxy</code> and <code>https_proxy</code> OS environment variables in a terminal from which VSC is run:</p>
+<pre class="prettyprint">
+$ export http_proxy=http://xxx.xxx.xxx.xxx
+$ export https_proxy=http://xxx.xxx.xxx.xxx
+</pre>
+<p>These export variables must also be set in your <code>.bashrc</code> file.</p>
+                       </li>
+</ul>
+
+
+<h2 id="buildclean">Cleaning the Build</h2>
+<p>To clean the NUI build:</p>
+<pre class="prettyprint">
+$ make maintainer-clean
+</pre>
+
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/nui/styling_controls_with_JSON.htm b/nui/styling_controls_with_JSON.htm
new file mode 100644 (file)
index 0000000..a02acae
--- /dev/null
@@ -0,0 +1,494 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>Styling Controls with JSON</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#visuals">Visuals</a></li>
+            <li><a href="#newview">Styling a New View</a></li>
+            <li><a href="#state">Styling for State</a></li>
+            <li><a href="#transitions">Transitions</a></li>
+            <li><a href="#example">Example Stylesheet</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>Styling Controls with JSON</h1>
+
+<p>You can style a toolkit control with JSON. This topic uses a PushButton as an example control.</p>
+
+<h2 id="visuals">Visuals</h2>
+<p>Visuals are the main building block of controls. A control is built from visuals with properties set as required.</p>
+<p>The following Visual types are available:</p>
+<table>
+<thead>
+<tr>
+    <th>Type</th>
+    <th>Example</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td>Border</td>
+    <td><img src="images/border-visual.png" alt="Border visual" /></td>
+</tr>
+<tr>
+    <td>Color</td>
+    <td><img src="images/color-visual.png" alt="Color visual" /></td>
+</tr>
+<tr>
+    <td>Gradient</td>
+    <td><img src="images/linear-gradient-visual.png" alt="Gradient visual" /></td>
+</tr>
+<tr>
+    <td>Image</td>
+    <td><img src="images/image-visual.png" alt="Image visual" /></td>
+</tr>
+<tr>
+    <td>Mesh</td>
+    <td><img src="images/mesh-visual.png" alt="Mesh visual" /></td>
+</tr>
+<tr>
+    <td>Primitive</td>
+    <td><img src="images/cube.png" alt="Primitive visual" /></td>
+</tr>
+<tr>
+    <td>Text</td>
+    <td><strong>Hello there</strong></td>
+</tr>
+</tbody>
+</table>
+<p>For more information on how to create, register, and use visuals, and lists all properties associated with each visual type, see <a href="visuals.htm">Visuals</a>.</p>
+
+<h2 id="newview">Styling a New View</h2>
+<p>Styling is inherited, so styling a parent automatically affects its child, unless overridden.</p>
+
+<p>The following table describes the Style properties offered by View and PushButton.</p>
+
+<table>
+<thead>
+<tr>
+    <th>Name</th>
+    <th>Type</th>
+    <th>Description</th></tr></thead>
+<tbody>
+<tr>
+    <td><code>heightResizePolicy</code></td>
+    <td><code>string</code></td>
+    <td>See <a href="creating_custom_view_controls.htm#sizenegotiation">Size Negotiation</a>.</td>
+</tr>
+<tr>
+    <td><code>widthResizePolicy</code></td>
+    <td><code>string</code></td>
+    <td>See <a href="creating_custom_view_controls.htm#sizenegotiation">Size Negotiation</a>.</td>
+</tr>
+<tr>
+    <td><code>sizeModeFactor</code></td>
+    <td><code>vector3</code></td>
+    <td>Gets/sets the relative to the parent size factor of the view.</td>
+</tr>
+<tr>
+    <td><code>minimumSize</code></td>
+    <td><code>Size2D</code></td>
+    <td>Gets/sets the minimum size a view can be assigned in size negotiation.</td>
+</tr>
+<tr>
+    <td><code>maximumSize</code></td>
+    <td><code>Size2D</code></td>
+    <td>Gets/sets the maximum size a view can be assigned in size negotiation.</td>
+</tr>
+</tbody>
+</table>
+
+<div class="note">
+       <strong>Note</strong>
+       <code>sizeModeFactor</code> is only used when <code>ResizePolicyType</code> is set to either <code>ResizePolicyType.SizeRelativeToParent</code> or <code>ResizePolicyType.SizeFixedOffsetFromParent</code>. The view's size is set to the view's size multiplied by or added to this factor, depending on <code>ResizePolicyType</code>.
+</div>
+
+
+<h2 id="state">Styling for State</h2>
+
+<p>A control has 3 states: <code>NORMAL</code>, <code>FOCUSED</code>, and <code>DISABLED</code>. In addition, a button has 2 substates, <code>SELECTED</code> and <code>UNSELECTED</code>, applicable for each of the 3 main states. Each state must have the required visuals, either as its own set of visuals or as a visual shared between states.</p>
+<p>A different <code>backgroundVisual</code> can be supplied for <code>NORMAL</code>, <code>FOCUSED</code>, and <code>DISABLED</code>, if required. A different <code>backgroundVisual</code> can also be defined for the <code>SELECTED</code> and <code>UNSELECTED</code> states.</p>
+
+<p>In the following example:</p>
+<ul>
+<li><strong>inherit</strong> means that the Push Button inherits any styles defined for Button.</li>
+<li><strong>"visuals"</strong> means that specific visual types can be put in that section.</li>
+<li><strong>"states"</strong> means that visuals for specific states can be put in that section.</li></ul>
+<pre class="prettyprint">
+"styles":
+{
+  "PushButton":
+  {
+    "inherit":["Button"],
+    "visuals":
+    {
+      "iconVisual": { "visualType":"IMAGE", "url":"icon1.png" },
+      "labelVisual": { "visualType":"TEXT", "text":"OK", "fontWeight":"bold" }
+    },
+    "states":
+    {
+
+    }
+  }
+}
+</pre>
+
+<p>The following process shows how you can build up a stylesheet, state by state:</p>
+
+<ol>
+<li>The following example defines the states common to all controls:
+<pre class="prettyprint">
+"states":
+{
+  "NORMAL":
+  {
+  },
+  "DISABLED":
+  {
+  },
+  "FOCUSED":
+  {
+  },
+}
+</pre>
+<p>At this point, the states have been defined, but no visuals are provided.</p>
+</li>
+<li>The following example adds the button substates (<code>UNSELECTED</code> and <code>SELECTED</code>) to the stylesheet, but still provides no visuals.
+<pre class="prettyprint">
+"states":
+{
+  "NORMAL":
+  {
+    "states":
+    {
+      "UNSELECTED":
+      {
+      },
+      "SELECTED":
+      {
+      }
+    },
+  "DISABLED":
+  {
+    "states":
+    {
+      "UNSELECTED":
+      {
+      },
+      "SELECTED":
+      {
+      }
+    }
+  },
+}
+</pre>
+</li>
+<li>The following example defines a background visual for each substate in the <code>NORMAL</code> state. The same can be done for <code>FOCUSED</code> and <code>DISABLED</code>.
+<pre class="prettyprint">
+"states":
+{
+  "NORMAL":
+  {
+    "states":
+    {
+      "UNSELECTED":
+      {
+        "visuals":
+        {
+          "backgroundVisual":
+           {
+             "visualType":"IMAGE",
+             "url":"backgroundUnSelected.png"
+           }
+        }
+      },
+      "SELECTED":
+      {
+        "visuals":
+        {
+          "backgroundVisual":
+           {
+             "visualType":"IMAGE",
+             "url":"backgroundSelected.png"
+           }
+        }
+      }
+    }
+  },
+}
+</pre>
+</li>
+</ol>
+
+<h2 id="transitions">Transitions</h2>
+
+<p>The control (Button) changes states based on user interaction. All controls can move between the <code>NORMAL</code>, <code>FOCUSED</code>, and <code>DISABLED</code> states. In addition, a button can have the <code>UNSELECTED</code> and <code>SELECTED</code> substates.</p>
+
+<p>To move between states and substates, transition animations can be defined. Each state and substate can have an "entry" and "exit" transition.</p>
+
+<p>To make defining common transitions easier, an effect can be used with a "from" and "to" state. One such effect is CROSSFADE, which animates the opacity of visuals fading in and out to give a nice transition. Initially, only CROSSFADE is available, but in time further effects can be provided.</p>
+
+<p>The transition can be placed in the state section, such as <code>NORMAL</code>. In the following example, the transition cross-fades between unselected and selected visuals:</p>
+
+<pre class="prettyprint">
+"transitions":
+[
+  {
+     "from":"UNSELECTED",
+     "to":"SELECTED",
+     "visualName":"*",
+     "effect":"CROSSFADE",
+     "animator":
+     {
+       "alphaFunction":"EASE_OUT",
+       "duration":"0.2,
+       "delay":0
+     }
+  }
+]
+</pre>
+
+<p>The following example uses the entry and exit transition for the <code>UNSELECTED</code> substate:</p>
+<pre class="prettyprint">
+"states":
+  {
+    "NORMAL":
+    {
+      "states":
+      {
+        "UNSELECTED":
+        {
+          "visuals":
+          {
+            "backgroundVisual":
+             {
+               "visualType":"IMAGE",
+               "url":"backgroundUnSelected.png"
+             }
+          },
+          "entryTransition":
+          {
+            "target":"backgroundVisual",
+            "property":"mixColor",
+            "targetValue":[1,1,1,1],
+            "animator":
+            {
+              "alphaFunction":"LINEAR",
+              "duration":0.3,
+              "delay":0.0
+            }
+         },
+         "exitTransition":
+         {
+            "target":"backgroundVisual",
+            "property":"mixColor",
+            "targetValue":[1,1,1,0.0],
+            "animator":
+            {
+              "alphaFunction":"LINEAR",
+              "duration":0.3,
+              "delay":0.0
+            }
+         }
+       }
+     }
+   }
+  }
+]
+</pre>
+
+<h2 id="example">Example Stylesheet</h2>
+<p>The following example shows a button stylesheet covering all states and various transitions:</p>
+<pre class="prettyprint">
+{
+  "styles":
+  {
+    "PushButton":
+    {
+      "inherit":["Button"],
+      "visuals":
+      {
+        "iconVisual":
+        {
+          "visualType":"IMAGE",
+          "url":"icon1.png"
+        },
+        "label":
+        {
+          "visualType":"TEXT",
+          "text":"OK",
+          "fontWeight":"bold"
+        }
+      },
+      "states":
+      {
+        "NORMAL":
+        {
+          "states":
+          {
+            "UNSELECTED":
+            {
+              "visuals":
+              {
+                "backgroundVisual":
+                {
+                  "visualType":"IMAGE",
+                  "url":"backgroundSelected.png"
+                }
+              }
+            },
+            "SELECTED":
+            {
+              "visuals":
+              {
+                "backgroundVisual":
+                {
+                  "visualType":"IMAGE",
+                  "url":"backgroundUnselected.png"
+                }
+              }
+            }
+          },
+          "transitions":
+          [
+            {
+              "from":"UNSELECTED",
+              "to":"SELECTED",
+              "visualName":"*",
+              "effect":"CROSSFADE",
+              "animator":
+              {
+                "alphaFunction":"EASE_OUT",
+                "duration":0.2,
+                "delay":0
+              }
+            }
+          ]
+        },
+        "FOCUSED":
+        {
+          "visuals":
+          {
+            "labelVisual":
+            {
+              "visualType":"TEXT",
+              "text":"OK",
+              "fontWeight":"bold"
+            }
+          },
+          "states":
+          {
+            "SELECTED":
+            {
+            },
+            "UNSELECTED":
+            {
+            }
+          }
+        },
+        "DISABLED":
+        {
+          "states":
+          {
+            "SELECTED":
+            {
+              "visuals":
+              {
+                "backgroundVisual":
+                {
+                  "visualType": "IMAGE",
+                  "url": "{DALI_IMAGE_DIR}button-down-disabled.9.png"
+                }
+              }
+            },
+            "UNSELECTED":
+            {
+              "visuals":
+              {
+                "backgroundVisual":
+                {
+                  "visualType": "IMAGE",
+                  "url": "{DALI_IMAGE_DIR}button-disabled.9.png"
+                }
+              }
+            }
+          },
+          "transitions":
+          {
+            "visualName":"*",
+            "effect":"CROSSFADE",
+            "animator":
+            {
+              "alphaFunction":"EASE_IN_OUT",
+              "duration":0.3
+            }
+          }
+        }
+      },
+      "autoRepeating":false,
+      "togglable":false,
+      "labelPadding":[ 12.0, 12.0, 12.0, 12.0 ],
+
+      "transitions":
+      [
+        {
+          "from":"NORMAL",
+          "to":"DISABLED",
+          "visualName":"*",
+          "effect":"CROSSFADE",
+          "animator":
+          {
+            "alphaFunction":"EASE_OUT",
+            "duration":0.2,
+            "delay":0
+          }
+        }
+      ]
+    }
+  }
+}
+</pre>
+
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
diff --git a/nui/textlabel.htm b/nui/textlabel.htm
new file mode 100644 (file)
index 0000000..c748374
--- /dev/null
@@ -0,0 +1,465 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>TextLabel</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#create">Creating a TextLabel</a></li>
+            <li><a href="#font">Selecting Fonts</a></li>
+            <li><a href="#align">Aligning Text</a></li>
+            <li><a href="#decorations">Using Decorations</a></li>
+            <li><a href="#markup">Using Markup Styling</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>TextLabel</h1>
+
+<p><code>TextLabel</code> is a NUI control that renders a short text string. Text labels are lightweight, non-editable, and do not respond to user input. They can support multiple languages and scripts, including right-to-left scripts, such as Arabic.</p>
+
+<p>The <a href="hello_world.htm">Hello World tutorial</a> describes how to display text using a <code>TextLabel</code>.</p>
+
+<h2 id="create">Creating a TextLabel</h2>
+
+<p>A <code>TextLabel</code> must be added to a Window, or to a View which is on the Window. The position of the label on-screen is specified by the <code>parentOrigin</code> property.</p>
+
+<pre class="prettyprint">
+TextLabel label = new TextLabel("Hello World");
+Window window = Window.Instance;
+window.Add(label);
+</pre>
+
+<p>The following figure shows a text label with <code>ParentOrigin.TopLeft</code>.</p>
+
+<p align="center"><strong>Figure: <code>TextLabel</code> aligned to top left</strong></p>
+<p align="center"><img src="images/TextLabelTopLeft.png" alt="TextLabel aligned to top left" /></p>
+<p>To display a <code>TextLabel</code> object properly, the <code>Text</code> property must be a UTF-8 string. Note that <code>CR+LF</code> new line characters are replaced by <code>LF</code>.</p>
+<h2 id="font">Selecting Fonts</h2>
+<p>By default, the <code>TextLabel</code> automatically selects a suitable font from the platform. Note that the selected font may not support all characters in your input text. For example, Latin fonts often do not provide Arabic glyphs.</p>
+<p>Alternatively, you can request a font using the <code>FontFamily</code>, <code>FontStyle</code>, and <code>PointSize</code> properties:</p>
+<ul>
+    <li><code>FontFamily</code> is a string with the font family name, for example, "FreeSerif".</li>
+    <li><code>FontStyle</code> is a JSON-formatted string with the font style. The following lists some possible keys and common values for them:
+    <ul>
+        <li>The <code>width</code> key defines the spacing between glyphs. Some commonly-used values include <code>condensed</code>, <code>semiCondensed</code>, <code>normal</code>, <code>semiExpanded</code>, and <code>expanded</code>.</li>
+        <li>The <code>weight</code> key defines the thickness or darkness of the glyphs. Some commonly-used values include <code>thin</code>, <code>light</code>, <code>normal</code>, <code>regular</code>, <code>medium</code>, and <code>bold</code>.</li>
+        <li>The <code>slant</code> key defines whether to use italics. Some commonly-used values include <code>normal</code> or <code>roman</code>, <code>italic</code>, and <code>oblique</code>.
+            <p>Usually <code>italic</code> is a separate font, while <code>oblique</code> is generated by slanting the <code>normal</code> font.</p></li>
+    </ul></li>
+    <li><code>PointSize</code> is a float with the font size in points. To calculate the point size from the height in pixels, use the following formula, where <code>vertical_dpi</code> is the device's vertical resolution in dots per inch:
+<pre class="prettyprint">
+point_size = 72 * pixels / vertical_dpi
+</pre>
+    </li>
+</ul>
+<pre class="prettyprint">
+label.FontFamily = "FreeSerif";
+
+PropertyMap fontStyle = new PropertyMap();
+fontStyle.Add( "weight", new PropertyValue("bold") );
+fontStyle.Add( "slant", new PropertyValue("italic") );
+label.FontStyle = fontStyle;
+label.PointSize = 12.0f;
+</pre>
+<p>If fonts are not specified, styling defaults are used.</p>
+
+<h3>Font Styles</h3>
+<p>Setting a font size programmatically is not ideal for applications which support multiple screen resolutions, and platforms which support multiple logical font sizes.  Also, any changes to the platform font settings override any sizes that have been programmatically set.</p>
+<p>A more flexible approach is to prepare various JSON stylesheets, and request a different style for each platform. The <code>NUIApplication</code> class has constructors which take a stylesheet argument:</p>
+<pre class="prettyprint">
+class Example : NUIApplication
+
+Example example = new Example("example-path/example.json");
+</pre>
+<p>To change the font for standard text controls, the following JSON syntax can be used:</p>
+<pre class="prettyprint">
+{
+  "styles":
+  {
+    "textlabel":
+    {
+      "fontFamily":"FreeSerif",
+      "fontStyle":
+      {
+        "weight":"bold",
+        "slant":"italic"
+      },
+      "pointSize":8
+    }
+  }
+}
+</pre>
+<p>However, the same <code>pointSize</code> is unlikely to be suitable for all text controls in an application. To define custom styles for existing controls, simply set a style name for each case, and provide a style override in JSON.</p>
+<p>Mapping the logical size to a physical size, in the stylesheet, can provide further flexibility for the end user.</p>
+
+<h2 id="align">Aligning Text</h2>
+<p>Text wrapping can be enabled using the <code>MultiLine</code> property:</p>
+<pre class="prettyprint">
+label.MultiLine = true;
+</pre>
+<p>The text can be aligned horizontally to the beginning, center, or end of the available area:</p>
+
+<pre class="prettyprint">
+label.HorizontalAlignment = HorizontalAlignmentType.Left;
+label.HorizontalAlignment = HorizontalAlignmentType.Center;
+label.HorizontalAlignment = HorizontalAlignmentType.Right;
+</pre>
+<table>
+<thead>
+<tr>
+    <th>Alignment</th>
+    <th>Left-to-right script example</th>
+    <th>Right-to-left script example</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td>BEGIN</td>
+    <td><center><img src="images/LatinBegin.png" alt="Latin script aligned to beginning" /></center></td>
+    <td><center><img src="images/ArabicBegin.png" alt="Arabic script aligned to beginning" /></center></td>
+</tr>
+<tr>
+    <td>CENTER</td>
+    <td><center><img src="images/LatinCenter.png" alt="Latin script aligned to center" /></center></td>
+    <td><center><img src="images/ArabicCenter.png" alt="Arabic script aligned to center" /></center></td>
+</tr>
+<tr>
+    <td>END</td>
+    <td><center><img src="images/LatinEnd.png" alt="Latin script aligned to end" /></center></td>
+    <td><center><img src="images/ArabicEnd.png" alt="Arabic script aligned to end" /></center></td>
+</tr>
+</tbody>
+</table>
+<p>The above examples assume that the label size is greater than the minimum required.</p>
+
+<h2 id="decorations">Using Decorations</h2>
+
+<p>For text decorations, <code>TextLabel</code> provides several properties. All properties are writable and none are animatable.</p>
+<p align="center" class="Table"><strong>Table: <code>TextLabel</code> properties</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th>Type</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Text</code></td>
+    <td>string</td>
+    <td>The text to display in UTF-8 format.</td>
+</tr>
+<tr>
+    <td><code>FontFamily</code></td>
+    <td>string</td>
+    <td>The requested font family to use.</td>
+</tr>
+<tr>
+    <td><code>FontStyle</code></td>
+    <td>Map</td>
+    <td>The requested font style to use.</td>
+</tr>
+<tr>
+    <td><code>PointSize</code></td>
+    <td>float</td>
+    <td>The font size in points.</td>
+</tr>
+<tr>
+    <td><code>MultiLine</code></td>
+    <td>bool</td>
+    <td>Whether to use the multi-line layout option.</td>
+</tr>
+<tr>
+    <td><code>HorizontalAlignment</code></td>
+    <td>string</td>
+    <td>The line horizontal alignment.</td>
+</tr>
+<tr>
+    <td><code>VerticalAlignment</code></td>
+    <td>string</td>
+    <td>The line vertical alignment.</td>
+</tr>
+<tr>
+    <td><code>TextColor</code></td>
+    <td>Color</td>
+    <td>The text color.</td>
+</tr>
+<tr>
+    <td><code>ShadowOffset</code></td>
+    <td>Vector2</td>
+    <td>The text shadow offset.</td>
+</tr>
+<tr>
+    <td><code>ShadowColor</code></td>
+    <td>Vector4</td>
+    <td>The text shadow color.</td>
+</tr>
+<tr>
+    <td><code>UnderlineEnabled</code></td>
+    <td>bool</td>
+    <td>Gets/sets whether to use underline.</td>
+</tr>
+<tr>
+    <td><code>UnderlineColor</code></td>
+    <td>Vector4</td>
+    <td>Gets/sets the underline color.</td>
+</tr>
+<tr>
+    <td><code>UnderlineHeight</code></td>
+    <td>float</td>
+    <td>Gets/sets the underline height.</td>
+</tr>
+<tr>
+    <td><code>EnableMarkup</code></td>
+    <td>bool</td>
+    <td>Whether markup processing is enabled.</td>
+</tr>
+<tr>
+    <td><code>EnableAutoScroll</code></td>
+    <td>bool</td>
+    <td>Starts or stops auto-scrolling.</td>
+</tr>
+<tr>
+    <td><code>AutoScrollSpeed</code></td>
+    <td>int</td>
+    <td>The scrolling speed, in pixels per second.</td>
+</tr>
+<tr>
+    <td><code>AutoScrollLoopCount</code></td>
+    <td>int</td>
+    <td>Number of complete loops to scroll, when scrolling is enabled.</td>
+</tr>
+<tr>
+    <td><code>AutoScrollGap</code></td>
+    <td>float</td>
+    <td>The gap before scrolling wraps.</td>
+</tr>
+<tr>
+    <td><code>LineSpacing</code></td>
+    <td>float</td>
+    <td>The default spacing between lines, in points.</td>
+</tr>
+<tr>
+    <td><code>Underline</code></td>
+    <td>Map</td>
+    <td>The default underline parameters.</td>
+</tr>
+<tr>
+    <td><code>Shadow</code></td>
+    <td>Map</td>
+    <td>The default shadow parameters.</td>
+</tr>
+<tr>
+    <td><code>Emboss</code></td>
+    <td>Map</td>
+    <td>The default emboss parameters.</td>
+</tr>
+<tr>
+    <td><code>Outline</code></td>
+    <td>Map</td>
+    <td>The default outline parameters.</td>
+</tr>
+<tr>
+    <td><code>PixelSize</code></td>
+    <td>float</td>
+    <td>The font size in pixels.</td>
+</tr>
+<tr>
+    <td><code>Ellipsis</code></td>
+    <td>bool</td>
+    <td>Gets/sets whether to enable ellipsis.</td>
+</tr>
+<tr>
+    <td><code>AutoScrollLoopDelay</code></td>
+    <td>float</td>
+    <td>Gets/sets the auto-scroll loop delay.</td>
+</tr>
+<tr>
+    <td><code>AutoScrollStopMode</code></td>
+    <td>AutoScrollStopMode</td>
+    <td>Gets/sets the auto-scroll stop mode.</td>
+</tr>
+</tbody>
+</table>
+
+<h3>Color</h3>
+<p>To change the color of the text, use the <code>TextColor</code> property. Note that unlike the View <code>Color</code> property, this does not affect child actors added to the <code>TextLabel</code>.</p>
+<pre class="prettyprint">
+label.Text = "Red Text";
+label.TextColor = Color.Red;
+</pre>
+<p align="center"><strong>Figure: Colored text</strong></p>
+<p align="center"><img src="images/RedText.png" alt="Colored text" /></p>
+
+<h3>Drop Shadow</h3>
+<p>To add a drop-shadow to the text, set the <code>Shadow</code> property. Shadow parameters can also be set through a JSON string:</p>
+<pre class="prettyprint">
+window.BackgroundColor( Color.Blue );
+
+label1.Text = "Plain Text";
+
+label2.Text = "Text with Shadow";
+PropertyMap shadow = new PropertyMap();
+shadow.Add("offset", new PropertyValue("1 1"));
+shadow.Add("color", new PropertyValue("black"));
+pixelLabel.Shadow = shadow;
+
+label3.Text = "Text with Bigger Shadow";
+PropertyMap shadow = new PropertyMap();
+shadow.Add("offset", new PropertyValue("2 2"));
+shadow.Add("color", new PropertyValue("black"));
+label3.Shadow = shadow;
+
+label4.Text = "Text with Color Shadow" );
+PropertyMap shadow = new PropertyMap();
+shadow.Add("offset", new PropertyValue("1 1"));
+shadow.Add("color", new PropertyValue("red"));
+label4.Shadow = shadow;
+</pre>
+
+<p align="center"><strong>Figure: Text with drop shadow</strong></p>
+<p align="center"><img src="images/TextWithShadow.png" alt="Text with drop shadow" /></p>
+<p align="center"><strong>Figure: Text with bigger shadow</strong></p>
+<p align="center"><img src="images/TextWithBiggerShadow.png" alt="Text with bigger shadow" /></p>
+<p align="center"><strong>Figure: Text with color shadow</strong></p>
+<p align="center"><img src="images/TextWithColorShadow.png" alt="Text with color shadow" /></p>
+
+<h3>Underline</h3>
+<p>Text underline properties can be set using a property map:</p>
+<pre class="prettyprint">
+label1.Text = "Text with Underline";
+
+PropertyMap textStyle = new PropertyMap();
+textStyle.Add("enable", new PropertyValue("true"));
+label1.Underline = textStyle;
+</pre>
+<p>You can set the underline color and height:</p>
+<pre class="prettyprint">
+label2.Text = "Text with Color Underline";
+
+PropertyMap textStyle = new PropertyMap();
+textStyle.Add("enable", new PropertyValue("true"));
+textStyle.Add("color", new PropertyValue(Color.Green));
+label2.Underline = textStyle;
+</pre>
+
+<p align="center"><strong>Figure: Text with underline</strong></p>
+<p align="center"><img src="images/TextWithUnderline.png" alt="Text with underline" /></p>
+<p align="center"><strong>Figure: Text with color underline</strong></p>
+<p align="center"><img src="images/TextWithColorUnderline.png" alt="Text with color underline" /></p>
+<p>By default the underline height is derived from the font metrics, however this can be overridden:</p>
+<pre class="prettyprint">
+PropertyMap textStyle = new PropertyMap();
+textStyle.Add("enable", new PropertyValue("true"));
+textStyle.Add("height", new PropertyValue(2.0f)); // 2 pixel height
+label1.Underline = textStyle;
+</pre>
+<p>The underline text figures above have a 1 pixel height.</p>
+
+<h3 id="scrolling">Auto-scrolling</h3>
+<p align="center"><strong>Figure: Auto-scrolling text</strong></p>
+<p align="center"><img src="images/AutoScroll.gif" alt="Auto-scrolling text" /></p>
+<p>Auto-scrolling enables text to scroll within the <code>TextLabel</code> control. You can use it if the text exceeds the boundary of the control, to show the full content. Auto-scrolling can also scroll text that is smaller than the control. To ensure that the same part of the text is not visible more than once at the same time, you can configure the gap between repetitions.</p>
+<p>Multi-line text does not scroll, and the text is shown with 'Begin' alignment.</p>
+<p>The <code>AutoScrollLoopCount</code> property sets the number of times the text scrolls. For example, if <code>AutoScrollLoopCount</code> is set to 3, the text scrolls across the control 3 times, then stops. If <code>AutoScrollLoopCount</code> is 0, then once started, scrolling continues until requested to stop.</p>
+
+<p>To enable text scrolling, set the <code>EnableAutoScroll</code> property to <code>true</code>:</p>
+<pre class="prettyprint">
+label.EnableAutoScroll = true;
+</pre>
+<p>Once enabled, scrolling continues until the loop count is reached, or <code>EnableAutoScroll</code> is set to <code>false</code>. When <code>EnableAutoScroll</code> is set to <code>false</code>, the text completes its current scrolling loop before stopping.</p>
+<p>The scroll speed, gap, and loop count can be set in the stylesheet, or through the following properties:</p>
+<ul>
+    <li>Auto-scroll speed
+    <p>The <code>AutoScrollSpeed</code> property defines the scrolling speed in pixels/second.</p></li>
+    <li>Auto-scroll loop count
+    <p><code>AutoScrollLoopCount</code> specifies how many times the text completes a full scroll cycle. If this property is 0, scrolling continues until <code>EnableAutoScroll</code> is set to <code>false</code>.</p>
+    <p>Setting <code>EnableAutoScroll</code> to <code>false</code> stops scrolling, whilst maintaining the original loop count value for the next start.</p></li>
+    <li>Auto-scroll gap
+    <p><code>AutoScrollGap</code> specifies the amount of whitespace, in pixels, to display before the scrolling text is shown again. This gap is automatically increased if the given value is not large enough to prevent the same part of the text from being visible twice at the same time.</p></li>
+    <li>Scroll Direction
+    <p>The scroll direction is defined by the following rules:</p>
+        <ul>
+            <li>Left-to-right text: Scroll left</li>
+            <li>Right-to-left text: Scroll right</li>
+        </ul>
+    </li>
+</ul>
+<h2 id="markup">Using Markup Styling</h2>
+<p>You can use markup elements to change the style of the text. By default, the text controls do not process markup strings. To process markup tags, the <code>EnableMarkup</code> property must be set to <code>true</code>.</p>
+<pre class="prettyprint">
+TextLabel label = new TextLabel("Hello World");
+label.EnableMarkup = true;
+Window window = Window.Instance;
+window.Add(label);
+</pre>
+<p>Note that the markup processor does not check for markup validity. This can cause the text to be badly rendered.</p>
+<p>There are priorities when styles are applied while rendering text.</p>
+<p>The following elements are currently supported:</p>
+<ul>
+    <li><code>&lt;color&gt;</code>
+    <p>Sets the color for the characters inside the tag. Use the <code>value</code> attribute to define the color. The supported attribute values are 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'black' and 'transparent'. Web colors and colors defined in 32-bit hexadecimal 0xAARRGGBB format are also supported.</p>
+<p>The following examples both create text in red:</p>
+<pre class="prettyprint">
+label.Text = "&lt;color value='red'&gt;Red Text&lt;/color&gt;" ); // Color coded with a text constant
+</pre>
+<pre class="prettyprint">
+label.Text = "&lt;color value='0xFFFF0000'&gt;Red Text&lt;/color&gt;" ); // Color packed inside an ARGB hexadecimal value
+</pre></li>
+<li><code>&lt;font&gt;</code>
+<p>Sets the font values for the characters inside the tag.</p>
+<p>The following attributes are supported:</p>
+<ul>
+<li><code>family</code>: Font name.</li>
+<li><code>size</code>: Font size in points.</li>
+<li><code>weight</code>: Font weight.</li>
+<li><code>width</code>: Font width</li>
+<li><code>slant</code>: Font slant.</li>
+</ul>
+<p>For information on attribute values, see <a href="#font">Selecting Fonts</a>.</p>
+<pre class="prettyprint">
+label.Text = "&lt;font family='SamsungSans' weight='bold'&gt;Hello world&lt;/font&gt;";
+</pre>
+</li></ul>
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/nui/visuals.htm b/nui/visuals.htm
new file mode 100644 (file)
index 0000000..9e7a242
--- /dev/null
@@ -0,0 +1,1113 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="css/snippet.css" />
+       <script type="text/javascript" src="scripts/snippet.js"></script>
+       <script type="text/javascript" src="scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="scripts/search.js" charset="utf-8"></script>
+
+       <title>Visuals</title>
+</head>
+
+<body onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+       <div id="toc_border"><div id="toc">
+               <p class="toc-title">Content</p>
+               <ul class="toc">
+            <li><a href="#visualproperties">Visual Properties</a></li>
+            <li><a href="#visualtype">Visual Type</a></li>
+            <li><a href="#visualcreation">Creating and Registering Visuals</a></li>
+            <li><a href="#visualdepthindex">Visual Depth Index</a></li>
+            <li><a href="#colorvisual">Color Visual</a></li>
+            <li><a href="#gradientvisual">Gradient Visual</a></li>
+            <li><a href="#imagevisual">Image Visual</a></li>
+            <li><a href="#bordervisual">Border Visual</a></li>
+            <li><a href="#meshvisual">Mesh Visual</a></li>
+            <li><a href="#primitivevisual">Primitive Visual</a></li>
+            <li><a href="#wireframevisual">Wireframe Visual</a></li>
+            <li><a href="#textvisual">Text Visual</a></li>
+            <li><a href="#visualtransform">Visual Transform</a></li>
+            <li><a href="#visualmap">VisualMap Class</a></li>
+            <li><a href="#visualview">VisualView Class</a></li>
+               </ul>
+       </div></div>
+</div>
+<div id="container"><div id="contents"><div class="content">
+
+<h1>Visuals</h1>
+<p>Visuals are the main building block for controls. You can create a reusable rendering logic, which can be used by all controls, using visuals. The content rendering can be controlled using properties. Visuals also respond to view size and color changes, and can perform clipping at the renderer level.</p>
+
+<p>As an example, images, icons and text are added to buttons using visuals. A control has 3 states - <code>NORMAL</code>, <code>FOCUSED</code>, and <code>DISABLED</code>. Additionally, buttons have 2 substates: <code>SELECTED</code> and <code>UNSELECTED</code>. The button's appearance can be modified by setting properties for the various 'state' visuals. Each state and sub-state has mandatory visuals, and several states can share a visual. When the button is clicked, it goes from the unselected state to the selected state. The unselected state visuals are replaced by the selected state visuals. When the button is disabled, the background, button, and selected state visuals are replaced by the disabled state visuals. To learn more about how to build up and transition between visuals for button states using JSON stylesheets, see <a href="styling_controls_with_JSON.htm">Styling Controls with JSON</a>.</p>
+
+<p>To create a visual:</p>
+<ol>
+<li>Create a property map.</li>
+<li>Add the visual type to the property map as the first entry.</li>
+<li>Add the required property values to the map.</li>
+<li>Create the visual in a 'factory' using the property map.</li>
+<li>Register the visual.</li>
+
+</ol>
+
+<h2 id="visualproperties">Visual Properties</h2>
+<p>Visual properties are set using a property map.</p>
+<p>You can use property maps in 2 ways:</p>
+<ul>
+<li>Use the specific <code>xxxProperty</code> structures for each visual, such as <code>ColorVisualProperty</code>, which specify the properties for that visual type.</li>
+<li>Use the <code>xxxVisual</code> <a href="#visualmap">visual maps</a>, such as <code>ColorVisual</code>.</li>
+</ul>
+<h2 id="visualtype">Visual Type</h2>
+<p>You must specify the visual type to use/create in the property map. This is required to avoid ambiguity, as multiple visuals can be capable of rendering the same content.</p>
+<p>The following visual types are available:</p>
+<ul>
+    <li>Border</li>
+    <li>Color</li>
+    <li>Gradient</li>
+    <li>Image
+        <ul>
+        <li>NPatch</li>
+        <li>SVG</li>
+        <li>Animated Image</li>
+        </ul></li>
+    <li>Mesh</li>
+    <li>Primitive</li>
+    <li>WireFrame</li>
+    <li>Text</li>
+</ul>
+
+<h2 id="visualcreation">Creating and Registering Visuals</h2>
+<p>Visuals are created using factory methods.</p>
+<p>Visuals must be registered with a unique property index, used for direct access to the visual. The index can be used to link a view to a visual when required. Registration also enables extra functionality, such as connecting the visual to the window. The <code>RegisterVisual()</code> method stores the visual 'handle' within the control.</p>
+<p>The examples in this topic demonstrate the recommended procedure for visual creation and registration, using explicit
+calls to the factory and register methods:</p>
+<pre class="prettyprint">
+_colorVisual =  VisualFactory.Instance.CreateVisual( colorVisual );
+
+RegisterVisual( ColorVisualPropertyIndex, _colorVisual );
+
+_colorVisual.DepthIndex = ColorVisualPropertyIndex;
+</pre>
+<p>Where specific visual assignment is possible, factory creation and registration can occur within the API. In the following example, visual factory creation and registration occur within the <code>Background</code> property.</p>
+<pre class="prettyprint">
+textView.Background = textVisual;
+</pre>
+<p>The <code>AddVisual</code> method of the <code>VisualView</code> class is another example of an API that creates a visual inherently.</p>
+<p>The example visuals in this topic use property registration based on a fixed property index range. The NUI code base has been modified to perform property registration based on automatic index generation. For more information, see <a href="creating_custom_view_controls.htm#properties">Properties in Custom Views</a>.</p>
+
+<h2 id="visualdepthindex">Visual Depth Index</h2>
+<p>The depth index is the draw order for visuals within a view. Whenever a visual is added, the depth index increases automatically. The last registered visual is always on top.</p>
+
+<h2 id="colorvisual">Color Visual</h2>
+<p>The color visual renders a solid color to the control's quad.</p>
+<p align="center"><strong>Figure: Color visual</strong></p>
+<p align="center"><img src="images/color-visual.png" alt="Color visual" /></p>
+<p>The following table lists the supported <code>ColorVisualProperty</code> properties. The visual type is <code>Color</code> and the visual map is <code>ColorVisual</code>.</p>
+
+<p align="center" class="Table"><strong>Table: <code>ColorVisualProperty</code> properties</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th><center>Type</center></th>
+    <th><center>Required</center></th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>MixColor</code></td>
+    <td><center>VECTOR4</center></td>
+    <td><center>Yes</center></td>
+    <td>The color required.</td>
+</tr>
+</tbody>
+</table>
+
+<p><strong>Usage:</strong></p>
+<pre class="prettyprint">
+private const int PROPERTY_REGISTRATION_START_INDEX = 10001000;
+private const int ColorVisualPropertyIndex = PROPERTY_REGISTRATION_START_INDEX+1 ;
+private const int PrimitiveVisualPropertyIndex = PROPERTY_REGISTRATION_START_INDEX+2;
+
+private VisualBase _colorVisual;
+
+PropertyMap colorVisual = new PropertyMap();
+colorVisual.Add( Visual.Property.Type, new PropertyValue( (int)Visual.Type.Color ))
+           .Add( ColorVisualProperty.MixColor, new PropertyValue( _color ));
+_colorVisual =  VisualFactory.Get().CreateVisual( colorVisual );
+
+RegisterVisual( ColorVisualPropertyIndex, _colorVisual );
+
+// Set the color visual depth index
+_colorVisual.DepthIndex = ColorVisualPropertyIndex;
+</pre>
+
+<h2 id="gradientvisual">Gradient Visual</h2>
+<p>The gradient visual renders a smooth transition of colors to the control's quad. Both linear (left in the following figure) and radial (right in the following figure) gradients are supported.</p>
+<p align="center"><strong>Figure: Gradient visual</strong></p>
+<p align="center"><img alt="Linear gradient visual" src="images/linear-gradient-visual.png"/> <img alt="Radial gradient visual" src="images/radial-gradient-visual.png"/></p>
+
+<p>The following table lists the supported <code>GradientVisualProperty</code> properties. The visual type is <code>Gradient</code> and the visual map is <code>GradientVisual</code>.</p>
+
+<p align="center" class="Table"><strong>Table: <code>GradientVisualProperty</code> properties</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th><center>Type</center></th>
+    <th><center>Required</center></th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>StartPosition</code></td>
+    <td><center>VECTOR2</center></td>
+    <td><center>For linear only</center></td>
+    <td>The start position of the linear gradient.</td>
+</tr>
+<tr>
+    <td><code>EndPosition</code></td>
+    <td><center>VECTOR2</center></td>
+    <td><center>For linear only</center></td>
+    <td>The end position of the linear gradient.</td>
+</tr>
+<tr>
+    <td><code>Center</code></td>
+    <td><center>VECTOR2</center></td>
+    <td><center>For radial only</center></td>
+    <td>The center point of the gradient.</td>
+</tr>
+<tr>
+    <td><code>Radius</code></td>
+    <td><center>FLOAT</center></td>
+    <td><center>For radial only</center></td>
+    <td>The size of the radius.</td>
+</tr>
+<tr>
+    <td><code>StopOffset</code></td>
+    <td><center>ARRAY of FLOAT</center></td>
+    <td><center>No</center></td>
+    <td>All the stop offsets. If not supplied, default is 0.0 and 1.0.</td>
+</tr>
+<tr>
+    <td><code>StopColor</code></td>
+    <td><center>ARRAY of VECTOR4</center></td>
+    <td><center>Yes</center></td>
+    <td>The color at the stop offsets. At least 2 are required to show a gradient.</td>
+</tr>
+<tr>
+    <td><code>Units</code></td>
+    <td><center>INTEGER or STRING</center></td>
+    <td><center>No</center></td>
+    <td>The coordinate system.</td>
+</tr>
+<tr>
+    <td><code>SpreadMethod</code></td>
+    <td><center>INTEGER or STRING</center></td>
+    <td><center>No</center></td>
+    <td>Indicates what happens if a gradient starts or ends inside bounds.</td>
+</tr>
+</tbody>
+</table>
+
+<ul>
+<li>The <code>Units</code> are used to define the coordinate system for the attributes:
+<ul>
+<li>Start (x1, y1) and end (x2, y2) points of a line, if using a linear gradient.</li>
+<li>Center point (cx, cy) and radius (r) of a circle, if using a radial gradient.</li>
+</ul></li>
+<li>The <code>SpreadMethod</code> property indicates what happens if the gradient starts or ends inside the bounds of the target rectangle.
+
+<p align="center" class="Table"><strong>Table: <code>SpreadMethod</code> values</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Enumeration value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Pad</code></td>
+                <td>Default. Uses the terminal colors of the gradient to fill the remainder of the quad.</td>
+</tr>
+<tr>
+    <td><code>Reflect</code></td>
+               <td>Reflects the gradient pattern start-to-end, end-to-start, start-to-end, and so on, until the quad is filled.</td>
+</tr>
+<tr>
+    <td><code>Repeat</code></td>
+               <td>Repeats the gradient pattern start-to-end, start-to-end, start-to-end, and so on, until the quad is filled.</td>
+</tr>
+</tbody>
+</table>
+</li>
+</ul>
+
+<p><strong>Usage:</strong></p>
+<p>The following example shows how to add a gradient visual to a <code>VisualView</code> instance.  <code>_visualView</code> is a custom view, and the visual is created using the <code>AddVisual()</code> method. For more information, see <a href="#visualview">VisualView Class</a>.</p>
+<pre class="prettyprint">
+// Radial
+_visualView = new VisualView();
+
+GradientVisual gradientVisualMap1 = new GradientVisual();
+
+PropertyArray stopPosition = new PropertyArray();
+stopPosition.Add(new PropertyValue(0.0f));
+stopPosition.Add(new PropertyValue(0.3f));
+stopPosition.Add(new PropertyValue(0.6f));
+stopPosition.Add(new PropertyValue(0.8f));
+stopPosition.Add(new PropertyValue(1.0f));
+gradientVisualMap1.StopOffset = stopPosition;
+
+PropertyArray stopColor = new PropertyArray();
+stopColor.Add(new PropertyValue(new Vector4(129.0f, 198.0f, 193.0f, 255.0f) / 255.0f));
+stopColor.Add(new PropertyValue(new Vector4(196.0f, 198.0f, 71.0f, 122.0f) / 255.0f));
+stopColor.Add(new PropertyValue(new Vector4(214.0f, 37.0f, 139.0f, 191.0f) / 255.0f));
+stopColor.Add(new PropertyValue(new Vector4(129.0f, 198.0f, 193.0f, 150.0f) / 255.0f));
+stopColor.Add(new PropertyValue(Color.Yellow));
+
+gradientVisualMap1.StopColor = stopColor;
+gradientVisualMap1.StartPosition = new Vector2(0.5f, 0.5f);
+gradientVisualMap1.EndPosition = new Vector2(-0.5f, -0.5f);
+gradientVisualMap1.Center = new Vector2(0.5f, 0.5f);
+gradientVisualMap1.Radius = 1.414f;
+gradientVisualMap1.Size = new Vector2(100.0f, 100.0f);
+gradientVisualMap1.Position = new Vector2(120.0f, 380.0f);
+gradientVisualMap1.PositionPolicy = VisualTransformPolicyType.Absolute;
+gradientVisualMap1.SizePolicy = VisualTransformPolicyType.Absolute;
+gradientVisualMap1.Origin = Visual.AlignType.TopBegin;
+gradientVisualMap1.AnchorPoint = Visual.AlignType.TopBegin;
+
+_visualView.AddVisual("gradientVisual1", gradientVisualMap1);
+</pre>
+
+
+<h2 id="imagevisual">Image Visual</h2>
+
+<p>The image visual renders an image into the control's quad. There are different rendering visuals depending on the image extension:</p>
+<ul>
+<li><a href="#normal">Normal (Quad) image</a></li>
+<li><a href="#npatch">N-patch image</a></li>
+<li><a href="#svg">SVG image</a></li>
+<li><a href="#animated">Animated image</a></li>
+
+</ul>
+<p>The visual type is <code>Image</code>.</p>
+
+<h3 id="normal">Normal Image</h3>
+<p>The normal image visual renders a raster image (such as JPG or PNG) into the control's quad.</p>
+
+<p align="center"><strong>Figure: Normal image visual</strong></p>
+<p align="center"><img src="images/image-visual.png" alt="Normal image visual" /></p>
+
+<p>The visual map for a normal image is <code>ImageVisual</code>.</p>
+
+<p align="center" class="Table"><strong>Table: <code>ImageVisualProperty</code> properties</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th><center>Type</center></th>
+    <th><center>Required</center></th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>URL</code></td>
+    <td><center>STRING</center></td>
+    <td><center>Yes</center></td>
+    <td>The URL of the image.</td>
+</tr>
+<tr>
+    <td><code>FittingMode</code></td>
+    <td><center>INTEGER or STRING</center></td>
+    <td><center>No</center></td>
+    <td>Fitting options, used when resizing images to fit the specified dimensions.</td>
+</tr>
+<tr>
+    <td><code>samplingMode</code></td>
+    <td><center>INTEGER or STRING</center></td>
+    <td><center>No</center></td>
+    <td>Filtering options, used when sampling original pixels to resize images.</td>
+</tr>
+<tr>
+    <td><code>DesiredWidth</code></td>
+    <td><center>INT</center></td>
+    <td><center>No</center></td>
+    <td>The desired image width. Uses actual image width if not specified.</td>
+</tr>
+<tr>
+    <td><code>DesiredHeight</code></td>
+    <td><center>INT</center></td>
+    <td><center>No</center></td>
+    <td>The desired image height. Uses actual image height if not specified.</td>
+</tr>
+<tr>
+    <td><code>PixelArea</code></td>
+    <td><center>VECTOR4</center></td>
+    <td><center>No</center></td>
+    <td>The image area to be displayed. The default value is [0.0, 0.0, 1.0, 1.0].</td>
+</tr>
+<tr>
+    <td><code>wrapModeU</code></td>
+    <td><center>INTEGER or STRING</center></td>
+    <td><center>No</center></td>
+    <td>Wrap mode for the U coordinate.</td>
+</tr>
+<tr>
+    <td><code>wrapModeV</code></td>
+    <td><center>INTEGER or STRING</center></td>
+    <td><center>No</center></td>
+    <td>Wrap mode for the V coordinate.</td>
+</tr>
+</tbody>
+</table>
+
+<p><strong>Usage:</strong></p>
+<pre class="prettyprint">
+PropertyMap imageVisual = new PropertyMap();
+imageVisual.Add( Visual.Property.Type, new PropertyValue( (int)Visual.Type.Image ))
+           .Add( ImageVisualProperty.URL, new PropertyValue( _imageURL ));
+_imageVisual = VisualFactory.Get().CreateVisual( imageVisual );
+
+RegisterVisual( ImageVisualPropertyIndex, _imageVisual );
+
+// Set the image visual depth index
+_imageVisual.DepthIndex = ImageVisualPropertyIndex;
+</pre>
+<h3 id="npatch">N-Patch Image</h3>
+<p>The n-patch image visual renders an n-patch or a 9-patch image. It uses non-quad geometry. Both geometry and texture are cached to reduce memory consumption, if the same n-patch image is used elsewhere.</p>
+<p align="center"><strong>Figure: N-patch image visual</strong></p>
+<p align="center"><img src="images/n-patch-visual.png" alt="N-patch image visual" /></p>
+<p>The visual map for an n-patch image is <code>NPatchVisual</code>.</p>
+
+<h3 id="svg">SVG Image</h3>
+<p>The SVG image visual renders an SVG image into the control's quad. It supports the following features from the <a href="https://www.w3.org/TR/SVGTiny12" target="_blank">SVG Tiny 1.2 Specification</a>:</p>
+
+<ul>
+<li>Basic shapes</li>
+<li>Paths</li>
+<li>Solid color fill</li>
+<li>Gradient color fill</li>
+<li>Solid color stroke</li>
+</ul>
+<p>The following features are not supported:</p>
+<ul>
+<li>Gradient color stroke</li>
+<li>Dash array stroke</li>
+<li>View box</li>
+<li>Text</li>
+<li>Clip path</li>
+</ul>
+<p align="center"><strong>Figure: SVG image visual</strong></p>
+<p align="center"><img src="images/svg-visual.svg" alt="SVG image visual" width="300"/></p>
+<p>The visual map for an SVG image is <code>SVGVisual</code>.</p>
+
+<h3 id="animated">Animated Image</h3>
+<p>The animated image visual renders an animated image into the control's quad. Currently, only the GIF format is supported,
+but an API to enable multiple images to be displayed sequentially is being developed.</p>
+<p align="center"><strong>Figure: Animated image visual</strong></p>
+<p align="center"><img src="images/animated-image-visual.gif" alt="Animated image visual" /></p>
+<p>The visual map for an animated image is <code>AnimatedImageVisual</code>.</p>
+
+<h2 id="bordervisual">Border Visual</h2>
+<p>The border visual renders a solid color as an internal border to the control's quad.</p>
+<p align="center"><strong>Figure: Border visual</strong></p>
+<p align="center"><img src="images/border-visual.png" alt="Border visual" /></p>
+<p>The following table lists the supported <code>BorderVisualProperty</code> properties. The visual type is <code>Border</code> and the visual map is <code>BorderVisual</code>.</p>
+
+<p align="center" class="Table"><strong>Table: <code>BorderVisualProperty</code> properties</strong></p>
+
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th><center>Type</center></th>
+    <th><center>Required</center></th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>BorderColor</code></td>
+    <td><center>VECTOR4</center></td>
+    <td><center>Yes</center></td>
+    <td>The border color.</td>
+</tr>
+<tr>
+    <td><code>BorderSize</code></td>
+    <td><center>FLOAT</center></td>
+    <td><center>Yes</center></td>
+    <td>The border width, in pixels.</td>
+</tr>
+<tr>
+    <td><code>AntiAliasing</code></td>
+    <td><center>BOOLEAN</center></td>
+    <td><center>No</center></td>
+    <td>Whether border anti-aliasing is required.</td>
+</tr>
+</tbody>
+</table>
+
+<p><strong>Usage:</strong></p>
+<p>The following example shows how to use a <code>BorderVisual</code> visual map. The visual is created in the <code>AddVisual()</code> method.</p>
+<pre class="prettyprint">
+private BorderVisual borderVisualMap1;
+
+borderVisualMap1 = new BorderVisual();
+
+borderVisualMap1.Color = Color.Red;
+borderVisualMap1.BorderSize = 5.0f;
+
+borderVisualMap1.Size = new Vector2(100.0f, 100.0f);
+borderVisualMap1.Position = new Vector2(10.0f, 380.0f);
+borderVisualMap1.PositionPolicy = VisualTransformPolicyType.Absolute;
+borderVisualMap1.SizePolicy = VisualTransformPolicyType.Absolute;
+borderVisualMap1.Origin = Visual.AlignType.TopBegin;
+borderVisualMap1.AnchorPoint = Visual.AlignType.TopBegin;
+
+_visualView.AddVisual("borderVisual1", borderVisualMap1);
+</pre>
+
+<h2 id="meshvisual">Mesh Visual</h2>
+<p>The mesh visual renders a mesh using a <code>.obj</code> file, optionally with textures provided by a <code>.mtl</code> file. The mesh is scaled to fit the control.</p>
+<p align="center"><strong>Figure: Mesh visual</strong></p>
+<p align="center"><img src="images/mesh-visual.png" alt="Mesh visual" /></p>
+<p>The following table lists the supported properties. The visual type is <code>Mesh</code> and the visual map is <code>MeshVisual</code>.</p>
+<p align="center" class="Table"><strong>Table: <code>MeshVisualProperty</code> properties</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th>Type</th>
+    <th>Required</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>ObjectURL</code></td>
+    <td>STRING</td>
+    <td>Yes</td>
+    <td>The location of the <code>.obj</code> file.</td>
+</tr>
+<tr>
+    <td><code>MaterialURL</code></td>
+    <td>STRING</td>
+    <td>No</td>
+    <td>The location of the <code>.mtl</code> file. Leave blank for a textureless object.</td>
+</tr>
+<tr>
+    <td><code>TexturesPath</code></td>
+    <td>STRING</td>
+    <td>If using material</td>
+    <td>The path to the directory the textures (including gloss and normal) are stored in.</td>
+</tr>
+<tr>
+    <td><code>ShadingMode</code></td>
+    <td>INTEGER or STRING</td>
+    <td>No</td>
+    <td>The type of the shading mode that the mesh uses.</td>
+</tr>
+<tr>
+    <td><code>UseMipmapping</code></td>
+    <td>BOOLEAN</td>
+    <td>No</td>
+    <td>Whether to use mipmaps for textures. By default, <code>true</code>.</td>
+</tr>
+<tr>
+    <td><code>UseSoftNormals</code></td>
+    <td>BOOLEAN</td>
+    <td>No</td>
+    <td>Whether to average normals at each point to smooth textures. By default, <code>true</code>.</td>
+</tr>
+<tr>
+    <td><code>LightPosition</code></td>
+    <td>VECTOR3</td>
+    <td>No</td>
+    <td>The position, in stage space, of the point light that applies lighting to the model.</td>
+</tr>
+</tbody>
+</table>
+
+
+<p align="center" class="Table"><strong>Table: Shading mode values</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Enumeration value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>TexturelessWithDefuseLighting</code></td> <!--typo?-->
+               <td>Simplest. One color that is lit by ambient and diffuse lighting.</td>
+</tr>
+<tr>
+    <td><code>TexturedWithSpecularLighting</code></td>
+    <td>Uses only the visual image textures provided with specular lighting in addition to ambient and diffuse lighting.</td>
+</tr>
+<tr>
+    <td><code>TexturedWIthDetailedSpecularLIghting</code></td>
+    <td>Uses all textures provided including a gloss, normal, and texture map along with specular, ambient, and diffuse lighting.</td>
+</tr>
+</tbody>
+</table>
+
+<p><strong>Usage:</strong></p>
+<p>The following example shows how to use a <code>MeshVisual</code> visual map. The visual is created in the <code>AddVisual()</code> method.</p>
+<pre class="prettyprint">
+MeshVisual meshVisualMap1 = new MeshVisual();
+
+meshVisualMap1.ObjectURL = resources + "/models/Dino.obj";
+meshVisualMap1.MaterialtURL = resources + "/models/Dino.mtl";
+meshVisualMap1.TexturesPath = resources + "/images/";
+meshVisualMap1.ShadingMode = MeshVisualShadingModeValue.TexturedWithSpecularLighting;
+
+meshVisualMap1.Size = new Size2D(400, 400);
+meshVisualMap1.Position = new Position2D(-50, 600);
+meshVisualMap1.PositionPolicy = VisualTransformPolicyType.Absolute;
+meshVisualMap1.SizePolicy = VisualTransformPolicyType.Absolute;
+meshVisualMap1.Origin = Visual.AlignType.TopBegin;
+meshVisualMap1.AnchorPoint = Visual.AlignType.TopBegin;
+
+_visualView.AddVisual("meshVisual1", meshVisualMap1);
+</pre>
+
+<h2 id="primitivevisual">Primitive Visual</h2>
+<p>The primitive visual renders a simple 3D shape, such as a cube or sphere. The shape is scaled to fit the control. The shapes are generated with clockwise winding and back-face culling on by default.</p>
+<p align="center"><strong>Figure: Primitive visual</strong></p>
+<p align="center"><img src="images/cube.png" alt="Primitive visual" /></p>
+<p>The following table lists the supported properties. The visual type is <code>Primitive</code> and the visual map is <code>PrimitiveVisual</code>.</p>
+
+<p align="center" class="Table"><strong>Table: <code>PrimitiveVisualProperty</code> properties</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th>Type</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Shape</code></td>
+    <td>INTEGER or STRING</td>
+    <td>The specific shape to render.</td>
+</tr>
+<tr>
+    <td><code>mixColor</code></td>
+    <td>VECTOR4</td>
+    <td>The color of the shape.</td>
+</tr>
+<tr>
+    <td><code>Slices</code></td>
+    <td>INTEGER</td>
+    <td>The number of slices as you go around the shape.</td>
+</tr>
+<tr>
+    <td><code>Stacks</code></td>
+    <td>INTEGER</td>
+    <td>The number of stacks as you go down the shape.</td>
+</tr>
+<tr>
+    <td><code>ScaleTopRadius</code></td>
+    <td>FLOAT</td>
+    <td>The scale of the radius of the top circle of a conical frustrum.</td>
+</tr>
+<tr>
+    <td><code>ScaleBottomRadius</code></td>
+    <td>FLOAT</td>
+    <td>The scale of the radius of the bottom circle of a conical frustrum.</td>
+</tr>
+<tr>
+    <td><code>ScaleHeight</code></td>
+    <td>FLOAT</td>
+    <td>The scale of the height of a conic.</td>
+</tr>
+<tr>
+    <td><code>ScaleRadius</code></td>
+    <td>FLOAT</td>
+    <td>The scale of the radius of a cylinder.</td>
+</tr>
+<tr>
+    <td><code>ScaleDimensions</code></td>
+    <td>VECTOR3</td>
+    <td>The dimensions of a cuboid. Scales in the same fashion as a 9-patch image.</td>
+</tr>
+<tr>
+    <td><code>BevelPercentage</code></td>
+    <td>FLOAT</td>
+    <td>Defines how beveled the cuboid is, based on the smallest dimension.</td>
+</tr>
+<tr>
+    <td><code>BevelSmoothness</code></td>
+    <td>FLOAT</td>
+    <td>Defines how smooth the beveled edges are.</td>
+</tr>
+<tr>
+    <td><code>LightPosition</code></td>
+    <td>VECTOR3</td>
+    <td>The position, in stage space, of the point light that applies lighting to the model.</td>
+</tr>
+</tbody>
+</table>
+<ul><li>You can select from 6 <code>shape</code> values, some of which are simplified specializations of another.
+
+<p align="center" class="Table"><strong>Table: Shape values</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Enumeration value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Sphere</code></td>
+    <td>Default.</td>
+</tr>
+<tr>
+    <td><code>ConicalFrustrum</code></td>
+    <td>The area bound between 2 circles (basically, a cone with the tip removed).</td>
+</tr>
+<tr>
+    <td><code>Cone</code></td>
+    <td>Equivalent to a conical frustrum with a top radius of zero.</td>
+</tr>
+<tr>
+    <td><code>Cylinder</code></td>
+    <td>Equivalent to a conical frustrum with equal radii for the top and bottom circles.</td>
+</tr>
+<tr>
+    <td><code>Cube</code></td>
+    <td>Equivalent to a beveled cube with a bevel percentage of 0.</td>
+</tr>
+<tr>
+    <td><code>Octohedron</code></td> <!--typo?-->
+    <td>Equivalent to a beveled cube with a bevel percentage of 1.</td>
+</tr>
+<tr>
+    <td><code>BevelledCube</code></td>
+    <td>A cube/cuboid with all edges flattened to some degree.</td>
+</tr>
+</tbody>
+</table>
+</li></ul>
+<p><strong>Usage:</strong></p>
+<p>The following example shows how to create a primitive visual. The shape is set using the <code>Shape</code> property.</p>
+<pre class="prettyprint">
+public int Shape
+{
+    get
+    {
+        return _shape;
+    }
+    set
+    {
+        _shape = value;
+
+        // Create and register the primitive visual
+        PropertyMap primitiveVisual = new PropertyMap();
+        primitiveVisual.Add( Visual.Property.Type, new PropertyValue( (int)Visual.Type.Primitive ))
+                       .Add( PrimitiveVisualProperty.Shape, new PropertyValue(_shape))
+                       .Add( PrimitiveVisualProperty.BevelPercentage, new PropertyValue(0.3f))
+                       .Add( PrimitiveVisualProperty.BevelSmoothness, new PropertyValue(0.0f))
+                       .Add( PrimitiveVisualProperty.ScaleDimensions, new PropertyValue(new Vector3(1.0f,1.0f,0.3f)))
+                       .Add( PrimitiveVisualProperty.MixColor, new PropertyValue(new Vector4((245.0f/255.0f), (188.0f/255.0f), (73.0f/255.0f), 1.0f)));
+        _primitiveVisual =  VisualFactory.Get().CreateVisual( primitiveVisual );
+        RegisterVisual( PrimitiveVisualPropertyIndex, _primitiveVisual );
+
+        // Set the primitive visual depth index
+        _primitiveVisual.DepthIndex = PrimitiveVisualPropertyIndex;
+    }
+}
+</pre>
+
+<h3>Primitive Visual Examples</h3>
+<ul>
+<li><strong>Sphere:</strong>
+<p align="center"><img src="images/sphere.png" alt="Sphere" /></p>
+</li>
+<li><strong>Conics:</strong>
+<table>
+<thead>
+<tr>
+    <th>Frustrum</th>
+    <th>Cone</th>
+    <th>Cylinder</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><p align="center"><img src="images/conical-frustrum.png" alt="Frustrum" /></p></td>
+    <td><p align="center"><img src="images/cone.png" alt="Cone" /></p></td>
+    <td><p align="center"><img src="images/cylinder.png" alt="Cylinder" /></p></td>
+</tr>
+</tbody>
+</table>
+</li>
+<li><strong>Bevel:</strong>
+
+<p>Bevel percentage ranges from 0.0 to 1.0. It affects the ratio of the outer face widths to the width of the overall cube.</p>
+<table>
+<tbody>
+<tr>
+    <th>0.0 (cube)</th>
+    <th>0.3</th>
+</tr>
+<tr>
+    <td><p align="center"><img src="images/cube.png" alt="Cube" /></p></td>
+    <td><p align="center"><img src="images/bevelled-cube-low.png" alt="Low bevel" /></p></td>
+</tr>
+<tr>
+    <th>0.7</th>
+    <th>1.0 (octahedron)</th>
+</tr>
+<tr>
+    <td><p align="center"><img src="images/bevelled-cube-high.png" alt="High bevel " /></p></td>
+    <td><p align="center"><img src="images/octahedron.png" alt="Octahedron" /></p></td>
+</tr>
+</tbody>
+</table>
+</li>
+<li><strong>Slices:</strong>
+<p>For spheres and conical frustrums, "slices" determine how many divisions there are as you go around the object.</p>
+<p align="center"><img src="images/slices.png" alt="Slice" /></p>
+</li>
+<li><strong>Stacks:</strong>
+<p>For spheres, "stacks" determines how many layers there are as you go down the object.</p>
+<p align="center"><img alt="Stacks" src="images/stacks.png"/></p>
+
+</li>
+</ul>
+<h2 id="wireframevisual">Wireframe Visual</h2>
+<p>The wireframe visual renders a wireframe around a control's quad. It is mainly used for debugging and is the visual that replaces all other visuals when <strong>Visual Debug Rendering</strong> is switched on.</p>
+<p align="center"><strong>Figure: Wireframe visual</strong></p>
+<p align="center"><img src="images/wireframe-visual.png" alt="WIreframe visual" /></p>
+
+<h2 id="textvisual">Text Visual</h2>
+<p>The text visual renders text within a control.</p>
+<p align="center"><strong>Figure: Text visual</strong></p>
+<p align="center"><img src="images/HelloWorld.png" alt="Text visual" /></p>
+<p>The following table lists the supported properties. The visual type is <code>Text</code> and the visual map is <code>TextVisual</code>.</p>
+
+<p align="center" class="Table"><strong>Table: <code>TextVisualProperty</code> properties</strong></p>
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th>Type</th>
+    <th>Required</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Text</code></td>
+    <td>STRING</td>
+    <td>Yes</td>
+    <td>The text to display in UTF-8 format.</td>
+</tr>
+<tr>
+    <td><code>FontFamily</code></td>
+    <td>STRING</td>
+    <td>No</td>
+    <td>The requested font family to use.</td>
+</tr>
+<tr>
+    <td><code>FontStyle</code></td>
+    <td>MAP</td>
+    <td>No</td>
+    <td>The requested font style to use.</td>
+</tr>
+<tr>
+    <td><code>PointSize</code></td>
+    <td>FLOAT</td>
+    <td>Yes</td>
+    <td>The font size in points.</td>
+</tr>
+<tr>
+    <td><code>MultiLine</code></td>
+    <td>BOOLEAN</td>
+    <td>No</td>
+    <td>Whether to use a multi-line layout.</td>
+</tr>
+<tr>
+    <td><code>HorizontalAlignment</code></td>
+    <td>STRING</td>
+    <td>No</td>
+    <td>The line horizontal alignment (<code>BEGIN</code>, <code>CENTER</code>, or <code>END</code>).</td>
+</tr>
+<tr>
+    <td><code>VerticalAlignment</code></td>
+    <td>STRING</td>
+    <td>No</td>
+    <td>The line vertical alignment(<code>TOP</code>, <code>CENTER</code>, or <code>BOTTOM</code>).</td>
+</tr>
+<tr>
+    <td><code>TextColor</code></td>
+    <td>VECTOR4</td>
+    <td>No</td>
+    <td>The text color.</td>
+</tr>
+<tr>
+    <td><code>EnableMarkup</code></td>
+    <td>BOOL</td>
+    <td>No</td>
+    <td>Whether markup processing is enabled.</td>
+</tr>
+</tbody>
+</table>
+<p><strong>Usage:</strong></p>
+<pre class="prettyprint">
+PropertyMap textVisual = new PropertyMap();
+textVisual.Add(Visual.Property.Type, new PropertyValue((int)Visual.Type.Text))
+          .Add(TextVisualProperty.Text, new PropertyValue(_name))
+          .Add(TextVisualProperty.TextColor, new PropertyValue(Color.White))
+          .Add(TextVisualProperty.PointSize, new PropertyValue(7))
+          .Add(TextVisualProperty.HorizontalAlignment, new PropertyValue("CENTER"))
+          .Add(TextVisualProperty.VerticalAlignment, new PropertyValue("CENTER"));
+_textVisual =  VisualFactory.Get().CreateVisual( textVisual );
+RegisterVisual( TextVisualPropertyIndex, _textVisual );
+
+// Set the text visual depth index
+_textVisual.DepthIndex = TextVisualPropertyIndex;
+</pre>
+
+<h2 id="visualtransform">Visual Transform</h2>
+<p>The visual transform map allows you to manipulate the visual layout within a control.</p>
+<p>The <a href="#visualmap">VisualMap</a> class contains properties that control the transformation:</p>
+<ul>
+<li>Transform type
+<p>The <code>VisualTransformPropertyType</code> enumeration specifies all the transform property types.</p>
+<table>
+<thead>
+<tr>
+    <th>Property</th>
+    <th>Type</th>
+    <th>Required</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Offset</code></td>
+    <td>VECTOR2</td>
+    <td>No</td>
+    <td>The visual offset.</td>
+</tr>
+<tr>
+    <td><code>Size</code></td>
+    <td>VECTOR2</td>
+    <td>No</td>
+    <td>The visual size.</td>
+</tr>
+<tr>
+    <td><code>OffsetPolicy</code></td>
+    <td>VECTOR4</td>
+    <td>No</td>
+    <td>Whether the offset components are relative or absolute.</td>
+</tr>
+<tr>
+    <td><code>SizePolicy</code></td>
+    <td>VECTOR4</td>
+    <td>No</td>
+    <td>Whether the size components are relative or absolute.</td>
+</tr>
+<tr>
+    <td><code>Origin</code></td>
+    <td>INTEGER or STRING</td>
+    <td>No</td>
+    <td>The visual's origin point within the control.</td>
+</tr>
+<tr>
+    <td><code>AnchorPoint</code></td>
+    <td>INTEGER or STRING</td>
+    <td>Mo</td>
+    <td>The visual's anchor point within the control.</td>
+</tr>
+</tbody>
+</table>
+</li>
+<li>Transform offset and size policy
+<p>The <code>VisualTransformPolicyType</code> enumeration values specify how to calculate the transform's offset or size.</p>
+<table>
+<thead>
+<tr>
+    <th>Value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>Relative</code></td>
+    <td>Default. The size or offset value represents a ratio of the control's size.</td>
+</tr>
+<tr>
+    <td><code>Absolute</code></td>
+    <td>The size or offset value represents world units (pixels).</td>
+</tr>
+</tbody>
+</table>
+<p>For example, if the <code>offsetPolicy</code> is <code>[RELATIVE, RELATIVE]</code>, the <code>sizePolicy</code> is <code>[ABSOLUTE, ABSOLUTE]</code>, the <code>offset</code> is (0, 0.25), and the <code>size</code> is (20, 20),
+the visual is 20x20 pixels in size, positioned 25% above the center of the control.</p>
+</li>
+<li>Visual alignment
+<p>The <code>AlignType</code> enumeration values specify the visual alignment.</p>
+<table>
+<thead>
+<tr>
+    <th>Value</th>
+    <th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td><code>TopBegin</code></td>
+    <td>Aligns to the top of the vertical axis and the beginning of the horizontal axis (the left or right edge in left-to-right or right-to-left layouts, respectively).</td>
+</tr>
+<tr>
+    <td><code>TopCenter</code></td>
+    <td>Aligns to the top of the vertical axis and the center of the horizontal axis.</td>
+</tr>
+<tr>
+    <td><code>TopEnd</code></td>
+    <td>Aligns to the top of the vertical axis and the end of the horizontal axis (the right or left edge in left-to-right or right-to-left layouts, respectively).</td>
+</tr>
+<tr>
+    <td><code>CenterBegin</code></td>
+    <td>Aligns to the center of the vertical axis and the beginning of the horizontal axis.</td>
+</tr>
+<tr>
+    <td><code>Center</code></td>
+    <td>Aligns to the center of the control.</td>
+</tr>
+<tr>
+    <td><code>CentreEnd</code></td>
+    <td>Aligns to the center of the vertical axis and the end of the horizontal axis.</td>
+</tr>
+<tr>
+    <td><code>BottomEnd</code></td>
+    <td>Aligns to the bottom of the vertical axis and the beginning of the horizontal axis.</td>
+</tr>
+
+<tr><td><code>BottomCentre</code></td>
+    <td>Aligns to the bottom of the vertical axis and the center of the horizontal axis.</td>
+</tr>
+
+<tr><td><code>BottomEnd</code></td>
+    <td>Aligns to the bottom of the vertical axis and the end of the horizontal axis.</td>
+</tr>
+</tbody></table>
+</li>
+</ul>
+<h3 id="visualtransformexample">Visual Transform Example</h3>
+<p>In the following example contact list, each of the contact entries are created using a <code>ContactView</code> custom view. Each <code>ContactView</code> consists of 4 visuals (image, primitive, text, and color).</p>
+<p align="center"><strong>Figure: Contacts list example</strong></p>
+<p align="center"><img src="images/ContactView.png" alt="Contacts list example" /></p>
+All these visuals can be configured using properties: Image URL (Image), Shape (Primitive), Name (Text) and Color. The tap gesture is also enabled on the <code>ContactView</code>. Whenever a <code>ContactView</code> is tapped, the color visual changes to a random color.</p>
+<p>During initial display, the configuration and size of the visuals are set using visual transforms in the <code>OnRelayout()</code> method. The following code shows the transforms for the image visual:</p>
+
+<pre class="prettyprint">
+OnRelayout(Vector2 viewSize, ...)
+
+// Configure the image visual transform and size
+PropertyMap imageVisualTransform = new PropertyMap();
+imageVisualTransform.Add((int)VisualTransformPropertyType.Offset, new PropertyValue(new Vector2(10.0f, 0.0f)))
+                    .Add((int)VisualTransformPropertyType.OffsetPolicy, new PropertyValue(new Vector2((int)VisualTransformPolicyType.Absolute, (int)VisualTransformPolicyType.Absolute)))
+                    .Add((int)VisualTransformPropertyType.SizePolicy, new PropertyValue(new Vector2((int)VisualTransformPolicyType.Absolute, (int)VisualTransformPolicyType.Absolute)))
+                    .Add((int)VisualTransformPropertyType.Size, new PropertyValue(new Vector2(40.0f, 40.0f)))
+                    .Add((int)VisualTransformPropertyType.Origin, new PropertyValue((int)Visual.AlignType.CenterBegin))
+                    .Add((int)VisualTransformPropertyType.AnchorPoint, new PropertyValue((int)Visual.AlignType.CenterBegin));
+_imageVisual.SetTransformAndSize(imageVisualTransform, size);
+</pre>
+<p>The code for the other visuals in <code>OnRelayout()</code> is similar. Although note that the <code>OffsetPolicy</code> for the text visual is <code>VisualTransformPolicyType.Relative</code>, in both axis.</p>
+
+<h2 id="visualmap">VisualMap Class</h2>
+<p>The <code>VisualMap</code> class is the base class for visuals. It encapsulates various visual properties, such as the size, offset, depth index, shader, mix color, and opacity. It also contains the <a href="#visualtransform">transform map</a> for the visual.</p>
+<p>The following sample code shows part of the derived <code>ColorVisual</code> class:</p>
+<pre class="prettyprint">
+   public class ColorVisual : VisualMap
+
+   private Color _mixColorForColorVisual = null;
+
+   public Color Color
+   {
+       get
+       {
+           return _mixColorForColorVisual;
+       }
+       set
+       {
+           _mixColorForColorVisual = value;
+           UpdateVisual();
+       }
+   }
+</pre>
+<p>The <code>VisualMap</code> class also contains the output visual map, used for visual creation.</p>
+<p>To create a visual from the output map:</p>
+<pre class="prettyprint">
+var colorMap = new ColorVisual{Color=Color.White;};
+var _colorVisual = VisualFactory.Instance.CreateVisual(colorMap.OutputVisualMap);
+RegisterVisual(ColorVisualPropertyIndex, _colorVisual);
+</pre>
+<p>To create a visual from the visual map in the <code>Background</code> property:</p>
+<pre class="prettyprint">
+ColorVisual colorVisualMap1 = new ColorVisual();
+colorVisualMap1.Color = Color.Green;
+_visualView.Background = colorVisualMap1.OutputVisualMap;
+
+window.GetDefaultLayer().Add(_visualView);
+</pre>
+<p>Visual maps have a custom <code>shader</code> property.</p>
+
+<h2 id="visualview">VisualView Class</h2>
+<p>The <code>VisualView</code> class is derived from the <code>CustomView</code> class, and enables the addition of any visual:</p>
+<pre class="prettyprint">
+public class VisualView : CustomView
+</pre>
+<p>To set up a <code>VisualView</code> instance:</p>
+<pre class="prettyprint">
+_visualView = new VisualView();
+_visualView.ParentOrigin = ParentOrigin.TopLeft;
+_visualView.PivotPoint = PivotPoint.TopLeft;
+_visualView.Size2D = new Size2D(window.Size.Width, window.Size.Height);
+</pre>
+<p>The <a href="#gradientvisual">Gradient Visual</a> usage example shows how to add a gradient visual to a <code>VisualView</code> instance.</p>
+
+
+
+<script type="text/javascript" src="scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
\ No newline at end of file