You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by bu...@apache.org on 2013/07/03 06:39:49 UTC

svn commit: r868224 [10/13] - in /websites/staging/chemistry/trunk/content: ./ php/docs/ php/docs/atom/ php/docs/atom/classes/ php/docs/atom/css/ php/docs/atom/img/ php/docs/atom/img/icons/ php/docs/atom/img/iviewer/ php/docs/atom/js/ php/docs/atom/js/...

Added: websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.cookie.js
==============================================================================
--- websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.cookie.js (added)
+++ websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.cookie.js Wed Jul  3 04:39:47 2013
@@ -0,0 +1,104 @@
+/**
+ * Cookie plugin
+ *
+ * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+
+/**
+ * Create a cookie with the given name and value and other optional parameters.
+ *
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Set the value of a cookie.
+ * @example $.cookie('the_cookie', 'the_value', {expires: 7, path: '/', domain: 'jquery.com', secure: true});
+ * @desc Create a cookie with all available options.
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Create a session cookie.
+ * @example $.cookie('the_cookie', null);
+ * @desc Delete a cookie by passing null as value.
+ *
+ * @param String name The name of the cookie.
+ * @param String value The value of the cookie.
+ * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
+ * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
+ *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
+ *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
+ *                             when the the browser exits.
+ * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
+ * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
+ * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
+ *                        require a secure protocol (like HTTPS).
+ * @type undefined
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
+ */
+
+/**
+ * Get the value of a cookie with the given name.
+ *
+ * @example $.cookie('the_cookie');
+ * @desc Get the value of a cookie.
+ *
+ * @param String name The name of the cookie.
+ * @return The value of the cookie.
+ * @type String
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
+ */
+jQuery.cookie = function(name, value, options)
+{
+  if (typeof value != 'undefined')
+  { // name and value given, set cookie
+    options = options || {};
+    if (value === null)
+    {
+      value = '';
+      options.expires = -1;
+    }
+    var expires = '';
+    if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString))
+    {
+      var date;
+      if (typeof options.expires == 'number')
+      {
+        date = new Date();
+        date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
+      }
+      else
+      {
+        date = options.expires;
+      }
+      expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
+    }
+    var path = options.path ? '; path=' + options.path : '';
+    var domain = options.domain ? '; domain=' + options.domain : '';
+    var secure = options.secure ? '; secure' : '';
+    document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
+  }
+  else
+  { // only name given, get cookie
+    var cookieValue = null;
+    if (document.cookie && document.cookie != '')
+    {
+      var cookies = document.cookie.split(';');
+      for (var i = 0; i < cookies.length; i++)
+      {
+        var cookie = jQuery.trim(cookies[i]);
+        // Does this cookie string begin with the name we want?
+        if (cookie.substring(0, name.length + 1) == (name + '='))
+        {
+          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+          break;
+        }
+      }
+    }
+    return cookieValue;
+  }
+};
\ No newline at end of file

Added: websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.iviewer.js
==============================================================================
--- websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.iviewer.js (added)
+++ websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.iviewer.js Wed Jul  3 04:39:47 2013
@@ -0,0 +1,1045 @@
+/*
+ * iviewer Widget for jQuery UI
+ * https://github.com/can3p/iviewer
+ *
+ * Copyright (c) 2009 - 2012 Dmitry Petrov
+ * Dual licensed under the MIT and GPL licenses.
+ *  - http://www.opensource.org/licenses/mit-license.php
+ *  - http://www.gnu.org/copyleft/gpl.html
+ *
+ * Author: Dmitry Petrov
+ * Version: 0.7
+ */
+
+( function( $, undefined ) {
+
+//this code was taken from the https://github.com/furf/jquery-ui-touch-punch
+var mouseEvents = {
+    touchstart: 'mousedown',
+    touchmove: 'mousemove',
+    touchend: 'mouseup'
+};
+
+/**
+ * Convert a touch event to a mouse-like
+ */
+function makeMouseEvent (event) {
+    var touch = event.originalEvent.changedTouches[0];
+
+    return $.extend(event, {
+        type:    mouseEvents[event.type],
+        which:   1,
+        pageX:   touch.pageX,
+        pageY:   touch.pageY,
+        screenX: touch.screenX,
+        screenY: touch.screenY,
+        clientX: touch.clientX,
+        clientY: touch.clientY,
+        isTouchEvent: true
+    });
+}
+
+var mouseProto = $.ui.mouse.prototype,
+    _mouseInit = $.ui.mouse.prototype._mouseInit;
+
+mouseProto._mouseInit = function() {
+    var self = this;
+    self._touchActive = false;
+
+    this.element.bind( 'touchstart.' + this.widgetName, function(event) {
+        self._touchActive = true;
+        return self._mouseDown(makeMouseEvent(event));
+    })
+
+    var self = this;
+    // these delegates are required to keep context
+    this._mouseMoveDelegate = function(event) {
+        if (self._touchActive) {
+            return self._mouseMove(makeMouseEvent(event));
+        }
+    };
+    this._mouseUpDelegate = function(event) {
+        if (self._touchActive) {
+            self._touchActive = false;
+            return self._mouseUp(makeMouseEvent(event));
+        }
+    };
+
+    $(document)
+        .bind('touchmove.'+ this.widgetName, this._mouseMoveDelegate)
+        .bind('touchend.' + this.widgetName, this._mouseUpDelegate);
+
+    _mouseInit.apply(this);
+}
+
+/**
+ * Simple implementation of jQuery like getters/setters
+ * var val = something();
+ * something(val);
+ */
+var setter = function(setter, getter) {
+    return function(val) {
+        if (arguments.length === 0) {
+            return getter.apply(this);
+        } else {
+            setter.apply(this, arguments);
+        }
+    }
+};
+
+/**
+ * Internet explorer rotates image relative left top corner, so we should
+ * shift image when it's rotated.
+ */
+var ieTransforms = {
+        '0': {
+            marginLeft: 0,
+            marginTop: 0,
+            filter: 'progid:DXImageTransform.Microsoft.Matrix(M11=1, M12=0, M21=0, M22=1, SizingMethod="auto expand")'
+        },
+
+        '90': {
+            marginLeft: -1,
+            marginTop: 1,
+            filter: 'progid:DXImageTransform.Microsoft.Matrix(M11=0, M12=-1, M21=1, M22=0, SizingMethod="auto expand")'
+        },
+
+        '180': {
+            marginLeft: 0,
+            marginTop: 0,
+            filter: 'progid:DXImageTransform.Microsoft.Matrix(M11=-1, M12=0, M21=0, M22=-1, SizingMethod="auto expand")'
+        },
+
+        '270': {
+            marginLeft: -1,
+            marginTop: 1,
+            filter: 'progid:DXImageTransform.Microsoft.Matrix(M11=0, M12=1, M21=-1, M22=0, SizingMethod="auto expand")'
+        }
+    },
+    useIeTransforms = (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) <= 8);
+
+$.widget( "ui.iviewer", $.ui.mouse, {
+    widgetEventPrefix: "iviewer",
+    options : {
+        /**
+        * start zoom value for image, not used now
+        * may be equal to "fit" to fit image into container or scale in %
+        **/
+        zoom: "fit",
+        /**
+        * base value to scale image
+        **/
+        zoom_base: 100,
+        /**
+        * maximum zoom
+        **/
+        zoom_max: 800,
+        /**
+        * minimum zoom
+        **/
+        zoom_min: 25,
+        /**
+        * base of rate multiplier.
+        * zoom is calculated by formula: zoom_base * zoom_delta^rate
+        **/
+        zoom_delta: 1.4,
+        /**
+        * whether the zoom should be animated.
+        */
+        zoom_animation: true,
+        /**
+        * if true plugin doesn't add its own controls
+        **/
+        ui_disabled: false,
+        /**
+        * if false, plugin doesn't bind resize event on window and this must
+        * be handled manually
+        **/
+        update_on_resize: true,
+        /**
+        * event is triggered when zoom value is changed
+        * @param int new zoom value
+        * @return boolean if false zoom action is aborted
+        **/
+        onZoom: jQuery.noop,
+        /**
+        * event is triggered when zoom value is changed after image is set to the new dimensions
+        * @param int new zoom value
+        * @return boolean if false zoom action is aborted
+        **/
+        onAfterZoom: jQuery.noop,
+        /**
+        * event is fired on drag begin
+        * @param object coords mouse coordinates on the image
+        * @return boolean if false is returned, drag action is aborted
+        **/
+        onStartDrag: jQuery.noop,
+        /**
+        * event is fired on drag action
+        * @param object coords mouse coordinates on the image
+        **/
+        onDrag: jQuery.noop,
+        /**
+        * event is fired on drag stop
+        * @param object coords mouse coordinates on the image
+        **/
+        onStopDrag: jQuery.noop,
+        /**
+        * event is fired when mouse moves over image
+        * @param object coords mouse coordinates on the image
+        **/
+        onMouseMove: jQuery.noop,
+        /**
+        * mouse click event
+        * @param object coords mouse coordinates on the image
+        **/
+        onClick: jQuery.noop,
+        /**
+        * event is fired when image starts to load
+        */
+        onStartLoad: null,
+        /**
+        * event is fired, when image is loaded and initially positioned
+        */
+        onFinishLoad: null
+    },
+
+    _create: function() {
+        var me = this;
+
+        //drag variables
+        this.dx = 0;
+        this.dy = 0;
+
+        /* object containing actual information about image
+        *   @img_object.object - jquery img object
+        *   @img_object.orig_{width|height} - original dimensions
+        *   @img_object.display_{width|height} - actual dimensions
+        */
+        this.img_object = {};
+
+        this.zoom_object = {}; //object to show zoom status
+
+        this._angle = 0;
+
+        this.current_zoom = this.options.zoom;
+
+        if(this.options.src === null){
+            return;
+        }
+
+        this.container = this.element;
+
+        this._updateContainerInfo();
+
+        //init container
+        this.container.css("overflow","hidden");
+
+        if(this.options.update_on_resize == true)
+        {
+            $(window).resize(function()
+            {
+                me._updateContainerInfo();
+            });
+        }
+
+        this.img_object = new $.ui.iviewer.ImageObject(this.options.zoom_animation);
+
+        //init object
+        this.img_object.object()
+            //bind mouse events
+            .click(function(e){return me._click(e)})
+            .mousewheel(function(ev, delta)
+            {
+                //this event is there instead of containing div, because
+                //at opera it triggers many times on div
+                var zoom = (delta > 0)?1:-1;
+                me.zoom_by(zoom);
+                return false;
+            })
+            .prependTo(this.container);
+
+        this.container.bind('mousemove', function(ev) { me._handleMouseMove(ev); });
+
+        this.loadImage(this.options.src);
+
+        if(!this.options.ui_disabled)
+        {
+            this.createui();
+        }
+
+        this._mouseInit();
+    },
+
+    destroy: function() {
+        this._mouseDestroy();
+    },
+
+    _updateContainerInfo: function()
+    {
+        this.options.height = this.container.height();
+        this.options.width = this.container.width();
+    },
+
+    loadImage: function( src )
+    {
+        this.current_zoom = this.options.zoom;
+        var me = this;
+
+        this._trigger('onStartLoad', 0, src);
+
+        this.img_object.load(src, function() {
+                me.container.addClass("iviewer_cursor");
+
+                if(me.options.zoom == "fit"){
+                    me.fit(true);
+                }
+                else {
+                    me.set_zoom(me.options.zoom, true);
+                }
+
+                if(me.options.onFinishLoad)
+                {
+                    me._trigger('onFinishLoad', 0, src);
+                }
+        });
+    },
+
+    /**
+    * fits image in the container
+    *
+    * @param {boolean} skip_animation
+    **/
+    fit: function(skip_animation)
+    {
+        var aspect_ratio = this.img_object.orig_width() / this.img_object.orig_height();
+        var window_ratio = this.options.width /  this.options.height;
+        var choose_left = (aspect_ratio > window_ratio);
+        var new_zoom = 0;
+
+        if(choose_left){
+            new_zoom = this.options.width / this.img_object.orig_width() * 100;
+        }
+        else {
+            new_zoom = this.options.height / this.img_object.orig_height() * 100;
+        }
+
+      this.set_zoom(new_zoom, skip_animation);
+    },
+
+    /**
+    * center image in container
+    **/
+    center: function()
+    {
+        this.setCoords(-Math.round((this.img_object.display_width() - this.options.width)/2),
+                -Math.round((this.img_object.display_height() - this.options.height)/2));
+    },
+
+    /**
+    *   move a point in container to the center of display area
+    *   @param x a point in container
+    *   @param y a point in container
+    **/
+    moveTo: function(x, y)
+    {
+        var dx = x-Math.round(this.options.width/2);
+        var dy = y-Math.round(this.options.height/2);
+
+        var new_x = this.img_object.x() - dx;
+        var new_y = this.img_object.y() - dy;
+
+        this.setCoords(new_x, new_y);
+    },
+
+    /**
+     * Get container offset object.
+     */
+    getContainerOffset: function() {
+        return jQuery.extend({}, this.container.offset());
+    },
+
+    /**
+    * set coordinates of upper left corner of image object
+    **/
+    setCoords: function(x,y)
+    {
+        //do nothing while image is being loaded
+        if(!this.img_object.loaded()) { return; }
+
+        var coords = this._correctCoords(x,y);
+        this.img_object.x(coords.x);
+        this.img_object.y(coords.y);
+    },
+
+    _correctCoords: function( x, y )
+    {
+        x = parseInt(x, 10);
+        y = parseInt(y, 10);
+
+        //check new coordinates to be correct (to be in rect)
+        if(y > 0){
+            y = 0;
+        }
+        if(x > 0){
+            x = 0;
+        }
+        if(y + this.img_object.display_height() < this.options.height){
+            y = this.options.height - this.img_object.display_height();
+        }
+        if(x + this.img_object.display_width() < this.options.width){
+            x = this.options.width - this.img_object.display_width();
+        }
+        if(this.img_object.display_width() <= this.options.width){
+            x = -(this.img_object.display_width() - this.options.width)/2;
+        }
+        if(this.img_object.display_height() <= this.options.height){
+            y = -(this.img_object.display_height() - this.options.height)/2;
+        }
+
+        return { x: x, y:y };
+    },
+
+
+    /**
+    * convert coordinates on the container to the coordinates on the image (in original size)
+    *
+    * @return object with fields x,y according to coordinates or false
+    * if initial coords are not inside image
+    **/
+    containerToImage : function (x,y)
+    {
+        var coords = { x : x - this.img_object.x(),
+                 y :  y - this.img_object.y()
+        };
+
+        coords = this.img_object.toOriginalCoords(coords);
+
+        return { x :  util.descaleValue(coords.x, this.current_zoom),
+                 y :  util.descaleValue(coords.y, this.current_zoom)
+        };
+    },
+
+    /**
+    * convert coordinates on the image (in original size, and zero angle) to the coordinates on the container
+    *
+    * @return object with fields x,y according to coordinates
+    **/
+    imageToContainer : function (x,y)
+    {
+        var coords = {
+                x : util.scaleValue(x, this.current_zoom),
+                y : util.scaleValue(y, this.current_zoom)
+            };
+
+        return this.img_object.toRealCoords(coords);
+    },
+
+    /**
+    * get mouse coordinates on the image
+    * @param e - object containing pageX and pageY fields, e.g. mouse event object
+    *
+    * @return object with fields x,y according to coordinates or false
+    * if initial coords are not inside image
+    **/
+    _getMouseCoords : function(e)
+    {
+        var containerOffset = this.container.offset();
+            coords = this.containerToImage(e.pageX - containerOffset.left, e.pageY - containerOffset.top);
+
+        return coords;
+    },
+
+    /**
+    * set image scale to the new_zoom
+    *
+    * @param {number} new_zoom image scale in %
+    * @param {boolean} skip_animation
+    **/
+    set_zoom: function(new_zoom, skip_animation)
+    {
+        if (this._trigger('onZoom', 0, new_zoom) == false) {
+            return;
+        }
+
+        //do nothing while image is being loaded
+        if(!this.img_object.loaded()) { return; }
+
+        if(new_zoom <  this.options.zoom_min)
+        {
+            new_zoom = this.options.zoom_min;
+        }
+        else if(new_zoom > this.options.zoom_max)
+        {
+            new_zoom = this.options.zoom_max;
+        }
+
+        /* we fake these values to make fit zoom properly work */
+        if(this.current_zoom == "fit")
+        {
+            var old_x = Math.round(this.options.width/2 + this.img_object.orig_width()/2);
+            var old_y = Math.round(this.options.height/2 + this.img_object.orig_height()/2);
+            this.current_zoom = 100;
+        }
+        else {
+            var old_x = -this.img_object.x() + Math.round(this.options.width/2);
+            var old_y = -this.img_object.y() + Math.round(this.options.height/2);
+        }
+
+        var new_width = util.scaleValue(this.img_object.orig_width(), new_zoom);
+        var new_height = util.scaleValue(this.img_object.orig_height(), new_zoom);
+        var new_x = util.scaleValue( util.descaleValue(old_x, this.current_zoom), new_zoom);
+        var new_y = util.scaleValue( util.descaleValue(old_y, this.current_zoom), new_zoom);
+
+        new_x = this.options.width/2 - new_x;
+        new_y = this.options.height/2 - new_y;
+
+        this.img_object.display_width(new_width);
+        this.img_object.display_height(new_height);
+
+        var coords = this._correctCoords( new_x, new_y ),
+            self = this;
+
+        this.img_object.setImageProps(new_width, new_height, coords.x, coords.y,
+                                        skip_animation, function() {
+            self._trigger('onAfterZoom', 0, new_zoom );
+        });
+        this.current_zoom = new_zoom;
+
+        this.update_status();
+    },
+
+    /**
+    * changes zoom scale by delta
+    * zoom is calculated by formula: zoom_base * zoom_delta^rate
+    * @param Integer delta number to add to the current multiplier rate number
+    **/
+    zoom_by: function(delta)
+    {
+        var closest_rate = this.find_closest_zoom_rate(this.current_zoom);
+
+        var next_rate = closest_rate + delta;
+        var next_zoom = this.options.zoom_base * Math.pow(this.options.zoom_delta, next_rate)
+        if(delta > 0 && next_zoom < this.current_zoom)
+        {
+            next_zoom *= this.options.zoom_delta;
+        }
+
+        if(delta < 0 && next_zoom > this.current_zoom)
+        {
+            next_zoom /= this.options.zoom_delta;
+        }
+
+        this.set_zoom(next_zoom);
+    },
+
+    /**
+    * Rotate image
+    * @param {num} deg Degrees amount to rotate. Positive values rotate image clockwise.
+    *     Currently 0, 90, 180, 270 and -90, -180, -270 values are supported
+    *
+    * @param {boolean} abs If the flag is true if, the deg parameter will be considered as
+    *     a absolute value and relative otherwise.
+    * @return {num|null} Method will return current image angle if called without any arguments.
+    **/
+    angle: function(deg, abs) {
+        if (arguments.length === 0) { return this.img_object.angle(); }
+
+        if (deg < -270 || deg > 270 || deg % 90 !== 0) { return; }
+        if (!abs) { deg += this.img_object.angle(); }
+        if (deg < 0) { deg += 360; }
+        if (deg >= 360) { deg -= 360; }
+
+        if (deg === this.img_object.angle()) { return; }
+
+        this.img_object.angle(deg);
+        //the rotate behavior is different in all editors. For now we  just center the
+        //image. However, it will be better to try to keep the position.
+        this.center();
+        this._trigger('angle', 0, { angle: this.img_object.angle() });
+    },
+
+    /**
+    * finds closest multiplier rate for value
+    * basing on zoom_base and zoom_delta values from settings
+    * @param Number value zoom value to examine
+    **/
+    find_closest_zoom_rate: function(value)
+    {
+        if(value == this.options.zoom_base)
+        {
+            return 0;
+        }
+
+        function div(val1,val2) { return val1 / val2 };
+        function mul(val1,val2) { return val1 * val2 };
+
+        var func = (value > this.options.zoom_base)?mul:div;
+        var sgn = (value > this.options.zoom_base)?1:-1;
+
+        var mltplr = this.options.zoom_delta;
+        var rate = 1;
+
+        while(Math.abs(func(this.options.zoom_base, Math.pow(mltplr,rate)) - value) >
+              Math.abs(func(this.options.zoom_base, Math.pow(mltplr,rate+1)) - value))
+        {
+            rate++;
+        }
+
+        return sgn * rate;
+    },
+
+    /* update scale info in the container */
+    update_status: function()
+    {
+        if(!this.options.ui_disabled)
+        {
+            var percent = Math.round(100*this.img_object.display_height()/this.img_object.orig_height());
+            if(percent)
+            {
+                this.zoom_object.html(percent + "%");
+            }
+        }
+    },
+
+    /**
+     * Get some information about the image.
+     *     Currently orig_(width|height), display_(width|height), angle, zoom and src params are supported.
+     *
+     *  @param {string} parameter to check
+     *  @param {boolean} withoutRotation if param is orig_width or orig_height and this flag is set to true,
+     *      method will return original image width without considering rotation.
+     *
+     */
+    info: function(param, withoutRotation) {
+        if (!param) { return; }
+
+        switch (param) {
+            case 'orig_width':
+            case 'orig_height':
+                if (withoutRotation) {
+                    return (this.img_object.angle() % 180 === 0 ? this.img_object[param]() :
+                            param === 'orig_width' ? this.img_object.orig_height() : 
+                                                        this.img_object.orig_width());
+                } else {
+                    return this.img_object[param]();
+                }
+            case 'display_width':
+            case 'display_height':
+            case 'angle':
+                return this.img_object[param]();
+            case 'zoom':
+                return this.current_zoom;
+            case 'src':
+                return this.img_object.object().attr('src');
+        }
+    },
+
+    /**
+    *   callback for handling mousdown event to start dragging image
+    **/
+    _mouseStart: function( e )
+    {
+        $.ui.mouse.prototype._mouseStart.call(this, e);
+        if (this._trigger('onStartDrag', 0, this._getMouseCoords(e)) === false) {
+            return false;
+        }
+
+        /* start drag event*/
+        this.container.addClass("iviewer_drag_cursor");
+
+        this.dx = e.pageX - this.img_object.x();
+        this.dy = e.pageY - this.img_object.y();
+        return true;
+    },
+
+    _mouseCapture: function( e ) {
+        return true;
+    },
+
+    /**
+     * Handle mouse move if needed. User can avoid using this callback, because
+     *    he can get the same information through public methods.
+     *  @param {jQuery.Event} e
+     */
+    _handleMouseMove: function(e) {
+        this._trigger('onMouseMove', e, this._getMouseCoords(e));
+    },
+
+    /**
+    *   callback for handling mousemove event to drag image
+    **/
+    _mouseDrag: function(e)
+    {
+        $.ui.mouse.prototype._mouseDrag.call(this, e);
+        var ltop =  e.pageY - this.dy;
+        var lleft = e.pageX - this.dx;
+
+        this.setCoords(lleft, ltop);
+        this._trigger('onDrag', e, this._getMouseCoords(e));
+        return false;
+    },
+
+    /**
+    *   callback for handling stop drag
+    **/
+    _mouseStop: function(e)
+    {
+        $.ui.mouse.prototype._mouseStop.call(this, e);
+        this.container.removeClass("iviewer_drag_cursor");
+        this._trigger('onStopDrag', 0, this._getMouseCoords(e));
+    },
+
+    _click: function(e)
+    {
+        this._trigger('onClick', 0, this._getMouseCoords(e));
+    },
+
+    /**
+    *   create zoom buttons info box
+    **/
+    createui: function()
+    {
+        var me=this;
+
+        $("<div>", { 'class': "iviewer_zoom_in iviewer_common iviewer_button"})
+                    .bind('mousedown touchstart',function(){me.zoom_by(1); return false;})
+                    .appendTo(this.container);
+
+        $("<div>", { 'class': "iviewer_zoom_out iviewer_common iviewer_button"})
+                    .bind('mousedown touchstart',function(){me.zoom_by(- 1); return false;})
+                    .appendTo(this.container);
+
+        $("<div>", { 'class': "iviewer_zoom_zero iviewer_common iviewer_button"})
+                    .bind('mousedown touchstart',function(){me.set_zoom(100); return false;})
+                    .appendTo(this.container);
+
+        $("<div>", { 'class': "iviewer_zoom_fit iviewer_common iviewer_button"})
+                    .bind('mousedown touchstart',function(){me.fit(this); return false;})
+                    .appendTo(this.container);
+
+        this.zoom_object = $("<div>").addClass("iviewer_zoom_status iviewer_common")
+                                    .appendTo(this.container);
+
+        $("<div>", { 'class': "iviewer_rotate_left iviewer_common iviewer_button"})
+                    .bind('mousedown touchstart',function(){me.angle(-90); return false;})
+                    .appendTo(this.container);
+
+        $("<div>", { 'class': "iviewer_rotate_right iviewer_common iviewer_button" })
+                    .bind('mousedown touchstart',function(){me.angle(90); return false;})
+                    .appendTo(this.container);
+
+        this.update_status(); //initial status update
+    }
+
+} );
+
+/**
+ * @class $.ui.iviewer.ImageObject Class represents image and provides public api without
+ *     extending image prototype.
+ * @constructor
+ * @param {boolean} do_anim Do we want to animate image on dimension changes?
+ */
+$.ui.iviewer.ImageObject = function(do_anim) {
+    this._img = $("<img>")
+            //this is needed, because chromium sets them auto otherwise
+            .css({ position: "absolute", top :"0px", left: "0px"});
+
+    this._loaded = false;
+    this._swapDimensions = false;
+    this._do_anim = do_anim || false;
+    this.x(0, true);
+    this.y(0, true);
+    this.angle(0);
+};
+
+
+/** @lends $.ui.iviewer.ImageObject.prototype */
+(function() {
+    /**
+     * Restore initial object state.
+     *
+     * @param {number} w Image width.
+     * @param {number} h Image height.
+     */
+    this._reset = function(w, h) {
+        this._angle = 0;
+        this._swapDimensions = false;
+        this.x(0);
+        this.y(0);
+
+        this.orig_width(w);
+        this.orig_height(h);
+        this.display_width(w);
+        this.display_height(h);
+    };
+
+    /**
+     * Check if image is loaded.
+     *
+     * @return {boolean}
+     */
+    this.loaded = function() { return this._loaded; };
+
+    /**
+     * Load image.
+     *
+     * @param {string} src Image url.
+     * @param {Function=} loaded Function will be called on image load.
+     */
+    this.load = function(src, loaded) {
+        var self = this;
+
+        loaded = loaded || jQuery.noop;
+        this._loaded = false;
+
+        //If we assign new image url to the this._img IE9 fires onload event and image width and
+        //height are set to zero. So, we create another image object and load image through it.
+        var img = new Image();
+        img.onload = function() {
+            self._loaded = true;
+            self._reset(this.width, this.height);
+
+            self._img[0].src = src;
+            loaded();
+        };
+        img.src = src;
+
+        this._img
+            .removeAttr("src")
+            .removeAttr("width")
+            .removeAttr("height")
+            .removeAttr("style")
+            .css({ position: "absolute", top :"0px", left: "0px"})
+
+        this.angle(0);
+    };
+
+    this._dimension = function(prefix, name) {
+        var horiz = '_' + prefix + '_' + name,
+            vert = '_' + prefix + '_' + (name === 'height' ? 'width' : 'height');
+        return setter(function(val) {
+                this[this._swapDimensions ? horiz: vert] = val;
+            },
+            function() {
+                return this[this._swapDimensions ? horiz: vert];
+            });
+    };
+
+    /**
+     * Getters and setter for common image dimensions.
+     *    display_ means real image tag dimensions
+     *    orig_ means physical image dimensions.
+     *  Note, that dimensions are swapped if image is rotated. It necessary,
+     *  because as little as possible code should know about rotation.
+     */
+    this.display_width = this._dimension('display', 'width'),
+    this.display_height = this._dimension('display', 'height'),
+    this.display_diff = function() { return Math.floor( this.display_width() - this.display_height() ) };
+    this.orig_width = this._dimension('orig', 'width'),
+    this.orig_height = this._dimension('orig', 'height'),
+
+    /**
+     * Setter for  X coordinate. If image is rotated we need to additionaly shift an
+     *     image to map image coordinate to the visual position.
+     *
+     * @param {number} val Coordinate value.
+     * @param {boolean} skipCss If true, we only set the value and do not touch the dom.
+     */
+    this.x = setter(function(val, skipCss) { 
+            this._x = val;
+            if (!skipCss) {
+                this._img.css("left",this._x + (this._swapDimensions ? this.display_diff() / 2 : 0) + "px");
+            }
+        },
+        function() {
+            return this._x;
+        });
+
+    /**
+     * Setter for  Y coordinate. If image is rotated we need to additionaly shift an
+     *     image to map image coordinate to the visual position.
+     *
+     * @param {number} val Coordinate value.
+     * @param {boolean} skipCss If true, we only set the value and do not touch the dom.
+     */
+    this.y = setter(function(val, skipCss) {
+            this._y = val;
+            if (!skipCss) {
+                this._img.css("top",this._y - (this._swapDimensions ? this.display_diff() / 2 : 0) + "px");
+            }
+        },
+       function() {
+            return this._y;
+       });
+
+    /**
+     * Perform image rotation.
+     *
+     * @param {number} deg Absolute image angle. The method will work with values 0, 90, 180, 270 degrees.
+     */
+    this.angle = setter(function(deg) {
+            var prevSwap = this._swapDimensions;
+
+            this._angle = deg;
+            this._swapDimensions = deg % 180 !== 0;
+            
+            if (prevSwap !== this._swapDimensions) {
+                var verticalMod = this._swapDimensions ? -1 : 1;
+                this.x(this.x() - verticalMod * this.display_diff() / 2, true);
+                this.y(this.y() + verticalMod * this.display_diff() / 2, true);
+            };
+
+            var cssVal = 'rotate(' + deg + 'deg)',
+                img = this._img;
+
+            jQuery.each(['', '-webkit-', '-moz-', '-o-', '-ms-'], function(i, prefix) {
+                img.css(prefix + 'transform', cssVal);
+            });
+
+            if (useIeTransforms) {
+                jQuery.each(['-ms-', ''], function(i, prefix) {
+                    img.css(prefix + 'filter', ieTransforms[deg].filter);
+                });
+
+                img.css({
+                    marginLeft: ieTransforms[deg].marginLeft * this.display_diff() / 2,
+                    marginTop: ieTransforms[deg].marginTop * this.display_diff() / 2
+                });
+            }
+        },
+       function() { return this._angle; });
+
+    /**
+     * Map point in the container coordinates to the point in image coordinates.
+     *     You will get coordinates of point on image with respect to rotation,
+     *     but will be set as if image was not rotated.
+     *     So, if image was rotated 90 degrees, it's (0,0) point will be on the
+     *     top right corner.
+     *
+     * @param {{x: number, y: number}} point Point in container coordinates.
+     * @return  {{x: number, y: number}}
+     */
+    this.toOriginalCoords = function(point) {
+        switch (this.angle()) {
+            case 0: return { x: point.x, y: point.y }
+            case 90: return { x: point.y, y: this.display_width() - point.x }
+            case 180: return { x: this.display_width() - point.x, y: this.display_height() - point.y }
+            case 270: return { x: this.display_height() - point.y, y: point.x }
+        }
+    };
+
+    /**
+     * Map point in the image coordinates to the point in container coordinates.
+     *     You will get coordinates of point on container with respect to rotation.
+     *     Note, if image was rotated 90 degrees, it's (0,0) point will be on the
+     *     top right corner.
+     *
+     * @param {{x: number, y: number}} point Point in container coordinates.
+     * @return  {{x: number, y: number}}
+     */
+    this.toRealCoords = function(point) {
+        switch (this.angle()) {
+            case 0: return { x: this.x() + point.x, y: this.y() + point.y }
+            case 90: return { x: this.x() + this.display_width() - point.y, y: this.y() + point.x}
+            case 180: return { x: this.x() + this.display_width() - point.x, y: this.y() + this.display_height() - point.y}
+            case 270: return { x: this.x() + point.y, y: this.y() + this.display_height() - point.x}
+        }
+    };
+
+    /**
+     * @return {jQuery} Return image node. this is needed to add event handlers.
+     */
+    this.object = setter(jQuery.noop,
+                           function() { return this._img; });
+
+    /**
+     * Change image properties.
+     *
+     * @param {number} disp_w Display width;
+     * @param {number} disp_h Display height;
+     * @param {number} x
+     * @param {number} y
+     * @param {boolean} skip_animation If true, the animation will be skiped despite the
+     *     value set in constructor.
+     * @param {Function=} complete Call back will be fired when zoom will be complete.
+     */
+    this.setImageProps = function(disp_w, disp_h, x, y, skip_animation, complete) {
+        complete = complete || jQuery.noop;
+
+        this.display_width(disp_w);
+        this.display_height(disp_h);
+        this.x(x, true);
+        this.y(y, true);
+
+        var w = this._swapDimensions ? disp_h : disp_w;
+        var h = this._swapDimensions ? disp_w : disp_h;
+
+        var params = {
+            width: w,
+            height: h,
+            top: y - (this._swapDimensions ? this.display_diff() / 2 : 0) + "px",
+            left: x + (this._swapDimensions ? this.display_diff() / 2 : 0) + "px" 
+        };
+
+        if (useIeTransforms) {
+            jQuery.extend(params, {
+                marginLeft: ieTransforms[this.angle()].marginLeft * this.display_diff() / 2,
+                marginTop: ieTransforms[this.angle()].marginTop * this.display_diff() / 2
+            });
+        }
+
+        var swapDims = this._swapDimensions,
+            img = this._img;
+
+        //here we come: another IE oddness. If image is rotated 90 degrees with a filter, than
+        //width and height getters return real width and height of rotated image. The bad news
+        //is that to set height you need to set a width and vice versa. Fuck IE.
+        //So, in this case we have to animate width and height manually.
+        if(useIeTransforms && swapDims) {
+            var ieh = this._img.width(),
+                iew = this._img.height(),
+                iedh = params.height - ieh;
+                iedw = params.width - iew;
+
+            delete params.width;
+            delete params.height;
+        }
+
+        if (this._do_anim && !skip_animation) {
+            this._img.animate(params, {
+                duration: 200, 
+                complete: complete,
+                step: function(now, fx) {
+                    if(useIeTransforms && swapDims && (fx.prop === 'top')) {
+                        var percent = (now - fx.start) / (fx.end - fx.start);
+
+                        img.height(ieh + iedh * percent);
+                        img.width(iew + iedw * percent);
+                        img.css('top', now);
+                    }
+                }
+            });
+        } else {
+            this._img.css(params);
+            setTimeout(complete, 0); //both if branches should behave equally.
+        }
+    };
+
+}).apply($.ui.iviewer.ImageObject.prototype);
+
+
+
+var util = {
+    scaleValue: function(value, toZoom)
+    {
+        return value * toZoom / 100;
+    },
+
+    descaleValue: function(value, fromZoom)
+    {
+        return value * 100 / fromZoom;
+    }
+};
+
+ } )( jQuery, undefined );

Added: websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.iviewer.min.js
==============================================================================
--- websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.iviewer.min.js (added)
+++ websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.iviewer.min.js Wed Jul  3 04:39:47 2013
@@ -0,0 +1,42 @@
+/*
+ * iviewer Widget for jQuery UI
+ * https://github.com/can3p/iviewer
+ *
+ * Copyright (c) 2009 - 2012 Dmitry Petrov
+ * Dual licensed under the MIT and GPL licenses.
+ *  - http://www.opensource.org/licenses/mit-license.php
+ *  - http://www.gnu.org/copyleft/gpl.html
+ *
+ * Author: Dmitry Petrov
+ * Version: 0.7
+ */
+(function($,undefined){var mouseEvents={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup"};function makeMouseEvent(event){var touch=event.originalEvent.changedTouches[0];return $.extend(event,{type:mouseEvents[event.type],which:1,pageX:touch.pageX,pageY:touch.pageY,screenX:touch.screenX,screenY:touch.screenY,clientX:touch.clientX,clientY:touch.clientY,isTouchEvent:true})}var mouseProto=$.ui.mouse.prototype,_mouseInit=$.ui.mouse.prototype._mouseInit;mouseProto._mouseInit=function(){var self=
+this;self._touchActive=false;this.element.bind("touchstart."+this.widgetName,function(event){self._touchActive=true;return self._mouseDown(makeMouseEvent(event))});var self=this;this._mouseMoveDelegate=function(event){if(self._touchActive)return self._mouseMove(makeMouseEvent(event))};this._mouseUpDelegate=function(event){if(self._touchActive){self._touchActive=false;return self._mouseUp(makeMouseEvent(event))}};$(document).bind("touchmove."+this.widgetName,this._mouseMoveDelegate).bind("touchend."+
+this.widgetName,this._mouseUpDelegate);_mouseInit.apply(this)};var setter=function(setter,getter){return function(val){if(arguments.length===0)return getter.apply(this);else setter.apply(this,arguments)}};var ieTransforms={"0":{marginLeft:0,marginTop:0,filter:'progid:DXImageTransform.Microsoft.Matrix(M11=1, M12=0, M21=0, M22=1, SizingMethod="auto expand")'},"90":{marginLeft:-1,marginTop:1,filter:'progid:DXImageTransform.Microsoft.Matrix(M11=0, M12=-1, M21=1, M22=0, SizingMethod="auto expand")'},"180":{marginLeft:0,
+marginTop:0,filter:'progid:DXImageTransform.Microsoft.Matrix(M11=-1, M12=0, M21=0, M22=-1, SizingMethod="auto expand")'},"270":{marginLeft:-1,marginTop:1,filter:'progid:DXImageTransform.Microsoft.Matrix(M11=0, M12=1, M21=-1, M22=0, SizingMethod="auto expand")'}},useIeTransforms=jQuery.browser.msie&&parseInt(jQuery.browser.version,10)<=8;$.widget("ui.iviewer",$.ui.mouse,{widgetEventPrefix:"iviewer",options:{zoom:"fit",zoom_base:100,zoom_max:800,zoom_min:25,zoom_delta:1.4,zoom_animation:true,ui_disabled:false,
+update_on_resize:true,onZoom:jQuery.noop,onAfterZoom:jQuery.noop,onStartDrag:jQuery.noop,onDrag:jQuery.noop,onStopDrag:jQuery.noop,onMouseMove:jQuery.noop,onClick:jQuery.noop,onStartLoad:null,onFinishLoad:null},_create:function(){var me=this;this.dx=0;this.dy=0;this.img_object={};this.zoom_object={};this._angle=0;this.current_zoom=this.options.zoom;if(this.options.src===null)return;this.container=this.element;this._updateContainerInfo();this.container.css("overflow","hidden");if(this.options.update_on_resize==
+true)$(window).resize(function(){me._updateContainerInfo()});this.img_object=new $.ui.iviewer.ImageObject(this.options.zoom_animation);this.img_object.object().click(function(e){return me._click(e)}).mousewheel(function(ev,delta){var zoom=delta>0?1:-1;me.zoom_by(zoom);return false}).prependTo(this.container);this.container.bind("mousemove",function(ev){me._handleMouseMove(ev)});this.loadImage(this.options.src);if(!this.options.ui_disabled)this.createui();this._mouseInit()},destroy:function(){this._mouseDestroy()},
+_updateContainerInfo:function(){this.options.height=this.container.height();this.options.width=this.container.width()},loadImage:function(src){this.current_zoom=this.options.zoom;var me=this;this._trigger("onStartLoad",0,src);this.img_object.load(src,function(){me.container.addClass("iviewer_cursor");if(me.options.zoom=="fit")me.fit(true);else me.set_zoom(me.options.zoom,true);if(me.options.onFinishLoad)me._trigger("onFinishLoad",0,src)})},fit:function(skip_animation){var aspect_ratio=this.img_object.orig_width()/
+this.img_object.orig_height();var window_ratio=this.options.width/this.options.height;var choose_left=aspect_ratio>window_ratio;var new_zoom=0;if(choose_left)new_zoom=this.options.width/this.img_object.orig_width()*100;else new_zoom=this.options.height/this.img_object.orig_height()*100;this.set_zoom(new_zoom,skip_animation)},center:function(){this.setCoords(-Math.round((this.img_object.display_width()-this.options.width)/2),-Math.round((this.img_object.display_height()-this.options.height)/2))},moveTo:function(x,
+y){var dx=x-Math.round(this.options.width/2);var dy=y-Math.round(this.options.height/2);var new_x=this.img_object.x()-dx;var new_y=this.img_object.y()-dy;this.setCoords(new_x,new_y)},getContainerOffset:function(){return jQuery.extend({},this.container.offset())},setCoords:function(x,y){if(!this.img_object.loaded())return;var coords=this._correctCoords(x,y);this.img_object.x(coords.x);this.img_object.y(coords.y)},_correctCoords:function(x,y){x=parseInt(x,10);y=parseInt(y,10);if(y>0)y=0;if(x>0)x=0;
+if(y+this.img_object.display_height()<this.options.height)y=this.options.height-this.img_object.display_height();if(x+this.img_object.display_width()<this.options.width)x=this.options.width-this.img_object.display_width();if(this.img_object.display_width()<=this.options.width)x=-(this.img_object.display_width()-this.options.width)/2;if(this.img_object.display_height()<=this.options.height)y=-(this.img_object.display_height()-this.options.height)/2;return{x:x,y:y}},containerToImage:function(x,y){var coords=
+{x:x-this.img_object.x(),y:y-this.img_object.y()};coords=this.img_object.toOriginalCoords(coords);return{x:util.descaleValue(coords.x,this.current_zoom),y:util.descaleValue(coords.y,this.current_zoom)}},imageToContainer:function(x,y){var coords={x:util.scaleValue(x,this.current_zoom),y:util.scaleValue(y,this.current_zoom)};return this.img_object.toRealCoords(coords)},_getMouseCoords:function(e){var containerOffset=this.container.offset();coords=this.containerToImage(e.pageX-containerOffset.left,e.pageY-
+containerOffset.top);return coords},set_zoom:function(new_zoom,skip_animation){if(this._trigger("onZoom",0,new_zoom)==false)return;if(!this.img_object.loaded())return;if(new_zoom<this.options.zoom_min)new_zoom=this.options.zoom_min;else if(new_zoom>this.options.zoom_max)new_zoom=this.options.zoom_max;if(this.current_zoom=="fit"){var old_x=Math.round(this.options.width/2+this.img_object.orig_width()/2);var old_y=Math.round(this.options.height/2+this.img_object.orig_height()/2);this.current_zoom=100}else{var old_x=
+-this.img_object.x()+Math.round(this.options.width/2);var old_y=-this.img_object.y()+Math.round(this.options.height/2)}var new_width=util.scaleValue(this.img_object.orig_width(),new_zoom);var new_height=util.scaleValue(this.img_object.orig_height(),new_zoom);var new_x=util.scaleValue(util.descaleValue(old_x,this.current_zoom),new_zoom);var new_y=util.scaleValue(util.descaleValue(old_y,this.current_zoom),new_zoom);new_x=this.options.width/2-new_x;new_y=this.options.height/2-new_y;this.img_object.display_width(new_width);
+this.img_object.display_height(new_height);var coords=this._correctCoords(new_x,new_y),self=this;this.img_object.setImageProps(new_width,new_height,coords.x,coords.y,skip_animation,function(){self._trigger("onAfterZoom",0,new_zoom)});this.current_zoom=new_zoom;this.update_status()},zoom_by:function(delta){var closest_rate=this.find_closest_zoom_rate(this.current_zoom);var next_rate=closest_rate+delta;var next_zoom=this.options.zoom_base*Math.pow(this.options.zoom_delta,next_rate);if(delta>0&&next_zoom<
+this.current_zoom)next_zoom*=this.options.zoom_delta;if(delta<0&&next_zoom>this.current_zoom)next_zoom/=this.options.zoom_delta;this.set_zoom(next_zoom)},angle:function(deg,abs){if(arguments.length===0)return this.img_object.angle();if(deg<-270||deg>270||deg%90!==0)return;if(!abs)deg+=this.img_object.angle();if(deg<0)deg+=360;if(deg>=360)deg-=360;if(deg===this.img_object.angle())return;this.img_object.angle(deg);this.center();this._trigger("angle",0,{angle:this.img_object.angle()})},find_closest_zoom_rate:function(value){if(value==
+this.options.zoom_base)return 0;function div(val1,val2){return val1/val2}function mul(val1,val2){return val1*val2}var func=value>this.options.zoom_base?mul:div;var sgn=value>this.options.zoom_base?1:-1;var mltplr=this.options.zoom_delta;var rate=1;while(Math.abs(func(this.options.zoom_base,Math.pow(mltplr,rate))-value)>Math.abs(func(this.options.zoom_base,Math.pow(mltplr,rate+1))-value))rate++;return sgn*rate},update_status:function(){if(!this.options.ui_disabled){var percent=Math.round(100*this.img_object.display_height()/
+this.img_object.orig_height());if(percent)this.zoom_object.html(percent+"%")}},info:function(param,withoutRotation){if(!param)return;switch(param){case "orig_width":case "orig_height":if(withoutRotation)return this.img_object.angle()%180===0?this.img_object[param]():param==="orig_width"?this.img_object.orig_height():this.img_object.orig_width();else return this.img_object[param]();case "display_width":case "display_height":case "angle":return this.img_object[param]();case "zoom":return this.current_zoom;
+case "src":return this.img_object.object().attr("src")}},_mouseStart:function(e){$.ui.mouse.prototype._mouseStart.call(this,e);if(this._trigger("onStartDrag",0,this._getMouseCoords(e))===false)return false;this.container.addClass("iviewer_drag_cursor");this.dx=e.pageX-this.img_object.x();this.dy=e.pageY-this.img_object.y();return true},_mouseCapture:function(e){return true},_handleMouseMove:function(e){this._trigger("onMouseMove",e,this._getMouseCoords(e))},_mouseDrag:function(e){$.ui.mouse.prototype._mouseDrag.call(this,
+e);var ltop=e.pageY-this.dy;var lleft=e.pageX-this.dx;this.setCoords(lleft,ltop);this._trigger("onDrag",e,this._getMouseCoords(e));return false},_mouseStop:function(e){$.ui.mouse.prototype._mouseStop.call(this,e);this.container.removeClass("iviewer_drag_cursor");this._trigger("onStopDrag",0,this._getMouseCoords(e))},_click:function(e){this._trigger("onClick",0,this._getMouseCoords(e))},createui:function(){var me=this;$("<div>",{"class":"iviewer_zoom_in iviewer_common iviewer_button"}).bind("mousedown touchstart",
+function(){me.zoom_by(1);return false}).appendTo(this.container);$("<div>",{"class":"iviewer_zoom_out iviewer_common iviewer_button"}).bind("mousedown touchstart",function(){me.zoom_by(-1);return false}).appendTo(this.container);$("<div>",{"class":"iviewer_zoom_zero iviewer_common iviewer_button"}).bind("mousedown touchstart",function(){me.set_zoom(100);return false}).appendTo(this.container);$("<div>",{"class":"iviewer_zoom_fit iviewer_common iviewer_button"}).bind("mousedown touchstart",function(){me.fit(this);
+return false}).appendTo(this.container);this.zoom_object=$("<div>").addClass("iviewer_zoom_status iviewer_common").appendTo(this.container);$("<div>",{"class":"iviewer_rotate_left iviewer_common iviewer_button"}).bind("mousedown touchstart",function(){me.angle(-90);return false}).appendTo(this.container);$("<div>",{"class":"iviewer_rotate_right iviewer_common iviewer_button"}).bind("mousedown touchstart",function(){me.angle(90);return false}).appendTo(this.container);this.update_status()}});$.ui.iviewer.ImageObject=
+function(do_anim){this._img=$("<img>").css({position:"absolute",top:"0px",left:"0px"});this._loaded=false;this._swapDimensions=false;this._do_anim=do_anim||false;this.x(0,true);this.y(0,true);this.angle(0)};(function(){this._reset=function(w,h){this._angle=0;this._swapDimensions=false;this.x(0);this.y(0);this.orig_width(w);this.orig_height(h);this.display_width(w);this.display_height(h)};this.loaded=function(){return this._loaded};this.load=function(src,loaded){var self=this;loaded=loaded||jQuery.noop;
+this._loaded=false;var img=new Image;img.onload=function(){self._loaded=true;self._reset(this.width,this.height);self._img[0].src=src;loaded()};img.src=src;this._img.removeAttr("src").removeAttr("width").removeAttr("height").removeAttr("style").css({position:"absolute",top:"0px",left:"0px"});this.angle(0)};this._dimension=function(prefix,name){var horiz="_"+prefix+"_"+name,vert="_"+prefix+"_"+(name==="height"?"width":"height");return setter(function(val){this[this._swapDimensions?horiz:vert]=val},
+function(){return this[this._swapDimensions?horiz:vert]})};this.display_width=this._dimension("display","width"),this.display_height=this._dimension("display","height"),this.display_diff=function(){return Math.floor(this.display_width()-this.display_height())};this.orig_width=this._dimension("orig","width"),this.orig_height=this._dimension("orig","height"),this.x=setter(function(val,skipCss){this._x=val;if(!skipCss)this._img.css("left",this._x+(this._swapDimensions?this.display_diff()/2:0)+"px")},
+function(){return this._x});this.y=setter(function(val,skipCss){this._y=val;if(!skipCss)this._img.css("top",this._y-(this._swapDimensions?this.display_diff()/2:0)+"px")},function(){return this._y});this.angle=setter(function(deg){var prevSwap=this._swapDimensions;this._angle=deg;this._swapDimensions=deg%180!==0;if(prevSwap!==this._swapDimensions){var verticalMod=this._swapDimensions?-1:1;this.x(this.x()-verticalMod*this.display_diff()/2,true);this.y(this.y()+verticalMod*this.display_diff()/2,true)}var cssVal=
+"rotate("+deg+"deg)",img=this._img;jQuery.each(["","-webkit-","-moz-","-o-","-ms-"],function(i,prefix){img.css(prefix+"transform",cssVal)});if(useIeTransforms){jQuery.each(["-ms-",""],function(i,prefix){img.css(prefix+"filter",ieTransforms[deg].filter)});img.css({marginLeft:ieTransforms[deg].marginLeft*this.display_diff()/2,marginTop:ieTransforms[deg].marginTop*this.display_diff()/2})}},function(){return this._angle});this.toOriginalCoords=function(point){switch(this.angle()){case 0:return{x:point.x,
+y:point.y};case 90:return{x:point.y,y:this.display_width()-point.x};case 180:return{x:this.display_width()-point.x,y:this.display_height()-point.y};case 270:return{x:this.display_height()-point.y,y:point.x}}};this.toRealCoords=function(point){switch(this.angle()){case 0:return{x:this.x()+point.x,y:this.y()+point.y};case 90:return{x:this.x()+this.display_width()-point.y,y:this.y()+point.x};case 180:return{x:this.x()+this.display_width()-point.x,y:this.y()+this.display_height()-point.y};case 270:return{x:this.x()+
+point.y,y:this.y()+this.display_height()-point.x}}};this.object=setter(jQuery.noop,function(){return this._img});this.setImageProps=function(disp_w,disp_h,x,y,skip_animation,complete){complete=complete||jQuery.noop;this.display_width(disp_w);this.display_height(disp_h);this.x(x,true);this.y(y,true);var w=this._swapDimensions?disp_h:disp_w;var h=this._swapDimensions?disp_w:disp_h;var params={width:w,height:h,top:y-(this._swapDimensions?this.display_diff()/2:0)+"px",left:x+(this._swapDimensions?this.display_diff()/
+2:0)+"px"};if(useIeTransforms)jQuery.extend(params,{marginLeft:ieTransforms[this.angle()].marginLeft*this.display_diff()/2,marginTop:ieTransforms[this.angle()].marginTop*this.display_diff()/2});var swapDims=this._swapDimensions,img=this._img;if(useIeTransforms&&swapDims){var ieh=this._img.width(),iew=this._img.height(),iedh=params.height-ieh;iedw=params.width-iew;delete params.width;delete params.height}if(this._do_anim&&!skip_animation)this._img.animate(params,{duration:200,complete:complete,step:function(now,
+fx){if(useIeTransforms&&swapDims&&fx.prop==="top"){var percent=(now-fx.start)/(fx.end-fx.start);img.height(ieh+iedh*percent);img.width(iew+iedw*percent);img.css("top",now)}}});else{this._img.css(params);setTimeout(complete,0)}}}).apply($.ui.iviewer.ImageObject.prototype);var util={scaleValue:function(value,toZoom){return value*toZoom/100},descaleValue:function(value,fromZoom){return value*100/fromZoom}}})(jQuery,undefined);

Added: websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.mousewheel.min.js
==============================================================================
--- websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.mousewheel.min.js (added)
+++ websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.mousewheel.min.js Wed Jul  3 04:39:47 2013
@@ -0,0 +1,13 @@
+/*! 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(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type="mousewheel";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;b.axis!==void 0&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);b.wheelDeltaY!==void 0&&(g=b.wheelDeltaY/120);b.wheelDeltaX!==void 0&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=
+d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,false);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,false);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
\ No newline at end of file

Added: websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.panzoom.js
==============================================================================
--- websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.panzoom.js (added)
+++ websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.panzoom.js Wed Jul  3 04:39:47 2013
@@ -0,0 +1,467 @@
+/*
+ * jQuery PanZoom Plugin
+ * Pan and zoom an image within a parent div.
+ *
+ * version: 0.9.0
+ * @requires jQuery v1.4.2 or later (earlier probably work, but untested so far)
+ *
+ * Copyright (c) 2011 Ben Lumley
+ * Examples and documentation at: https://github.com/benlumley/jQuery-PanZoom
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+*/
+
+(function( $ ){
+
+  $.fn.panZoom = function(method) {
+
+    if ( methods[method] ) {
+      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
+    } else if ( typeof method === 'object' || ! method ) {
+      return methods.init.apply( this, arguments );
+    } else {
+      $.error( 'Method ' +  method + ' does not exist' );
+    }
+
+  };
+
+	$.fn.panZoom.defaults = {
+      zoomIn   					: 	false,
+      zoomOut 					: 	false,
+		  panUp							:		false,
+		  panDown						:		false,
+		  panLeft						:		false,
+		  panRight					:		false,
+			fit								: 	false,
+		  out_x1						:		false,
+		  out_y1						:		false,
+		  out_x2						:		false,
+		  out_y2						:		false,
+			min_width					:   20,
+			min_height 				:   20,
+			zoom_step					:   3,
+			pan_step  				:   3,
+			debug							: 	false,
+			directedit				:   false,
+      aspect    				:   true,
+      factor    				:   1,
+		  animate   				:   true,
+			animate_duration	: 	200,
+		 	animate_easing		: 	'linear',
+			double_click	 		: 	true,
+			mousewheel				: 	true,
+			mousewheel_delta	: 	1,
+			draggable					:   true,
+			clickandhold			: 	true
+  };
+
+	var settings = {}
+
+  var methods = {
+		'init': function (options) {
+			$.extend(settings, $.fn.panZoom.defaults, options);
+  		setupCSS.apply(this);
+			setupData.apply(this);
+			setupBindings.apply(this);
+			methods.readPosition.apply(this);
+		},
+
+		'destroy': function () {
+			$(window).unbind('.panZoom');
+			this.removeData('panZoom');
+		},
+
+		'loadImage': function () {
+			var data = this.data('panZoom');
+      loadTargetDimensions.apply(this);
+			methods.updatePosition.apply(this);
+			if (data.last_image != null && data.last_image != this.attr('src')) {
+        methods.fit.apply(this);
+			}
+			data.last_image = this.attr('src');
+			data.loaded = true;
+		},
+
+	  'readPosition': function () {
+				var data = this.data('panZoom');
+		 		if (settings.out_x1) { data.position.x1 = settings.out_x1.val()*settings.factor }
+		 		if (settings.out_y1) { data.position.y1 = settings.out_y1.val()*settings.factor }
+		 		if (settings.out_x2) { data.position.x2 = settings.out_x2.val()*settings.factor }
+		 		if (settings.out_y2) { data.position.y2 = settings.out_y2.val()*settings.factor }
+				methods.updatePosition.apply(this);
+		 },
+
+		'updatePosition': function() {
+			validatePosition.apply(this);
+			writePosition.apply(this);
+			applyPosition.apply(this);
+		},
+
+	  'fit': function () {
+			var data = this.data('panZoom');
+			data.position.x1 = 0;
+			data.position.y1 = 0;
+			data.position.x2 = data.viewport_dimensions.x;
+			data.position.y2 = data.viewport_dimensions.y;
+			methods.updatePosition.apply(this);
+		},
+
+		'zoomIn': function (steps) {
+			var data = this.data('panZoom');
+			if (typeof(steps) == 'undefined') {
+				var steps = getStepDimensions.apply(this);
+			}
+            console.debug(data.position);
+			console.debug(data.viewport_dimensions);
+			data.position.x1 = data.position.x1*1 - steps.zoom.x;
+			data.position.x2 = data.position.x2*1 + steps.zoom.x;
+			data.position.y1 = data.position.y1*1 - steps.zoom.y;
+			data.position.y2 = data.position.y2*1 + steps.zoom.y;
+			methods.updatePosition.apply(this);
+		 },
+
+		'zoomOut': function (steps) {
+			var data = this.data('panZoom');
+			if (typeof(steps) == 'undefined') {
+				var steps = getStepDimensions.apply(this);
+			}
+			data.position.x1 = data.position.x1*1 + steps.zoom.x;
+			data.position.x2 = data.position.x2*1 - steps.zoom.x;
+			data.position.y1 = data.position.y1*1 + steps.zoom.y;
+			data.position.y2 = data.position.y2*1 - steps.zoom.y;
+			methods.updatePosition.apply(this);
+		 },
+
+		'panUp': function () {
+			var data = this.data('panZoom');
+			var steps = getStepDimensions.apply(this);
+			data.position.y1 -= steps.pan.y;
+			data.position.y2 -= steps.pan.y;
+			methods.updatePosition.apply(this);
+		},
+
+		'panDown': function () {
+			var data = this.data('panZoom');
+			var steps = getStepDimensions.apply(this);
+			data.position.y1 = data.position.y1*1 + steps.pan.y;
+			data.position.y2 = data.position.y2*1 + steps.pan.y;
+			methods.updatePosition.apply(this);
+		},
+
+		'panLeft': function () {
+			var data = this.data('panZoom');
+			var steps = getStepDimensions.apply(this);
+			data.position.x1 -= steps.pan.x;
+			data.position.x2 -= steps.pan.x;
+			methods.updatePosition.apply(this);
+		},
+
+		'panRight': function () {
+			var data = this.data('panZoom');
+			var steps = getStepDimensions.apply(this);
+			data.position.x1 = data.position.x1*1 + steps.pan.x;
+			data.position.x2 = data.position.x2*1 + steps.pan.x;
+			methods.updatePosition.apply(this);
+		},
+
+		'mouseWheel': function (delta) {
+			// first calculate how much to zoom in/out
+			var steps = getStepDimensions.apply(this);
+			steps.zoom.x = steps.zoom.x * (Math.abs(delta) / settings.mousewheel_delta);
+			steps.zoom.y = steps.zoom.y * (Math.abs(delta) / settings.mousewheel_delta);
+
+			// then do it
+			if (delta > 0) {
+				methods.zoomIn.apply(this, [steps]);
+			} else if (delta < 0) {
+				methods.zoomOut.apply(this, [steps]);
+			}
+		},
+
+		'dragComplete': function() {
+			var data = this.data('panZoom');
+			data.position.x1 = this.position().left;
+			data.position.y1 = this.position().top;
+			data.position.x2 = this.position().left*1 + this.width();
+			data.position.y2 = this.position().top*1 + this.height();
+			methods.updatePosition.apply(this);
+		},
+
+		'mouseDown': function (action) {
+			methods[action].apply(this);
+
+			if (settings.clickandhold) {
+				var data = this.data('panZoom');
+				methods.mouseUp.apply(this);
+				data.mousedown_interval = window.setInterval(function (that, action) {
+					that.panZoom(action);
+				}, settings.animate_duration, this, action);
+			}
+		},
+
+		'mouseUp': function() {
+			var data = this.data('panZoom');
+			window.clearInterval(data.mousedown_interval);
+		}
+
+  }
+
+	function setupBindings() {
+
+		eventData = { target: this }
+
+		// bind up controls
+		if (settings.zoomIn) {
+			settings.zoomIn.bind('mousedown.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseDown', 'zoomIn');
+			}).bind('mouseleave.panZoom mouseup.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseUp');
+			});
+		}
+
+		if (settings.zoomOut) {
+			settings.zoomOut.bind('mousedown.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseDown', 'zoomOut');
+			}).bind('mouseleave.panZoom mouseup.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseUp');
+			});
+		}
+
+		if (settings.panUp) {
+			settings.panUp.bind('mousedown.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseDown', 'panUp');
+			}).bind('mouseleave.panZoom mouseup.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseUp');
+			});
+		}
+
+		if (settings.panDown) {
+			settings.panDown.bind('mousedown.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseDown', 'panDown');
+			}).bind('mouseleave.panZoom mouseup.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseUp');
+			});
+		}
+
+		if (settings.panLeft) {
+			settings.panLeft.bind('mousedown.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseDown', 'panLeft');
+			}).bind('mouseleave.panZoom mouseup.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseUp');
+			});
+		}
+
+		if (settings.panRight) {
+			settings.panRight.bind('mousedown.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseDown', 'panRight');
+			}).bind('mouseleave.panZoom mouseup.panZoom', eventData, function(event) {
+				event.preventDefault(); event.data.target.panZoom('mouseUp');
+			});
+		}
+
+		if (settings.fit) { settings.fit.bind('click.panZoom', eventData, function(event) { event.preventDefault(); event.data.target.panZoom('fit'); } ); }
+
+		// double click
+		if (settings.double_click) {
+			this.bind('dblclick.panZoom', eventData, function(event, delta) { event.data.target.panZoom('zoomIn') } );
+		}
+
+		// mousewheel
+		if (settings.mousewheel && typeof(this.mousewheel) == 'function') {
+			this.parent().mousewheel(function(event, delta) { event.preventDefault(); $(this).find('img').panZoom('mouseWheel', delta) } );
+		} else if (settings.mousewheel) {
+			alert('Mousewheel requires mousewheel from jQuery tools - please include jQuery tools or disable mousewheel to remove this warning.')
+		}
+
+		// direct form input
+		if (settings.directedit) {
+			$(settings.out_x1).add(settings.out_y1).add(settings.out_x2).add(settings.out_y2).bind('change.panZoom blur.panZoom', eventData, function(event) { event.data.target.panZoom('readPosition') } );
+		}
+
+		if (settings.draggable && typeof(this.draggable) == 'function') {
+			this.draggable({
+				stop: function () { $(this).panZoom('dragComplete');	}
+			});
+		}	else if (settings.draggable) {
+				alert('Draggable requires jQuery UI - please include jQuery UI or disable draggable to remove this warning.')
+		}
+
+		// image load
+		$(this).bind('load.panZoom', eventData, function (event) { event.data.target.panZoom('loadImage') })
+
+	}
+
+	function setupData() {
+		this.data('panZoom', {
+			target_element: this,
+			target_dimensions: { x: null, y: null },
+			viewport_element: this.parent(),
+			viewport_dimensions: { x: this.parent().width(), y: this.parent().height() },
+			position: { x1: null, y1: null, x2: null, y2: null },
+			last_image: null,
+			loaded: false,
+			mousewheel_delta: 0,
+			mousedown_interval: false
+		});
+		if (settings.debug) {
+			console.log(this.data('panZoom'));
+		}
+	}
+
+	function setupCSS() {
+		if (this.parent().css('position') == 'static') {
+			this.parent().css('position', 'relative');
+		}
+		this.css({
+			'position': 'absolute',
+			'top': 0,
+			'left': 0
+		});
+		if (settings.draggable) {
+			this.css({
+				'cursor': 'move'
+			});
+		}
+	}
+
+	function validatePosition() {
+		var data = this.data('panZoom');
+		// if dimensions are too small...
+		if ( data.position.x2 - data.position.x1 < settings.min_width/settings.factor || data.position.y2 - data.position.y1 < settings.min_height/settings.factor ) {
+			// and second co-ords are zero (IE: no dims set), fit image
+			if (data.position.x2 == 0 || data.position.y2 == 0) {
+				methods.fit.apply(this);
+			}
+			// otherwise, backout a bit
+			else {
+				if (data.position.x2 - data.position.x1 < settings.min_width/settings.factor) {
+					data.position.x2 = data.position.x1*1+settings.min_width/settings.factor;
+				}
+				if (data.position.y2 - data.position.y1 < settings.min_height/settings.factor) {
+	  			data.position.y2 = data.position.y1*1+settings.min_height/settings.factor;
+				}
+			}
+		}
+
+		if (settings.aspect) {
+			target = data.target_dimensions.ratio;
+			current = getCurrentAspectRatio.apply(this)
+			if (current > target) {
+				new_width = getHeight.apply(this) * target;
+				diff = getWidth.apply(this) - new_width;
+				data.position.x1 = data.position.x1*1 + (diff/2);
+				data.position.x2 = data.position.x2*1 - (diff/2);
+			} else if (current < target) {
+				new_height = getWidth.apply(this) / target;
+				diff = getHeight.apply(this) - new_height;
+				data.position.y1 = data.position.y1*1 + (diff/2);
+				data.position.y2 = data.position.y2*1 - (diff/2);
+			}
+		}
+
+
+	}
+
+  function applyPosition() {
+		var data = this.data('panZoom');
+
+    width = getWidth.apply(this);
+    height = getHeight.apply(this);
+    left_offset = getLeftOffset.apply(this);
+    top_offset = getTopOffset.apply(this);
+
+		properties = {
+			'top': Math.round(top_offset),
+			'left': Math.round(left_offset),
+			'width': Math.round(width),
+			'height': Math.round(height)
+		}
+
+		if (data.loaded && settings.animate) {
+			applyAnimate.apply(this, [ properties ]);
+		} else {
+			applyCSS.apply(this, [ properties ]);
+		}
+
+		if (settings.debug) {
+			console.log('--');
+			console.log('width:' + width);
+			console.log('height:' + height);
+			console.log('left:' + left_offset);
+			console.log('top:' + top_offset);
+		}
+	}
+
+	function applyCSS() {
+		this.css(	properties );
+	}
+
+	function applyAnimate() {
+		this.stop().animate(	properties , settings.animate_duration, settings.animate_easing);
+	}
+
+  function getWidth() {
+		var data = this.data('panZoom');
+    width = (data.position.x2 - data.position.x1);
+    return width;
+  }
+
+  function getLeftOffset() {
+		var data = this.data('panZoom');
+    return data.position.x1;
+  }
+
+  function getHeight() {
+		var data = this.data('panZoom');
+		height = (data.position.y2 - data.position.y1);
+    return height;
+  }
+
+  function getTopOffset() {
+		var data = this.data('panZoom');
+		top_offset = data.position.y1;
+    return top_offset;
+  }
+
+	function getCurrentAspectRatio() {
+		return (getWidth.apply(this) / getHeight.apply(this));
+	}
+
+	function writePosition() {
+		var data = this.data('panZoom');
+ 		if (settings.out_x1) { settings.out_x1.val(Math.round(data.position.x1 / settings.factor)) }
+ 		if (settings.out_y1) { settings.out_y1.val(Math.round(data.position.y1 / settings.factor)) }
+ 		if (settings.out_x2) { settings.out_x2.val(Math.round(data.position.x2 / settings.factor)) }
+ 		if (settings.out_y2) { settings.out_y2.val(Math.round(data.position.y2 / settings.factor)) }
+	}
+
+	function getStepDimensions() {
+		var data = this.data('panZoom');
+		ret = {
+			zoom: {
+				x: (settings.zoom_step/100 * data.viewport_dimensions.x),
+				y: (settings.zoom_step/100 * data.viewport_dimensions.y)
+			},
+			pan: {
+				x: (settings.pan_step/100 * data.viewport_dimensions.x),
+				y: (settings.pan_step/100 * data.viewport_dimensions.y)
+			}
+		}
+		return ret;
+	}
+
+	function loadTargetDimensions() {
+		var data = this.data('panZoom');
+		var img = document.createElement('img');
+    img.src = this.attr('src');
+    img.id = "jqpz-temp";
+    $('body').append(img);
+    data.target_dimensions.x = $('#jqpz-temp').width();
+		data.target_dimensions.y = $('#jqpz-temp').height();
+    $('#jqpz-temp').remove();
+    data.target_dimensions.ratio = data.target_dimensions.x / data.target_dimensions.y;
+	}
+
+})( jQuery );
\ No newline at end of file

Added: websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.splitter.js
==============================================================================
--- websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.splitter.js (added)
+++ websites/staging/chemistry/trunk/content/php/docs/atom/js/jquery.splitter.js Wed Jul  3 04:39:47 2013
@@ -0,0 +1,228 @@
+/*
+ * jQuery.splitter.js - two-pane splitter window plugin
+ *
+ * version 1.51 (2009/01/09)
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ */
+
+/**
+ * The splitter() plugin implements a two-pane resizable splitter window.
+ * The selected elements in the jQuery object are converted to a splitter;
+ * each selected element should have two child elements, used for the panes
+ * of the splitter. The plugin adds a third child element for the splitbar.
+ *
+ * For more details see: http://methvin.com/splitter/
+ *
+ *
+ * @example $('#MySplitter').splitter();
+ * @desc Create a vertical splitter with default settings
+ *
+ * @example $('#MySplitter').splitter({type: 'h', accessKey: 'M'});
+ * @desc Create a horizontal splitter resizable via Alt+Shift+M
+ *
+ * @name splitter
+ * @type jQuery
+ * @param Object options Options for the splitter (not required)
+ * @cat Plugins/Splitter
+ * @return jQuery
+ * @author Dave Methvin (dave.methvin@gmail.com)
+ */
+;
+(function($) {
+
+    $.fn.splitter = function(args) {
+        args = args || {};
+        return this.each(function() {
+            var zombie;      // left-behind splitbar for outline resizes
+            function startSplitMouse(evt) {
+                if (opts.outline)
+                    zombie = zombie || bar.clone(false).insertAfter(A);
+                panes.css("-webkit-user-select", "none");   // Safari selects A/B text on a move
+                bar.addClass(opts.activeClass);
+                $('<div class="splitterMask"></div>').insertAfter(bar);
+                A._posSplit = A[0][opts.pxSplit] - evt[opts.eventPos];
+                $(document)
+                        .bind("mousemove", doSplitMouse)
+                        .bind("mouseup", endSplitMouse);
+            }
+
+            function doSplitMouse(evt) {
+                var newPos = A._posSplit + evt[opts.eventPos];
+                if (opts.outline) {
+                    newPos = Math.max(0, Math.min(newPos, splitter._DA - bar._DA));
+                    bar.css(opts.origin, newPos);
+                } else
+                    resplit(newPos);
+            }
+
+            function endSplitMouse(evt) {
+                $('div.splitterMask').remove();
+                bar.removeClass(opts.activeClass);
+                var newPos = A._posSplit + evt[opts.eventPos];
+                if (opts.outline) {
+                    zombie.remove();
+                    zombie = null;
+                    resplit(newPos);
+                }
+                panes.css("-webkit-user-select", "text");   // let Safari select text again
+                $(document)
+                        .unbind("mousemove", doSplitMouse)
+                        .unbind("mouseup", endSplitMouse);
+            }
+
+            function resplit(newPos) {
+                // Constrain new splitbar position to fit pane size limits
+                newPos = Math.max(A._min, splitter._DA - B._max,
+                        Math.min(newPos, A._max, splitter._DA - bar._DA - B._min));
+                // Resize/position the two panes
+                bar._DA = bar[0][opts.pxSplit];      // bar size may change during dock
+                bar.css(opts.origin, newPos).css(opts.fixed, splitter._DF);
+                A.css(opts.origin, 0).css(opts.split, newPos).css(opts.fixed, splitter._DF);
+                B.css(opts.origin, newPos + bar._DA)
+                        .css(opts.split, splitter._DA - bar._DA - newPos).css(opts.fixed, splitter._DF);
+                // IE fires resize for us; all others pay cash
+                if (!$.browser.msie)
+                    panes.trigger("resize");
+            }
+
+            function dimSum(jq, dims) {
+                // Opera returns -1 for missing min/max width, turn into 0
+                var sum = 0;
+                for (var i = 1; i < arguments.length; i++)
+                    sum += Math.max(parseInt(jq.css(arguments[i])) || 0, 0);
+                return sum;
+            }
+
+            // Determine settings based on incoming opts, element classes, and defaults
+            var vh = (args.splitHorizontal ? 'h' : args.splitVertical ? 'v' : args.type) || 'v';
+            var opts = $.extend({
+                activeClass: 'active',   // class name for active splitter
+                pxPerKey: 8,         // splitter px moved per keypress
+                tabIndex: 0,         // tab order indicator
+                accessKey: ''         // accessKey for splitbar
+            }, {
+                v: {               // Vertical splitters:
+                    keyLeft: 39, keyRight: 37, cursor: "e-resize",
+                    splitbarClass: "vsplitbar", outlineClass: "voutline",
+                    type: 'v', eventPos: "pageX", origin: "left",
+                    split: "width",  pxSplit: "offsetWidth",  side1: "Left", side2: "Right",
+                    fixed: "height", pxFixed: "offsetHeight", side3: "Top",  side4: "Bottom"
+                },
+                h: {               // Horizontal splitters:
+                    keyTop: 40, keyBottom: 38,  cursor: "n-resize",
+                    splitbarClass: "hsplitbar", outlineClass: "houtline",
+                    type: 'h', eventPos: "pageY", origin: "top",
+                    split: "height", pxSplit: "offsetHeight", side1: "Top",  side2: "Bottom",
+                    fixed: "width",  pxFixed: "offsetWidth",  side3: "Left", side4: "Right"
+                }
+            }[vh], args);
+
+            // Create jQuery object closures for splitter and both panes
+            var splitter = $(this).css({position: "relative"});
+            var panes = $(">*", splitter[0]).css({
+                position: "absolute",          // positioned inside splitter container
+                "z-index": "1",               // splitbar is positioned above
+                "-moz-outline-style": "none"   // don't show dotted outline
+            });
+            var A = $(panes[0]);      // left  or top
+            var B = $(panes[1]);      // right or bottom
+
+            // Focuser element, provides keyboard support; title is shown by Opera accessKeys
+            var focuser = $('<a href="javascript:void(0)"></a>')
+                    .attr({accessKey: opts.accessKey, tabIndex: opts.tabIndex, title: opts.splitbarClass})
+                    .bind($.browser.opera ? "click" : "focus", function() {
+                        this.focus();
+                        bar.addClass(opts.activeClass)
+                    })
+                    .bind("keydown", function(e) {
+                        var key = e.which || e.keyCode;
+                        var dir = key == opts["key" + opts.side1] ? 1 : key == opts["key" + opts.side2] ? -1 : 0;
+                        if (dir)
+                            resplit(A[0][opts.pxSplit] + dir * opts.pxPerKey, false);
+                    })
+                    .bind("blur", function() {
+                        bar.removeClass(opts.activeClass)
+                    });
+
+            // Splitbar element, can be already in the doc or we create one
+            var bar = $(panes[2] || '<div></div>')
+                    .insertAfter(A).css("z-index", "100").append(focuser)
+                    .attr({"class": opts.splitbarClass, unselectable: "on"})
+                    .css({position: "absolute",   "user-select": "none", "-webkit-user-select": "none",
+                        "-khtml-user-select": "none", "-moz-user-select": "none", "top": "0px"})
+                    .bind("mousedown", startSplitMouse);
+            // Use our cursor unless the style specifies a non-default cursor
+            if (/^(auto|default|)$/.test(bar.css("cursor")))
+                bar.css("cursor", opts.cursor);
+
+            // Cache several dimensions for speed, rather than re-querying constantly
+            bar._DA = bar[0][opts.pxSplit];
+            splitter._PBF = $.boxModel ? dimSum(splitter, "border" + opts.side3 + "Width", "border" + opts.side4 + "Width") : 0;
+            splitter._PBA = $.boxModel ? dimSum(splitter, "border" + opts.side1 + "Width", "border" + opts.side2 + "Width") : 0;
+            A._pane = opts.side1;
+            B._pane = opts.side2;
+            $.each([A,B], function() {
+                this._min = opts["min" + this._pane] || dimSum(this, "min-" + opts.split);
+                this._max = opts["max" + this._pane] || dimSum(this, "max-" + opts.split) || 9999;
+                this._init = opts["size" + this._pane] === true ?
+                        parseInt($.curCSS(this[0], opts.split)) : opts["size" + this._pane];
+            });
+
+            // Determine initial position, get from cookie if specified
+            var initPos = A._init;
+            if (!isNaN(B._init))   // recalc initial B size as an offset from the top or left side
+                initPos = splitter[0][opts.pxSplit] - splitter._PBA - B._init - bar._DA;
+            if (opts.cookie) {
+                if (!$.cookie)
+                    alert('jQuery.splitter(): jQuery cookie plugin required');
+                var ckpos = parseInt($.cookie(opts.cookie));
+                if (!isNaN(ckpos))
+                    initPos = ckpos;
+                $(window).bind("unload", function() {
+                    var state = String(bar.css(opts.origin));   // current location of splitbar
+                    $.cookie(opts.cookie, state, {expires: opts.cookieExpires || 365,
+                        path: opts.cookiePath || document.location.pathname});
+                });
+            }
+            if (isNaN(initPos))   // King Solomon's algorithm
+                initPos = Math.round((splitter[0][opts.pxSplit] - splitter._PBA - bar._DA) / 2);
+
+            // Resize event propagation and splitter sizing
+            if (opts.anchorToWindow) {
+                // Account for margin or border on the splitter container and enforce min height
+                splitter._hadjust = dimSum(splitter, "borderTopWidth", "borderBottomWidth", "marginBottom");
+                splitter._hmin = Math.max(dimSum(splitter, "minHeight"), 20);
+                $(window).bind("resize",
+                        function() {
+                            var top = splitter.offset().top;
+                            var wh = $(window).height();
+                            splitter.css("height", Math.max(wh - top - splitter._hadjust, splitter._hmin) + "px");
+                            if (!$.browser.msie) splitter.trigger("resize");
+                        }).trigger("resize");
+            }
+            else if (opts.resizeToWidth && !$.browser.msie)
+                $(window).bind("resize", function() {
+                    splitter.trigger("resize");
+                });
+
+            // Resize event handler; triggered immediately to set initial position
+            splitter.bind("resize",
+                    function(e, size) {
+                        // Custom events bubble in jQuery 1.3; don't Yo Dawg
+                        if (e.target != this) return;
+                        // Determine new width/height of splitter container
+                        splitter._DF = splitter[0][opts.pxFixed] - splitter._PBF;
+                        splitter._DA = splitter[0][opts.pxSplit] - splitter._PBA;
+                        // Bail if splitter isn't visible or content isn't there yet
+                        if (splitter._DF <= 0 || splitter._DA <= 0) return;
+                        // Re-divvy the adjustable dimension; maintain size of the preferred pane
+                        resplit(!isNaN(size) ? size : (!(opts.sizeRight || opts.sizeBottom) ? A[0][opts.pxSplit] :
+                                splitter._DA - B[0][opts.pxSplit] - bar._DA));
+                    }).trigger("resize", [initPos]);
+        });
+    };
+
+})(jQuery);
\ No newline at end of file