diff --git a/code/ryzom/tools/server/ryzom_ams/ams_lib/translations/fr.ini b/code/ryzom/tools/server/ryzom_ams/ams_lib/translations/fr.ini
index 348b44b69..2c00c81ef 100644
--- a/code/ryzom/tools/server/ryzom_ams/ams_lib/translations/fr.ini
+++ b/code/ryzom/tools/server/ryzom_ams/ams_lib/translations/fr.ini
@@ -4,5 +4,18 @@
[register]
title = "RYZOM base dans ENREGISTREMENT DU JEU"
welcome_message = "Bienvenue! S'il vous plaît remplissez les champs ci-dessous pour obtenir votre nouveau compte de base de Ryzom:"
+
username_tag = "Nom d'utilisateur désiré:"
-username_tooltip = "5-12 caractères et de chiffres minuscules. Le login (nom d'utilisateur) que vous créez ici sera votre nom de connexion. Le nom de vos personnages de jeu sera choisi plus tard."
\ No newline at end of file
+username_tooltip = "5-12 caractères et de chiffres minuscules. Le login (nom d'utilisateur) que vous créez ici sera votre nom de connexion. Le nom de vos personnages de jeu sera choisi plus tard."
+
+password_tag = "désiré Mot de passe:"
+password_message = "mot de passe doit être 5-20 caractères."
+
+cpassword_tag = "Confirmer le mot de passe:"
+cpassword_message = "Retapez votre mot de passe"
+
+email_tag = "Adresse de courriel (pour qui un email de confirmation vous sera envoyé):"
+email_message = "Veuillez vérifier que l'adresse e-mail que vous entrez ici est valable et restera valable à l'avenir. Elle ne sera utilisée que pour gérer votre compte de base de Ryzom."
+
+tac_tag = "OUI, j'accepte les termes de service."
+tac_message = "Vous devez accepter les Conditions d'utilisation."
diff --git a/code/ryzom/tools/server/ryzom_ams/www/config.php b/code/ryzom/tools/server/ryzom_ams/www/config.php
index db8e7a126..db2571b3a 100644
--- a/code/ryzom/tools/server/ryzom_ams/www/config.php
+++ b/code/ryzom/tools/server/ryzom_ams/www/config.php
@@ -22,3 +22,5 @@ $AMS_TRANS = $AMS_LIB . '/translations';
$AMS_CACHEDIR = $AMS_LIB . '/cache';
$DEFAULT_LANGUAGE = 'en';
+
+$SITEBASE = dirname( __FILE__ ) . '/html/' ;
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/README.md b/code/ryzom/tools/server/ryzom_ams/www/html/README.md
new file mode 100644
index 000000000..b539a2627
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/README.md
@@ -0,0 +1,10 @@
+Charisma
+========
+
+#### free, premium quality, responsive, multiple skin admin template.
+
+I have created Charisma to ease the repeat work I have to do on my projects. Now I re-use Charisma as a base for my admin panel work and I am sharing it with you :)
+
+[See Live Demo](http://usman.it/themes/charisma/ "")
+
+Please visit [http://usman.it/free-responsive-admin-template](http://usman.it/free-responsive-admin-template "") for more information.
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/blank.php b/code/ryzom/tools/server/ryzom_ams/www/html/blank.php
new file mode 100644
index 000000000..e6d4b3268
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/blank.php
@@ -0,0 +1,33 @@
+
+
+
+
Thank you for using the template. If you have any questions that are beyond the scope of this file, please feel free to ask on the comment section of the article page, but there is no warranty.
+
+Please share the template on your social network.
+
+Apart from this doc there is a live preview with examples and also the code is commented for your convenience.
+
+
Please note: when you access it from a server like localhost, by default php-version is served even though you browse using .html extension, remove .htaccess file if you need HTML files to be served.
+
+Thanks.
+
Intro
+
Charisma is a fully featured, responsive admin template based on Bootstrap from Twitter, which comes with 9 different themes to suite your style and application type. It is featured with many plugins and UI elements to ease your work. It works on all major browsers and optimizes itself for tablets and mobile phones.
+
+
+
Features
+
+
9 different themes
+
Fully responsive, optimized UI for tablets and mobile phones
+
Based on Bootstrap, jQuery UI can be also used without hassle
+
HTML5 valid and CSS3, though compatible with HTML4, works on IE8+
+ Without Twitter Bootstrap this template won't be possible, I am grateful to all the jQuery plugin authors, Opa Library for icons and Bootswatch for skins which are modified.
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.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:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
Instead of making every icon an extra request, we've compiled them into a sprite—a bunch of images in one file that uses CSS to position the images with background-position. This is the same method we use on Twitter.com and it has worked well for us.
+
All icons classes are prefixed with .icon- for proper namespacing and scoping, much like our other components. This will help avoid conflicts with other tools.
+
+
+
How to use
+
Bootstrap uses an <i> tag for all icons, but they have no case class—only a shared prefix. To use, place the following code just about anywhere:
+
<i class="icon-search"></i>
+
There are also styles available for inverted (white) icons, made ready with one extra class:
+
<i class="icon-search icon-white"></i>
+
In dark themes (Cyborg and Slate) normal icons become white and icon-white become black.
+
There are 140 classes to choose from for your icons. Just add an <i> tag with the right classes and you're set. You can find the full list in sprites.less or right here in this document.
+
+ Heads up!
+ When using beside strings of text, as in buttons or nav links, be sure to leave a space after the <i> tag for proper spacing.
+
+
+
+
Use cases
+
Icons are great, but where would one use them? Here are a few ideas:
+
+
As visuals for your sidebar navigation
+
For a purely icon-driven navigation
+
For buttons to help convey the meaning of an action
+
With links to share context on a user's destination
+
+
Essentially, anywhere you can put an <i> tag, you can put an icon.
+
+
+
+
Examples
+
Use them in buttons, button groups for a toolbar, navigation, or prepended form inputs.
Default icon set has gray style suitable for white and light backgrounds, but a number of functional classes can be applied for different icon color styles.
+ These classes include a 5-color (blue, green, red, yellow and gray) .icon-color class, a black .icon-black class, a white .icon-white class, and a dark-gray .icon-darkgray class.
+
+ Note: place your cursor on the chosen icon image to see its class.
+
+
+
+
Default Icon Sets
+
Default icon classes .icon or .icon32 are best suitable for white and light backgrounds.
+
16x16 pixels icon set
+
Set .icon class for 16x16 pixels icon followed by a class corresponding to the chosen image.
+
<span class="icon icon-home"/>
+
+
32x32 pixels icon set
Set .icon32 class for 32x32 pixels icon followed by a class corresponding to the chosen image.
<span class="icon32 icon-user"/>
Special class for the whole section
To use gray icon set for the whole section set .icons-gray class on the parent element.
Its a live demo of the template. I have created Charisma to ease the repeat work I have to do on my projects. Now I re-use Charisma as a base for my admin panel work and I am sharing it with you :)
+
All pages in the menu are functional, take a look at all, please share this with your followers.
Its a fully featured, responsive template for your admin panel. Its optimized for tablet and mobile phones. Scan the QR code below to view it in your mobile device.
+
+
+
Custom small text
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur bibendum ornare dolor.
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur bibendum ornare dolor, quis ullamcorper ligula sodales at. Nulla tellus elit, varius non commodo eget, mattis vel eros. In sed ornare nulla. Donec consectetur, velit a pharetra ultricies, diam lorem lacinia risus, ac commodo orci erat eu massa. Sed sit amet nulla ipsum. Donec felis mauris, vulputate sed tempor at, aliquam a ligula. Pellentesque non pulvinar nisi.
+
+
+
Messages small text
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur bibendum ornare dolor, quis ullamcorper ligula sodales at. Nulla tellus elit, varius non commodo eget, mattis vel eros. In sed ornare nulla. Donec consectetur, velit a pharetra ultricies, diam lorem lacinia risus, ac commodo orci erat eu massa. Sed sit amet nulla ipsum. Donec felis mauris, vulputate sed tempor at, aliquam a ligula. Pellentesque non pulvinar nisi.
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur bibendum ornare dolor.
+
+
+
+
+
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/index_old.php b/code/ryzom/tools/server/ryzom_ams/www/html/index_old.php
new file mode 100644
index 000000000..9556f50c7
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/index_old.php
@@ -0,0 +1,20 @@
+ (children.length - 1) || pos < 0) return
+
+ if (this.sliding) {
+ return this.$element.one('slid', function () {
+ that.to(pos)
+ })
+ }
+
+ if (activePos == pos) {
+ return this.pause().cycle()
+ }
+
+ return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
+ }
+
+ , pause: function (e) {
+ if (!e) this.paused = true
+ clearInterval(this.interval)
+ this.interval = null
+ return this
+ }
+
+ , next: function () {
+ if (this.sliding) return
+ return this.slide('next')
+ }
+
+ , prev: function () {
+ if (this.sliding) return
+ return this.slide('prev')
+ }
+
+ , slide: function (type, next) {
+ var $active = this.$element.find('.active')
+ , $next = next || $active[type]()
+ , isCycling = this.interval
+ , direction = type == 'next' ? 'left' : 'right'
+ , fallback = type == 'next' ? 'first' : 'last'
+ , that = this
+ , e = $.Event('slide')
+
+ this.sliding = true
+
+ isCycling && this.pause()
+
+ $next = $next.length ? $next : this.$element.find('.item')[fallback]()
+
+ if ($next.hasClass('active')) return
+
+ if ($.support.transition && this.$element.hasClass('slide')) {
+ this.$element.trigger(e)
+ if (e.isDefaultPrevented()) return
+ $next.addClass(type)
+ $next[0].offsetWidth // force reflow
+ $active.addClass(direction)
+ $next.addClass(direction)
+ this.$element.one($.support.transition.end, function () {
+ $next.removeClass([type, direction].join(' ')).addClass('active')
+ $active.removeClass(['active', direction].join(' '))
+ that.sliding = false
+ setTimeout(function () { that.$element.trigger('slid') }, 0)
+ })
+ } else {
+ this.$element.trigger(e)
+ if (e.isDefaultPrevented()) return
+ $active.removeClass('active')
+ $next.addClass('active')
+ this.sliding = false
+ this.$element.trigger('slid')
+ }
+
+ isCycling && this.cycle()
+
+ return this
+ }
+
+ }
+
+
+ /* CAROUSEL PLUGIN DEFINITION
+ * ========================== */
+
+ $.fn.carousel = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('carousel')
+ , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
+ if (!data) $this.data('carousel', (data = new Carousel(this, options)))
+ if (typeof option == 'number') data.to(option)
+ else if (typeof option == 'string' || (option = options.slide)) data[option]()
+ else if (options.interval) data.cycle()
+ })
+ }
+
+ $.fn.carousel.defaults = {
+ interval: 5000
+ , pause: 'hover'
+ }
+
+ $.fn.carousel.Constructor = Carousel
+
+
+ /* CAROUSEL DATA-API
+ * ================= */
+
+ $(function () {
+ $('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
+ var $this = $(this), href
+ , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
+ , options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())
+ $target.carousel(options)
+ e.preventDefault()
+ })
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-collapse.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-collapse.js
new file mode 100644
index 000000000..fbc915b9f
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-collapse.js
@@ -0,0 +1,157 @@
+/* =============================================================
+ * bootstrap-collapse.js v2.0.4
+ * http://twitter.github.com/bootstrap/javascript.html#collapse
+ * =============================================================
+ * Copyright 2012 Twitter, 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.
+ * ============================================================ */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* COLLAPSE PUBLIC CLASS DEFINITION
+ * ================================ */
+
+ var Collapse = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, $.fn.collapse.defaults, options)
+
+ if (this.options.parent) {
+ this.$parent = $(this.options.parent)
+ }
+
+ this.options.toggle && this.toggle()
+ }
+
+ Collapse.prototype = {
+
+ constructor: Collapse
+
+ , dimension: function () {
+ var hasWidth = this.$element.hasClass('width')
+ return hasWidth ? 'width' : 'height'
+ }
+
+ , show: function () {
+ var dimension
+ , scroll
+ , actives
+ , hasData
+
+ if (this.transitioning) return
+
+ dimension = this.dimension()
+ scroll = $.camelCase(['scroll', dimension].join('-'))
+ actives = this.$parent && this.$parent.find('> .accordion-group > .in')
+
+ if (actives && actives.length) {
+ hasData = actives.data('collapse')
+ if (hasData && hasData.transitioning) return
+ actives.collapse('hide')
+ hasData || actives.data('collapse', null)
+ }
+
+ this.$element[dimension](0)
+ this.transition('addClass', $.Event('show'), 'shown')
+ this.$element[dimension](this.$element[0][scroll])
+ }
+
+ , hide: function () {
+ var dimension
+ if (this.transitioning) return
+ dimension = this.dimension()
+ this.reset(this.$element[dimension]())
+ this.transition('removeClass', $.Event('hide'), 'hidden')
+ this.$element[dimension](0)
+ }
+
+ , reset: function (size) {
+ var dimension = this.dimension()
+
+ this.$element
+ .removeClass('collapse')
+ [dimension](size || 'auto')
+ [0].offsetWidth
+
+ this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
+
+ return this
+ }
+
+ , transition: function (method, startEvent, completeEvent) {
+ var that = this
+ , complete = function () {
+ if (startEvent.type == 'show') that.reset()
+ that.transitioning = 0
+ that.$element.trigger(completeEvent)
+ }
+
+ this.$element.trigger(startEvent)
+
+ if (startEvent.isDefaultPrevented()) return
+
+ this.transitioning = 1
+
+ this.$element[method]('in')
+
+ $.support.transition && this.$element.hasClass('collapse') ?
+ this.$element.one($.support.transition.end, complete) :
+ complete()
+ }
+
+ , toggle: function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ }
+
+ }
+
+
+ /* COLLAPSIBLE PLUGIN DEFINITION
+ * ============================== */
+
+ $.fn.collapse = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('collapse')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('collapse', (data = new Collapse(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.collapse.defaults = {
+ toggle: true
+ }
+
+ $.fn.collapse.Constructor = Collapse
+
+
+ /* COLLAPSIBLE DATA-API
+ * ==================== */
+
+ $(function () {
+ $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
+ var $this = $(this), href
+ , target = $this.attr('data-target')
+ || e.preventDefault()
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
+ , option = $(target).data('collapse') ? 'toggle' : $this.data()
+ $(target).collapse(option)
+ })
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-dropdown.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-dropdown.js
new file mode 100644
index 000000000..454a9684b
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-dropdown.js
@@ -0,0 +1,100 @@
+/* ============================================================
+ * bootstrap-dropdown.js v2.0.4
+ * http://twitter.github.com/bootstrap/javascript.html#dropdowns
+ * ============================================================
+ * Copyright 2012 Twitter, 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.
+ * ============================================================ */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* DROPDOWN CLASS DEFINITION
+ * ========================= */
+
+ var toggle = '[data-toggle="dropdown"]'
+ , Dropdown = function (element) {
+ var $el = $(element).on('click.dropdown.data-api', this.toggle)
+ $('html').on('click.dropdown.data-api', function () {
+ $el.parent().removeClass('open')
+ })
+ }
+
+ Dropdown.prototype = {
+
+ constructor: Dropdown
+
+ , toggle: function (e) {
+ var $this = $(this)
+ , $parent
+ , selector
+ , isActive
+
+ if ($this.is('.disabled, :disabled')) return
+
+ selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ $parent = $(selector)
+ $parent.length || ($parent = $this.parent())
+
+ isActive = $parent.hasClass('open')
+
+ clearMenus()
+
+ if (!isActive) $parent.toggleClass('open')
+
+ return false
+ }
+
+ }
+
+ function clearMenus() {
+ $(toggle).parent().removeClass('open')
+ }
+
+
+ /* DROPDOWN PLUGIN DEFINITION
+ * ========================== */
+
+ $.fn.dropdown = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('dropdown')
+ if (!data) $this.data('dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ $.fn.dropdown.Constructor = Dropdown
+
+
+ /* APPLY TO STANDARD DROPDOWN ELEMENTS
+ * =================================== */
+
+ $(function () {
+ $('html').on('click.dropdown.data-api', clearMenus)
+ $('body')
+ .on('click.dropdown', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-modal.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-modal.js
new file mode 100644
index 000000000..38fd0c846
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-modal.js
@@ -0,0 +1,218 @@
+/* =========================================================
+ * bootstrap-modal.js v2.0.4
+ * http://twitter.github.com/bootstrap/javascript.html#modals
+ * =========================================================
+ * Copyright 2012 Twitter, 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.
+ * ========================================================= */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* MODAL CLASS DEFINITION
+ * ====================== */
+
+ var Modal = function (content, options) {
+ this.options = options
+ this.$element = $(content)
+ .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
+ }
+
+ Modal.prototype = {
+
+ constructor: Modal
+
+ , toggle: function () {
+ return this[!this.isShown ? 'show' : 'hide']()
+ }
+
+ , show: function () {
+ var that = this
+ , e = $.Event('show')
+
+ this.$element.trigger(e)
+
+ if (this.isShown || e.isDefaultPrevented()) return
+
+ $('body').addClass('modal-open')
+
+ this.isShown = true
+
+ escape.call(this)
+ backdrop.call(this, function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
+
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(document.body) //don't move modals dom position
+ }
+
+ that.$element
+ .show()
+
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
+
+ that.$element.addClass('in')
+
+ transition ?
+ that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
+ that.$element.trigger('shown')
+
+ })
+ }
+
+ , hide: function (e) {
+ e && e.preventDefault()
+
+ var that = this
+
+ e = $.Event('hide')
+
+ this.$element.trigger(e)
+
+ if (!this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = false
+
+ $('body').removeClass('modal-open')
+
+ escape.call(this)
+
+ this.$element.removeClass('in')
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ hideWithTransition.call(this) :
+ hideModal.call(this)
+ }
+
+ }
+
+
+ /* MODAL PRIVATE METHODS
+ * ===================== */
+
+ function hideWithTransition() {
+ var that = this
+ , timeout = setTimeout(function () {
+ that.$element.off($.support.transition.end)
+ hideModal.call(that)
+ }, 500)
+
+ this.$element.one($.support.transition.end, function () {
+ clearTimeout(timeout)
+ hideModal.call(that)
+ })
+ }
+
+ function hideModal(that) {
+ this.$element
+ .hide()
+ .trigger('hidden')
+
+ backdrop.call(this)
+ }
+
+ function backdrop(callback) {
+ var that = this
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
+
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate
+
+ this.$backdrop = $('')
+ .appendTo(document.body)
+
+ if (this.options.backdrop != 'static') {
+ this.$backdrop.click($.proxy(this.hide, this))
+ }
+
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+
+ this.$backdrop.addClass('in')
+
+ doAnimate ?
+ this.$backdrop.one($.support.transition.end, callback) :
+ callback()
+
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in')
+
+ $.support.transition && this.$element.hasClass('fade')?
+ this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
+ removeBackdrop.call(this)
+
+ } else if (callback) {
+ callback()
+ }
+ }
+
+ function removeBackdrop() {
+ this.$backdrop.remove()
+ this.$backdrop = null
+ }
+
+ function escape() {
+ var that = this
+ if (this.isShown && this.options.keyboard) {
+ $(document).on('keyup.dismiss.modal', function ( e ) {
+ e.which == 27 && that.hide()
+ })
+ } else if (!this.isShown) {
+ $(document).off('keyup.dismiss.modal')
+ }
+ }
+
+
+ /* MODAL PLUGIN DEFINITION
+ * ======================= */
+
+ $.fn.modal = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('modal')
+ , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
+ if (!data) $this.data('modal', (data = new Modal(this, options)))
+ if (typeof option == 'string') data[option]()
+ else if (options.show) data.show()
+ })
+ }
+
+ $.fn.modal.defaults = {
+ backdrop: true
+ , keyboard: true
+ , show: true
+ }
+
+ $.fn.modal.Constructor = Modal
+
+
+ /* MODAL DATA-API
+ * ============== */
+
+ $(function () {
+ $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
+ var $this = $(this), href
+ , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
+ , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
+
+ e.preventDefault()
+ $target.modal(option)
+ })
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-popover.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-popover.js
new file mode 100644
index 000000000..39fbe358e
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-popover.js
@@ -0,0 +1,98 @@
+/* ===========================================================
+ * bootstrap-popover.js v2.0.4
+ * http://twitter.github.com/bootstrap/javascript.html#popovers
+ * ===========================================================
+ * Copyright 2012 Twitter, 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.
+ * =========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* POPOVER PUBLIC CLASS DEFINITION
+ * =============================== */
+
+ var Popover = function ( element, options ) {
+ this.init('popover', element, options)
+ }
+
+
+ /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
+ ========================================== */
+
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
+
+ constructor: Popover
+
+ , setContent: function () {
+ var $tip = this.tip()
+ , title = this.getTitle()
+ , content = this.getContent()
+
+ $tip.find('.popover-title')[this.isHTML(title) ? 'html' : 'text'](title)
+ $tip.find('.popover-content > *')[this.isHTML(content) ? 'html' : 'text'](content)
+
+ $tip.removeClass('fade top bottom left right in')
+ }
+
+ , hasContent: function () {
+ return this.getTitle() || this.getContent()
+ }
+
+ , getContent: function () {
+ var content
+ , $e = this.$element
+ , o = this.options
+
+ content = $e.attr('data-content')
+ || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
+
+ return content
+ }
+
+ , tip: function () {
+ if (!this.$tip) {
+ this.$tip = $(this.options.template)
+ }
+ return this.$tip
+ }
+
+ })
+
+
+ /* POPOVER PLUGIN DEFINITION
+ * ======================= */
+
+ $.fn.popover = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('popover')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('popover', (data = new Popover(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.popover.Constructor = Popover
+
+ $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
+ placement: 'right'
+ , content: ''
+ , template: '
'
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-scrollspy.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-scrollspy.js
new file mode 100644
index 000000000..dce371812
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-scrollspy.js
@@ -0,0 +1,151 @@
+/* =============================================================
+ * bootstrap-scrollspy.js v2.0.4
+ * http://twitter.github.com/bootstrap/javascript.html#scrollspy
+ * =============================================================
+ * Copyright 2012 Twitter, 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.
+ * ============================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* SCROLLSPY CLASS DEFINITION
+ * ========================== */
+
+ function ScrollSpy( element, options) {
+ var process = $.proxy(this.process, this)
+ , $element = $(element).is('body') ? $(window) : $(element)
+ , href
+ this.options = $.extend({}, $.fn.scrollspy.defaults, options)
+ this.$scrollElement = $element.on('scroll.scroll.data-api', process)
+ this.selector = (this.options.target
+ || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
+ || '') + ' .nav li > a'
+ this.$body = $('body')
+ this.refresh()
+ this.process()
+ }
+
+ ScrollSpy.prototype = {
+
+ constructor: ScrollSpy
+
+ , refresh: function () {
+ var self = this
+ , $targets
+
+ this.offsets = $([])
+ this.targets = $([])
+
+ $targets = this.$body
+ .find(this.selector)
+ .map(function () {
+ var $el = $(this)
+ , href = $el.data('target') || $el.attr('href')
+ , $href = /^#\w/.test(href) && $(href)
+ return ( $href
+ && href.length
+ && [[ $href.position().top, href ]] ) || null
+ })
+ .sort(function (a, b) { return a[0] - b[0] })
+ .each(function () {
+ self.offsets.push(this[0])
+ self.targets.push(this[1])
+ })
+ }
+
+ , process: function () {
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
+ , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
+ , maxScroll = scrollHeight - this.$scrollElement.height()
+ , offsets = this.offsets
+ , targets = this.targets
+ , activeTarget = this.activeTarget
+ , i
+
+ if (scrollTop >= maxScroll) {
+ return activeTarget != (i = targets.last()[0])
+ && this.activate ( i )
+ }
+
+ for (i = offsets.length; i--;) {
+ activeTarget != targets[i]
+ && scrollTop >= offsets[i]
+ && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
+ && this.activate( targets[i] )
+ }
+ }
+
+ , activate: function (target) {
+ var active
+ , selector
+
+ this.activeTarget = target
+
+ $(this.selector)
+ .parent('.active')
+ .removeClass('active')
+
+ selector = this.selector
+ + '[data-target="' + target + '"],'
+ + this.selector + '[href="' + target + '"]'
+
+ active = $(selector)
+ .parent('li')
+ .addClass('active')
+
+ if (active.parent('.dropdown-menu')) {
+ active = active.closest('li.dropdown').addClass('active')
+ }
+
+ active.trigger('activate')
+ }
+
+ }
+
+
+ /* SCROLLSPY PLUGIN DEFINITION
+ * =========================== */
+
+ $.fn.scrollspy = function ( option ) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('scrollspy')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.scrollspy.Constructor = ScrollSpy
+
+ $.fn.scrollspy.defaults = {
+ offset: 10
+ }
+
+
+ /* SCROLLSPY DATA-API
+ * ================== */
+
+ $(function () {
+ $('[data-spy="scroll"]').each(function () {
+ var $spy = $(this)
+ $spy.scrollspy($spy.data())
+ })
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-tab.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-tab.js
new file mode 100644
index 000000000..d87f35099
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-tab.js
@@ -0,0 +1,135 @@
+/* ========================================================
+ * bootstrap-tab.js v2.0.4
+ * http://twitter.github.com/bootstrap/javascript.html#tabs
+ * ========================================================
+ * Copyright 2012 Twitter, 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.
+ * ======================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* TAB CLASS DEFINITION
+ * ==================== */
+
+ var Tab = function ( element ) {
+ this.element = $(element)
+ }
+
+ Tab.prototype = {
+
+ constructor: Tab
+
+ , show: function () {
+ var $this = this.element
+ , $ul = $this.closest('ul:not(.dropdown-menu)')
+ , selector = $this.attr('data-target')
+ , previous
+ , $target
+ , e
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ if ( $this.parent('li').hasClass('active') ) return
+
+ previous = $ul.find('.active a').last()[0]
+
+ e = $.Event('show', {
+ relatedTarget: previous
+ })
+
+ $this.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ $target = $(selector)
+
+ this.activate($this.parent('li'), $ul)
+ this.activate($target, $target.parent(), function () {
+ $this.trigger({
+ type: 'shown'
+ , relatedTarget: previous
+ })
+ })
+ }
+
+ , activate: function ( element, container, callback) {
+ var $active = container.find('> .active')
+ , transition = callback
+ && $.support.transition
+ && $active.hasClass('fade')
+
+ function next() {
+ $active
+ .removeClass('active')
+ .find('> .dropdown-menu > .active')
+ .removeClass('active')
+
+ element.addClass('active')
+
+ if (transition) {
+ element[0].offsetWidth // reflow for transition
+ element.addClass('in')
+ } else {
+ element.removeClass('fade')
+ }
+
+ if ( element.parent('.dropdown-menu') ) {
+ element.closest('li.dropdown').addClass('active')
+ }
+
+ callback && callback()
+ }
+
+ transition ?
+ $active.one($.support.transition.end, next) :
+ next()
+
+ $active.removeClass('in')
+ }
+ }
+
+
+ /* TAB PLUGIN DEFINITION
+ * ===================== */
+
+ $.fn.tab = function ( option ) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('tab')
+ if (!data) $this.data('tab', (data = new Tab(this)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.tab.Constructor = Tab
+
+
+ /* TAB DATA-API
+ * ============ */
+
+ $(function () {
+ $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
+ e.preventDefault()
+ $(this).tab('show')
+ })
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-toggle.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-toggle.js
new file mode 100644
index 000000000..dfad8744c
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-toggle.js
@@ -0,0 +1,99 @@
+/**
+ * bootstrap-toggle.js v1.0
+ * http://github.com/Nijikokun/bootstrap-toggle/
+ * --
+ * http://twitter.com/nijikokun
+ * Copyright 2012 Nijiko Yonskai, Goodybag 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.
+ */
+
+!function ($) {
+
+ var Toggle = function (element, options) {
+ var self = this;
+
+ // Collect elements
+ this.$element = $(element)
+ this.$checkbox = this.$element.children('.checkbox')
+ this.options = $.extend({}, $.fn.toggle.defaults, options)
+
+ // Initial Setup from options
+ if(this.options.text.enabled) this.$element.attr('data-enabled', this.options.text.enabled)
+ if(this.options.text.disabled) this.$element.attr('data-disabled', this.options.text.disabled)
+
+ // setup state
+ this.setState(this.$checkbox.is(':checked'))
+
+ // Setup Click
+ this.$element.click(function (e) {
+ if(self.options.onClick) self.options.onClick(e, self.$checkbox.is(':checked'))
+ self.toggle()
+ });
+ }
+
+ Toggle.prototype.setState = function (state) {
+ // change checkbox state
+ this.$checkbox.attr('checked', state)
+
+ if(state) {
+ this.$element.removeClass('disabled')
+ if(this.options.style.disabled)
+ this.$element.removeClass('disabled-' + this.options.style.disabled)
+ if(this.options.style.enabled)
+ this.$element.addClass(this.options.style.enabled)
+ } else {
+ this.$element.addClass('disabled')
+ if(this.options.style.enabled)
+ this.$element.removeClass(this.options.style.enabled)
+ if(this.options.style.disabled)
+ this.$element.addClass('disabled-' + this.options.style.disabled)
+ }
+ }
+
+ Toggle.prototype.on = function () {
+ this.setState(true)
+ }
+
+ Toggle.prototype.off = function () {
+ this.setState(false)
+ }
+
+ Toggle.prototype.toggle = function () {
+ var status = this.$checkbox.is(':checked')
+
+ // Toggle status
+ this.setState(!status)
+ }
+
+ /*
+ * Toggle Definition
+ */
+ $.fn.toggle = function (options) {
+ return new Toggle(this, typeof options == 'object' ? options : {})
+ }
+
+ $.fn.toggle.defaults = {
+ onClick: function () {},
+ text: {
+ enabled: false,
+ disabled: false
+ },
+ style: {
+ enabled: false,
+ disabled: false
+ }
+ }
+
+ $.fn.toggle.Constructor = Toggle
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-tooltip.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-tooltip.js
new file mode 100644
index 000000000..b476f1c4e
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-tooltip.js
@@ -0,0 +1,275 @@
+/* ===========================================================
+ * bootstrap-tooltip.js v2.0.4
+ * http://twitter.github.com/bootstrap/javascript.html#tooltips
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ===========================================================
+ * Copyright 2012 Twitter, 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.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* TOOLTIP PUBLIC CLASS DEFINITION
+ * =============================== */
+
+ var Tooltip = function (element, options) {
+ this.init('tooltip', element, options)
+ }
+
+ Tooltip.prototype = {
+
+ constructor: Tooltip
+
+ , init: function (type, element, options) {
+ var eventIn
+ , eventOut
+
+ this.type = type
+ this.$element = $(element)
+ this.options = this.getOptions(options)
+ this.enabled = true
+
+ if (this.options.trigger != 'manual') {
+ eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
+ eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
+ this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
+ this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
+ }
+
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+ this.fixTitle()
+ }
+
+ , getOptions: function (options) {
+ options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
+
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay
+ , hide: options.delay
+ }
+ }
+
+ return options
+ }
+
+ , enter: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+ if (!self.options.delay || !self.options.delay.show) return self.show()
+
+ clearTimeout(this.timeout)
+ self.hoverState = 'in'
+ this.timeout = setTimeout(function() {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ }
+
+ , leave: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+ if (this.timeout) clearTimeout(this.timeout)
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+ self.hoverState = 'out'
+ this.timeout = setTimeout(function() {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ }
+
+ , show: function () {
+ var $tip
+ , inside
+ , pos
+ , actualWidth
+ , actualHeight
+ , placement
+ , tp
+
+ if (this.hasContent() && this.enabled) {
+ $tip = this.tip()
+ this.setContent()
+
+ if (this.options.animation) {
+ $tip.addClass('fade')
+ }
+
+ placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement
+
+ inside = /in/.test(placement)
+
+ $tip
+ .remove()
+ .css({ top: 0, left: 0, display: 'block' })
+ .appendTo(inside ? this.$element : document.body)
+
+ pos = this.getPosition(inside)
+
+ actualWidth = $tip[0].offsetWidth
+ actualHeight = $tip[0].offsetHeight
+
+ switch (inside ? placement.split(' ')[1] : placement) {
+ case 'bottom':
+ tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
+ break
+ case 'top':
+ tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
+ break
+ case 'left':
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
+ break
+ case 'right':
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
+ break
+ }
+
+ $tip
+ .css(tp)
+ .addClass(placement)
+ .addClass('in')
+ }
+ }
+
+ , isHTML: function(text) {
+ // html string detection logic adapted from jQuery
+ return typeof text != 'string'
+ || ( text.charAt(0) === "<"
+ && text.charAt( text.length - 1 ) === ">"
+ && text.length >= 3
+ ) || /^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(text)
+ }
+
+ , setContent: function () {
+ var $tip = this.tip()
+ , title = this.getTitle()
+
+ $tip.find('.tooltip-inner')[this.isHTML(title) ? 'html' : 'text'](title)
+ $tip.removeClass('fade in top bottom left right')
+ }
+
+ , hide: function () {
+ var that = this
+ , $tip = this.tip()
+
+ $tip.removeClass('in')
+
+ function removeWithAnimation() {
+ var timeout = setTimeout(function () {
+ $tip.off($.support.transition.end).remove()
+ }, 500)
+
+ $tip.one($.support.transition.end, function () {
+ clearTimeout(timeout)
+ $tip.remove()
+ })
+ }
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ removeWithAnimation() :
+ $tip.remove()
+ }
+
+ , fixTitle: function () {
+ var $e = this.$element
+ if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
+ }
+ }
+
+ , hasContent: function () {
+ return this.getTitle()
+ }
+
+ , getPosition: function (inside) {
+ return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
+ width: this.$element[0].offsetWidth
+ , height: this.$element[0].offsetHeight
+ })
+ }
+
+ , getTitle: function () {
+ var title
+ , $e = this.$element
+ , o = this.options
+
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+
+ return title
+ }
+
+ , tip: function () {
+ return this.$tip = this.$tip || $(this.options.template)
+ }
+
+ , validate: function () {
+ if (!this.$element[0].parentNode) {
+ this.hide()
+ this.$element = null
+ this.options = null
+ }
+ }
+
+ , enable: function () {
+ this.enabled = true
+ }
+
+ , disable: function () {
+ this.enabled = false
+ }
+
+ , toggleEnabled: function () {
+ this.enabled = !this.enabled
+ }
+
+ , toggle: function () {
+ this[this.tip().hasClass('in') ? 'hide' : 'show']()
+ }
+
+ }
+
+
+ /* TOOLTIP PLUGIN DEFINITION
+ * ========================= */
+
+ $.fn.tooltip = function ( option ) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('tooltip')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.tooltip.Constructor = Tooltip
+
+ $.fn.tooltip.defaults = {
+ animation: true
+ , placement: 'top'
+ , selector: false
+ , template: '
'
+ , trigger: 'hover'
+ , title: ''
+ , delay: 0
+ }
+
+}(window.jQuery);
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-tour.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-tour.js
new file mode 100644
index 000000000..0e648460d
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-tour.js
@@ -0,0 +1,226 @@
+// Generated by CoffeeScript 1.3.3
+
+/* ============================================================
+# bootstrap-tour.js v0.1
+# http://pushly.github.com/bootstrap-tour/
+# ==============================================================
+# Copyright 2012 Push.ly
+#
+# 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.
+*/
+
+
+(function() {
+
+ (function($, window) {
+ var Tour, document;
+ document = window.document;
+ Tour = (function() {
+
+ function Tour(options) {
+ var _this = this;
+ this._options = $.extend({
+ afterSetState: function(key, value) {},
+ afterGetState: function(key, value) {}
+ }, options);
+ this._steps = [];
+ this.setCurrentStep();
+ $(document).on("click", ".popover .next", function(e) {
+ e.preventDefault();
+ return _this.next();
+ });
+ $(document).on("click", ".popover .end", function(e) {
+ e.preventDefault();
+ return _this.end();
+ });
+ }
+
+ Tour.prototype.setState = function(key, value) {
+ $.cookie("tour_" + key, value, {
+ expires: 36500,
+ path: '/'
+ });
+ return this._options.afterSetState(key, value);
+ };
+
+ Tour.prototype.getState = function(key) {
+ var value;
+ value = $.cookie("tour_" + key);
+ this._options.afterGetState(key, value);
+ return value;
+ };
+
+ Tour.prototype.addStep = function(step) {
+ return this._steps.push(step);
+ };
+
+ Tour.prototype.getStep = function(i) {
+ return $.extend({
+ path: "",
+ placement: "right",
+ title: "",
+ content: "",
+ next: i + 1,
+ end: i === this._steps.length - 1,
+ animation: true
+ }, this._steps[i]);
+ };
+
+ Tour.prototype.start = function(force) {
+ if (force == null) {
+ force = false;
+ }
+ if (force || !this.ended()) {
+ return this.showStep(this._current);
+ }
+ };
+
+ Tour.prototype.next = function() {
+ this.hideStep(this._current);
+ return this.showNextStep();
+ };
+
+ Tour.prototype.end = function() {
+ this.hideStep(this._current);
+ return this.setState("end", "yes");
+ };
+
+ Tour.prototype.ended = function() {
+ return !!this.getState("end");
+ };
+
+ Tour.prototype.restart = function() {
+ this.setState("current_step", null);
+ this.setState("end", null);
+ this.setCurrentStep(0);
+ return this.start();
+ };
+
+ Tour.prototype.hideStep = function(i) {
+ var step;
+ step = this.getStep(i);
+ if (step.onHide != null) {
+ step.onHide(this);
+ }
+ return $(step.element).popover("hide");
+ };
+
+ Tour.prototype.showStep = function(i) {
+ var endOnClick, step,
+ _this = this;
+ step = this.getStep(i);
+ if (step.element == null) {
+ this.end;
+ return;
+ }
+ this.setCurrentStep(i);
+ if (step.path !== "" && document.location.pathname !== step.path && document.location.pathname.replace(/^.*[\\\/]/, '') !== step.path) {
+ document.location.href = step.path;
+ return;
+ }
+ if ($(step.element).is(":hidden")) {
+ this.showNextStep();
+ return;
+ }
+ endOnClick = step.endOnClick || step.element;
+ $(endOnClick).one("click", function() {
+ return _this.endCurrentStep();
+ });
+ if (step.onShow != null) {
+ step.onShow(this);
+ }
+ return this._showPopover(step, i);
+ };
+
+ Tour.prototype.setCurrentStep = function(value) {
+ if (value != null) {
+ this._current = value;
+ return this.setState("current_step", value);
+ } else {
+ this._current = this.getState("current_step");
+ if (this._current === null || this._current === "null") {
+ return this._current = 0;
+ } else {
+ return this._current = parseInt(this._current);
+ }
+ }
+ };
+
+ Tour.prototype.endCurrentStep = function() {
+ var step;
+ this.hideStep(this._current);
+ step = this.getStep(this._current);
+ return this.setCurrentStep(step.next);
+ };
+
+ Tour.prototype.showNextStep = function() {
+ var step;
+ step = this.getStep(this._current);
+ return this.showStep(step.next);
+ };
+
+ Tour.prototype._showPopover = function(step, i) {
+ var content, tip;
+ content = "" + step.content + "
";
+ if (step.end) {
+ content += "End";
+ } else {
+ content += "Next »End tour
";
+ }
+ $(step.element).popover({
+ placement: step.placement,
+ trigger: "manual",
+ title: step.title,
+ content: content,
+ animation: step.animation
+ }).popover("show");
+ tip = $(step.element).data("popover").tip();
+ this._reposition(tip);
+ return this._scrollIntoView(tip);
+ };
+
+ Tour.prototype._reposition = function(tip) {
+ var offsetBottom, offsetRight, tipOffset;
+ tipOffset = tip.offset();
+ offsetBottom = $(document).outerHeight() - tipOffset.top - $(tip).outerHeight();
+ if (offsetBottom < 0) {
+ tipOffset.top = tipOffset.top + offsetBottom;
+ }
+ offsetRight = $(document).outerWidth() - tipOffset.left - $(tip).outerWidth();
+ if (offsetRight < 0) {
+ tipOffset.left = tipOffset.left + offsetRight;
+ }
+ if (tipOffset.top < 0) {
+ tipOffset.top = 0;
+ }
+ if (tipOffset.left < 0) {
+ tipOffset.left = 0;
+ }
+ return tip.offset(tipOffset);
+ };
+
+ Tour.prototype._scrollIntoView = function(tip) {
+ var tipRect;
+ tipRect = tip.get(0).getBoundingClientRect();
+ if (!(tipRect.top > 0 && tipRect.bottom < $(window).height() && tipRect.left > 0 && tipRect.right < $(window).width())) {
+ return tip.get(0).scrollIntoView(true);
+ }
+ };
+
+ return Tour;
+
+ })();
+ return window.Tour = Tour;
+ })(jQuery, window);
+
+}).call(this);
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-transition.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-transition.js
new file mode 100644
index 000000000..534182622
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-transition.js
@@ -0,0 +1,61 @@
+/* ===================================================
+ * bootstrap-transition.js v2.0.4
+ * http://twitter.github.com/bootstrap/javascript.html#transitions
+ * ===================================================
+ * Copyright 2012 Twitter, 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.
+ * ========================================================== */
+
+
+!function ($) {
+
+ $(function () {
+
+ "use strict"; // jshint ;_;
+
+
+ /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
+ * ======================================================= */
+
+ $.support.transition = (function () {
+
+ var transitionEnd = (function () {
+
+ var el = document.createElement('bootstrap')
+ , transEndEventNames = {
+ 'WebkitTransition' : 'webkitTransitionEnd'
+ , 'MozTransition' : 'transitionend'
+ , 'OTransition' : 'oTransitionEnd'
+ , 'msTransition' : 'MSTransitionEnd'
+ , 'transition' : 'transitionend'
+ }
+ , name
+
+ for (name in transEndEventNames){
+ if (el.style[name] !== undefined) {
+ return transEndEventNames[name]
+ }
+ }
+
+ }())
+
+ return transitionEnd && {
+ end: transitionEnd
+ }
+
+ })()
+
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-typeahead.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-typeahead.js
new file mode 100644
index 000000000..ad44b9085
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/bootstrap-typeahead.js
@@ -0,0 +1,285 @@
+/* =============================================================
+ * bootstrap-typeahead.js v2.0.4
+ * http://twitter.github.com/bootstrap/javascript.html#typeahead
+ * =============================================================
+ * Copyright 2012 Twitter, 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.
+ * ============================================================ */
+
+
+!function($){
+
+ "use strict"; // jshint ;_;
+
+
+ /* TYPEAHEAD PUBLIC CLASS DEFINITION
+ * ================================= */
+
+ var Typeahead = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, $.fn.typeahead.defaults, options)
+ this.matcher = this.options.matcher || this.matcher
+ this.sorter = this.options.sorter || this.sorter
+ this.highlighter = this.options.highlighter || this.highlighter
+ this.updater = this.options.updater || this.updater
+ this.$menu = $(this.options.menu).appendTo('body')
+ this.source = this.options.source
+ this.shown = false
+ this.listen()
+ }
+
+ Typeahead.prototype = {
+
+ constructor: Typeahead
+
+ , select: function () {
+ var val = this.$menu.find('.active').attr('data-value')
+ this.$element
+ .val(this.updater(val))
+ .change()
+ return this.hide()
+ }
+
+ , updater: function (item) {
+ return item
+ }
+
+ , show: function () {
+ var pos = $.extend({}, this.$element.offset(), {
+ height: this.$element[0].offsetHeight
+ })
+
+ this.$menu.css({
+ top: pos.top + pos.height
+ , left: pos.left
+ })
+
+ this.$menu.show()
+ this.shown = true
+ return this
+ }
+
+ , hide: function () {
+ this.$menu.hide()
+ this.shown = false
+ return this
+ }
+
+ , lookup: function (event) {
+ var that = this
+ , items
+ , q
+
+ this.query = this.$element.val()
+
+ if (!this.query) {
+ return this.shown ? this.hide() : this
+ }
+
+ items = $.grep(this.source, function (item) {
+ return that.matcher(item)
+ })
+
+ items = this.sorter(items)
+
+ if (!items.length) {
+ return this.shown ? this.hide() : this
+ }
+
+ return this.render(items.slice(0, this.options.items)).show()
+ }
+
+ , matcher: function (item) {
+ return ~item.toLowerCase().indexOf(this.query.toLowerCase())
+ }
+
+ , sorter: function (items) {
+ var beginswith = []
+ , caseSensitive = []
+ , caseInsensitive = []
+ , item
+
+ while (item = items.shift()) {
+ if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
+ else if (~item.indexOf(this.query)) caseSensitive.push(item)
+ else caseInsensitive.push(item)
+ }
+
+ return beginswith.concat(caseSensitive, caseInsensitive)
+ }
+
+ , highlighter: function (item) {
+ var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
+ return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
+ return '' + match + ''
+ })
+ }
+
+ , render: function (items) {
+ var that = this
+
+ items = $(items).map(function (i, item) {
+ i = $(that.options.item).attr('data-value', item)
+ i.find('a').html(that.highlighter(item))
+ return i[0]
+ })
+
+ items.first().addClass('active')
+ this.$menu.html(items)
+ return this
+ }
+
+ , next: function (event) {
+ var active = this.$menu.find('.active').removeClass('active')
+ , next = active.next()
+
+ if (!next.length) {
+ next = $(this.$menu.find('li')[0])
+ }
+
+ next.addClass('active')
+ }
+
+ , prev: function (event) {
+ var active = this.$menu.find('.active').removeClass('active')
+ , prev = active.prev()
+
+ if (!prev.length) {
+ prev = this.$menu.find('li').last()
+ }
+
+ prev.addClass('active')
+ }
+
+ , listen: function () {
+ this.$element
+ .on('blur', $.proxy(this.blur, this))
+ .on('keypress', $.proxy(this.keypress, this))
+ .on('keyup', $.proxy(this.keyup, this))
+
+ if ($.browser.webkit || $.browser.msie) {
+ this.$element.on('keydown', $.proxy(this.keypress, this))
+ }
+
+ this.$menu
+ .on('click', $.proxy(this.click, this))
+ .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
+ }
+
+ , keyup: function (e) {
+ switch(e.keyCode) {
+ case 40: // down arrow
+ case 38: // up arrow
+ break
+
+ case 9: // tab
+ case 13: // enter
+ if (!this.shown) return
+ this.select()
+ break
+
+ case 27: // escape
+ if (!this.shown) return
+ this.hide()
+ break
+
+ default:
+ this.lookup()
+ }
+
+ e.stopPropagation()
+ e.preventDefault()
+ }
+
+ , keypress: function (e) {
+ if (!this.shown) return
+
+ switch(e.keyCode) {
+ case 9: // tab
+ case 13: // enter
+ case 27: // escape
+ e.preventDefault()
+ break
+
+ case 38: // up arrow
+ if (e.type != 'keydown') break
+ e.preventDefault()
+ this.prev()
+ break
+
+ case 40: // down arrow
+ if (e.type != 'keydown') break
+ e.preventDefault()
+ this.next()
+ break
+ }
+
+ e.stopPropagation()
+ }
+
+ , blur: function (e) {
+ var that = this
+ setTimeout(function () { that.hide() }, 150)
+ }
+
+ , click: function (e) {
+ e.stopPropagation()
+ e.preventDefault()
+ this.select()
+ }
+
+ , mouseenter: function (e) {
+ this.$menu.find('.active').removeClass('active')
+ $(e.currentTarget).addClass('active')
+ }
+
+ }
+
+
+ /* TYPEAHEAD PLUGIN DEFINITION
+ * =========================== */
+
+ $.fn.typeahead = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('typeahead')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.typeahead.defaults = {
+ source: []
+ , items: 8
+ , menu: '
'
+ , item: '
'
+ }
+
+ $.fn.typeahead.Constructor = Typeahead
+
+
+ /* TYPEAHEAD DATA-API
+ * ================== */
+
+ $(function () {
+ $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
+ var $this = $(this)
+ if ($this.data('typeahead')) return
+ e.preventDefault()
+ $this.typeahead($this.data())
+ })
+ })
+
+}(window.jQuery);
\ No newline at end of file
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/charisma.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/charisma.js
new file mode 100644
index 000000000..579174176
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/charisma.js
@@ -0,0 +1,702 @@
+$(document).ready(function(){
+ //themes, change CSS with JS
+ //default theme(CSS) is cerulean, change it if needed
+ var current_theme = $.cookie('current_theme')==null ? 'cerulean' :$.cookie('current_theme');
+ switch_theme(current_theme);
+
+ $('#themes a[data-value="'+current_theme+'"]').find('i').addClass('icon-ok');
+
+ $('#themes a').click(function(e){
+ e.preventDefault();
+ current_theme=$(this).attr('data-value');
+ $.cookie('current_theme',current_theme,{expires:365});
+ switch_theme(current_theme);
+ $('#themes i').removeClass('icon-ok');
+ $(this).find('i').addClass('icon-ok');
+ });
+
+
+ function switch_theme(theme_name)
+ {
+ $('#bs-css').attr('href','css/bootstrap-'+theme_name+'.css');
+ }
+
+ //ajax menu checkbox
+ $('#is-ajax').click(function(e){
+ $.cookie('is-ajax',$(this).prop('checked'),{expires:365});
+ });
+ $('#is-ajax').prop('checked',$.cookie('is-ajax')==='true' ? true : false);
+
+ //disbaling some functions for Internet Explorer
+ if($.browser.msie)
+ {
+ $('#is-ajax').prop('checked',false);
+ $('#for-is-ajax').hide();
+ $('#toggle-fullscreen').hide();
+ $('.login-box').find('.input-large').removeClass('span10');
+
+ }
+
+
+ //highlight current / active link
+ $('ul.main-menu li a').each(function(){
+ if($($(this))[0].href==String(window.location))
+ $(this).parent().addClass('active');
+ });
+
+ //establish history variables
+ var
+ History = window.History, // Note: We are using a capital H instead of a lower h
+ State = History.getState(),
+ $log = $('#log');
+
+ //bind to State Change
+ History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
+ var State = History.getState(); // Note: We are using History.getState() instead of event.state
+ $.ajax({
+ url:State.url,
+ success:function(msg){
+ $('#content').html($(msg).find('#content').html());
+ $('#loading').remove();
+ $('#content').fadeIn();
+ var newTitle = $(msg).filter('title').text();
+ $('title').text(newTitle);
+ docReady();
+ }
+ });
+ });
+
+ //ajaxify menus
+ $('a.ajax-link').click(function(e){
+ if($.browser.msie) e.which=1;
+ if(e.which!=1 || !$('#is-ajax').prop('checked') || $(this).parent().hasClass('active')) return;
+ e.preventDefault();
+ if($('.btn-navbar').is(':visible'))
+ {
+ $('.btn-navbar').click();
+ }
+ $('#loading').remove();
+ $('#content').fadeOut().parent().append('
Loading...
');
+ var $clink=$(this);
+ History.pushState(null, null, $clink.attr('href'));
+ $('ul.main-menu li.active').removeClass('active');
+ $clink.parent('li').addClass('active');
+ });
+
+ //animating menus on hover
+ $('ul.main-menu li:not(.nav-header)').hover(function(){
+ $(this).animate({'margin-left':'+=5'},300);
+ },
+ function(){
+ $(this).animate({'margin-left':'-=5'},300);
+ });
+
+ //other things to do on document ready, seperated for ajax calls
+ docReady();
+});
+
+
+function docReady(){
+ //prevent # links from moving to top
+ $('a[href="#"][data-top!=true]').click(function(e){
+ e.preventDefault();
+ });
+
+ //rich text editor
+ $('.cleditor').cleditor();
+
+ //datepicker
+ $('.datepicker').datepicker();
+
+ //notifications
+ $('.noty').click(function(e){
+ e.preventDefault();
+ var options = $.parseJSON($(this).attr('data-noty-options'));
+ noty(options);
+ });
+
+
+ //uniform - styler for checkbox, radio and file input
+ $("input:checkbox, input:radio, input:file").not('[data-no-uniform="true"],#uniform-is-ajax').uniform();
+
+ //chosen - improves select
+ $('[data-rel="chosen"],[rel="chosen"]').chosen();
+
+ //tabs
+ $('#myTab a:first').tab('show');
+ $('#myTab a').click(function (e) {
+ e.preventDefault();
+ $(this).tab('show');
+ });
+
+ //makes elements soratble, elements that sort need to have id attribute to save the result
+ $('.sortable').sortable({
+ revert:true,
+ cancel:'.btn,.box-content,.nav-header',
+ update:function(event,ui){
+ //line below gives the ids of elements, you can make ajax call here to save it to the database
+ //console.log($(this).sortable('toArray'));
+ }
+ });
+
+ //slider
+ $('.slider').slider({range:true,values:[10,65]});
+
+ //tooltip
+ $('[rel="tooltip"],[data-rel="tooltip"]').tooltip({"placement":"bottom",delay: { show: 400, hide: 200 }});
+
+ //auto grow textarea
+ $('textarea.autogrow').autogrow();
+
+ //popover
+ $('[rel="popover"],[data-rel="popover"]').popover();
+
+ //file manager
+ var elf = $('.file-manager').elfinder({
+ url : 'misc/elfinder-connector/connector.php' // connector URL (REQUIRED)
+ }).elfinder('instance');
+
+ //iOS / iPhone style toggle switch
+ $('.iphone-toggle').iphoneStyle();
+
+ //star rating
+ $('.raty').raty({
+ score : 4 //default stars
+ });
+
+ //uploadify - multiple uploads
+ $('#file_upload').uploadify({
+ 'swf' : 'misc/uploadify.swf',
+ 'uploader' : 'misc/uploadify.php'
+ // Put your options here
+ });
+
+ //gallery controlls container animation
+ $('ul.gallery li').hover(function(){
+ $('img',this).fadeToggle(1000);
+ $(this).find('.gallery-controls').remove();
+ $(this).append('
'+
+ '
'+
+ '
');
+ $(this).find('.gallery-controls').stop().animate({'margin-top':'-1'},400,'easeInQuint');
+ },function(){
+ $('img',this).fadeToggle(1000);
+ $(this).find('.gallery-controls').stop().animate({'margin-top':'-30'},200,'easeInQuint',function(){
+ $(this).remove();
+ });
+ });
+
+
+ //gallery image controls example
+ //gallery delete
+ $('.thumbnails').on('click','.gallery-delete',function(e){
+ e.preventDefault();
+ //get image id
+ //alert($(this).parents('.thumbnail').attr('id'));
+ $(this).parents('.thumbnail').fadeOut();
+ });
+ //gallery edit
+ $('.thumbnails').on('click','.gallery-edit',function(e){
+ e.preventDefault();
+ //get image id
+ //alert($(this).parents('.thumbnail').attr('id'));
+ });
+
+ //gallery colorbox
+ $('.thumbnail a').colorbox({rel:'thumbnail a', transition:"elastic", maxWidth:"95%", maxHeight:"95%"});
+
+ //gallery fullscreen
+ $('#toggle-fullscreen').button().click(function () {
+ var button = $(this), root = document.documentElement;
+ if (!button.hasClass('active')) {
+ $('#thumbnails').addClass('modal-fullscreen');
+ if (root.webkitRequestFullScreen) {
+ root.webkitRequestFullScreen(
+ window.Element.ALLOW_KEYBOARD_INPUT
+ );
+ } else if (root.mozRequestFullScreen) {
+ root.mozRequestFullScreen();
+ }
+ } else {
+ $('#thumbnails').removeClass('modal-fullscreen');
+ (document.webkitCancelFullScreen ||
+ document.mozCancelFullScreen ||
+ $.noop).apply(document);
+ }
+ });
+
+ //tour
+ if($('.tour').length && typeof(tour)=='undefined')
+ {
+ var tour = new Tour();
+ tour.addStep({
+ element: ".span10:first", /* html element next to which the step popover should be shown */
+ placement: "top",
+ title: "Custom Tour", /* title of the popover */
+ content: "You can create tour like this. Click Next." /* content of the popover */
+ });
+ tour.addStep({
+ element: ".theme-container",
+ placement: "left",
+ title: "Themes",
+ content: "You change your theme from here."
+ });
+ tour.addStep({
+ element: "ul.main-menu a:first",
+ title: "Dashboard",
+ content: "This is your dashboard from here you will find highlights."
+ });
+ tour.addStep({
+ element: "#for-is-ajax",
+ title: "Ajax",
+ content: "You can change if pages load with Ajax or not."
+ });
+ tour.addStep({
+ element: ".top-nav a:first",
+ placement: "bottom",
+ title: "Visit Site",
+ content: "Visit your front end from here."
+ });
+
+ tour.restart();
+ }
+
+ //datatable
+ $('.datatable').dataTable({
+ "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span12'i><'span12 center'p>>",
+ "sPaginationType": "bootstrap",
+ "oLanguage": {
+ "sLengthMenu": "_MENU_ records per page"
+ }
+ } );
+ $('.btn-close').click(function(e){
+ e.preventDefault();
+ $(this).parent().parent().parent().fadeOut();
+ });
+ $('.btn-minimize').click(function(e){
+ e.preventDefault();
+ var $target = $(this).parent().parent().next('.box-content');
+ if($target.is(':visible')) $('i',$(this)).removeClass('icon-chevron-up').addClass('icon-chevron-down');
+ else $('i',$(this)).removeClass('icon-chevron-down').addClass('icon-chevron-up');
+ $target.slideToggle();
+ });
+ $('.btn-setting').click(function(e){
+ e.preventDefault();
+ $('#myModal').modal('show');
+ });
+
+
+
+
+ //initialize the external events for calender
+
+ $('#external-events div.external-event').each(function() {
+
+ // it doesn't need to have a start or end
+ var eventObject = {
+ title: $.trim($(this).text()) // use the element's text as the event title
+ };
+
+ // store the Event Object in the DOM element so we can get to it later
+ $(this).data('eventObject', eventObject);
+
+ // make the event draggable using jQuery UI
+ $(this).draggable({
+ zIndex: 999,
+ revert: true, // will cause the event to go back to its
+ revertDuration: 0 // original position after the drag
+ });
+
+ });
+
+
+ //initialize the calendar
+ $('#calendar').fullCalendar({
+ header: {
+ left: 'prev,next today',
+ center: 'title',
+ right: 'month,agendaWeek,agendaDay'
+ },
+ editable: true,
+ droppable: true, // this allows things to be dropped onto the calendar !!!
+ drop: function(date, allDay) { // this function is called when something is dropped
+
+ // retrieve the dropped element's stored Event Object
+ var originalEventObject = $(this).data('eventObject');
+
+ // we need to copy it, so that multiple events don't have a reference to the same object
+ var copiedEventObject = $.extend({}, originalEventObject);
+
+ // assign it the date that was reported
+ copiedEventObject.start = date;
+ copiedEventObject.allDay = allDay;
+
+ // render the event on the calendar
+ // the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/)
+ $('#calendar').fullCalendar('renderEvent', copiedEventObject, true);
+
+ // is the "remove after drop" checkbox checked?
+ if ($('#drop-remove').is(':checked')) {
+ // if so, remove the element from the "Draggable Events" list
+ $(this).remove();
+ }
+
+ }
+ });
+
+
+ //chart with points
+ if($("#sincos").length)
+ {
+ var sin = [], cos = [];
+
+ for (var i = 0; i < 14; i += 0.5) {
+ sin.push([i, Math.sin(i)/i]);
+ cos.push([i, Math.cos(i)]);
+ }
+
+ var plot = $.plot($("#sincos"),
+ [ { data: sin, label: "sin(x)/x"}, { data: cos, label: "cos(x)" } ], {
+ series: {
+ lines: { show: true },
+ points: { show: true }
+ },
+ grid: { hoverable: true, clickable: true, backgroundColor: { colors: ["#fff", "#eee"] } },
+ yaxis: { min: -1.2, max: 1.2 },
+ colors: ["#539F2E", "#3C67A5"]
+ });
+
+ function showTooltip(x, y, contents) {
+ $('
' + contents + '
').css( {
+ position: 'absolute',
+ display: 'none',
+ top: y + 5,
+ left: x + 5,
+ border: '1px solid #fdd',
+ padding: '2px',
+ 'background-color': '#dfeffc',
+ opacity: 0.80
+ }).appendTo("body").fadeIn(200);
+ }
+
+ var previousPoint = null;
+ $("#sincos").bind("plothover", function (event, pos, item) {
+ $("#x").text(pos.x.toFixed(2));
+ $("#y").text(pos.y.toFixed(2));
+
+ if (item) {
+ if (previousPoint != item.dataIndex) {
+ previousPoint = item.dataIndex;
+
+ $("#tooltip").remove();
+ var x = item.datapoint[0].toFixed(2),
+ y = item.datapoint[1].toFixed(2);
+
+ showTooltip(item.pageX, item.pageY,
+ item.series.label + " of " + x + " = " + y);
+ }
+ }
+ else {
+ $("#tooltip").remove();
+ previousPoint = null;
+ }
+ });
+
+
+
+ $("#sincos").bind("plotclick", function (event, pos, item) {
+ if (item) {
+ $("#clickdata").text("You clicked point " + item.dataIndex + " in " + item.series.label + ".");
+ plot.highlight(item.series, item.datapoint);
+ }
+ });
+ }
+
+ //flot chart
+ if($("#flotchart").length)
+ {
+ var d1 = [];
+ for (var i = 0; i < Math.PI * 2; i += 0.25)
+ d1.push([i, Math.sin(i)]);
+
+ var d2 = [];
+ for (var i = 0; i < Math.PI * 2; i += 0.25)
+ d2.push([i, Math.cos(i)]);
+
+ var d3 = [];
+ for (var i = 0; i < Math.PI * 2; i += 0.1)
+ d3.push([i, Math.tan(i)]);
+
+ $.plot($("#flotchart"), [
+ { label: "sin(x)", data: d1},
+ { label: "cos(x)", data: d2},
+ { label: "tan(x)", data: d3}
+ ], {
+ series: {
+ lines: { show: true },
+ points: { show: true }
+ },
+ xaxis: {
+ ticks: [0, [Math.PI/2, "\u03c0/2"], [Math.PI, "\u03c0"], [Math.PI * 3/2, "3\u03c0/2"], [Math.PI * 2, "2\u03c0"]]
+ },
+ yaxis: {
+ ticks: 10,
+ min: -2,
+ max: 2
+ },
+ grid: {
+ backgroundColor: { colors: ["#fff", "#eee"] }
+ }
+ });
+ }
+
+ //stack chart
+ if($("#stackchart").length)
+ {
+ var d1 = [];
+ for (var i = 0; i <= 10; i += 1)
+ d1.push([i, parseInt(Math.random() * 30)]);
+
+ var d2 = [];
+ for (var i = 0; i <= 10; i += 1)
+ d2.push([i, parseInt(Math.random() * 30)]);
+
+ var d3 = [];
+ for (var i = 0; i <= 10; i += 1)
+ d3.push([i, parseInt(Math.random() * 30)]);
+
+ var stack = 0, bars = true, lines = false, steps = false;
+
+ function plotWithOptions() {
+ $.plot($("#stackchart"), [ d1, d2, d3 ], {
+ series: {
+ stack: stack,
+ lines: { show: lines, fill: true, steps: steps },
+ bars: { show: bars, barWidth: 0.6 }
+ }
+ });
+ }
+
+ plotWithOptions();
+
+ $(".stackControls input").click(function (e) {
+ e.preventDefault();
+ stack = $(this).val() == "With stacking" ? true : null;
+ plotWithOptions();
+ });
+ $(".graphControls input").click(function (e) {
+ e.preventDefault();
+ bars = $(this).val().indexOf("Bars") != -1;
+ lines = $(this).val().indexOf("Lines") != -1;
+ steps = $(this).val().indexOf("steps") != -1;
+ plotWithOptions();
+ });
+ }
+
+ //pie chart
+ var data = [
+ { label: "Internet Explorer", data: 12},
+ { label: "Mobile", data: 27},
+ { label: "Safari", data: 85},
+ { label: "Opera", data: 64},
+ { label: "Firefox", data: 90},
+ { label: "Chrome", data: 112}
+ ];
+
+ if($("#piechart").length)
+ {
+ $.plot($("#piechart"), data,
+ {
+ series: {
+ pie: {
+ show: true
+ }
+ },
+ grid: {
+ hoverable: true,
+ clickable: true
+ },
+ legend: {
+ show: false
+ }
+ });
+
+ function pieHover(event, pos, obj)
+ {
+ if (!obj)
+ return;
+ percent = parseFloat(obj.series.percent).toFixed(2);
+ $("#hover").html(''+obj.series.label+' ('+percent+'%)');
+ }
+ $("#piechart").bind("plothover", pieHover);
+ }
+
+ //donut chart
+ if($("#donutchart").length)
+ {
+ $.plot($("#donutchart"), data,
+ {
+ series: {
+ pie: {
+ innerRadius: 0.5,
+ show: true
+ }
+ },
+ legend: {
+ show: false
+ }
+ });
+ }
+
+
+
+
+ // we use an inline data source in the example, usually data would
+ // be fetched from a server
+ var data = [], totalPoints = 300;
+ function getRandomData() {
+ if (data.length > 0)
+ data = data.slice(1);
+
+ // do a random walk
+ while (data.length < totalPoints) {
+ var prev = data.length > 0 ? data[data.length - 1] : 50;
+ var y = prev + Math.random() * 10 - 5;
+ if (y < 0)
+ y = 0;
+ if (y > 100)
+ y = 100;
+ data.push(y);
+ }
+
+ // zip the generated y values with the x values
+ var res = [];
+ for (var i = 0; i < data.length; ++i)
+ res.push([i, data[i]])
+ return res;
+ }
+
+ // setup control widget
+ var updateInterval = 30;
+ $("#updateInterval").val(updateInterval).change(function () {
+ var v = $(this).val();
+ if (v && !isNaN(+v)) {
+ updateInterval = +v;
+ if (updateInterval < 1)
+ updateInterval = 1;
+ if (updateInterval > 2000)
+ updateInterval = 2000;
+ $(this).val("" + updateInterval);
+ }
+ });
+
+ //realtime chart
+ if($("#realtimechart").length)
+ {
+ var options = {
+ series: { shadowSize: 1 }, // drawing is faster without shadows
+ yaxis: { min: 0, max: 100 },
+ xaxis: { show: false }
+ };
+ var plot = $.plot($("#realtimechart"), [ getRandomData() ], options);
+ function update() {
+ plot.setData([ getRandomData() ]);
+ // since the axes don't change, we don't need to call plot.setupGrid()
+ plot.draw();
+
+ setTimeout(update, updateInterval);
+ }
+
+ update();
+ }
+}
+
+
+//additional functions for data table
+$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
+{
+ return {
+ "iStart": oSettings._iDisplayStart,
+ "iEnd": oSettings.fnDisplayEnd(),
+ "iLength": oSettings._iDisplayLength,
+ "iTotal": oSettings.fnRecordsTotal(),
+ "iFilteredTotal": oSettings.fnRecordsDisplay(),
+ "iPage": Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
+ "iTotalPages": Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
+ };
+}
+$.extend( $.fn.dataTableExt.oPagination, {
+ "bootstrap": {
+ "fnInit": function( oSettings, nPaging, fnDraw ) {
+ var oLang = oSettings.oLanguage.oPaginate;
+ var fnClickHandler = function ( e ) {
+ e.preventDefault();
+ if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
+ fnDraw( oSettings );
+ }
+ };
+
+ $(nPaging).addClass('pagination').append(
+ '
'
+ );
+ var els = $('a', nPaging);
+ $(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
+ $(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
+ },
+
+ "fnUpdate": function ( oSettings, fnDraw ) {
+ var iListLength = 5;
+ var oPaging = oSettings.oInstance.fnPagingInfo();
+ var an = oSettings.aanFeatures.p;
+ var i, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);
+
+ if ( oPaging.iTotalPages < iListLength) {
+ iStart = 1;
+ iEnd = oPaging.iTotalPages;
+ }
+ else if ( oPaging.iPage <= iHalf ) {
+ iStart = 1;
+ iEnd = iListLength;
+ } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {
+ iStart = oPaging.iTotalPages - iListLength + 1;
+ iEnd = oPaging.iTotalPages;
+ } else {
+ iStart = oPaging.iPage - iHalf + 1;
+ iEnd = iStart + iListLength - 1;
+ }
+
+ for ( i=0, iLen=an.length ; i'+j+'')
+ .insertBefore( $('li:last', an[i])[0] )
+ .bind('click', function (e) {
+ e.preventDefault();
+ oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
+ fnDraw( oSettings );
+ } );
+ }
+
+ // add / remove disabled classes from the static elements
+ if ( oPaging.iPage === 0 ) {
+ $('li:first', an[i]).addClass('disabled');
+ } else {
+ $('li:first', an[i]).removeClass('disabled');
+ }
+
+ if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
+ $('li:last', an[i]).addClass('disabled');
+ } else {
+ $('li:last', an[i]).removeClass('disabled');
+ }
+ }
+ }
+ }
+});
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/excanvas.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/excanvas.js
new file mode 100644
index 000000000..c40d6f701
--- /dev/null
+++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/excanvas.js
@@ -0,0 +1,1427 @@
+// Copyright 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.
+
+
+// Known Issues:
+//
+// * Patterns only support repeat.
+// * Radial gradient are not implemented. The VML version of these look very
+// different from the canvas one.
+// * Clipping paths are not implemented.
+// * Coordsize. The width and height attribute have higher priority than the
+// width and height style values which isn't correct.
+// * Painting mode isn't implemented.
+// * Canvas width/height should is using content-box by default. IE in
+// Quirks mode will draw the canvas using border-box. Either change your
+// doctype to HTML5
+// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
+// or use Box Sizing Behavior from WebFX
+// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
+// * Non uniform scaling does not correctly scale strokes.
+// * Filling very large shapes (above 5000 points) is buggy.
+// * Optimize. There is always room for speed improvements.
+
+// Only add this code if we do not already have a canvas implementation
+if (!document.createElement('canvas').getContext) {
+
+(function() {
+
+ // alias some functions to make (compiled) code shorter
+ var m = Math;
+ var mr = m.round;
+ var ms = m.sin;
+ var mc = m.cos;
+ var abs = m.abs;
+ var sqrt = m.sqrt;
+
+ // this is used for sub pixel precision
+ var Z = 10;
+ var Z2 = Z / 2;
+
+ /**
+ * This funtion is assigned to the