r65331 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r65330‎ | r65331 | r65332 >
Date:16:32, 20 April 2010
Author:ialex
Status:ok
Tags:
Comment:
svn:eol-style native
Modified paths:
  • /trunk/extensions/MultilingualLiquidThreads/.project (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/LiquidThreads.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/classes/.copy.33c5ae11-2801-0010-9c4b-5d124da4a9ce.tmp (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/classes/.copy.5083af11-2801-0010-9c4b-5d124da4a9ce.tmp (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/classes/LogFormatter.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/jquery/plugins.js (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/langrid/HTMLTranslator.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/langrid/MetaTranslator.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/langrid/MultilangLqt.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/langrid/MultilangLqtHooks.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/langrid/MultilangThreadController.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/langrid/SourceView.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/langrid/TranslatedThread.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/lqt.pg.sql (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/schema-changes/thread_signature.sql (modified) (history)

Diff [purge]

Index: trunk/extensions/MultilingualLiquidThreads/jquery/plugins.js
@@ -1,3783 +1,3783 @@
2 -/*
3 - * jQuery UI 1.7.2
4 - *
5 - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
6 - * Dual licensed under the MIT (MIT-LICENSE.txt)
7 - * and GPL (GPL-LICENSE.txt) licenses.
8 - *
9 - * http://docs.jquery.com/UI
10 - */
11 -;jQuery.ui || (function($) {
12 -
13 -var _remove = $.fn.remove,
14 - isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
15 -
16 -//Helper functions and ui object
17 -$.ui = {
18 - version: "1.7.2",
19 -
20 - // $.ui.plugin is deprecated. Use the proxy pattern instead.
21 - plugin: {
22 - add: function(module, option, set) {
23 - var proto = $.ui[module].prototype;
24 - for(var i in set) {
25 - proto.plugins[i] = proto.plugins[i] || [];
26 - proto.plugins[i].push([option, set[i]]);
27 - }
28 - },
29 - call: function(instance, name, args) {
30 - var set = instance.plugins[name];
31 - if(!set || !instance.element[0].parentNode) { return; }
32 -
33 - for (var i = 0; i < set.length; i++) {
34 - if (instance.options[set[i][0]]) {
35 - set[i][1].apply(instance.element, args);
36 - }
37 - }
38 - }
39 - },
40 -
41 - contains: function(a, b) {
42 - return document.compareDocumentPosition
43 - ? a.compareDocumentPosition(b) & 16
44 - : a !== b && a.contains(b);
45 - },
46 -
47 - hasScroll: function(el, a) {
48 -
49 - //If overflow is hidden, the element might have extra content, but the user wants to hide it
50 - if ($(el).css('overflow') == 'hidden') { return false; }
51 -
52 - var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
53 - has = false;
54 -
55 - if (el[scroll] > 0) { return true; }
56 -
57 - // TODO: determine which cases actually cause this to happen
58 - // if the element doesn't have the scroll set, see if it's possible to
59 - // set the scroll
60 - el[scroll] = 1;
61 - has = (el[scroll] > 0);
62 - el[scroll] = 0;
63 - return has;
64 - },
65 -
66 - isOverAxis: function(x, reference, size) {
67 - //Determines when x coordinate is over "b" element axis
68 - return (x > reference) && (x < (reference + size));
69 - },
70 -
71 - isOver: function(y, x, top, left, height, width) {
72 - //Determines when x, y coordinates is over "b" element
73 - return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
74 - },
75 -
76 - keyCode: {
77 - BACKSPACE: 8,
78 - CAPS_LOCK: 20,
79 - COMMA: 188,
80 - CONTROL: 17,
81 - DELETE: 46,
82 - DOWN: 40,
83 - END: 35,
84 - ENTER: 13,
85 - ESCAPE: 27,
86 - HOME: 36,
87 - INSERT: 45,
88 - LEFT: 37,
89 - NUMPAD_ADD: 107,
90 - NUMPAD_DECIMAL: 110,
91 - NUMPAD_DIVIDE: 111,
92 - NUMPAD_ENTER: 108,
93 - NUMPAD_MULTIPLY: 106,
94 - NUMPAD_SUBTRACT: 109,
95 - PAGE_DOWN: 34,
96 - PAGE_UP: 33,
97 - PERIOD: 190,
98 - RIGHT: 39,
99 - SHIFT: 16,
100 - SPACE: 32,
101 - TAB: 9,
102 - UP: 38
103 - }
104 -};
105 -
106 -// WAI-ARIA normalization
107 -if (isFF2) {
108 - var attr = $.attr,
109 - removeAttr = $.fn.removeAttr,
110 - ariaNS = "http://www.w3.org/2005/07/aaa",
111 - ariaState = /^aria-/,
112 - ariaRole = /^wairole:/;
113 -
114 - $.attr = function(elem, name, value) {
115 - var set = value !== undefined;
116 -
117 - return (name == 'role'
118 - ? (set
119 - ? attr.call(this, elem, name, "wairole:" + value)
120 - : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
121 - : (ariaState.test(name)
122 - ? (set
123 - ? elem.setAttributeNS(ariaNS,
124 - name.replace(ariaState, "aaa:"), value)
125 - : attr.call(this, elem, name.replace(ariaState, "aaa:")))
126 - : attr.apply(this, arguments)));
127 - };
128 -
129 - $.fn.removeAttr = function(name) {
130 - return (ariaState.test(name)
131 - ? this.each(function() {
132 - this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
133 - }) : removeAttr.call(this, name));
134 - };
135 -}
136 -
137 -//jQuery plugins
138 -$.fn.extend({
139 - remove: function() {
140 - // Safari has a native remove event which actually removes DOM elements,
141 - // so we have to use triggerHandler instead of trigger (#3037).
142 - $("*", this).add(this).each(function() {
143 - $(this).triggerHandler("remove");
144 - });
145 - return _remove.apply(this, arguments );
146 - },
147 -
148 - enableSelection: function() {
149 - return this
150 - .attr('unselectable', 'off')
151 - .css('MozUserSelect', '')
152 - .unbind('selectstart.ui');
153 - },
154 -
155 - disableSelection: function() {
156 - return this
157 - .attr('unselectable', 'on')
158 - .css('MozUserSelect', 'none')
159 - .bind('selectstart.ui', function() { return false; });
160 - },
161 -
162 - scrollParent: function() {
163 - var scrollParent;
164 - if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
165 - scrollParent = this.parents().filter(function() {
166 - return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
167 - }).eq(0);
168 - } else {
169 - scrollParent = this.parents().filter(function() {
170 - return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
171 - }).eq(0);
172 - }
173 -
174 - return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
175 - }
176 -});
177 -
178 -
179 -//Additional selectors
180 -$.extend($.expr[':'], {
181 - data: function(elem, i, match) {
182 - return !!$.data(elem, match[3]);
183 - },
184 -
185 - focusable: function(element) {
186 - var nodeName = element.nodeName.toLowerCase(),
187 - tabIndex = $.attr(element, 'tabindex');
188 - return (/input|select|textarea|button|object/.test(nodeName)
189 - ? !element.disabled
190 - : 'a' == nodeName || 'area' == nodeName
191 - ? element.href || !isNaN(tabIndex)
192 - : !isNaN(tabIndex))
193 - // the element and all of its ancestors must be visible
194 - // the browser may report that the area is hidden
195 - && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
196 - },
197 -
198 - tabbable: function(element) {
199 - var tabIndex = $.attr(element, 'tabindex');
200 - return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
201 - }
202 -});
203 -
204 -
205 -// $.widget is a factory to create jQuery plugins
206 -// taking some boilerplate code out of the plugin code
207 -function getter(namespace, plugin, method, args) {
208 - function getMethods(type) {
209 - var methods = $[namespace][plugin][type] || [];
210 - return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
211 - }
212 -
213 - var methods = getMethods('getter');
214 - if (args.length == 1 && typeof args[0] == 'string') {
215 - methods = methods.concat(getMethods('getterSetter'));
216 - }
217 - return ($.inArray(method, methods) != -1);
218 -}
219 -
220 -$.widget = function(name, prototype) {
221 - var namespace = name.split(".")[0];
222 - name = name.split(".")[1];
223 -
224 - // create plugin method
225 - $.fn[name] = function(options) {
226 - var isMethodCall = (typeof options == 'string'),
227 - args = Array.prototype.slice.call(arguments, 1);
228 -
229 - // prevent calls to internal methods
230 - if (isMethodCall && options.substring(0, 1) == '_') {
231 - return this;
232 - }
233 -
234 - // handle getter methods
235 - if (isMethodCall && getter(namespace, name, options, args)) {
236 - var instance = $.data(this[0], name);
237 - return (instance ? instance[options].apply(instance, args)
238 - : undefined);
239 - }
240 -
241 - // handle initialization and non-getter methods
242 - return this.each(function() {
243 - var instance = $.data(this, name);
244 -
245 - // constructor
246 - (!instance && !isMethodCall &&
247 - $.data(this, name, new $[namespace][name](this, options))._init());
248 -
249 - // method call
250 - (instance && isMethodCall && $.isFunction(instance[options]) &&
251 - instance[options].apply(instance, args));
252 - });
253 - };
254 -
255 - // create widget constructor
256 - $[namespace] = $[namespace] || {};
257 - $[namespace][name] = function(element, options) {
258 - var self = this;
259 -
260 - this.namespace = namespace;
261 - this.widgetName = name;
262 - this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
263 - this.widgetBaseClass = namespace + '-' + name;
264 -
265 - this.options = $.extend({},
266 - $.widget.defaults,
267 - $[namespace][name].defaults,
268 - $.metadata && $.metadata.get(element)[name],
269 - options);
270 -
271 - this.element = $(element)
272 - .bind('setData.' + name, function(event, key, value) {
273 - if (event.target == element) {
274 - return self._setData(key, value);
275 - }
276 - })
277 - .bind('getData.' + name, function(event, key) {
278 - if (event.target == element) {
279 - return self._getData(key);
280 - }
281 - })
282 - .bind('remove', function() {
283 - return self.destroy();
284 - });
285 - };
286 -
287 - // add widget prototype
288 - $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
289 -
290 - // TODO: merge getter and getterSetter properties from widget prototype
291 - // and plugin prototype
292 - $[namespace][name].getterSetter = 'option';
293 -};
294 -
295 -$.widget.prototype = {
296 - _init: function() {},
297 - destroy: function() {
298 - this.element.removeData(this.widgetName)
299 - .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
300 - .removeAttr('aria-disabled');
301 - },
302 -
303 - option: function(key, value) {
304 - var options = key,
305 - self = this;
306 -
307 - if (typeof key == "string") {
308 - if (value === undefined) {
309 - return this._getData(key);
310 - }
311 - options = {};
312 - options[key] = value;
313 - }
314 -
315 - $.each(options, function(key, value) {
316 - self._setData(key, value);
317 - });
318 - },
319 - _getData: function(key) {
320 - return this.options[key];
321 - },
322 - _setData: function(key, value) {
323 - this.options[key] = value;
324 -
325 - if (key == 'disabled') {
326 - this.element
327 - [value ? 'addClass' : 'removeClass'](
328 - this.widgetBaseClass + '-disabled' + ' ' +
329 - this.namespace + '-state-disabled')
330 - .attr("aria-disabled", value);
331 - }
332 - },
333 -
334 - enable: function() {
335 - this._setData('disabled', false);
336 - },
337 - disable: function() {
338 - this._setData('disabled', true);
339 - },
340 -
341 - _trigger: function(type, event, data) {
342 - var callback = this.options[type],
343 - eventName = (type == this.widgetEventPrefix
344 - ? type : this.widgetEventPrefix + type);
345 -
346 - event = $.Event(event);
347 - event.type = eventName;
348 -
349 - // copy original event properties over to the new event
350 - // this would happen if we could call $.event.fix instead of $.Event
351 - // but we don't have a way to force an event to be fixed multiple times
352 - if (event.originalEvent) {
353 - for (var i = $.event.props.length, prop; i;) {
354 - prop = $.event.props[--i];
355 - event[prop] = event.originalEvent[prop];
356 - }
357 - }
358 -
359 - this.element.trigger(event, data);
360 -
361 - return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
362 - || event.isDefaultPrevented());
363 - }
364 -};
365 -
366 -$.widget.defaults = {
367 - disabled: false
368 -};
369 -
370 -
371 -/** Mouse Interaction Plugin **/
372 -
373 -$.ui.mouse = {
374 - _mouseInit: function() {
375 - var self = this;
376 -
377 - this.element
378 - .bind('mousedown.'+this.widgetName, function(event) {
379 - return self._mouseDown(event);
380 - })
381 - .bind('click.'+this.widgetName, function(event) {
382 - if(self._preventClickEvent) {
383 - self._preventClickEvent = false;
384 - event.stopImmediatePropagation();
385 - return false;
386 - }
387 - });
388 -
389 - // Prevent text selection in IE
390 - if ($.browser.msie) {
391 - this._mouseUnselectable = this.element.attr('unselectable');
392 - this.element.attr('unselectable', 'on');
393 - }
394 -
395 - this.started = false;
396 - },
397 -
398 - // TODO: make sure destroying one instance of mouse doesn't mess with
399 - // other instances of mouse
400 - _mouseDestroy: function() {
401 - this.element.unbind('.'+this.widgetName);
402 -
403 - // Restore text selection in IE
404 - ($.browser.msie
405 - && this.element.attr('unselectable', this._mouseUnselectable));
406 - },
407 -
408 - _mouseDown: function(event) {
409 - // don't let more than one widget handle mouseStart
410 - // TODO: figure out why we have to use originalEvent
411 - event.originalEvent = event.originalEvent || {};
412 - if (event.originalEvent.mouseHandled) { return; }
413 -
414 - // we may have missed mouseup (out of window)
415 - (this._mouseStarted && this._mouseUp(event));
416 -
417 - this._mouseDownEvent = event;
418 -
419 - var self = this,
420 - btnIsLeft = (event.which == 1),
421 - elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
422 - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
423 - return true;
424 - }
425 -
426 - this.mouseDelayMet = !this.options.delay;
427 - if (!this.mouseDelayMet) {
428 - this._mouseDelayTimer = setTimeout(function() {
429 - self.mouseDelayMet = true;
430 - }, this.options.delay);
431 - }
432 -
433 - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
434 - this._mouseStarted = (this._mouseStart(event) !== false);
435 - if (!this._mouseStarted) {
436 - event.preventDefault();
437 - return true;
438 - }
439 - }
440 -
441 - // these delegates are required to keep context
442 - this._mouseMoveDelegate = function(event) {
443 - return self._mouseMove(event);
444 - };
445 - this._mouseUpDelegate = function(event) {
446 - return self._mouseUp(event);
447 - };
448 - $(document)
449 - .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
450 - .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
451 -
452 - // preventDefault() is used to prevent the selection of text here -
453 - // however, in Safari, this causes select boxes not to be selectable
454 - // anymore, so this fix is needed
455 - ($.browser.safari || event.preventDefault());
456 -
457 - event.originalEvent.mouseHandled = true;
458 - return true;
459 - },
460 -
461 - _mouseMove: function(event) {
462 - // IE mouseup check - mouseup happened when mouse was out of window
463 - if ($.browser.msie && !event.button) {
464 - return this._mouseUp(event);
465 - }
466 -
467 - if (this._mouseStarted) {
468 - this._mouseDrag(event);
469 - return event.preventDefault();
470 - }
471 -
472 - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
473 - this._mouseStarted =
474 - (this._mouseStart(this._mouseDownEvent, event) !== false);
475 - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
476 - }
477 -
478 - return !this._mouseStarted;
479 - },
480 -
481 - _mouseUp: function(event) {
482 - $(document)
483 - .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
484 - .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
485 -
486 - if (this._mouseStarted) {
487 - this._mouseStarted = false;
488 - this._preventClickEvent = (event.target == this._mouseDownEvent.target);
489 - this._mouseStop(event);
490 - }
491 -
492 - return false;
493 - },
494 -
495 - _mouseDistanceMet: function(event) {
496 - return (Math.max(
497 - Math.abs(this._mouseDownEvent.pageX - event.pageX),
498 - Math.abs(this._mouseDownEvent.pageY - event.pageY)
499 - ) >= this.options.distance
500 - );
501 - },
502 -
503 - _mouseDelayMet: function(event) {
504 - return this.mouseDelayMet;
505 - },
506 -
507 - // These are placeholder methods, to be overriden by extending plugin
508 - _mouseStart: function(event) {},
509 - _mouseDrag: function(event) {},
510 - _mouseStop: function(event) {},
511 - _mouseCapture: function(event) { return true; }
512 -};
513 -
514 -$.ui.mouse.defaults = {
515 - cancel: null,
516 - distance: 1,
517 - delay: 0
518 -};
519 -
520 -})(jQuery);
521 -/*
522 - * jQuery UI Draggable 1.7.2
523 - *
524 - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
525 - * Dual licensed under the MIT (MIT-LICENSE.txt)
526 - * and GPL (GPL-LICENSE.txt) licenses.
527 - *
528 - * http://docs.jquery.com/UI/Draggables
529 - *
530 - * Depends:
531 - * ui.core.js
532 - */
533 -(function($) {
534 -
535 -$.widget("ui.draggable", $.extend({}, $.ui.mouse, {
536 -
537 - _init: function() {
538 -
539 - if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
540 - this.element[0].style.position = 'relative';
541 -
542 - (this.options.addClasses && this.element.addClass("ui-draggable"));
543 - (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
544 -
545 - this._mouseInit();
546 -
547 - },
548 -
549 - destroy: function() {
550 - if(!this.element.data('draggable')) return;
551 - this.element
552 - .removeData("draggable")
553 - .unbind(".draggable")
554 - .removeClass("ui-draggable"
555 - + " ui-draggable-dragging"
556 - + " ui-draggable-disabled");
557 - this._mouseDestroy();
558 - },
559 -
560 - _mouseCapture: function(event) {
561 -
562 - var o = this.options;
563 -
564 - if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
565 - return false;
566 -
567 - //Quit if we're not on a valid handle
568 - this.handle = this._getHandle(event);
569 - if (!this.handle)
570 - return false;
571 -
572 - return true;
573 -
574 - },
575 -
576 - _mouseStart: function(event) {
577 -
578 - var o = this.options;
579 -
580 - //Create and append the visible helper
581 - this.helper = this._createHelper(event);
582 -
583 - //Cache the helper size
584 - this._cacheHelperProportions();
585 -
586 - //If ddmanager is used for droppables, set the global draggable
587 - if($.ui.ddmanager)
588 - $.ui.ddmanager.current = this;
589 -
590 - /*
591 - * - Position generation -
592 - * This block generates everything position related - it's the core of draggables.
593 - */
594 -
595 - //Cache the margins of the original element
596 - this._cacheMargins();
597 -
598 - //Store the helper's css position
599 - this.cssPosition = this.helper.css("position");
600 - this.scrollParent = this.helper.scrollParent();
601 -
602 - //The element's absolute position on the page minus margins
603 - this.offset = this.element.offset();
604 - this.offset = {
605 - top: this.offset.top - this.margins.top,
606 - left: this.offset.left - this.margins.left
607 - };
608 -
609 - $.extend(this.offset, {
610 - click: { //Where the click happened, relative to the element
611 - left: event.pageX - this.offset.left,
612 - top: event.pageY - this.offset.top
613 - },
614 - parent: this._getParentOffset(),
615 - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
616 - });
617 -
618 - //Generate the original position
619 - this.originalPosition = this._generatePosition(event);
620 - this.originalPageX = event.pageX;
621 - this.originalPageY = event.pageY;
622 -
623 - //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
624 - if(o.cursorAt)
625 - this._adjustOffsetFromHelper(o.cursorAt);
626 -
627 - //Set a containment if given in the options
628 - if(o.containment)
629 - this._setContainment();
630 -
631 - //Call plugins and callbacks
632 - this._trigger("start", event);
633 -
634 - //Recache the helper size
635 - this._cacheHelperProportions();
636 -
637 - //Prepare the droppable offsets
638 - if ($.ui.ddmanager && !o.dropBehaviour)
639 - $.ui.ddmanager.prepareOffsets(this, event);
640 -
641 - this.helper.addClass("ui-draggable-dragging");
642 - this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
643 - return true;
644 - },
645 -
646 - _mouseDrag: function(event, noPropagation) {
647 -
648 - //Compute the helpers position
649 - this.position = this._generatePosition(event);
650 - this.positionAbs = this._convertPositionTo("absolute");
651 -
652 - //Call plugins and callbacks and use the resulting position if something is returned
653 - if (!noPropagation) {
654 - var ui = this._uiHash();
655 - this._trigger('drag', event, ui);
656 - this.position = ui.position;
657 - }
658 -
659 - if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
660 - if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
661 - if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
662 -
663 - return false;
664 - },
665 -
666 - _mouseStop: function(event) {
667 -
668 - //If we are using droppables, inform the manager about the drop
669 - var dropped = false;
670 - if ($.ui.ddmanager && !this.options.dropBehaviour)
671 - dropped = $.ui.ddmanager.drop(this, event);
672 -
673 - //if a drop comes from outside (a sortable)
674 - if(this.dropped) {
675 - dropped = this.dropped;
676 - this.dropped = false;
677 - }
678 -
679 - if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
680 - var self = this;
681 - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
682 - self._trigger("stop", event);
683 - self._clear();
684 - });
685 - } else {
686 - this._trigger("stop", event);
687 - this._clear();
688 - }
689 -
690 - return false;
691 - },
692 -
693 - _getHandle: function(event) {
694 -
695 - var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
696 - $(this.options.handle, this.element)
697 - .find("*")
698 - .andSelf()
699 - .each(function() {
700 - if(this == event.target) handle = true;
701 - });
702 -
703 - return handle;
704 -
705 - },
706 -
707 - _createHelper: function(event) {
708 -
709 - var o = this.options;
710 - var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
711 -
712 - if(!helper.parents('body').length)
713 - helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
714 -
715 - if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
716 - helper.css("position", "absolute");
717 -
718 - return helper;
719 -
720 - },
721 -
722 - _adjustOffsetFromHelper: function(obj) {
723 - if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
724 - if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
725 - if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
726 - if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
727 - },
728 -
729 - _getParentOffset: function() {
730 -
731 - //Get the offsetParent and cache its position
732 - this.offsetParent = this.helper.offsetParent();
733 - var po = this.offsetParent.offset();
734 -
735 - // This is a special case where we need to modify a offset calculated on start, since the following happened:
736 - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
737 - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
738 - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
739 - if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
740 - po.left += this.scrollParent.scrollLeft();
741 - po.top += this.scrollParent.scrollTop();
742 - }
743 -
744 - if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
745 - || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
746 - po = { top: 0, left: 0 };
747 -
748 - return {
749 - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
750 - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
751 - };
752 -
753 - },
754 -
755 - _getRelativeOffset: function() {
756 -
757 - if(this.cssPosition == "relative") {
758 - var p = this.element.position();
759 - return {
760 - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
761 - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
762 - };
763 - } else {
764 - return { top: 0, left: 0 };
765 - }
766 -
767 - },
768 -
769 - _cacheMargins: function() {
770 - this.margins = {
771 - left: (parseInt(this.element.css("marginLeft"),10) || 0),
772 - top: (parseInt(this.element.css("marginTop"),10) || 0)
773 - };
774 - },
775 -
776 - _cacheHelperProportions: function() {
777 - this.helperProportions = {
778 - width: this.helper.outerWidth(),
779 - height: this.helper.outerHeight()
780 - };
781 - },
782 -
783 - _setContainment: function() {
784 -
785 - var o = this.options;
786 - if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
787 - if(o.containment == 'document' || o.containment == 'window') this.containment = [
788 - 0 - this.offset.relative.left - this.offset.parent.left,
789 - 0 - this.offset.relative.top - this.offset.parent.top,
790 - $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
791 - ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
792 - ];
793 -
794 - if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
795 - var ce = $(o.containment)[0]; if(!ce) return;
796 - var co = $(o.containment).offset();
797 - var over = ($(ce).css("overflow") != 'hidden');
798 -
799 - this.containment = [
800 - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
801 - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
802 - co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
803 - co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
804 - ];
805 - } else if(o.containment.constructor == Array) {
806 - this.containment = o.containment;
807 - }
808 -
809 - },
810 -
811 - _convertPositionTo: function(d, pos) {
812 -
813 - if(!pos) pos = this.position;
814 - var mod = d == "absolute" ? 1 : -1;
815 - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
816 -
817 - return {
818 - top: (
819 - pos.top // The absolute mouse position
820 - + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
821 - + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
822 - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
823 - ),
824 - left: (
825 - pos.left // The absolute mouse position
826 - + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
827 - + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
828 - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
829 - )
830 - };
831 -
832 - },
833 -
834 - _generatePosition: function(event) {
835 -
836 - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
837 -
838 - // This is another very weird special case that only happens for relative elements:
839 - // 1. If the css position is relative
840 - // 2. and the scroll parent is the document or similar to the offset parent
841 - // we have to refresh the relative offset during the scroll so there are no jumps
842 - if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
843 - this.offset.relative = this._getRelativeOffset();
844 - }
845 -
846 - var pageX = event.pageX;
847 - var pageY = event.pageY;
848 -
849 - /*
850 - * - Position constraining -
851 - * Constrain the position to a mix of grid, containment.
852 - */
853 -
854 - if(this.originalPosition) { //If we are not dragging yet, we won't check for options
855 -
856 - if(this.containment) {
857 - if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
858 - if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
859 - if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
860 - if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
861 - }
862 -
863 - if(o.grid) {
864 - var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
865 - pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
866 -
867 - var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
868 - pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
869 - }
870 -
871 - }
872 -
873 - return {
874 - top: (
875 - pageY // The absolute mouse position
876 - - this.offset.click.top // Click offset (relative to the element)
877 - - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
878 - - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
879 - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
880 - ),
881 - left: (
882 - pageX // The absolute mouse position
883 - - this.offset.click.left // Click offset (relative to the element)
884 - - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
885 - - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
886 - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
887 - )
888 - };
889 -
890 - },
891 -
892 - _clear: function() {
893 - this.helper.removeClass("ui-draggable-dragging");
894 - if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
895 - //if($.ui.ddmanager) $.ui.ddmanager.current = null;
896 - this.helper = null;
897 - this.cancelHelperRemoval = false;
898 - },
899 -
900 - // From now on bulk stuff - mainly helpers
901 -
902 - _trigger: function(type, event, ui) {
903 - ui = ui || this._uiHash();
904 - $.ui.plugin.call(this, type, [event, ui]);
905 - if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
906 - return $.widget.prototype._trigger.call(this, type, event, ui);
907 - },
908 -
909 - plugins: {},
910 -
911 - _uiHash: function(event) {
912 - return {
913 - helper: this.helper,
914 - position: this.position,
915 - absolutePosition: this.positionAbs, //deprecated
916 - offset: this.positionAbs
917 - };
918 - }
919 -
920 -}));
921 -
922 -$.extend($.ui.draggable, {
923 - version: "1.7.2",
924 - eventPrefix: "drag",
925 - defaults: {
926 - addClasses: true,
927 - appendTo: "parent",
928 - axis: false,
929 - cancel: ":input,option",
930 - connectToSortable: false,
931 - containment: false,
932 - cursor: "auto",
933 - cursorAt: false,
934 - delay: 0,
935 - distance: 1,
936 - grid: false,
937 - handle: false,
938 - helper: "original",
939 - iframeFix: false,
940 - opacity: false,
941 - refreshPositions: false,
942 - revert: false,
943 - revertDuration: 500,
944 - scope: "default",
945 - scroll: true,
946 - scrollSensitivity: 20,
947 - scrollSpeed: 20,
948 - snap: false,
949 - snapMode: "both",
950 - snapTolerance: 20,
951 - stack: false,
952 - zIndex: false
953 - }
954 -});
955 -
956 -$.ui.plugin.add("draggable", "connectToSortable", {
957 - start: function(event, ui) {
958 -
959 - var inst = $(this).data("draggable"), o = inst.options,
960 - uiSortable = $.extend({}, ui, { item: inst.element });
961 - inst.sortables = [];
962 - $(o.connectToSortable).each(function() {
963 - var sortable = $.data(this, 'sortable');
964 - if (sortable && !sortable.options.disabled) {
965 - inst.sortables.push({
966 - instance: sortable,
967 - shouldRevert: sortable.options.revert
968 - });
969 - sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache
970 - sortable._trigger("activate", event, uiSortable);
971 - }
972 - });
973 -
974 - },
975 - stop: function(event, ui) {
976 -
977 - //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
978 - var inst = $(this).data("draggable"),
979 - uiSortable = $.extend({}, ui, { item: inst.element });
980 -
981 - $.each(inst.sortables, function() {
982 - if(this.instance.isOver) {
983 -
984 - this.instance.isOver = 0;
985 -
986 - inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
987 - this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
988 -
989 - //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
990 - if(this.shouldRevert) this.instance.options.revert = true;
991 -
992 - //Trigger the stop of the sortable
993 - this.instance._mouseStop(event);
994 -
995 - this.instance.options.helper = this.instance.options._helper;
996 -
997 - //If the helper has been the original item, restore properties in the sortable
998 - if(inst.options.helper == 'original')
999 - this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1000 -
1001 - } else {
1002 - this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1003 - this.instance._trigger("deactivate", event, uiSortable);
1004 - }
1005 -
1006 - });
1007 -
1008 - },
1009 - drag: function(event, ui) {
1010 -
1011 - var inst = $(this).data("draggable"), self = this;
1012 -
1013 - var checkPos = function(o) {
1014 - var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1015 - var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1016 - var itemHeight = o.height, itemWidth = o.width;
1017 - var itemTop = o.top, itemLeft = o.left;
1018 -
1019 - return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1020 - };
1021 -
1022 - $.each(inst.sortables, function(i) {
1023 -
1024 - //Copy over some variables to allow calling the sortable's native _intersectsWith
1025 - this.instance.positionAbs = inst.positionAbs;
1026 - this.instance.helperProportions = inst.helperProportions;
1027 - this.instance.offset.click = inst.offset.click;
1028 -
1029 - if(this.instance._intersectsWith(this.instance.containerCache)) {
1030 -
1031 - //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1032 - if(!this.instance.isOver) {
1033 -
1034 - this.instance.isOver = 1;
1035 - //Now we fake the start of dragging for the sortable instance,
1036 - //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1037 - //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1038 - this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
1039 - this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1040 - this.instance.options.helper = function() { return ui.helper[0]; };
1041 -
1042 - event.target = this.instance.currentItem[0];
1043 - this.instance._mouseCapture(event, true);
1044 - this.instance._mouseStart(event, true, true);
1045 -
1046 - //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1047 - this.instance.offset.click.top = inst.offset.click.top;
1048 - this.instance.offset.click.left = inst.offset.click.left;
1049 - this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1050 - this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1051 -
1052 - inst._trigger("toSortable", event);
1053 - inst.dropped = this.instance.element; //draggable revert needs that
1054 - //hack so receive/update callbacks work (mostly)
1055 - inst.currentItem = inst.element;
1056 - this.instance.fromOutside = inst;
1057 -
1058 - }
1059 -
1060 - //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1061 - if(this.instance.currentItem) this.instance._mouseDrag(event);
1062 -
1063 - } else {
1064 -
1065 - //If it doesn't intersect with the sortable, and it intersected before,
1066 - //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1067 - if(this.instance.isOver) {
1068 -
1069 - this.instance.isOver = 0;
1070 - this.instance.cancelHelperRemoval = true;
1071 -
1072 - //Prevent reverting on this forced stop
1073 - this.instance.options.revert = false;
1074 -
1075 - // The out event needs to be triggered independently
1076 - this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1077 -
1078 - this.instance._mouseStop(event, true);
1079 - this.instance.options.helper = this.instance.options._helper;
1080 -
1081 - //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1082 - this.instance.currentItem.remove();
1083 - if(this.instance.placeholder) this.instance.placeholder.remove();
1084 -
1085 - inst._trigger("fromSortable", event);
1086 - inst.dropped = false; //draggable revert needs that
1087 - }
1088 -
1089 - };
1090 -
1091 - });
1092 -
1093 - }
1094 -});
1095 -
1096 -$.ui.plugin.add("draggable", "cursor", {
1097 - start: function(event, ui) {
1098 - var t = $('body'), o = $(this).data('draggable').options;
1099 - if (t.css("cursor")) o._cursor = t.css("cursor");
1100 - t.css("cursor", o.cursor);
1101 - },
1102 - stop: function(event, ui) {
1103 - var o = $(this).data('draggable').options;
1104 - if (o._cursor) $('body').css("cursor", o._cursor);
1105 - }
1106 -});
1107 -
1108 -$.ui.plugin.add("draggable", "iframeFix", {
1109 - start: function(event, ui) {
1110 - var o = $(this).data('draggable').options;
1111 - $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1112 - $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1113 - .css({
1114 - width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1115 - position: "absolute", opacity: "0.001", zIndex: 1000
1116 - })
1117 - .css($(this).offset())
1118 - .appendTo("body");
1119 - });
1120 - },
1121 - stop: function(event, ui) {
1122 - $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
1123 - }
1124 -});
1125 -
1126 -$.ui.plugin.add("draggable", "opacity", {
1127 - start: function(event, ui) {
1128 - var t = $(ui.helper), o = $(this).data('draggable').options;
1129 - if(t.css("opacity")) o._opacity = t.css("opacity");
1130 - t.css('opacity', o.opacity);
1131 - },
1132 - stop: function(event, ui) {
1133 - var o = $(this).data('draggable').options;
1134 - if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1135 - }
1136 -});
1137 -
1138 -$.ui.plugin.add("draggable", "scroll", {
1139 - start: function(event, ui) {
1140 - var i = $(this).data("draggable");
1141 - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1142 - },
1143 - drag: function(event, ui) {
1144 -
1145 - var i = $(this).data("draggable"), o = i.options, scrolled = false;
1146 -
1147 - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1148 -
1149 - if(!o.axis || o.axis != 'x') {
1150 - if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1151 - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1152 - else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1153 - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1154 - }
1155 -
1156 - if(!o.axis || o.axis != 'y') {
1157 - if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1158 - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1159 - else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1160 - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1161 - }
1162 -
1163 - } else {
1164 -
1165 - if(!o.axis || o.axis != 'x') {
1166 - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1167 - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1168 - else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1169 - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1170 - }
1171 -
1172 - if(!o.axis || o.axis != 'y') {
1173 - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1174 - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1175 - else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1176 - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1177 - }
1178 -
1179 - }
1180 -
1181 - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1182 - $.ui.ddmanager.prepareOffsets(i, event);
1183 -
1184 - }
1185 -});
1186 -
1187 -$.ui.plugin.add("draggable", "snap", {
1188 - start: function(event, ui) {
1189 -
1190 - var i = $(this).data("draggable"), o = i.options;
1191 - i.snapElements = [];
1192 -
1193 - $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1194 - var $t = $(this); var $o = $t.offset();
1195 - if(this != i.element[0]) i.snapElements.push({
1196 - item: this,
1197 - width: $t.outerWidth(), height: $t.outerHeight(),
1198 - top: $o.top, left: $o.left
1199 - });
1200 - });
1201 -
1202 - },
1203 - drag: function(event, ui) {
1204 -
1205 - var inst = $(this).data("draggable"), o = inst.options;
1206 - var d = o.snapTolerance;
1207 -
1208 - var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1209 - y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1210 -
1211 - for (var i = inst.snapElements.length - 1; i >= 0; i--){
1212 -
1213 - var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1214 - t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1215 -
1216 - //Yes, I know, this is insane ;)
1217 - if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
1218 - if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1219 - inst.snapElements[i].snapping = false;
1220 - continue;
1221 - }
1222 -
1223 - if(o.snapMode != 'inner') {
1224 - var ts = Math.abs(t - y2) <= d;
1225 - var bs = Math.abs(b - y1) <= d;
1226 - var ls = Math.abs(l - x2) <= d;
1227 - var rs = Math.abs(r - x1) <= d;
1228 - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1229 - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1230 - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1231 - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1232 - }
1233 -
1234 - var first = (ts || bs || ls || rs);
1235 -
1236 - if(o.snapMode != 'outer') {
1237 - var ts = Math.abs(t - y1) <= d;
1238 - var bs = Math.abs(b - y2) <= d;
1239 - var ls = Math.abs(l - x1) <= d;
1240 - var rs = Math.abs(r - x2) <= d;
1241 - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1242 - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1243 - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1244 - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1245 - }
1246 -
1247 - if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1248 - (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1249 - inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1250 -
1251 - };
1252 -
1253 - }
1254 -});
1255 -
1256 -$.ui.plugin.add("draggable", "stack", {
1257 - start: function(event, ui) {
1258 -
1259 - var o = $(this).data("draggable").options;
1260 -
1261 - var group = $.makeArray($(o.stack.group)).sort(function(a,b) {
1262 - return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min);
1263 - });
1264 -
1265 - $(group).each(function(i) {
1266 - this.style.zIndex = o.stack.min + i;
1267 - });
1268 -
1269 - this[0].style.zIndex = o.stack.min + group.length;
1270 -
1271 - }
1272 -});
1273 -
1274 -$.ui.plugin.add("draggable", "zIndex", {
1275 - start: function(event, ui) {
1276 - var t = $(ui.helper), o = $(this).data("draggable").options;
1277 - if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1278 - t.css('zIndex', o.zIndex);
1279 - },
1280 - stop: function(event, ui) {
1281 - var o = $(this).data("draggable").options;
1282 - if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1283 - }
1284 -});
1285 -
1286 -})(jQuery);
1287 -
1288 -/*
1289 - * jQuery UI Droppable 1.7.2
1290 - *
1291 - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
1292 - * Dual licensed under the MIT (MIT-LICENSE.txt)
1293 - * and GPL (GPL-LICENSE.txt) licenses.
1294 - *
1295 - * http://docs.jquery.com/UI/Droppables
1296 - *
1297 - * Depends:
1298 - * ui.core.js
1299 - * ui.draggable.js
1300 - */
1301 -(function($) {
1302 -
1303 -$.widget("ui.droppable", {
1304 -
1305 - _init: function() {
1306 -
1307 - var o = this.options, accept = o.accept;
1308 - this.isover = 0; this.isout = 1;
1309 -
1310 - this.options.accept = this.options.accept && $.isFunction(this.options.accept) ? this.options.accept : function(d) {
1311 - return d.is(accept);
1312 - };
1313 -
1314 - //Store the droppable's proportions
1315 - this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1316 -
1317 - // Add the reference and positions to the manager
1318 - $.ui.ddmanager.droppables[this.options.scope] = $.ui.ddmanager.droppables[this.options.scope] || [];
1319 - $.ui.ddmanager.droppables[this.options.scope].push(this);
1320 -
1321 - (this.options.addClasses && this.element.addClass("ui-droppable"));
1322 -
1323 - },
1324 -
1325 - destroy: function() {
1326 - var drop = $.ui.ddmanager.droppables[this.options.scope];
1327 - for ( var i = 0; i < drop.length; i++ )
1328 - if ( drop[i] == this )
1329 - drop.splice(i, 1);
1330 -
1331 - this.element
1332 - .removeClass("ui-droppable ui-droppable-disabled")
1333 - .removeData("droppable")
1334 - .unbind(".droppable");
1335 - },
1336 -
1337 - _setData: function(key, value) {
1338 -
1339 - if(key == 'accept') {
1340 - this.options.accept = value && $.isFunction(value) ? value : function(d) {
1341 - return d.is(value);
1342 - };
1343 - } else {
1344 - $.widget.prototype._setData.apply(this, arguments);
1345 - }
1346 -
1347 - },
1348 -
1349 - _activate: function(event) {
1350 - var draggable = $.ui.ddmanager.current;
1351 - if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1352 - (draggable && this._trigger('activate', event, this.ui(draggable)));
1353 - },
1354 -
1355 - _deactivate: function(event) {
1356 - var draggable = $.ui.ddmanager.current;
1357 - if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1358 - (draggable && this._trigger('deactivate', event, this.ui(draggable)));
1359 - },
1360 -
1361 - _over: function(event) {
1362 -
1363 - var draggable = $.ui.ddmanager.current;
1364 - if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1365 -
1366 - if (this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1367 - if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1368 - this._trigger('over', event, this.ui(draggable));
1369 - }
1370 -
1371 - },
1372 -
1373 - _out: function(event) {
1374 -
1375 - var draggable = $.ui.ddmanager.current;
1376 - if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1377 -
1378 - if (this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1379 - if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1380 - this._trigger('out', event, this.ui(draggable));
1381 - }
1382 -
1383 - },
1384 -
1385 - _drop: function(event,custom) {
1386 -
1387 - var draggable = custom || $.ui.ddmanager.current;
1388 - if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1389 -
1390 - var childrenIntersection = false;
1391 - this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1392 - var inst = $.data(this, 'droppable');
1393 - if(inst.options.greedy && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) {
1394 - childrenIntersection = true; return false;
1395 - }
1396 - });
1397 - if(childrenIntersection) return false;
1398 -
1399 - if(this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1400 - if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1401 - if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1402 - this._trigger('drop', event, this.ui(draggable));
1403 - return this.element;
1404 - }
1405 -
1406 - return false;
1407 -
1408 - },
1409 -
1410 - ui: function(c) {
1411 - return {
1412 - draggable: (c.currentItem || c.element),
1413 - helper: c.helper,
1414 - position: c.position,
1415 - absolutePosition: c.positionAbs, //deprecated
1416 - offset: c.positionAbs
1417 - };
1418 - }
1419 -
1420 -});
1421 -
1422 -$.extend($.ui.droppable, {
1423 - version: "1.7.2",
1424 - eventPrefix: 'drop',
1425 - defaults: {
1426 - accept: '*',
1427 - activeClass: false,
1428 - addClasses: true,
1429 - greedy: false,
1430 - hoverClass: false,
1431 - scope: 'default',
1432 - tolerance: 'intersect'
1433 - }
1434 -});
1435 -
1436 -$.ui.intersect = function(draggable, droppable, toleranceMode) {
1437 -
1438 - if (!droppable.offset) return false;
1439 -
1440 - var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1441 - y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1442 - var l = droppable.offset.left, r = l + droppable.proportions.width,
1443 - t = droppable.offset.top, b = t + droppable.proportions.height;
1444 -
1445 - switch (toleranceMode) {
1446 - case 'fit':
1447 - return (l < x1 && x2 < r
1448 - && t < y1 && y2 < b);
1449 - break;
1450 - case 'intersect':
1451 - return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1452 - && x2 - (draggable.helperProportions.width / 2) < r // Left Half
1453 - && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1454 - && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1455 - break;
1456 - case 'pointer':
1457 - var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
1458 - draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
1459 - isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
1460 - return isOver;
1461 - break;
1462 - case 'touch':
1463 - return (
1464 - (y1 >= t && y1 <= b) || // Top edge touching
1465 - (y2 >= t && y2 <= b) || // Bottom edge touching
1466 - (y1 < t && y2 > b) // Surrounded vertically
1467 - ) && (
1468 - (x1 >= l && x1 <= r) || // Left edge touching
1469 - (x2 >= l && x2 <= r) || // Right edge touching
1470 - (x1 < l && x2 > r) // Surrounded horizontally
1471 - );
1472 - break;
1473 - default:
1474 - return false;
1475 - break;
1476 - }
1477 -
1478 -};
1479 -
1480 -/*
1481 - This manager tracks offsets of draggables and droppables
1482 -*/
1483 -$.ui.ddmanager = {
1484 - current: null,
1485 - droppables: { 'default': [] },
1486 - prepareOffsets: function(t, event) {
1487 -
1488 - var m = $.ui.ddmanager.droppables[t.options.scope];
1489 - var type = event ? event.type : null; // workaround for #2317
1490 - var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
1491 -
1492 - droppablesLoop: for (var i = 0; i < m.length; i++) {
1493 -
1494 - if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
1495 - for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
1496 - m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
1497 -
1498 - m[i].offset = m[i].element.offset();
1499 - m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
1500 -
1501 - if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
1502 -
1503 - }
1504 -
1505 - },
1506 - drop: function(draggable, event) {
1507 -
1508 - var dropped = false;
1509 - $.each($.ui.ddmanager.droppables[draggable.options.scope], function() {
1510 -
1511 - if(!this.options) return;
1512 - if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
1513 - dropped = this._drop.call(this, event);
1514 -
1515 - if (!this.options.disabled && this.visible && this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1516 - this.isout = 1; this.isover = 0;
1517 - this._deactivate.call(this, event);
1518 - }
1519 -
1520 - });
1521 - return dropped;
1522 -
1523 - },
1524 - drag: function(draggable, event) {
1525 -
1526 - //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
1527 - if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
1528 -
1529 - //Run through all droppables and check their positions based on specific tolerance options
1530 -
1531 - $.each($.ui.ddmanager.droppables[draggable.options.scope], function() {
1532 -
1533 - if(this.options.disabled || this.greedyChild || !this.visible) return;
1534 - var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
1535 -
1536 - var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
1537 - if(!c) return;
1538 -
1539 - var parentInstance;
1540 - if (this.options.greedy) {
1541 - var parent = this.element.parents(':data(droppable):eq(0)');
1542 - if (parent.length) {
1543 - parentInstance = $.data(parent[0], 'droppable');
1544 - parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
1545 - }
1546 - }
1547 -
1548 - // we just moved into a greedy child
1549 - if (parentInstance && c == 'isover') {
1550 - parentInstance['isover'] = 0;
1551 - parentInstance['isout'] = 1;
1552 - parentInstance._out.call(parentInstance, event);
1553 - }
1554 -
1555 - this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
1556 - this[c == "isover" ? "_over" : "_out"].call(this, event);
1557 -
1558 - // we just moved out of a greedy child
1559 - if (parentInstance && c == 'isout') {
1560 - parentInstance['isout'] = 0;
1561 - parentInstance['isover'] = 1;
1562 - parentInstance._over.call(parentInstance, event);
1563 - }
1564 - });
1565 -
1566 - }
1567 -};
1568 -
1569 -})(jQuery);
1570 -
1571 -/*
1572 - * jQuery UI Resizable 1.7.2
1573 - *
1574 - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
1575 - * Dual licensed under the MIT (MIT-LICENSE.txt)
1576 - * and GPL (GPL-LICENSE.txt) licenses.
1577 - *
1578 - * http://docs.jquery.com/UI/Resizables
1579 - *
1580 - * Depends:
1581 - * ui.core.js
1582 - */
1583 -(function($) {
1584 -
1585 -$.widget("ui.resizable", $.extend({}, $.ui.mouse, {
1586 -
1587 - _init: function() {
1588 -
1589 - var self = this, o = this.options;
1590 - this.element.addClass("ui-resizable");
1591 -
1592 - $.extend(this, {
1593 - _aspectRatio: !!(o.aspectRatio),
1594 - aspectRatio: o.aspectRatio,
1595 - originalElement: this.element,
1596 - _proportionallyResizeElements: [],
1597 - _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
1598 - });
1599 -
1600 - //Wrap the element if it cannot hold child nodes
1601 - if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
1602 -
1603 - //Opera fix for relative positioning
1604 - if (/relative/.test(this.element.css('position')) && $.browser.opera)
1605 - this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
1606 -
1607 - //Create a wrapper element and set the wrapper to the new current internal element
1608 - this.element.wrap(
1609 - $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
1610 - position: this.element.css('position'),
1611 - width: this.element.outerWidth(),
1612 - height: this.element.outerHeight(),
1613 - top: this.element.css('top'),
1614 - left: this.element.css('left')
1615 - })
1616 - );
1617 -
1618 - //Overwrite the original this.element
1619 - this.element = this.element.parent().data(
1620 - "resizable", this.element.data('resizable')
1621 - );
1622 -
1623 - this.elementIsWrapper = true;
1624 -
1625 - //Move margins to the wrapper
1626 - this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
1627 - this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
1628 -
1629 - //Prevent Safari textarea resize
1630 - this.originalResizeStyle = this.originalElement.css('resize');
1631 - this.originalElement.css('resize', 'none');
1632 -
1633 - //Push the actual element to our proportionallyResize internal array
1634 - this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
1635 -
1636 - // avoid IE jump (hard set the margin)
1637 - this.originalElement.css({ margin: this.originalElement.css('margin') });
1638 -
1639 - // fix handlers offset
1640 - this._proportionallyResize();
1641 -
1642 - }
1643 -
1644 - this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
1645 - if(this.handles.constructor == String) {
1646 -
1647 - if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
1648 - var n = this.handles.split(","); this.handles = {};
1649 -
1650 - for(var i = 0; i < n.length; i++) {
1651 -
1652 - var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
1653 - var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
1654 -
1655 - // increase zIndex of sw, se, ne, nw axis
1656 - //TODO : this modifies original option
1657 - if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
1658 -
1659 - //TODO : What's going on here?
1660 - if ('se' == handle) {
1661 - axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
1662 - };
1663 -
1664 - //Insert into internal handles object and append to element
1665 - this.handles[handle] = '.ui-resizable-'+handle;
1666 - this.element.append(axis);
1667 - }
1668 -
1669 - }
1670 -
1671 - this._renderAxis = function(target) {
1672 -
1673 - target = target || this.element;
1674 -
1675 - for(var i in this.handles) {
1676 -
1677 - if(this.handles[i].constructor == String)
1678 - this.handles[i] = $(this.handles[i], this.element).show();
1679 -
1680 - //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
1681 - if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
1682 -
1683 - var axis = $(this.handles[i], this.element), padWrapper = 0;
1684 -
1685 - //Checking the correct pad and border
1686 - padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
1687 -
1688 - //The padding type i have to apply...
1689 - var padPos = [ 'padding',
1690 - /ne|nw|n/.test(i) ? 'Top' :
1691 - /se|sw|s/.test(i) ? 'Bottom' :
1692 - /^e$/.test(i) ? 'Right' : 'Left' ].join("");
1693 -
1694 - target.css(padPos, padWrapper);
1695 -
1696 - this._proportionallyResize();
1697 -
1698 - }
1699 -
1700 - //TODO: What's that good for? There's not anything to be executed left
1701 - if(!$(this.handles[i]).length)
1702 - continue;
1703 -
1704 - }
1705 - };
1706 -
1707 - //TODO: make renderAxis a prototype function
1708 - this._renderAxis(this.element);
1709 -
1710 - this._handles = $('.ui-resizable-handle', this.element)
1711 - .disableSelection();
1712 -
1713 - //Matching axis name
1714 - this._handles.mouseover(function() {
1715 - if (!self.resizing) {
1716 - if (this.className)
1717 - var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
1718 - //Axis, default = se
1719 - self.axis = axis && axis[1] ? axis[1] : 'se';
1720 - }
1721 - });
1722 -
1723 - //If we want to auto hide the elements
1724 - if (o.autoHide) {
1725 - this._handles.hide();
1726 - $(this.element)
1727 - .addClass("ui-resizable-autohide")
1728 - .hover(function() {
1729 - $(this).removeClass("ui-resizable-autohide");
1730 - self._handles.show();
1731 - },
1732 - function(){
1733 - if (!self.resizing) {
1734 - $(this).addClass("ui-resizable-autohide");
1735 - self._handles.hide();
1736 - }
1737 - });
1738 - }
1739 -
1740 - //Initialize the mouse interaction
1741 - this._mouseInit();
1742 -
1743 - },
1744 -
1745 - destroy: function() {
1746 -
1747 - this._mouseDestroy();
1748 -
1749 - var _destroy = function(exp) {
1750 - $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
1751 - .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
1752 - };
1753 -
1754 - //TODO: Unwrap at same DOM position
1755 - if (this.elementIsWrapper) {
1756 - _destroy(this.element);
1757 - var wrapper = this.element;
1758 - wrapper.parent().append(
1759 - this.originalElement.css({
1760 - position: wrapper.css('position'),
1761 - width: wrapper.outerWidth(),
1762 - height: wrapper.outerHeight(),
1763 - top: wrapper.css('top'),
1764 - left: wrapper.css('left')
1765 - })
1766 - ).end().remove();
1767 - }
1768 -
1769 - this.originalElement.css('resize', this.originalResizeStyle);
1770 - _destroy(this.originalElement);
1771 -
1772 - },
1773 -
1774 - _mouseCapture: function(event) {
1775 -
1776 - var handle = false;
1777 - for(var i in this.handles) {
1778 - if($(this.handles[i])[0] == event.target) handle = true;
1779 - }
1780 -
1781 - return this.options.disabled || !!handle;
1782 -
1783 - },
1784 -
1785 - _mouseStart: function(event) {
1786 -
1787 - var o = this.options, iniPos = this.element.position(), el = this.element;
1788 -
1789 - this.resizing = true;
1790 - this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
1791 -
1792 - // bugfix for http://dev.jquery.com/ticket/1749
1793 - if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
1794 - el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
1795 - }
1796 -
1797 - //Opera fixing relative position
1798 - if ($.browser.opera && (/relative/).test(el.css('position')))
1799 - el.css({ position: 'relative', top: 'auto', left: 'auto' });
1800 -
1801 - this._renderProxy();
1802 -
1803 - var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
1804 -
1805 - if (o.containment) {
1806 - curleft += $(o.containment).scrollLeft() || 0;
1807 - curtop += $(o.containment).scrollTop() || 0;
1808 - }
1809 -
1810 - //Store needed variables
1811 - this.offset = this.helper.offset();
1812 - this.position = { left: curleft, top: curtop };
1813 - this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
1814 - this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
1815 - this.originalPosition = { left: curleft, top: curtop };
1816 - this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
1817 - this.originalMousePosition = { left: event.pageX, top: event.pageY };
1818 -
1819 - //Aspect Ratio
1820 - this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
1821 -
1822 - var cursor = $('.ui-resizable-' + this.axis).css('cursor');
1823 - $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
1824 -
1825 - el.addClass("ui-resizable-resizing");
1826 - this._propagate("start", event);
1827 - return true;
1828 - },
1829 -
1830 - _mouseDrag: function(event) {
1831 -
1832 - //Increase performance, avoid regex
1833 - var el = this.helper, o = this.options, props = {},
1834 - self = this, smp = this.originalMousePosition, a = this.axis;
1835 -
1836 - var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
1837 - var trigger = this._change[a];
1838 - if (!trigger) return false;
1839 -
1840 - // Calculate the attrs that will be change
1841 - var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
1842 -
1843 - if (this._aspectRatio || event.shiftKey)
1844 - data = this._updateRatio(data, event);
1845 -
1846 - data = this._respectSize(data, event);
1847 -
1848 - // plugins callbacks need to be called first
1849 - this._propagate("resize", event);
1850 -
1851 - el.css({
1852 - top: this.position.top + "px", left: this.position.left + "px",
1853 - width: this.size.width + "px", height: this.size.height + "px"
1854 - });
1855 -
1856 - if (!this._helper && this._proportionallyResizeElements.length)
1857 - this._proportionallyResize();
1858 -
1859 - this._updateCache(data);
1860 -
1861 - // calling the user callback at the end
1862 - this._trigger('resize', event, this.ui());
1863 -
1864 - return false;
1865 - },
1866 -
1867 - _mouseStop: function(event) {
1868 -
1869 - this.resizing = false;
1870 - var o = this.options, self = this;
1871 -
1872 - if(this._helper) {
1873 - var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
1874 - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
1875 - soffsetw = ista ? 0 : self.sizeDiff.width;
1876 -
1877 - var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
1878 - left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
1879 - top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
1880 -
1881 - if (!o.animate)
1882 - this.element.css($.extend(s, { top: top, left: left }));
1883 -
1884 - self.helper.height(self.size.height);
1885 - self.helper.width(self.size.width);
1886 -
1887 - if (this._helper && !o.animate) this._proportionallyResize();
1888 - }
1889 -
1890 - $('body').css('cursor', 'auto');
1891 -
1892 - this.element.removeClass("ui-resizable-resizing");
1893 -
1894 - this._propagate("stop", event);
1895 -
1896 - if (this._helper) this.helper.remove();
1897 - return false;
1898 -
1899 - },
1900 -
1901 - _updateCache: function(data) {
1902 - var o = this.options;
1903 - this.offset = this.helper.offset();
1904 - if (isNumber(data.left)) this.position.left = data.left;
1905 - if (isNumber(data.top)) this.position.top = data.top;
1906 - if (isNumber(data.height)) this.size.height = data.height;
1907 - if (isNumber(data.width)) this.size.width = data.width;
1908 - },
1909 -
1910 - _updateRatio: function(data, event) {
1911 -
1912 - var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
1913 -
1914 - if (data.height) data.width = (csize.height * this.aspectRatio);
1915 - else if (data.width) data.height = (csize.width / this.aspectRatio);
1916 -
1917 - if (a == 'sw') {
1918 - data.left = cpos.left + (csize.width - data.width);
1919 - data.top = null;
1920 - }
1921 - if (a == 'nw') {
1922 - data.top = cpos.top + (csize.height - data.height);
1923 - data.left = cpos.left + (csize.width - data.width);
1924 - }
1925 -
1926 - return data;
1927 - },
1928 -
1929 - _respectSize: function(data, event) {
1930 -
1931 - var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
1932 - ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
1933 - isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
1934 -
1935 - if (isminw) data.width = o.minWidth;
1936 - if (isminh) data.height = o.minHeight;
1937 - if (ismaxw) data.width = o.maxWidth;
1938 - if (ismaxh) data.height = o.maxHeight;
1939 -
1940 - var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
1941 - var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
1942 -
1943 - if (isminw && cw) data.left = dw - o.minWidth;
1944 - if (ismaxw && cw) data.left = dw - o.maxWidth;
1945 - if (isminh && ch) data.top = dh - o.minHeight;
1946 - if (ismaxh && ch) data.top = dh - o.maxHeight;
1947 -
1948 - // fixing jump error on top/left - bug #2330
1949 - var isNotwh = !data.width && !data.height;
1950 - if (isNotwh && !data.left && data.top) data.top = null;
1951 - else if (isNotwh && !data.top && data.left) data.left = null;
1952 -
1953 - return data;
1954 - },
1955 -
1956 - _proportionallyResize: function() {
1957 -
1958 - var o = this.options;
1959 - if (!this._proportionallyResizeElements.length) return;
1960 - var element = this.helper || this.element;
1961 -
1962 - for (var i=0; i < this._proportionallyResizeElements.length; i++) {
1963 -
1964 - var prel = this._proportionallyResizeElements[i];
1965 -
1966 - if (!this.borderDif) {
1967 - var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
1968 - p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
1969 -
1970 - this.borderDif = $.map(b, function(v, i) {
1971 - var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
1972 - return border + padding;
1973 - });
1974 - }
1975 -
1976 - if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
1977 - continue;
1978 -
1979 - prel.css({
1980 - height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
1981 - width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
1982 - });
1983 -
1984 - };
1985 -
1986 - },
1987 -
1988 - _renderProxy: function() {
1989 -
1990 - var el = this.element, o = this.options;
1991 - this.elementOffset = el.offset();
1992 -
1993 - if(this._helper) {
1994 -
1995 - this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
1996 -
1997 - // fix ie6 offset TODO: This seems broken
1998 - var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
1999 - pxyoffset = ( ie6 ? 2 : -1 );
2000 -
2001 - this.helper.addClass(this._helper).css({
2002 - width: this.element.outerWidth() + pxyoffset,
2003 - height: this.element.outerHeight() + pxyoffset,
2004 - position: 'absolute',
2005 - left: this.elementOffset.left - ie6offset +'px',
2006 - top: this.elementOffset.top - ie6offset +'px',
2007 - zIndex: ++o.zIndex //TODO: Don't modify option
2008 - });
2009 -
2010 - this.helper
2011 - .appendTo("body")
2012 - .disableSelection();
2013 -
2014 - } else {
2015 - this.helper = this.element;
2016 - }
2017 -
2018 - },
2019 -
2020 - _change: {
2021 - e: function(event, dx, dy) {
2022 - return { width: this.originalSize.width + dx };
2023 - },
2024 - w: function(event, dx, dy) {
2025 - var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2026 - return { left: sp.left + dx, width: cs.width - dx };
2027 - },
2028 - n: function(event, dx, dy) {
2029 - var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2030 - return { top: sp.top + dy, height: cs.height - dy };
2031 - },
2032 - s: function(event, dx, dy) {
2033 - return { height: this.originalSize.height + dy };
2034 - },
2035 - se: function(event, dx, dy) {
2036 - return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2037 - },
2038 - sw: function(event, dx, dy) {
2039 - return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2040 - },
2041 - ne: function(event, dx, dy) {
2042 - return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2043 - },
2044 - nw: function(event, dx, dy) {
2045 - return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2046 - }
2047 - },
2048 -
2049 - _propagate: function(n, event) {
2050 - $.ui.plugin.call(this, n, [event, this.ui()]);
2051 - (n != "resize" && this._trigger(n, event, this.ui()));
2052 - },
2053 -
2054 - plugins: {},
2055 -
2056 - ui: function() {
2057 - return {
2058 - originalElement: this.originalElement,
2059 - element: this.element,
2060 - helper: this.helper,
2061 - position: this.position,
2062 - size: this.size,
2063 - originalSize: this.originalSize,
2064 - originalPosition: this.originalPosition
2065 - };
2066 - }
2067 -
2068 -}));
2069 -
2070 -$.extend($.ui.resizable, {
2071 - version: "1.7.2",
2072 - eventPrefix: "resize",
2073 - defaults: {
2074 - alsoResize: false,
2075 - animate: false,
2076 - animateDuration: "slow",
2077 - animateEasing: "swing",
2078 - aspectRatio: false,
2079 - autoHide: false,
2080 - cancel: ":input,option",
2081 - containment: false,
2082 - delay: 0,
2083 - distance: 1,
2084 - ghost: false,
2085 - grid: false,
2086 - handles: "e,s,se",
2087 - helper: false,
2088 - maxHeight: null,
2089 - maxWidth: null,
2090 - minHeight: 10,
2091 - minWidth: 10,
2092 - zIndex: 1000
2093 - }
2094 -});
2095 -
2096 -/*
2097 - * Resizable Extensions
2098 - */
2099 -
2100 -$.ui.plugin.add("resizable", "alsoResize", {
2101 -
2102 - start: function(event, ui) {
2103 -
2104 - var self = $(this).data("resizable"), o = self.options;
2105 -
2106 - _store = function(exp) {
2107 - $(exp).each(function() {
2108 - $(this).data("resizable-alsoresize", {
2109 - width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
2110 - left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
2111 - });
2112 - });
2113 - };
2114 -
2115 - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2116 - if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2117 - else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); }
2118 - }else{
2119 - _store(o.alsoResize);
2120 - }
2121 - },
2122 -
2123 - resize: function(event, ui){
2124 - var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2125 -
2126 - var delta = {
2127 - height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2128 - top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2129 - },
2130 -
2131 - _alsoResize = function(exp, c) {
2132 - $(exp).each(function() {
2133 - var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
2134 -
2135 - $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
2136 - var sum = (start[prop]||0) + (delta[prop]||0);
2137 - if (sum && sum >= 0)
2138 - style[prop] = sum || null;
2139 - });
2140 -
2141 - //Opera fixing relative position
2142 - if (/relative/.test(el.css('position')) && $.browser.opera) {
2143 - self._revertToRelativePosition = true;
2144 - el.css({ position: 'absolute', top: 'auto', left: 'auto' });
2145 - }
2146 -
2147 - el.css(style);
2148 - });
2149 - };
2150 -
2151 - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2152 - $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });
2153 - }else{
2154 - _alsoResize(o.alsoResize);
2155 - }
2156 - },
2157 -
2158 - stop: function(event, ui){
2159 - var self = $(this).data("resizable");
2160 -
2161 - //Opera fixing relative position
2162 - if (self._revertToRelativePosition && $.browser.opera) {
2163 - self._revertToRelativePosition = false;
2164 - el.css({ position: 'relative' });
2165 - }
2166 -
2167 - $(this).removeData("resizable-alsoresize-start");
2168 - }
2169 -});
2170 -
2171 -$.ui.plugin.add("resizable", "animate", {
2172 -
2173 - stop: function(event, ui) {
2174 - var self = $(this).data("resizable"), o = self.options;
2175 -
2176 - var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2177 - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2178 - soffsetw = ista ? 0 : self.sizeDiff.width;
2179 -
2180 - var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2181 - left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2182 - top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2183 -
2184 - self.element.animate(
2185 - $.extend(style, top && left ? { top: top, left: left } : {}), {
2186 - duration: o.animateDuration,
2187 - easing: o.animateEasing,
2188 - step: function() {
2189 -
2190 - var data = {
2191 - width: parseInt(self.element.css('width'), 10),
2192 - height: parseInt(self.element.css('height'), 10),
2193 - top: parseInt(self.element.css('top'), 10),
2194 - left: parseInt(self.element.css('left'), 10)
2195 - };
2196 -
2197 - if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2198 -
2199 - // propagating resize, and updating values for each animation step
2200 - self._updateCache(data);
2201 - self._propagate("resize", event);
2202 -
2203 - }
2204 - }
2205 - );
2206 - }
2207 -
2208 -});
2209 -
2210 -$.ui.plugin.add("resizable", "containment", {
2211 -
2212 - start: function(event, ui) {
2213 - var self = $(this).data("resizable"), o = self.options, el = self.element;
2214 - var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2215 - if (!ce) return;
2216 -
2217 - self.containerElement = $(ce);
2218 -
2219 - if (/document/.test(oc) || oc == document) {
2220 - self.containerOffset = { left: 0, top: 0 };
2221 - self.containerPosition = { left: 0, top: 0 };
2222 -
2223 - self.parentData = {
2224 - element: $(document), left: 0, top: 0,
2225 - width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2226 - };
2227 - }
2228 -
2229 - // i'm a node, so compute top, left, right, bottom
2230 - else {
2231 - var element = $(ce), p = [];
2232 - $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2233 -
2234 - self.containerOffset = element.offset();
2235 - self.containerPosition = element.position();
2236 - self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2237 -
2238 - var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
2239 - width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2240 -
2241 - self.parentData = {
2242 - element: ce, left: co.left, top: co.top, width: width, height: height
2243 - };
2244 - }
2245 - },
2246 -
2247 - resize: function(event, ui) {
2248 - var self = $(this).data("resizable"), o = self.options,
2249 - ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2250 - pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2251 -
2252 - if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2253 -
2254 - if (cp.left < (self._helper ? co.left : 0)) {
2255 - self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2256 - if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2257 - self.position.left = o.helper ? co.left : 0;
2258 - }
2259 -
2260 - if (cp.top < (self._helper ? co.top : 0)) {
2261 - self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2262 - if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2263 - self.position.top = self._helper ? co.top : 0;
2264 - }
2265 -
2266 - self.offset.left = self.parentData.left+self.position.left;
2267 - self.offset.top = self.parentData.top+self.position.top;
2268 -
2269 - var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2270 - hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2271 -
2272 - var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2273 - isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2274 -
2275 - if(isParent && isOffsetRelative) woset -= self.parentData.left;
2276 -
2277 - if (woset + self.size.width >= self.parentData.width) {
2278 - self.size.width = self.parentData.width - woset;
2279 - if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2280 - }
2281 -
2282 - if (hoset + self.size.height >= self.parentData.height) {
2283 - self.size.height = self.parentData.height - hoset;
2284 - if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2285 - }
2286 - },
2287 -
2288 - stop: function(event, ui){
2289 - var self = $(this).data("resizable"), o = self.options, cp = self.position,
2290 - co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2291 -
2292 - var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2293 -
2294 - if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2295 - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2296 -
2297 - if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2298 - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2299 -
2300 - }
2301 -});
2302 -
2303 -$.ui.plugin.add("resizable", "ghost", {
2304 -
2305 - start: function(event, ui) {
2306 -
2307 - var self = $(this).data("resizable"), o = self.options, cs = self.size;
2308 -
2309 - self.ghost = self.originalElement.clone();
2310 - self.ghost
2311 - .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2312 - .addClass('ui-resizable-ghost')
2313 - .addClass(typeof o.ghost == 'string' ? o.ghost : '');
2314 -
2315 - self.ghost.appendTo(self.helper);
2316 -
2317 - },
2318 -
2319 - resize: function(event, ui){
2320 - var self = $(this).data("resizable"), o = self.options;
2321 - if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2322 - },
2323 -
2324 - stop: function(event, ui){
2325 - var self = $(this).data("resizable"), o = self.options;
2326 - if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2327 - }
2328 -
2329 -});
2330 -
2331 -$.ui.plugin.add("resizable", "grid", {
2332 -
2333 - resize: function(event, ui) {
2334 - var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
2335 - o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2336 - var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
2337 -
2338 - if (/^(se|s|e)$/.test(a)) {
2339 - self.size.width = os.width + ox;
2340 - self.size.height = os.height + oy;
2341 - }
2342 - else if (/^(ne)$/.test(a)) {
2343 - self.size.width = os.width + ox;
2344 - self.size.height = os.height + oy;
2345 - self.position.top = op.top - oy;
2346 - }
2347 - else if (/^(sw)$/.test(a)) {
2348 - self.size.width = os.width + ox;
2349 - self.size.height = os.height + oy;
2350 - self.position.left = op.left - ox;
2351 - }
2352 - else {
2353 - self.size.width = os.width + ox;
2354 - self.size.height = os.height + oy;
2355 - self.position.top = op.top - oy;
2356 - self.position.left = op.left - ox;
2357 - }
2358 - }
2359 -
2360 -});
2361 -
2362 -var num = function(v) {
2363 - return parseInt(v, 10) || 0;
2364 -};
2365 -
2366 -var isNumber = function(value) {
2367 - return !isNaN(parseInt(value, 10));
2368 -};
2369 -
2370 -})(jQuery);
2371 -/*
2372 - * jQuery UI Dialog 1.7.2
2373 - *
2374 - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
2375 - * Dual licensed under the MIT (MIT-LICENSE.txt)
2376 - * and GPL (GPL-LICENSE.txt) licenses.
2377 - *
2378 - * http://docs.jquery.com/UI/Dialog
2379 - *
2380 - * Depends:
2381 - * ui.core.js
2382 - * ui.draggable.js
2383 - * ui.resizable.js
2384 - */
2385 -(function($) {
2386 -
2387 -var setDataSwitch = {
2388 - dragStart: "start.draggable",
2389 - drag: "drag.draggable",
2390 - dragStop: "stop.draggable",
2391 - maxHeight: "maxHeight.resizable",
2392 - minHeight: "minHeight.resizable",
2393 - maxWidth: "maxWidth.resizable",
2394 - minWidth: "minWidth.resizable",
2395 - resizeStart: "start.resizable",
2396 - resize: "drag.resizable",
2397 - resizeStop: "stop.resizable"
2398 - },
2399 -
2400 - uiDialogClasses =
2401 - 'ui-dialog ' +
2402 - 'ui-widget ' +
2403 - 'ui-widget-content ' +
2404 - 'ui-corner-all ';
2405 -
2406 -$.widget("ui.dialog", {
2407 -
2408 - _init: function() {
2409 - this.originalTitle = this.element.attr('title');
2410 -
2411 - var self = this,
2412 - options = this.options,
2413 -
2414 - title = options.title || this.originalTitle || '&nbsp;',
2415 - titleId = $.ui.dialog.getTitleId(this.element),
2416 -
2417 - uiDialog = (this.uiDialog = $('<div/>'))
2418 - .appendTo(document.body)
2419 - .hide()
2420 - .addClass(uiDialogClasses + options.dialogClass)
2421 - .css({
2422 - position: 'absolute',
2423 - overflow: 'hidden',
2424 - zIndex: options.zIndex
2425 - })
2426 - // setting tabIndex makes the div focusable
2427 - // setting outline to 0 prevents a border on focus in Mozilla
2428 - .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
2429 - (options.closeOnEscape && event.keyCode
2430 - && event.keyCode == $.ui.keyCode.ESCAPE && self.close(event));
2431 - })
2432 - .attr({
2433 - role: 'dialog',
2434 - 'aria-labelledby': titleId
2435 - })
2436 - .mousedown(function(event) {
2437 - self.moveToTop(false, event);
2438 - }),
2439 -
2440 - uiDialogContent = this.element
2441 - .show()
2442 - .removeAttr('title')
2443 - .addClass(
2444 - 'ui-dialog-content ' +
2445 - 'ui-widget-content')
2446 - .appendTo(uiDialog),
2447 -
2448 - uiDialogTitlebar = (this.uiDialogTitlebar = $('<div></div>'))
2449 - .addClass(
2450 - 'ui-dialog-titlebar ' +
2451 - 'ui-widget-header ' +
2452 - 'ui-corner-all ' +
2453 - 'ui-helper-clearfix'
2454 - )
2455 - .prependTo(uiDialog),
2456 -
2457 - uiDialogTitlebarClose = $('<a href="#"/>')
2458 - .addClass(
2459 - 'ui-dialog-titlebar-close ' +
2460 - 'ui-corner-all'
2461 - )
2462 - .attr('role', 'button')
2463 - .hover(
2464 - function() {
2465 - uiDialogTitlebarClose.addClass('ui-state-hover');
2466 - },
2467 - function() {
2468 - uiDialogTitlebarClose.removeClass('ui-state-hover');
2469 - }
2470 - )
2471 - .focus(function() {
2472 - uiDialogTitlebarClose.addClass('ui-state-focus');
2473 - })
2474 - .blur(function() {
2475 - uiDialogTitlebarClose.removeClass('ui-state-focus');
2476 - })
2477 - .mousedown(function(ev) {
2478 - ev.stopPropagation();
2479 - })
2480 - .click(function(event) {
2481 - self.close(event);
2482 - return false;
2483 - })
2484 - .appendTo(uiDialogTitlebar),
2485 -
2486 - uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>'))
2487 - .addClass(
2488 - 'ui-icon ' +
2489 - 'ui-icon-closethick'
2490 - )
2491 - .text(options.closeText)
2492 - .appendTo(uiDialogTitlebarClose),
2493 -
2494 - uiDialogTitle = $('<span/>')
2495 - .addClass('ui-dialog-title')
2496 - .attr('id', titleId)
2497 - .html(title)
2498 - .prependTo(uiDialogTitlebar);
2499 -
2500 - uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
2501 -
2502 - (options.draggable && $.fn.draggable && this._makeDraggable());
2503 - (options.resizable && $.fn.resizable && this._makeResizable());
2504 -
2505 - this._createButtons(options.buttons);
2506 - this._isOpen = false;
2507 -
2508 - (options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe());
2509 - (options.autoOpen && this.open());
2510 -
2511 - },
2512 -
2513 - destroy: function() {
2514 - (this.overlay && this.overlay.destroy());
2515 - this.uiDialog.hide();
2516 - this.element
2517 - .unbind('.dialog')
2518 - .removeData('dialog')
2519 - .removeClass('ui-dialog-content ui-widget-content')
2520 - .hide().appendTo('body');
2521 - this.uiDialog.remove();
2522 -
2523 - (this.originalTitle && this.element.attr('title', this.originalTitle));
2524 - },
2525 -
2526 - close: function(event) {
2527 - var self = this;
2528 -
2529 - if (false === self._trigger('beforeclose', event)) {
2530 - return;
2531 - }
2532 -
2533 - (self.overlay && self.overlay.destroy());
2534 - self.uiDialog.unbind('keypress.ui-dialog');
2535 -
2536 - (self.options.hide
2537 - ? self.uiDialog.hide(self.options.hide, function() {
2538 - self._trigger('close', event);
2539 - })
2540 - : self.uiDialog.hide() && self._trigger('close', event));
2541 -
2542 - $.ui.dialog.overlay.resize();
2543 -
2544 - self._isOpen = false;
2545 -
2546 - // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
2547 - if (self.options.modal) {
2548 - var maxZ = 0;
2549 - $('.ui-dialog').each(function() {
2550 - if (this != self.uiDialog[0]) {
2551 - maxZ = Math.max(maxZ, $(this).css('z-index'));
2552 - }
2553 - });
2554 - $.ui.dialog.maxZ = maxZ;
2555 - }
2556 - },
2557 -
2558 - isOpen: function() {
2559 - return this._isOpen;
2560 - },
2561 -
2562 - // the force parameter allows us to move modal dialogs to their correct
2563 - // position on open
2564 - moveToTop: function(force, event) {
2565 -
2566 - if ((this.options.modal && !force)
2567 - || (!this.options.stack && !this.options.modal)) {
2568 - return this._trigger('focus', event);
2569 - }
2570 -
2571 - if (this.options.zIndex > $.ui.dialog.maxZ) {
2572 - $.ui.dialog.maxZ = this.options.zIndex;
2573 - }
2574 - (this.overlay && this.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = ++$.ui.dialog.maxZ));
2575 -
2576 - //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
2577 - // http://ui.jquery.com/bugs/ticket/3193
2578 - var saveScroll = { scrollTop: this.element.attr('scrollTop'), scrollLeft: this.element.attr('scrollLeft') };
2579 - this.uiDialog.css('z-index', ++$.ui.dialog.maxZ);
2580 - this.element.attr(saveScroll);
2581 - this._trigger('focus', event);
2582 - },
2583 -
2584 - open: function() {
2585 - if (this._isOpen) { return; }
2586 -
2587 - var options = this.options,
2588 - uiDialog = this.uiDialog;
2589 -
2590 - this.overlay = options.modal ? new $.ui.dialog.overlay(this) : null;
2591 - (uiDialog.next().length && uiDialog.appendTo('body'));
2592 - this._size();
2593 - this._position(options.position);
2594 - uiDialog.show(options.show);
2595 - this.moveToTop(true);
2596 -
2597 - // prevent tabbing out of modal dialogs
2598 - (options.modal && uiDialog.bind('keypress.ui-dialog', function(event) {
2599 - if (event.keyCode != $.ui.keyCode.TAB) {
2600 - return;
2601 - }
2602 -
2603 - var tabbables = $(':tabbable', this),
2604 - first = tabbables.filter(':first')[0],
2605 - last = tabbables.filter(':last')[0];
2606 -
2607 - if (event.target == last && !event.shiftKey) {
2608 - setTimeout(function() {
2609 - first.focus();
2610 - }, 1);
2611 - } else if (event.target == first && event.shiftKey) {
2612 - setTimeout(function() {
2613 - last.focus();
2614 - }, 1);
2615 - }
2616 - }));
2617 -
2618 - // set focus to the first tabbable element in the content area or the first button
2619 - // if there are no tabbable elements, set focus on the dialog itself
2620 - $([])
2621 - .add(uiDialog.find('.ui-dialog-content :tabbable:first'))
2622 - .add(uiDialog.find('.ui-dialog-buttonpane :tabbable:first'))
2623 - .add(uiDialog)
2624 - .filter(':first')
2625 - .focus();
2626 -
2627 - this._trigger('open');
2628 - this._isOpen = true;
2629 - },
2630 -
2631 - _createButtons: function(buttons) {
2632 - var self = this,
2633 - hasButtons = false,
2634 - uiDialogButtonPane = $('<div></div>')
2635 - .addClass(
2636 - 'ui-dialog-buttonpane ' +
2637 - 'ui-widget-content ' +
2638 - 'ui-helper-clearfix'
2639 - );
2640 -
2641 - // if we already have a button pane, remove it
2642 - this.uiDialog.find('.ui-dialog-buttonpane').remove();
2643 -
2644 - (typeof buttons == 'object' && buttons !== null &&
2645 - $.each(buttons, function() { return !(hasButtons = true); }));
2646 - if (hasButtons) {
2647 - $.each(buttons, function(name, fn) {
2648 - $('<button type="button"></button>')
2649 - .addClass(
2650 - 'ui-state-default ' +
2651 - 'ui-corner-all'
2652 - )
2653 - .text(name)
2654 - .click(function() { fn.apply(self.element[0], arguments); })
2655 - .hover(
2656 - function() {
2657 - $(this).addClass('ui-state-hover');
2658 - },
2659 - function() {
2660 - $(this).removeClass('ui-state-hover');
2661 - }
2662 - )
2663 - .focus(function() {
2664 - $(this).addClass('ui-state-focus');
2665 - })
2666 - .blur(function() {
2667 - $(this).removeClass('ui-state-focus');
2668 - })
2669 - .appendTo(uiDialogButtonPane);
2670 - });
2671 - uiDialogButtonPane.appendTo(this.uiDialog);
2672 - }
2673 - },
2674 -
2675 - _makeDraggable: function() {
2676 - var self = this,
2677 - options = this.options,
2678 - heightBeforeDrag;
2679 -
2680 - this.uiDialog.draggable({
2681 - cancel: '.ui-dialog-content',
2682 - handle: '.ui-dialog-titlebar',
2683 - containment: 'document',
2684 - start: function() {
2685 - heightBeforeDrag = options.height;
2686 - $(this).height($(this).height()).addClass("ui-dialog-dragging");
2687 - (options.dragStart && options.dragStart.apply(self.element[0], arguments));
2688 - },
2689 - drag: function() {
2690 - (options.drag && options.drag.apply(self.element[0], arguments));
2691 - },
2692 - stop: function() {
2693 - $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
2694 - (options.dragStop && options.dragStop.apply(self.element[0], arguments));
2695 - $.ui.dialog.overlay.resize();
2696 - }
2697 - });
2698 - },
2699 -
2700 - _makeResizable: function(handles) {
2701 - handles = (handles === undefined ? this.options.resizable : handles);
2702 - var self = this,
2703 - options = this.options,
2704 - resizeHandles = typeof handles == 'string'
2705 - ? handles
2706 - : 'n,e,s,w,se,sw,ne,nw';
2707 -
2708 - this.uiDialog.resizable({
2709 - cancel: '.ui-dialog-content',
2710 - alsoResize: this.element,
2711 - maxWidth: options.maxWidth,
2712 - maxHeight: options.maxHeight,
2713 - minWidth: options.minWidth,
2714 - minHeight: options.minHeight,
2715 - start: function() {
2716 - $(this).addClass("ui-dialog-resizing");
2717 - (options.resizeStart && options.resizeStart.apply(self.element[0], arguments));
2718 - },
2719 - resize: function() {
2720 - (options.resize && options.resize.apply(self.element[0], arguments));
2721 - },
2722 - handles: resizeHandles,
2723 - stop: function() {
2724 - $(this).removeClass("ui-dialog-resizing");
2725 - options.height = $(this).height();
2726 - options.width = $(this).width();
2727 - (options.resizeStop && options.resizeStop.apply(self.element[0], arguments));
2728 - $.ui.dialog.overlay.resize();
2729 - }
2730 - })
2731 - .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
2732 - },
2733 -
2734 - _position: function(pos) {
2735 - var wnd = $(window), doc = $(document),
2736 - pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
2737 - minTop = pTop;
2738 -
2739 - if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
2740 - pos = [
2741 - pos == 'right' || pos == 'left' ? pos : 'center',
2742 - pos == 'top' || pos == 'bottom' ? pos : 'middle'
2743 - ];
2744 - }
2745 - if (pos.constructor != Array) {
2746 - pos = ['center', 'middle'];
2747 - }
2748 - if (pos[0].constructor == Number) {
2749 - pLeft += pos[0];
2750 - } else {
2751 - switch (pos[0]) {
2752 - case 'left':
2753 - pLeft += 0;
2754 - break;
2755 - case 'right':
2756 - pLeft += wnd.width() - this.uiDialog.outerWidth();
2757 - break;
2758 - default:
2759 - case 'center':
2760 - pLeft += (wnd.width() - this.uiDialog.outerWidth()) / 2;
2761 - }
2762 - }
2763 - if (pos[1].constructor == Number) {
2764 - pTop += pos[1];
2765 - } else {
2766 - switch (pos[1]) {
2767 - case 'top':
2768 - pTop += 0;
2769 - break;
2770 - case 'bottom':
2771 - pTop += wnd.height() - this.uiDialog.outerHeight();
2772 - break;
2773 - default:
2774 - case 'middle':
2775 - pTop += (wnd.height() - this.uiDialog.outerHeight()) / 2;
2776 - }
2777 - }
2778 -
2779 - // prevent the dialog from being too high (make sure the titlebar
2780 - // is accessible)
2781 - pTop = Math.max(pTop, minTop);
2782 - this.uiDialog.css({top: pTop, left: pLeft});
2783 - },
2784 -
2785 - _setData: function(key, value){
2786 - (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
2787 - switch (key) {
2788 - case "buttons":
2789 - this._createButtons(value);
2790 - break;
2791 - case "closeText":
2792 - this.uiDialogTitlebarCloseText.text(value);
2793 - break;
2794 - case "dialogClass":
2795 - this.uiDialog
2796 - .removeClass(this.options.dialogClass)
2797 - .addClass(uiDialogClasses + value);
2798 - break;
2799 - case "draggable":
2800 - (value
2801 - ? this._makeDraggable()
2802 - : this.uiDialog.draggable('destroy'));
2803 - break;
2804 - case "height":
2805 - this.uiDialog.height(value);
2806 - break;
2807 - case "position":
2808 - this._position(value);
2809 - break;
2810 - case "resizable":
2811 - var uiDialog = this.uiDialog,
2812 - isResizable = this.uiDialog.is(':data(resizable)');
2813 -
2814 - // currently resizable, becoming non-resizable
2815 - (isResizable && !value && uiDialog.resizable('destroy'));
2816 -
2817 - // currently resizable, changing handles
2818 - (isResizable && typeof value == 'string' &&
2819 - uiDialog.resizable('option', 'handles', value));
2820 -
2821 - // currently non-resizable, becoming resizable
2822 - (isResizable || this._makeResizable(value));
2823 - break;
2824 - case "title":
2825 - $(".ui-dialog-title", this.uiDialogTitlebar).html(value || '&nbsp;');
2826 - break;
2827 - case "width":
2828 - this.uiDialog.width(value);
2829 - break;
2830 - }
2831 -
2832 - $.widget.prototype._setData.apply(this, arguments);
2833 - },
2834 -
2835 - _size: function() {
2836 - /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
2837 - * divs will both have width and height set, so we need to reset them
2838 - */
2839 - var options = this.options;
2840 -
2841 - // reset content sizing
2842 - this.element.css({
2843 - height: 0,
2844 - minHeight: 0,
2845 - width: 'auto'
2846 - });
2847 -
2848 - // reset wrapper sizing
2849 - // determine the height of all the non-content elements
2850 - var nonContentHeight = this.uiDialog.css({
2851 - height: 'auto',
2852 - width: options.width
2853 - })
2854 - .height();
2855 -
2856 - this.element
2857 - .css({
2858 - minHeight: Math.max(options.minHeight - nonContentHeight, 0),
2859 - height: options.height == 'auto'
2860 - ? 'auto'
2861 - : Math.max(options.height - nonContentHeight, 0)
2862 - });
2863 - }
2864 -});
2865 -
2866 -$.extend($.ui.dialog, {
2867 - version: "1.7.2",
2868 - defaults: {
2869 - autoOpen: true,
2870 - bgiframe: false,
2871 - buttons: {},
2872 - closeOnEscape: true,
2873 - closeText: 'close',
2874 - dialogClass: '',
2875 - draggable: true,
2876 - hide: null,
2877 - height: 'auto',
2878 - maxHeight: false,
2879 - maxWidth: false,
2880 - minHeight: 150,
2881 - minWidth: 150,
2882 - modal: false,
2883 - position: 'center',
2884 - resizable: true,
2885 - show: null,
2886 - stack: true,
2887 - title: '',
2888 - width: 300,
2889 - zIndex: 1000
2890 - },
2891 -
2892 - getter: 'isOpen',
2893 -
2894 - uuid: 0,
2895 - maxZ: 0,
2896 -
2897 - getTitleId: function($el) {
2898 - return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid);
2899 - },
2900 -
2901 - overlay: function(dialog) {
2902 - this.$el = $.ui.dialog.overlay.create(dialog);
2903 - }
2904 -});
2905 -
2906 -$.extend($.ui.dialog.overlay, {
2907 - instances: [],
2908 - maxZ: 0,
2909 - events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
2910 - function(event) { return event + '.dialog-overlay'; }).join(' '),
2911 - create: function(dialog) {
2912 - if (this.instances.length === 0) {
2913 - // prevent use of anchors and inputs
2914 - // we use a setTimeout in case the overlay is created from an
2915 - // event that we're going to be cancelling (see #2804)
2916 - setTimeout(function() {
2917 - // handle $(el).dialog().dialog('close') (see #4065)
2918 - if ($.ui.dialog.overlay.instances.length) {
2919 - $(document).bind($.ui.dialog.overlay.events, function(event) {
2920 - var dialogZ = $(event.target).parents('.ui-dialog').css('zIndex') || 0;
2921 - return (dialogZ > $.ui.dialog.overlay.maxZ);
2922 - });
2923 - }
2924 - }, 1);
2925 -
2926 - // allow closing by pressing the escape key
2927 - $(document).bind('keydown.dialog-overlay', function(event) {
2928 - (dialog.options.closeOnEscape && event.keyCode
2929 - && event.keyCode == $.ui.keyCode.ESCAPE && dialog.close(event));
2930 - });
2931 -
2932 - // handle window resize
2933 - $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
2934 - }
2935 -
2936 - var $el = $('<div></div>').appendTo(document.body)
2937 - .addClass('ui-widget-overlay').css({
2938 - width: this.width(),
2939 - height: this.height()
2940 - });
2941 -
2942 - (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());
2943 -
2944 - this.instances.push($el);
2945 - return $el;
2946 - },
2947 -
2948 - destroy: function($el) {
2949 - this.instances.splice($.inArray(this.instances, $el), 1);
2950 -
2951 - if (this.instances.length === 0) {
2952 - $([document, window]).unbind('.dialog-overlay');
2953 - }
2954 -
2955 - $el.remove();
2956 -
2957 - // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
2958 - var maxZ = 0;
2959 - $.each(this.instances, function() {
2960 - maxZ = Math.max(maxZ, this.css('z-index'));
2961 - });
2962 - this.maxZ = maxZ;
2963 - },
2964 -
2965 - height: function() {
2966 - // handle IE 6
2967 - if ($.browser.msie && $.browser.version < 7) {
2968 - var scrollHeight = Math.max(
2969 - document.documentElement.scrollHeight,
2970 - document.body.scrollHeight
2971 - );
2972 - var offsetHeight = Math.max(
2973 - document.documentElement.offsetHeight,
2974 - document.body.offsetHeight
2975 - );
2976 -
2977 - if (scrollHeight < offsetHeight) {
2978 - return $(window).height() + 'px';
2979 - } else {
2980 - return scrollHeight + 'px';
2981 - }
2982 - // handle "good" browsers
2983 - } else {
2984 - return $(document).height() + 'px';
2985 - }
2986 - },
2987 -
2988 - width: function() {
2989 - // handle IE 6
2990 - if ($.browser.msie && $.browser.version < 7) {
2991 - var scrollWidth = Math.max(
2992 - document.documentElement.scrollWidth,
2993 - document.body.scrollWidth
2994 - );
2995 - var offsetWidth = Math.max(
2996 - document.documentElement.offsetWidth,
2997 - document.body.offsetWidth
2998 - );
2999 -
3000 - if (scrollWidth < offsetWidth) {
3001 - return $(window).width() + 'px';
3002 - } else {
3003 - return scrollWidth + 'px';
3004 - }
3005 - // handle "good" browsers
3006 - } else {
3007 - return $(document).width() + 'px';
3008 - }
3009 - },
3010 -
3011 - resize: function() {
3012 - /* If the dialog is draggable and the user drags it past the
3013 - * right edge of the window, the document becomes wider so we
3014 - * need to stretch the overlay. If the user then drags the
3015 - * dialog back to the left, the document will become narrower,
3016 - * so we need to shrink the overlay to the appropriate size.
3017 - * This is handled by shrinking the overlay before setting it
3018 - * to the full document size.
3019 - */
3020 - var $overlays = $([]);
3021 - $.each($.ui.dialog.overlay.instances, function() {
3022 - $overlays = $overlays.add(this);
3023 - });
3024 -
3025 - $overlays.css({
3026 - width: 0,
3027 - height: 0
3028 - }).css({
3029 - width: $.ui.dialog.overlay.width(),
3030 - height: $.ui.dialog.overlay.height()
3031 - });
3032 - }
3033 -});
3034 -
3035 -$.extend($.ui.dialog.overlay.prototype, {
3036 - destroy: function() {
3037 - $.ui.dialog.overlay.destroy(this.$el);
3038 - }
3039 -});
3040 -
3041 -})(jQuery);
3042 -/*
3043 - * jQuery UI Tabs 1.7.2
3044 - *
3045 - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
3046 - * Dual licensed under the MIT (MIT-LICENSE.txt)
3047 - * and GPL (GPL-LICENSE.txt) licenses.
3048 - *
3049 - * http://docs.jquery.com/UI/Tabs
3050 - *
3051 - * Depends:
3052 - * ui.core.js
3053 - */
3054 -(function($) {
3055 -
3056 -$.widget("ui.tabs", {
3057 -
3058 - _init: function() {
3059 - if (this.options.deselectable !== undefined) {
3060 - this.options.collapsible = this.options.deselectable;
3061 - }
3062 - this._tabify(true);
3063 - },
3064 -
3065 - _setData: function(key, value) {
3066 - if (key == 'selected') {
3067 - if (this.options.collapsible && value == this.options.selected) {
3068 - return;
3069 - }
3070 - this.select(value);
3071 - }
3072 - else {
3073 - this.options[key] = value;
3074 - if (key == 'deselectable') {
3075 - this.options.collapsible = value;
3076 - }
3077 - this._tabify();
3078 - }
3079 - },
3080 -
3081 - _tabId: function(a) {
3082 - return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') ||
3083 - this.options.idPrefix + $.data(a);
3084 - },
3085 -
3086 - _sanitizeSelector: function(hash) {
3087 - return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":"
3088 - },
3089 -
3090 - _cookie: function() {
3091 - var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + $.data(this.list[0]));
3092 - return $.cookie.apply(null, [cookie].concat($.makeArray(arguments)));
3093 - },
3094 -
3095 - _ui: function(tab, panel) {
3096 - return {
3097 - tab: tab,
3098 - panel: panel,
3099 - index: this.anchors.index(tab)
3100 - };
3101 - },
3102 -
3103 - _cleanup: function() {
3104 - // restore all former loading tabs labels
3105 - this.lis.filter('.ui-state-processing').removeClass('ui-state-processing')
3106 - .find('span:data(label.tabs)')
3107 - .each(function() {
3108 - var el = $(this);
3109 - el.html(el.data('label.tabs')).removeData('label.tabs');
3110 - });
3111 - },
3112 -
3113 - _tabify: function(init) {
3114 -
3115 - this.list = this.element.children('ul:first');
3116 - this.lis = $('li:has(a[href])', this.list);
3117 - this.anchors = this.lis.map(function() { return $('a', this)[0]; });
3118 - this.panels = $([]);
3119 -
3120 - var self = this, o = this.options;
3121 -
3122 - var fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
3123 - this.anchors.each(function(i, a) {
3124 - var href = $(a).attr('href');
3125 -
3126 - // For dynamically created HTML that contains a hash as href IE < 8 expands
3127 - // such href to the full page url with hash and then misinterprets tab as ajax.
3128 - // Same consideration applies for an added tab with a fragment identifier
3129 - // since a[href=#fragment-identifier] does unexpectedly not match.
3130 - // Thus normalize href attribute...
3131 - var hrefBase = href.split('#')[0], baseEl;
3132 - if (hrefBase && (hrefBase === location.toString().split('#')[0] ||
3133 - (baseEl = $('base')[0]) && hrefBase === baseEl.href)) {
3134 - href = a.hash;
3135 - a.href = href;
3136 - }
3137 -
3138 - // inline tab
3139 - if (fragmentId.test(href)) {
3140 - self.panels = self.panels.add(self._sanitizeSelector(href));
3141 - }
3142 -
3143 - // remote tab
3144 - else if (href != '#') { // prevent loading the page itself if href is just "#"
3145 - $.data(a, 'href.tabs', href); // required for restore on destroy
3146 -
3147 - // TODO until #3808 is fixed strip fragment identifier from url
3148 - // (IE fails to load from such url)
3149 - $.data(a, 'load.tabs', href.replace(/#.*$/, '')); // mutable data
3150 -
3151 - var id = self._tabId(a);
3152 - a.href = '#' + id;
3153 - var $panel = $('#' + id);
3154 - if (!$panel.length) {
3155 - $panel = $(o.panelTemplate).attr('id', id).addClass('ui-tabs-panel ui-widget-content ui-corner-bottom')
3156 - .insertAfter(self.panels[i - 1] || self.list);
3157 - $panel.data('destroy.tabs', true);
3158 - }
3159 - self.panels = self.panels.add($panel);
3160 - }
3161 -
3162 - // invalid tab href
3163 - else {
3164 - o.disabled.push(i);
3165 - }
3166 - });
3167 -
3168 - // initialization from scratch
3169 - if (init) {
3170 -
3171 - // attach necessary classes for styling
3172 - this.element.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all');
3173 - this.list.addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');
3174 - this.lis.addClass('ui-state-default ui-corner-top');
3175 - this.panels.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom');
3176 -
3177 - // Selected tab
3178 - // use "selected" option or try to retrieve:
3179 - // 1. from fragment identifier in url
3180 - // 2. from cookie
3181 - // 3. from selected class attribute on <li>
3182 - if (o.selected === undefined) {
3183 - if (location.hash) {
3184 - this.anchors.each(function(i, a) {
3185 - if (a.hash == location.hash) {
3186 - o.selected = i;
3187 - return false; // break
3188 - }
3189 - });
3190 - }
3191 - if (typeof o.selected != 'number' && o.cookie) {
3192 - o.selected = parseInt(self._cookie(), 10);
3193 - }
3194 - if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) {
3195 - o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));
3196 - }
3197 - o.selected = o.selected || 0;
3198 - }
3199 - else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release
3200 - o.selected = -1;
3201 - }
3202 -
3203 - // sanity check - default to first tab...
3204 - o.selected = ((o.selected >= 0 && this.anchors[o.selected]) || o.selected < 0) ? o.selected : 0;
3205 -
3206 - // Take disabling tabs via class attribute from HTML
3207 - // into account and update option properly.
3208 - // A selected tab cannot become disabled.
3209 - o.disabled = $.unique(o.disabled.concat(
3210 - $.map(this.lis.filter('.ui-state-disabled'),
3211 - function(n, i) { return self.lis.index(n); } )
3212 - )).sort();
3213 -
3214 - if ($.inArray(o.selected, o.disabled) != -1) {
3215 - o.disabled.splice($.inArray(o.selected, o.disabled), 1);
3216 - }
3217 -
3218 - // highlight selected tab
3219 - this.panels.addClass('ui-tabs-hide');
3220 - this.lis.removeClass('ui-tabs-selected ui-state-active');
3221 - if (o.selected >= 0 && this.anchors.length) { // check for length avoids error when initializing empty list
3222 - this.panels.eq(o.selected).removeClass('ui-tabs-hide');
3223 - this.lis.eq(o.selected).addClass('ui-tabs-selected ui-state-active');
3224 -
3225 - // seems to be expected behavior that the show callback is fired
3226 - self.element.queue("tabs", function() {
3227 - self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected]));
3228 - });
3229 -
3230 - this.load(o.selected);
3231 - }
3232 -
3233 - // clean up to avoid memory leaks in certain versions of IE 6
3234 - $(window).bind('unload', function() {
3235 - self.lis.add(self.anchors).unbind('.tabs');
3236 - self.lis = self.anchors = self.panels = null;
3237 - });
3238 -
3239 - }
3240 - // update selected after add/remove
3241 - else {
3242 - o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));
3243 - }
3244 -
3245 - // update collapsible
3246 - this.element[o.collapsible ? 'addClass' : 'removeClass']('ui-tabs-collapsible');
3247 -
3248 - // set or update cookie after init and add/remove respectively
3249 - if (o.cookie) {
3250 - this._cookie(o.selected, o.cookie);
3251 - }
3252 -
3253 - // disable tabs
3254 - for (var i = 0, li; (li = this.lis[i]); i++) {
3255 - $(li)[$.inArray(i, o.disabled) != -1 &&
3256 - !$(li).hasClass('ui-tabs-selected') ? 'addClass' : 'removeClass']('ui-state-disabled');
3257 - }
3258 -
3259 - // reset cache if switching from cached to not cached
3260 - if (o.cache === false) {
3261 - this.anchors.removeData('cache.tabs');
3262 - }
3263 -
3264 - // remove all handlers before, tabify may run on existing tabs after add or option change
3265 - this.lis.add(this.anchors).unbind('.tabs');
3266 -
3267 - if (o.event != 'mouseover') {
3268 - var addState = function(state, el) {
3269 - if (el.is(':not(.ui-state-disabled)')) {
3270 - el.addClass('ui-state-' + state);
3271 - }
3272 - };
3273 - var removeState = function(state, el) {
3274 - el.removeClass('ui-state-' + state);
3275 - };
3276 - this.lis.bind('mouseover.tabs', function() {
3277 - addState('hover', $(this));
3278 - });
3279 - this.lis.bind('mouseout.tabs', function() {
3280 - removeState('hover', $(this));
3281 - });
3282 - this.anchors.bind('focus.tabs', function() {
3283 - addState('focus', $(this).closest('li'));
3284 - });
3285 - this.anchors.bind('blur.tabs', function() {
3286 - removeState('focus', $(this).closest('li'));
3287 - });
3288 - }
3289 -
3290 - // set up animations
3291 - var hideFx, showFx;
3292 - if (o.fx) {
3293 - if ($.isArray(o.fx)) {
3294 - hideFx = o.fx[0];
3295 - showFx = o.fx[1];
3296 - }
3297 - else {
3298 - hideFx = showFx = o.fx;
3299 - }
3300 - }
3301 -
3302 - // Reset certain styles left over from animation
3303 - // and prevent IE's ClearType bug...
3304 - function resetStyle($el, fx) {
3305 - $el.css({ display: '' });
3306 - if ($.browser.msie && fx.opacity) {
3307 - $el[0].style.removeAttribute('filter');
3308 - }
3309 - }
3310 -
3311 - // Show a tab...
3312 - var showTab = showFx ?
3313 - function(clicked, $show) {
3314 - $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active');
3315 - $show.hide().removeClass('ui-tabs-hide') // avoid flicker that way
3316 - .animate(showFx, showFx.duration || 'normal', function() {
3317 - resetStyle($show, showFx);
3318 - self._trigger('show', null, self._ui(clicked, $show[0]));
3319 - });
3320 - } :
3321 - function(clicked, $show) {
3322 - $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active');
3323 - $show.removeClass('ui-tabs-hide');
3324 - self._trigger('show', null, self._ui(clicked, $show[0]));
3325 - };
3326 -
3327 - // Hide a tab, $show is optional...
3328 - var hideTab = hideFx ?
3329 - function(clicked, $hide) {
3330 - $hide.animate(hideFx, hideFx.duration || 'normal', function() {
3331 - self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default');
3332 - $hide.addClass('ui-tabs-hide');
3333 - resetStyle($hide, hideFx);
3334 - self.element.dequeue("tabs");
3335 - });
3336 - } :
3337 - function(clicked, $hide, $show) {
3338 - self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default');
3339 - $hide.addClass('ui-tabs-hide');
3340 - self.element.dequeue("tabs");
3341 - };
3342 -
3343 - // attach tab event handler, unbind to avoid duplicates from former tabifying...
3344 - this.anchors.bind(o.event + '.tabs', function() {
3345 - var el = this, $li = $(this).closest('li'), $hide = self.panels.filter(':not(.ui-tabs-hide)'),
3346 - $show = $(self._sanitizeSelector(this.hash));
3347 -
3348 - // If tab is already selected and not collapsible or tab disabled or
3349 - // or is already loading or click callback returns false stop here.
3350 - // Check if click handler returns false last so that it is not executed
3351 - // for a disabled or loading tab!
3352 - if (($li.hasClass('ui-tabs-selected') && !o.collapsible) ||
3353 - $li.hasClass('ui-state-disabled') ||
3354 - $li.hasClass('ui-state-processing') ||
3355 - self._trigger('select', null, self._ui(this, $show[0])) === false) {
3356 - this.blur();
3357 - return false;
3358 - }
3359 -
3360 - o.selected = self.anchors.index(this);
3361 -
3362 - self.abort();
3363 -
3364 - // if tab may be closed
3365 - if (o.collapsible) {
3366 - if ($li.hasClass('ui-tabs-selected')) {
3367 - o.selected = -1;
3368 -
3369 - if (o.cookie) {
3370 - self._cookie(o.selected, o.cookie);
3371 - }
3372 -
3373 - self.element.queue("tabs", function() {
3374 - hideTab(el, $hide);
3375 - }).dequeue("tabs");
3376 -
3377 - this.blur();
3378 - return false;
3379 - }
3380 - else if (!$hide.length) {
3381 - if (o.cookie) {
3382 - self._cookie(o.selected, o.cookie);
3383 - }
3384 -
3385 - self.element.queue("tabs", function() {
3386 - showTab(el, $show);
3387 - });
3388 -
3389 - self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
3390 -
3391 - this.blur();
3392 - return false;
3393 - }
3394 - }
3395 -
3396 - if (o.cookie) {
3397 - self._cookie(o.selected, o.cookie);
3398 - }
3399 -
3400 - // show new tab
3401 - if ($show.length) {
3402 - if ($hide.length) {
3403 - self.element.queue("tabs", function() {
3404 - hideTab(el, $hide);
3405 - });
3406 - }
3407 - self.element.queue("tabs", function() {
3408 - showTab(el, $show);
3409 - });
3410 -
3411 - self.load(self.anchors.index(this));
3412 - }
3413 - else {
3414 - throw 'jQuery UI Tabs: Mismatching fragment identifier.';
3415 - }
3416 -
3417 - // Prevent IE from keeping other link focussed when using the back button
3418 - // and remove dotted border from clicked link. This is controlled via CSS
3419 - // in modern browsers; blur() removes focus from address bar in Firefox
3420 - // which can become a usability and annoying problem with tabs('rotate').
3421 - if ($.browser.msie) {
3422 - this.blur();
3423 - }
3424 -
3425 - });
3426 -
3427 - // disable click in any case
3428 - this.anchors.bind('click.tabs', function(){return false;});
3429 -
3430 - },
3431 -
3432 - destroy: function() {
3433 - var o = this.options;
3434 -
3435 - this.abort();
3436 -
3437 - this.element.unbind('.tabs')
3438 - .removeClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible')
3439 - .removeData('tabs');
3440 -
3441 - this.list.removeClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');
3442 -
3443 - this.anchors.each(function() {
3444 - var href = $.data(this, 'href.tabs');
3445 - if (href) {
3446 - this.href = href;
3447 - }
3448 - var $this = $(this).unbind('.tabs');
3449 - $.each(['href', 'load', 'cache'], function(i, prefix) {
3450 - $this.removeData(prefix + '.tabs');
3451 - });
3452 - });
3453 -
3454 - this.lis.unbind('.tabs').add(this.panels).each(function() {
3455 - if ($.data(this, 'destroy.tabs')) {
3456 - $(this).remove();
3457 - }
3458 - else {
3459 - $(this).removeClass([
3460 - 'ui-state-default',
3461 - 'ui-corner-top',
3462 - 'ui-tabs-selected',
3463 - 'ui-state-active',
3464 - 'ui-state-hover',
3465 - 'ui-state-focus',
3466 - 'ui-state-disabled',
3467 - 'ui-tabs-panel',
3468 - 'ui-widget-content',
3469 - 'ui-corner-bottom',
3470 - 'ui-tabs-hide'
3471 - ].join(' '));
3472 - }
3473 - });
3474 -
3475 - if (o.cookie) {
3476 - this._cookie(null, o.cookie);
3477 - }
3478 - },
3479 -
3480 - add: function(url, label, index) {
3481 - if (index === undefined) {
3482 - index = this.anchors.length; // append by default
3483 - }
3484 -
3485 - var self = this, o = this.options,
3486 - $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label)),
3487 - id = !url.indexOf('#') ? url.replace('#', '') : this._tabId($('a', $li)[0]);
3488 -
3489 - $li.addClass('ui-state-default ui-corner-top').data('destroy.tabs', true);
3490 -
3491 - // try to find an existing element before creating a new one
3492 - var $panel = $('#' + id);
3493 - if (!$panel.length) {
3494 - $panel = $(o.panelTemplate).attr('id', id).data('destroy.tabs', true);
3495 - }
3496 - $panel.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide');
3497 -
3498 - if (index >= this.lis.length) {
3499 - $li.appendTo(this.list);
3500 - $panel.appendTo(this.list[0].parentNode);
3501 - }
3502 - else {
3503 - $li.insertBefore(this.lis[index]);
3504 - $panel.insertBefore(this.panels[index]);
3505 - }
3506 -
3507 - o.disabled = $.map(o.disabled,
3508 - function(n, i) { return n >= index ? ++n : n; });
3509 -
3510 - this._tabify();
3511 -
3512 - if (this.anchors.length == 1) { // after tabify
3513 - $li.addClass('ui-tabs-selected ui-state-active');
3514 - $panel.removeClass('ui-tabs-hide');
3515 - this.element.queue("tabs", function() {
3516 - self._trigger('show', null, self._ui(self.anchors[0], self.panels[0]));
3517 - });
3518 -
3519 - this.load(0);
3520 - }
3521 -
3522 - // callback
3523 - this._trigger('add', null, this._ui(this.anchors[index], this.panels[index]));
3524 - },
3525 -
3526 - remove: function(index) {
3527 - var o = this.options, $li = this.lis.eq(index).remove(),
3528 - $panel = this.panels.eq(index).remove();
3529 -
3530 - // If selected tab was removed focus tab to the right or
3531 - // in case the last tab was removed the tab to the left.
3532 - if ($li.hasClass('ui-tabs-selected') && this.anchors.length > 1) {
3533 - this.select(index + (index + 1 < this.anchors.length ? 1 : -1));
3534 - }
3535 -
3536 - o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
3537 - function(n, i) { return n >= index ? --n : n; });
3538 -
3539 - this._tabify();
3540 -
3541 - // callback
3542 - this._trigger('remove', null, this._ui($li.find('a')[0], $panel[0]));
3543 - },
3544 -
3545 - enable: function(index) {
3546 - var o = this.options;
3547 - if ($.inArray(index, o.disabled) == -1) {
3548 - return;
3549 - }
3550 -
3551 - this.lis.eq(index).removeClass('ui-state-disabled');
3552 - o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });
3553 -
3554 - // callback
3555 - this._trigger('enable', null, this._ui(this.anchors[index], this.panels[index]));
3556 - },
3557 -
3558 - disable: function(index) {
3559 - var self = this, o = this.options;
3560 - if (index != o.selected) { // cannot disable already selected tab
3561 - this.lis.eq(index).addClass('ui-state-disabled');
3562 -
3563 - o.disabled.push(index);
3564 - o.disabled.sort();
3565 -
3566 - // callback
3567 - this._trigger('disable', null, this._ui(this.anchors[index], this.panels[index]));
3568 - }
3569 - },
3570 -
3571 - select: function(index) {
3572 - if (typeof index == 'string') {
3573 - index = this.anchors.index(this.anchors.filter('[href$=' + index + ']'));
3574 - }
3575 - else if (index === null) { // usage of null is deprecated, TODO remove in next release
3576 - index = -1;
3577 - }
3578 - if (index == -1 && this.options.collapsible) {
3579 - index = this.options.selected;
3580 - }
3581 -
3582 - this.anchors.eq(index).trigger(this.options.event + '.tabs');
3583 - },
3584 -
3585 - load: function(index) {
3586 - var self = this, o = this.options, a = this.anchors.eq(index)[0], url = $.data(a, 'load.tabs');
3587 -
3588 - this.abort();
3589 -
3590 - // not remote or from cache
3591 - if (!url || this.element.queue("tabs").length !== 0 && $.data(a, 'cache.tabs')) {
3592 - this.element.dequeue("tabs");
3593 - return;
3594 - }
3595 -
3596 - // load remote from here on
3597 - this.lis.eq(index).addClass('ui-state-processing');
3598 -
3599 - if (o.spinner) {
3600 - var span = $('span', a);
3601 - span.data('label.tabs', span.html()).html(o.spinner);
3602 - }
3603 -
3604 - this.xhr = $.ajax($.extend({}, o.ajaxOptions, {
3605 - url: url,
3606 - success: function(r, s) {
3607 - $(self._sanitizeSelector(a.hash)).html(r);
3608 -
3609 - // take care of tab labels
3610 - self._cleanup();
3611 -
3612 - if (o.cache) {
3613 - $.data(a, 'cache.tabs', true); // if loaded once do not load them again
3614 - }
3615 -
3616 - // callbacks
3617 - self._trigger('load', null, self._ui(self.anchors[index], self.panels[index]));
3618 - try {
3619 - o.ajaxOptions.success(r, s);
3620 - }
3621 - catch (e) {}
3622 -
3623 - // last, so that load event is fired before show...
3624 - self.element.dequeue("tabs");
3625 - }
3626 - }));
3627 - },
3628 -
3629 - abort: function() {
3630 - // stop possibly running animations
3631 - this.element.queue([]);
3632 - this.panels.stop(false, true);
3633 -
3634 - // terminate pending requests from other tabs
3635 - if (this.xhr) {
3636 - this.xhr.abort();
3637 - delete this.xhr;
3638 - }
3639 -
3640 - // take care of tab labels
3641 - this._cleanup();
3642 -
3643 - },
3644 -
3645 - url: function(index, url) {
3646 - this.anchors.eq(index).removeData('cache.tabs').data('load.tabs', url);
3647 - },
3648 -
3649 - length: function() {
3650 - return this.anchors.length;
3651 - }
3652 -
3653 -});
3654 -
3655 -$.extend($.ui.tabs, {
3656 - version: '1.7.2',
3657 - getter: 'length',
3658 - defaults: {
3659 - ajaxOptions: null,
3660 - cache: false,
3661 - cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
3662 - collapsible: false,
3663 - disabled: [],
3664 - event: 'click',
3665 - fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
3666 - idPrefix: 'ui-tabs-',
3667 - panelTemplate: '<div></div>',
3668 - spinner: '<em>Loading&#8230;</em>',
3669 - tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>'
3670 - }
3671 -});
3672 -
3673 -/*
3674 - * Tabs Extensions
3675 - */
3676 -
3677 -/*
3678 - * Rotate
3679 - */
3680 -$.extend($.ui.tabs.prototype, {
3681 - rotation: null,
3682 - rotate: function(ms, continuing) {
3683 -
3684 - var self = this, o = this.options;
3685 -
3686 - var rotate = self._rotate || (self._rotate = function(e) {
3687 - clearTimeout(self.rotation);
3688 - self.rotation = setTimeout(function() {
3689 - var t = o.selected;
3690 - self.select( ++t < self.anchors.length ? t : 0 );
3691 - }, ms);
3692 -
3693 - if (e) {
3694 - e.stopPropagation();
3695 - }
3696 - });
3697 -
3698 - var stop = self._unrotate || (self._unrotate = !continuing ?
3699 - function(e) {
3700 - if (e.clientX) { // in case of a true click
3701 - self.rotate(null);
3702 - }
3703 - } :
3704 - function(e) {
3705 - t = o.selected;
3706 - rotate();
3707 - });
3708 -
3709 - // start rotation
3710 - if (ms) {
3711 - this.element.bind('tabsshow', rotate);
3712 - this.anchors.bind(o.event + '.tabs', stop);
3713 - rotate();
3714 - }
3715 - // stop rotation
3716 - else {
3717 - clearTimeout(self.rotation);
3718 - this.element.unbind('tabsshow', rotate);
3719 - this.anchors.unbind(o.event + '.tabs', stop);
3720 - delete this._rotate;
3721 - delete this._unrotate;
3722 - }
3723 - }
3724 -});
3725 -
3726 -})(jQuery);
3727 -/* JavaScript for MediaWIki JS2 */
3728 -
3729 -/**
3730 - * This is designed to be directly compatible with (and is essentially taken
3731 - * directly from) the mv_embed code for bringing internationalized messages into
3732 - * the JavaScript space. As such, if we get to the point of merging that stuff
3733 - * into the main branch this code will be uneeded and probably cause issues.
3734 - */
3735 -// Creates global message object if not already in existence
3736 -if ( !gMsg ) var gMsg = {};
3737 -if( ! mw ) var mw = { };
3738 -
3739 -/**
3740 - * Caches a list of messages for later retrieval
3741 - * @param {Object} msgSet Hash of key:value pairs of messages to cache
3742 - */
3743 -if( ! mw.addMessages ){
3744 - mw.addMessages = function( msgSet ){
3745 - for ( var i in msgSet ){
3746 - gMsg[ i ] = msgSet[i];
3747 - }
3748 - }
3749 -}
3750 -
3751 -/**
3752 - * Retieves a message from the global message cache, performing on-the-fly
3753 - * replacements using MediaWiki message syntax ($1, $2, etc.)
3754 - * @param {String} key Name of message as it is in MediaWiki
3755 - * @param {Array} args Array of replacement arguments
3756 - */
3757 -function gM( key, args ) {
3758 - var ms = '';
3759 - if ( key in gMsg ) {
3760 - ms = gMsg[ key ];
3761 - if ( typeof args == 'object' || typeof args == 'array' ) {
3762 - for ( var v in args ){
3763 - var rep = '\$'+ ( parseInt(v) + 1 );
3764 - ms = ms.replace( rep, args[v]);
3765 - }
3766 - } else if ( typeof args =='string' || typeof args =='number' ) {
3767 - ms = ms.replace( /\$1/, args );
3768 - }
3769 - return ms;
3770 - } else {
3771 - return '[' + key + ']';
3772 - }
3773 -}
3774 -/**
3775 - * Mimics the no-conflict method used by the js2 stuff
3776 - */
3777 -$j = jQuery.noConflict();
3778 -/**
3779 - * Provides js2 compatible onload hook
3780 - * @param func Function to call when ready
3781 - */
3782 -mw.addOnloadHook = function( func ) {
3783 - $j(document).ready( func );
3784 -}
 2+/*
 3+ * jQuery UI 1.7.2
 4+ *
 5+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 6+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 7+ * and GPL (GPL-LICENSE.txt) licenses.
 8+ *
 9+ * http://docs.jquery.com/UI
 10+ */
 11+;jQuery.ui || (function($) {
 12+
 13+var _remove = $.fn.remove,
 14+ isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
 15+
 16+//Helper functions and ui object
 17+$.ui = {
 18+ version: "1.7.2",
 19+
 20+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
 21+ plugin: {
 22+ add: function(module, option, set) {
 23+ var proto = $.ui[module].prototype;
 24+ for(var i in set) {
 25+ proto.plugins[i] = proto.plugins[i] || [];
 26+ proto.plugins[i].push([option, set[i]]);
 27+ }
 28+ },
 29+ call: function(instance, name, args) {
 30+ var set = instance.plugins[name];
 31+ if(!set || !instance.element[0].parentNode) { return; }
 32+
 33+ for (var i = 0; i < set.length; i++) {
 34+ if (instance.options[set[i][0]]) {
 35+ set[i][1].apply(instance.element, args);
 36+ }
 37+ }
 38+ }
 39+ },
 40+
 41+ contains: function(a, b) {
 42+ return document.compareDocumentPosition
 43+ ? a.compareDocumentPosition(b) & 16
 44+ : a !== b && a.contains(b);
 45+ },
 46+
 47+ hasScroll: function(el, a) {
 48+
 49+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
 50+ if ($(el).css('overflow') == 'hidden') { return false; }
 51+
 52+ var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
 53+ has = false;
 54+
 55+ if (el[scroll] > 0) { return true; }
 56+
 57+ // TODO: determine which cases actually cause this to happen
 58+ // if the element doesn't have the scroll set, see if it's possible to
 59+ // set the scroll
 60+ el[scroll] = 1;
 61+ has = (el[scroll] > 0);
 62+ el[scroll] = 0;
 63+ return has;
 64+ },
 65+
 66+ isOverAxis: function(x, reference, size) {
 67+ //Determines when x coordinate is over "b" element axis
 68+ return (x > reference) && (x < (reference + size));
 69+ },
 70+
 71+ isOver: function(y, x, top, left, height, width) {
 72+ //Determines when x, y coordinates is over "b" element
 73+ return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
 74+ },
 75+
 76+ keyCode: {
 77+ BACKSPACE: 8,
 78+ CAPS_LOCK: 20,
 79+ COMMA: 188,
 80+ CONTROL: 17,
 81+ DELETE: 46,
 82+ DOWN: 40,
 83+ END: 35,
 84+ ENTER: 13,
 85+ ESCAPE: 27,
 86+ HOME: 36,
 87+ INSERT: 45,
 88+ LEFT: 37,
 89+ NUMPAD_ADD: 107,
 90+ NUMPAD_DECIMAL: 110,
 91+ NUMPAD_DIVIDE: 111,
 92+ NUMPAD_ENTER: 108,
 93+ NUMPAD_MULTIPLY: 106,
 94+ NUMPAD_SUBTRACT: 109,
 95+ PAGE_DOWN: 34,
 96+ PAGE_UP: 33,
 97+ PERIOD: 190,
 98+ RIGHT: 39,
 99+ SHIFT: 16,
 100+ SPACE: 32,
 101+ TAB: 9,
 102+ UP: 38
 103+ }
 104+};
 105+
 106+// WAI-ARIA normalization
 107+if (isFF2) {
 108+ var attr = $.attr,
 109+ removeAttr = $.fn.removeAttr,
 110+ ariaNS = "http://www.w3.org/2005/07/aaa",
 111+ ariaState = /^aria-/,
 112+ ariaRole = /^wairole:/;
 113+
 114+ $.attr = function(elem, name, value) {
 115+ var set = value !== undefined;
 116+
 117+ return (name == 'role'
 118+ ? (set
 119+ ? attr.call(this, elem, name, "wairole:" + value)
 120+ : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
 121+ : (ariaState.test(name)
 122+ ? (set
 123+ ? elem.setAttributeNS(ariaNS,
 124+ name.replace(ariaState, "aaa:"), value)
 125+ : attr.call(this, elem, name.replace(ariaState, "aaa:")))
 126+ : attr.apply(this, arguments)));
 127+ };
 128+
 129+ $.fn.removeAttr = function(name) {
 130+ return (ariaState.test(name)
 131+ ? this.each(function() {
 132+ this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
 133+ }) : removeAttr.call(this, name));
 134+ };
 135+}
 136+
 137+//jQuery plugins
 138+$.fn.extend({
 139+ remove: function() {
 140+ // Safari has a native remove event which actually removes DOM elements,
 141+ // so we have to use triggerHandler instead of trigger (#3037).
 142+ $("*", this).add(this).each(function() {
 143+ $(this).triggerHandler("remove");
 144+ });
 145+ return _remove.apply(this, arguments );
 146+ },
 147+
 148+ enableSelection: function() {
 149+ return this
 150+ .attr('unselectable', 'off')
 151+ .css('MozUserSelect', '')
 152+ .unbind('selectstart.ui');
 153+ },
 154+
 155+ disableSelection: function() {
 156+ return this
 157+ .attr('unselectable', 'on')
 158+ .css('MozUserSelect', 'none')
 159+ .bind('selectstart.ui', function() { return false; });
 160+ },
 161+
 162+ scrollParent: function() {
 163+ var scrollParent;
 164+ if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
 165+ scrollParent = this.parents().filter(function() {
 166+ return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
 167+ }).eq(0);
 168+ } else {
 169+ scrollParent = this.parents().filter(function() {
 170+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
 171+ }).eq(0);
 172+ }
 173+
 174+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
 175+ }
 176+});
 177+
 178+
 179+//Additional selectors
 180+$.extend($.expr[':'], {
 181+ data: function(elem, i, match) {
 182+ return !!$.data(elem, match[3]);
 183+ },
 184+
 185+ focusable: function(element) {
 186+ var nodeName = element.nodeName.toLowerCase(),
 187+ tabIndex = $.attr(element, 'tabindex');
 188+ return (/input|select|textarea|button|object/.test(nodeName)
 189+ ? !element.disabled
 190+ : 'a' == nodeName || 'area' == nodeName
 191+ ? element.href || !isNaN(tabIndex)
 192+ : !isNaN(tabIndex))
 193+ // the element and all of its ancestors must be visible
 194+ // the browser may report that the area is hidden
 195+ && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
 196+ },
 197+
 198+ tabbable: function(element) {
 199+ var tabIndex = $.attr(element, 'tabindex');
 200+ return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
 201+ }
 202+});
 203+
 204+
 205+// $.widget is a factory to create jQuery plugins
 206+// taking some boilerplate code out of the plugin code
 207+function getter(namespace, plugin, method, args) {
 208+ function getMethods(type) {
 209+ var methods = $[namespace][plugin][type] || [];
 210+ return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
 211+ }
 212+
 213+ var methods = getMethods('getter');
 214+ if (args.length == 1 && typeof args[0] == 'string') {
 215+ methods = methods.concat(getMethods('getterSetter'));
 216+ }
 217+ return ($.inArray(method, methods) != -1);
 218+}
 219+
 220+$.widget = function(name, prototype) {
 221+ var namespace = name.split(".")[0];
 222+ name = name.split(".")[1];
 223+
 224+ // create plugin method
 225+ $.fn[name] = function(options) {
 226+ var isMethodCall = (typeof options == 'string'),
 227+ args = Array.prototype.slice.call(arguments, 1);
 228+
 229+ // prevent calls to internal methods
 230+ if (isMethodCall && options.substring(0, 1) == '_') {
 231+ return this;
 232+ }
 233+
 234+ // handle getter methods
 235+ if (isMethodCall && getter(namespace, name, options, args)) {
 236+ var instance = $.data(this[0], name);
 237+ return (instance ? instance[options].apply(instance, args)
 238+ : undefined);
 239+ }
 240+
 241+ // handle initialization and non-getter methods
 242+ return this.each(function() {
 243+ var instance = $.data(this, name);
 244+
 245+ // constructor
 246+ (!instance && !isMethodCall &&
 247+ $.data(this, name, new $[namespace][name](this, options))._init());
 248+
 249+ // method call
 250+ (instance && isMethodCall && $.isFunction(instance[options]) &&
 251+ instance[options].apply(instance, args));
 252+ });
 253+ };
 254+
 255+ // create widget constructor
 256+ $[namespace] = $[namespace] || {};
 257+ $[namespace][name] = function(element, options) {
 258+ var self = this;
 259+
 260+ this.namespace = namespace;
 261+ this.widgetName = name;
 262+ this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
 263+ this.widgetBaseClass = namespace + '-' + name;
 264+
 265+ this.options = $.extend({},
 266+ $.widget.defaults,
 267+ $[namespace][name].defaults,
 268+ $.metadata && $.metadata.get(element)[name],
 269+ options);
 270+
 271+ this.element = $(element)
 272+ .bind('setData.' + name, function(event, key, value) {
 273+ if (event.target == element) {
 274+ return self._setData(key, value);
 275+ }
 276+ })
 277+ .bind('getData.' + name, function(event, key) {
 278+ if (event.target == element) {
 279+ return self._getData(key);
 280+ }
 281+ })
 282+ .bind('remove', function() {
 283+ return self.destroy();
 284+ });
 285+ };
 286+
 287+ // add widget prototype
 288+ $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
 289+
 290+ // TODO: merge getter and getterSetter properties from widget prototype
 291+ // and plugin prototype
 292+ $[namespace][name].getterSetter = 'option';
 293+};
 294+
 295+$.widget.prototype = {
 296+ _init: function() {},
 297+ destroy: function() {
 298+ this.element.removeData(this.widgetName)
 299+ .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
 300+ .removeAttr('aria-disabled');
 301+ },
 302+
 303+ option: function(key, value) {
 304+ var options = key,
 305+ self = this;
 306+
 307+ if (typeof key == "string") {
 308+ if (value === undefined) {
 309+ return this._getData(key);
 310+ }
 311+ options = {};
 312+ options[key] = value;
 313+ }
 314+
 315+ $.each(options, function(key, value) {
 316+ self._setData(key, value);
 317+ });
 318+ },
 319+ _getData: function(key) {
 320+ return this.options[key];
 321+ },
 322+ _setData: function(key, value) {
 323+ this.options[key] = value;
 324+
 325+ if (key == 'disabled') {
 326+ this.element
 327+ [value ? 'addClass' : 'removeClass'](
 328+ this.widgetBaseClass + '-disabled' + ' ' +
 329+ this.namespace + '-state-disabled')
 330+ .attr("aria-disabled", value);
 331+ }
 332+ },
 333+
 334+ enable: function() {
 335+ this._setData('disabled', false);
 336+ },
 337+ disable: function() {
 338+ this._setData('disabled', true);
 339+ },
 340+
 341+ _trigger: function(type, event, data) {
 342+ var callback = this.options[type],
 343+ eventName = (type == this.widgetEventPrefix
 344+ ? type : this.widgetEventPrefix + type);
 345+
 346+ event = $.Event(event);
 347+ event.type = eventName;
 348+
 349+ // copy original event properties over to the new event
 350+ // this would happen if we could call $.event.fix instead of $.Event
 351+ // but we don't have a way to force an event to be fixed multiple times
 352+ if (event.originalEvent) {
 353+ for (var i = $.event.props.length, prop; i;) {
 354+ prop = $.event.props[--i];
 355+ event[prop] = event.originalEvent[prop];
 356+ }
 357+ }
 358+
 359+ this.element.trigger(event, data);
 360+
 361+ return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
 362+ || event.isDefaultPrevented());
 363+ }
 364+};
 365+
 366+$.widget.defaults = {
 367+ disabled: false
 368+};
 369+
 370+
 371+/** Mouse Interaction Plugin **/
 372+
 373+$.ui.mouse = {
 374+ _mouseInit: function() {
 375+ var self = this;
 376+
 377+ this.element
 378+ .bind('mousedown.'+this.widgetName, function(event) {
 379+ return self._mouseDown(event);
 380+ })
 381+ .bind('click.'+this.widgetName, function(event) {
 382+ if(self._preventClickEvent) {
 383+ self._preventClickEvent = false;
 384+ event.stopImmediatePropagation();
 385+ return false;
 386+ }
 387+ });
 388+
 389+ // Prevent text selection in IE
 390+ if ($.browser.msie) {
 391+ this._mouseUnselectable = this.element.attr('unselectable');
 392+ this.element.attr('unselectable', 'on');
 393+ }
 394+
 395+ this.started = false;
 396+ },
 397+
 398+ // TODO: make sure destroying one instance of mouse doesn't mess with
 399+ // other instances of mouse
 400+ _mouseDestroy: function() {
 401+ this.element.unbind('.'+this.widgetName);
 402+
 403+ // Restore text selection in IE
 404+ ($.browser.msie
 405+ && this.element.attr('unselectable', this._mouseUnselectable));
 406+ },
 407+
 408+ _mouseDown: function(event) {
 409+ // don't let more than one widget handle mouseStart
 410+ // TODO: figure out why we have to use originalEvent
 411+ event.originalEvent = event.originalEvent || {};
 412+ if (event.originalEvent.mouseHandled) { return; }
 413+
 414+ // we may have missed mouseup (out of window)
 415+ (this._mouseStarted && this._mouseUp(event));
 416+
 417+ this._mouseDownEvent = event;
 418+
 419+ var self = this,
 420+ btnIsLeft = (event.which == 1),
 421+ elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
 422+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
 423+ return true;
 424+ }
 425+
 426+ this.mouseDelayMet = !this.options.delay;
 427+ if (!this.mouseDelayMet) {
 428+ this._mouseDelayTimer = setTimeout(function() {
 429+ self.mouseDelayMet = true;
 430+ }, this.options.delay);
 431+ }
 432+
 433+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 434+ this._mouseStarted = (this._mouseStart(event) !== false);
 435+ if (!this._mouseStarted) {
 436+ event.preventDefault();
 437+ return true;
 438+ }
 439+ }
 440+
 441+ // these delegates are required to keep context
 442+ this._mouseMoveDelegate = function(event) {
 443+ return self._mouseMove(event);
 444+ };
 445+ this._mouseUpDelegate = function(event) {
 446+ return self._mouseUp(event);
 447+ };
 448+ $(document)
 449+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
 450+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
 451+
 452+ // preventDefault() is used to prevent the selection of text here -
 453+ // however, in Safari, this causes select boxes not to be selectable
 454+ // anymore, so this fix is needed
 455+ ($.browser.safari || event.preventDefault());
 456+
 457+ event.originalEvent.mouseHandled = true;
 458+ return true;
 459+ },
 460+
 461+ _mouseMove: function(event) {
 462+ // IE mouseup check - mouseup happened when mouse was out of window
 463+ if ($.browser.msie && !event.button) {
 464+ return this._mouseUp(event);
 465+ }
 466+
 467+ if (this._mouseStarted) {
 468+ this._mouseDrag(event);
 469+ return event.preventDefault();
 470+ }
 471+
 472+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 473+ this._mouseStarted =
 474+ (this._mouseStart(this._mouseDownEvent, event) !== false);
 475+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
 476+ }
 477+
 478+ return !this._mouseStarted;
 479+ },
 480+
 481+ _mouseUp: function(event) {
 482+ $(document)
 483+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
 484+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
 485+
 486+ if (this._mouseStarted) {
 487+ this._mouseStarted = false;
 488+ this._preventClickEvent = (event.target == this._mouseDownEvent.target);
 489+ this._mouseStop(event);
 490+ }
 491+
 492+ return false;
 493+ },
 494+
 495+ _mouseDistanceMet: function(event) {
 496+ return (Math.max(
 497+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
 498+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
 499+ ) >= this.options.distance
 500+ );
 501+ },
 502+
 503+ _mouseDelayMet: function(event) {
 504+ return this.mouseDelayMet;
 505+ },
 506+
 507+ // These are placeholder methods, to be overriden by extending plugin
 508+ _mouseStart: function(event) {},
 509+ _mouseDrag: function(event) {},
 510+ _mouseStop: function(event) {},
 511+ _mouseCapture: function(event) { return true; }
 512+};
 513+
 514+$.ui.mouse.defaults = {
 515+ cancel: null,
 516+ distance: 1,
 517+ delay: 0
 518+};
 519+
 520+})(jQuery);
 521+/*
 522+ * jQuery UI Draggable 1.7.2
 523+ *
 524+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 525+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 526+ * and GPL (GPL-LICENSE.txt) licenses.
 527+ *
 528+ * http://docs.jquery.com/UI/Draggables
 529+ *
 530+ * Depends:
 531+ * ui.core.js
 532+ */
 533+(function($) {
 534+
 535+$.widget("ui.draggable", $.extend({}, $.ui.mouse, {
 536+
 537+ _init: function() {
 538+
 539+ if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
 540+ this.element[0].style.position = 'relative';
 541+
 542+ (this.options.addClasses && this.element.addClass("ui-draggable"));
 543+ (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
 544+
 545+ this._mouseInit();
 546+
 547+ },
 548+
 549+ destroy: function() {
 550+ if(!this.element.data('draggable')) return;
 551+ this.element
 552+ .removeData("draggable")
 553+ .unbind(".draggable")
 554+ .removeClass("ui-draggable"
 555+ + " ui-draggable-dragging"
 556+ + " ui-draggable-disabled");
 557+ this._mouseDestroy();
 558+ },
 559+
 560+ _mouseCapture: function(event) {
 561+
 562+ var o = this.options;
 563+
 564+ if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
 565+ return false;
 566+
 567+ //Quit if we're not on a valid handle
 568+ this.handle = this._getHandle(event);
 569+ if (!this.handle)
 570+ return false;
 571+
 572+ return true;
 573+
 574+ },
 575+
 576+ _mouseStart: function(event) {
 577+
 578+ var o = this.options;
 579+
 580+ //Create and append the visible helper
 581+ this.helper = this._createHelper(event);
 582+
 583+ //Cache the helper size
 584+ this._cacheHelperProportions();
 585+
 586+ //If ddmanager is used for droppables, set the global draggable
 587+ if($.ui.ddmanager)
 588+ $.ui.ddmanager.current = this;
 589+
 590+ /*
 591+ * - Position generation -
 592+ * This block generates everything position related - it's the core of draggables.
 593+ */
 594+
 595+ //Cache the margins of the original element
 596+ this._cacheMargins();
 597+
 598+ //Store the helper's css position
 599+ this.cssPosition = this.helper.css("position");
 600+ this.scrollParent = this.helper.scrollParent();
 601+
 602+ //The element's absolute position on the page minus margins
 603+ this.offset = this.element.offset();
 604+ this.offset = {
 605+ top: this.offset.top - this.margins.top,
 606+ left: this.offset.left - this.margins.left
 607+ };
 608+
 609+ $.extend(this.offset, {
 610+ click: { //Where the click happened, relative to the element
 611+ left: event.pageX - this.offset.left,
 612+ top: event.pageY - this.offset.top
 613+ },
 614+ parent: this._getParentOffset(),
 615+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
 616+ });
 617+
 618+ //Generate the original position
 619+ this.originalPosition = this._generatePosition(event);
 620+ this.originalPageX = event.pageX;
 621+ this.originalPageY = event.pageY;
 622+
 623+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
 624+ if(o.cursorAt)
 625+ this._adjustOffsetFromHelper(o.cursorAt);
 626+
 627+ //Set a containment if given in the options
 628+ if(o.containment)
 629+ this._setContainment();
 630+
 631+ //Call plugins and callbacks
 632+ this._trigger("start", event);
 633+
 634+ //Recache the helper size
 635+ this._cacheHelperProportions();
 636+
 637+ //Prepare the droppable offsets
 638+ if ($.ui.ddmanager && !o.dropBehaviour)
 639+ $.ui.ddmanager.prepareOffsets(this, event);
 640+
 641+ this.helper.addClass("ui-draggable-dragging");
 642+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
 643+ return true;
 644+ },
 645+
 646+ _mouseDrag: function(event, noPropagation) {
 647+
 648+ //Compute the helpers position
 649+ this.position = this._generatePosition(event);
 650+ this.positionAbs = this._convertPositionTo("absolute");
 651+
 652+ //Call plugins and callbacks and use the resulting position if something is returned
 653+ if (!noPropagation) {
 654+ var ui = this._uiHash();
 655+ this._trigger('drag', event, ui);
 656+ this.position = ui.position;
 657+ }
 658+
 659+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
 660+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
 661+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
 662+
 663+ return false;
 664+ },
 665+
 666+ _mouseStop: function(event) {
 667+
 668+ //If we are using droppables, inform the manager about the drop
 669+ var dropped = false;
 670+ if ($.ui.ddmanager && !this.options.dropBehaviour)
 671+ dropped = $.ui.ddmanager.drop(this, event);
 672+
 673+ //if a drop comes from outside (a sortable)
 674+ if(this.dropped) {
 675+ dropped = this.dropped;
 676+ this.dropped = false;
 677+ }
 678+
 679+ if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
 680+ var self = this;
 681+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
 682+ self._trigger("stop", event);
 683+ self._clear();
 684+ });
 685+ } else {
 686+ this._trigger("stop", event);
 687+ this._clear();
 688+ }
 689+
 690+ return false;
 691+ },
 692+
 693+ _getHandle: function(event) {
 694+
 695+ var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
 696+ $(this.options.handle, this.element)
 697+ .find("*")
 698+ .andSelf()
 699+ .each(function() {
 700+ if(this == event.target) handle = true;
 701+ });
 702+
 703+ return handle;
 704+
 705+ },
 706+
 707+ _createHelper: function(event) {
 708+
 709+ var o = this.options;
 710+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
 711+
 712+ if(!helper.parents('body').length)
 713+ helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
 714+
 715+ if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
 716+ helper.css("position", "absolute");
 717+
 718+ return helper;
 719+
 720+ },
 721+
 722+ _adjustOffsetFromHelper: function(obj) {
 723+ if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
 724+ if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
 725+ if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
 726+ if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
 727+ },
 728+
 729+ _getParentOffset: function() {
 730+
 731+ //Get the offsetParent and cache its position
 732+ this.offsetParent = this.helper.offsetParent();
 733+ var po = this.offsetParent.offset();
 734+
 735+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
 736+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
 737+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
 738+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
 739+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
 740+ po.left += this.scrollParent.scrollLeft();
 741+ po.top += this.scrollParent.scrollTop();
 742+ }
 743+
 744+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
 745+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
 746+ po = { top: 0, left: 0 };
 747+
 748+ return {
 749+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
 750+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
 751+ };
 752+
 753+ },
 754+
 755+ _getRelativeOffset: function() {
 756+
 757+ if(this.cssPosition == "relative") {
 758+ var p = this.element.position();
 759+ return {
 760+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
 761+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
 762+ };
 763+ } else {
 764+ return { top: 0, left: 0 };
 765+ }
 766+
 767+ },
 768+
 769+ _cacheMargins: function() {
 770+ this.margins = {
 771+ left: (parseInt(this.element.css("marginLeft"),10) || 0),
 772+ top: (parseInt(this.element.css("marginTop"),10) || 0)
 773+ };
 774+ },
 775+
 776+ _cacheHelperProportions: function() {
 777+ this.helperProportions = {
 778+ width: this.helper.outerWidth(),
 779+ height: this.helper.outerHeight()
 780+ };
 781+ },
 782+
 783+ _setContainment: function() {
 784+
 785+ var o = this.options;
 786+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
 787+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
 788+ 0 - this.offset.relative.left - this.offset.parent.left,
 789+ 0 - this.offset.relative.top - this.offset.parent.top,
 790+ $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
 791+ ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
 792+ ];
 793+
 794+ if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
 795+ var ce = $(o.containment)[0]; if(!ce) return;
 796+ var co = $(o.containment).offset();
 797+ var over = ($(ce).css("overflow") != 'hidden');
 798+
 799+ this.containment = [
 800+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
 801+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
 802+ co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
 803+ co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
 804+ ];
 805+ } else if(o.containment.constructor == Array) {
 806+ this.containment = o.containment;
 807+ }
 808+
 809+ },
 810+
 811+ _convertPositionTo: function(d, pos) {
 812+
 813+ if(!pos) pos = this.position;
 814+ var mod = d == "absolute" ? 1 : -1;
 815+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
 816+
 817+ return {
 818+ top: (
 819+ pos.top // The absolute mouse position
 820+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
 821+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
 822+ - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
 823+ ),
 824+ left: (
 825+ pos.left // The absolute mouse position
 826+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
 827+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
 828+ - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
 829+ )
 830+ };
 831+
 832+ },
 833+
 834+ _generatePosition: function(event) {
 835+
 836+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
 837+
 838+ // This is another very weird special case that only happens for relative elements:
 839+ // 1. If the css position is relative
 840+ // 2. and the scroll parent is the document or similar to the offset parent
 841+ // we have to refresh the relative offset during the scroll so there are no jumps
 842+ if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
 843+ this.offset.relative = this._getRelativeOffset();
 844+ }
 845+
 846+ var pageX = event.pageX;
 847+ var pageY = event.pageY;
 848+
 849+ /*
 850+ * - Position constraining -
 851+ * Constrain the position to a mix of grid, containment.
 852+ */
 853+
 854+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
 855+
 856+ if(this.containment) {
 857+ if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
 858+ if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
 859+ if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
 860+ if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
 861+ }
 862+
 863+ if(o.grid) {
 864+ var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
 865+ pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
 866+
 867+ var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
 868+ pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
 869+ }
 870+
 871+ }
 872+
 873+ return {
 874+ top: (
 875+ pageY // The absolute mouse position
 876+ - this.offset.click.top // Click offset (relative to the element)
 877+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
 878+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
 879+ + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
 880+ ),
 881+ left: (
 882+ pageX // The absolute mouse position
 883+ - this.offset.click.left // Click offset (relative to the element)
 884+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
 885+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
 886+ + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
 887+ )
 888+ };
 889+
 890+ },
 891+
 892+ _clear: function() {
 893+ this.helper.removeClass("ui-draggable-dragging");
 894+ if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
 895+ //if($.ui.ddmanager) $.ui.ddmanager.current = null;
 896+ this.helper = null;
 897+ this.cancelHelperRemoval = false;
 898+ },
 899+
 900+ // From now on bulk stuff - mainly helpers
 901+
 902+ _trigger: function(type, event, ui) {
 903+ ui = ui || this._uiHash();
 904+ $.ui.plugin.call(this, type, [event, ui]);
 905+ if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
 906+ return $.widget.prototype._trigger.call(this, type, event, ui);
 907+ },
 908+
 909+ plugins: {},
 910+
 911+ _uiHash: function(event) {
 912+ return {
 913+ helper: this.helper,
 914+ position: this.position,
 915+ absolutePosition: this.positionAbs, //deprecated
 916+ offset: this.positionAbs
 917+ };
 918+ }
 919+
 920+}));
 921+
 922+$.extend($.ui.draggable, {
 923+ version: "1.7.2",
 924+ eventPrefix: "drag",
 925+ defaults: {
 926+ addClasses: true,
 927+ appendTo: "parent",
 928+ axis: false,
 929+ cancel: ":input,option",
 930+ connectToSortable: false,
 931+ containment: false,
 932+ cursor: "auto",
 933+ cursorAt: false,
 934+ delay: 0,
 935+ distance: 1,
 936+ grid: false,
 937+ handle: false,
 938+ helper: "original",
 939+ iframeFix: false,
 940+ opacity: false,
 941+ refreshPositions: false,
 942+ revert: false,
 943+ revertDuration: 500,
 944+ scope: "default",
 945+ scroll: true,
 946+ scrollSensitivity: 20,
 947+ scrollSpeed: 20,
 948+ snap: false,
 949+ snapMode: "both",
 950+ snapTolerance: 20,
 951+ stack: false,
 952+ zIndex: false
 953+ }
 954+});
 955+
 956+$.ui.plugin.add("draggable", "connectToSortable", {
 957+ start: function(event, ui) {
 958+
 959+ var inst = $(this).data("draggable"), o = inst.options,
 960+ uiSortable = $.extend({}, ui, { item: inst.element });
 961+ inst.sortables = [];
 962+ $(o.connectToSortable).each(function() {
 963+ var sortable = $.data(this, 'sortable');
 964+ if (sortable && !sortable.options.disabled) {
 965+ inst.sortables.push({
 966+ instance: sortable,
 967+ shouldRevert: sortable.options.revert
 968+ });
 969+ sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache
 970+ sortable._trigger("activate", event, uiSortable);
 971+ }
 972+ });
 973+
 974+ },
 975+ stop: function(event, ui) {
 976+
 977+ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
 978+ var inst = $(this).data("draggable"),
 979+ uiSortable = $.extend({}, ui, { item: inst.element });
 980+
 981+ $.each(inst.sortables, function() {
 982+ if(this.instance.isOver) {
 983+
 984+ this.instance.isOver = 0;
 985+
 986+ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
 987+ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
 988+
 989+ //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
 990+ if(this.shouldRevert) this.instance.options.revert = true;
 991+
 992+ //Trigger the stop of the sortable
 993+ this.instance._mouseStop(event);
 994+
 995+ this.instance.options.helper = this.instance.options._helper;
 996+
 997+ //If the helper has been the original item, restore properties in the sortable
 998+ if(inst.options.helper == 'original')
 999+ this.instance.currentItem.css({ top: 'auto', left: 'auto' });
 1000+
 1001+ } else {
 1002+ this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
 1003+ this.instance._trigger("deactivate", event, uiSortable);
 1004+ }
 1005+
 1006+ });
 1007+
 1008+ },
 1009+ drag: function(event, ui) {
 1010+
 1011+ var inst = $(this).data("draggable"), self = this;
 1012+
 1013+ var checkPos = function(o) {
 1014+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
 1015+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
 1016+ var itemHeight = o.height, itemWidth = o.width;
 1017+ var itemTop = o.top, itemLeft = o.left;
 1018+
 1019+ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
 1020+ };
 1021+
 1022+ $.each(inst.sortables, function(i) {
 1023+
 1024+ //Copy over some variables to allow calling the sortable's native _intersectsWith
 1025+ this.instance.positionAbs = inst.positionAbs;
 1026+ this.instance.helperProportions = inst.helperProportions;
 1027+ this.instance.offset.click = inst.offset.click;
 1028+
 1029+ if(this.instance._intersectsWith(this.instance.containerCache)) {
 1030+
 1031+ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
 1032+ if(!this.instance.isOver) {
 1033+
 1034+ this.instance.isOver = 1;
 1035+ //Now we fake the start of dragging for the sortable instance,
 1036+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
 1037+ //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
 1038+ this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
 1039+ this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
 1040+ this.instance.options.helper = function() { return ui.helper[0]; };
 1041+
 1042+ event.target = this.instance.currentItem[0];
 1043+ this.instance._mouseCapture(event, true);
 1044+ this.instance._mouseStart(event, true, true);
 1045+
 1046+ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
 1047+ this.instance.offset.click.top = inst.offset.click.top;
 1048+ this.instance.offset.click.left = inst.offset.click.left;
 1049+ this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
 1050+ this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
 1051+
 1052+ inst._trigger("toSortable", event);
 1053+ inst.dropped = this.instance.element; //draggable revert needs that
 1054+ //hack so receive/update callbacks work (mostly)
 1055+ inst.currentItem = inst.element;
 1056+ this.instance.fromOutside = inst;
 1057+
 1058+ }
 1059+
 1060+ //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
 1061+ if(this.instance.currentItem) this.instance._mouseDrag(event);
 1062+
 1063+ } else {
 1064+
 1065+ //If it doesn't intersect with the sortable, and it intersected before,
 1066+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
 1067+ if(this.instance.isOver) {
 1068+
 1069+ this.instance.isOver = 0;
 1070+ this.instance.cancelHelperRemoval = true;
 1071+
 1072+ //Prevent reverting on this forced stop
 1073+ this.instance.options.revert = false;
 1074+
 1075+ // The out event needs to be triggered independently
 1076+ this.instance._trigger('out', event, this.instance._uiHash(this.instance));
 1077+
 1078+ this.instance._mouseStop(event, true);
 1079+ this.instance.options.helper = this.instance.options._helper;
 1080+
 1081+ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
 1082+ this.instance.currentItem.remove();
 1083+ if(this.instance.placeholder) this.instance.placeholder.remove();
 1084+
 1085+ inst._trigger("fromSortable", event);
 1086+ inst.dropped = false; //draggable revert needs that
 1087+ }
 1088+
 1089+ };
 1090+
 1091+ });
 1092+
 1093+ }
 1094+});
 1095+
 1096+$.ui.plugin.add("draggable", "cursor", {
 1097+ start: function(event, ui) {
 1098+ var t = $('body'), o = $(this).data('draggable').options;
 1099+ if (t.css("cursor")) o._cursor = t.css("cursor");
 1100+ t.css("cursor", o.cursor);
 1101+ },
 1102+ stop: function(event, ui) {
 1103+ var o = $(this).data('draggable').options;
 1104+ if (o._cursor) $('body').css("cursor", o._cursor);
 1105+ }
 1106+});
 1107+
 1108+$.ui.plugin.add("draggable", "iframeFix", {
 1109+ start: function(event, ui) {
 1110+ var o = $(this).data('draggable').options;
 1111+ $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
 1112+ $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
 1113+ .css({
 1114+ width: this.offsetWidth+"px", height: this.offsetHeight+"px",
 1115+ position: "absolute", opacity: "0.001", zIndex: 1000
 1116+ })
 1117+ .css($(this).offset())
 1118+ .appendTo("body");
 1119+ });
 1120+ },
 1121+ stop: function(event, ui) {
 1122+ $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
 1123+ }
 1124+});
 1125+
 1126+$.ui.plugin.add("draggable", "opacity", {
 1127+ start: function(event, ui) {
 1128+ var t = $(ui.helper), o = $(this).data('draggable').options;
 1129+ if(t.css("opacity")) o._opacity = t.css("opacity");
 1130+ t.css('opacity', o.opacity);
 1131+ },
 1132+ stop: function(event, ui) {
 1133+ var o = $(this).data('draggable').options;
 1134+ if(o._opacity) $(ui.helper).css('opacity', o._opacity);
 1135+ }
 1136+});
 1137+
 1138+$.ui.plugin.add("draggable", "scroll", {
 1139+ start: function(event, ui) {
 1140+ var i = $(this).data("draggable");
 1141+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
 1142+ },
 1143+ drag: function(event, ui) {
 1144+
 1145+ var i = $(this).data("draggable"), o = i.options, scrolled = false;
 1146+
 1147+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
 1148+
 1149+ if(!o.axis || o.axis != 'x') {
 1150+ if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
 1151+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
 1152+ else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
 1153+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
 1154+ }
 1155+
 1156+ if(!o.axis || o.axis != 'y') {
 1157+ if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
 1158+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
 1159+ else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
 1160+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
 1161+ }
 1162+
 1163+ } else {
 1164+
 1165+ if(!o.axis || o.axis != 'x') {
 1166+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
 1167+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
 1168+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
 1169+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
 1170+ }
 1171+
 1172+ if(!o.axis || o.axis != 'y') {
 1173+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
 1174+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
 1175+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
 1176+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
 1177+ }
 1178+
 1179+ }
 1180+
 1181+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
 1182+ $.ui.ddmanager.prepareOffsets(i, event);
 1183+
 1184+ }
 1185+});
 1186+
 1187+$.ui.plugin.add("draggable", "snap", {
 1188+ start: function(event, ui) {
 1189+
 1190+ var i = $(this).data("draggable"), o = i.options;
 1191+ i.snapElements = [];
 1192+
 1193+ $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
 1194+ var $t = $(this); var $o = $t.offset();
 1195+ if(this != i.element[0]) i.snapElements.push({
 1196+ item: this,
 1197+ width: $t.outerWidth(), height: $t.outerHeight(),
 1198+ top: $o.top, left: $o.left
 1199+ });
 1200+ });
 1201+
 1202+ },
 1203+ drag: function(event, ui) {
 1204+
 1205+ var inst = $(this).data("draggable"), o = inst.options;
 1206+ var d = o.snapTolerance;
 1207+
 1208+ var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
 1209+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
 1210+
 1211+ for (var i = inst.snapElements.length - 1; i >= 0; i--){
 1212+
 1213+ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
 1214+ t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
 1215+
 1216+ //Yes, I know, this is insane ;)
 1217+ if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
 1218+ if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
 1219+ inst.snapElements[i].snapping = false;
 1220+ continue;
 1221+ }
 1222+
 1223+ if(o.snapMode != 'inner') {
 1224+ var ts = Math.abs(t - y2) <= d;
 1225+ var bs = Math.abs(b - y1) <= d;
 1226+ var ls = Math.abs(l - x2) <= d;
 1227+ var rs = Math.abs(r - x1) <= d;
 1228+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
 1229+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
 1230+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
 1231+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
 1232+ }
 1233+
 1234+ var first = (ts || bs || ls || rs);
 1235+
 1236+ if(o.snapMode != 'outer') {
 1237+ var ts = Math.abs(t - y1) <= d;
 1238+ var bs = Math.abs(b - y2) <= d;
 1239+ var ls = Math.abs(l - x1) <= d;
 1240+ var rs = Math.abs(r - x2) <= d;
 1241+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
 1242+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
 1243+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
 1244+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
 1245+ }
 1246+
 1247+ if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
 1248+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
 1249+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
 1250+
 1251+ };
 1252+
 1253+ }
 1254+});
 1255+
 1256+$.ui.plugin.add("draggable", "stack", {
 1257+ start: function(event, ui) {
 1258+
 1259+ var o = $(this).data("draggable").options;
 1260+
 1261+ var group = $.makeArray($(o.stack.group)).sort(function(a,b) {
 1262+ return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min);
 1263+ });
 1264+
 1265+ $(group).each(function(i) {
 1266+ this.style.zIndex = o.stack.min + i;
 1267+ });
 1268+
 1269+ this[0].style.zIndex = o.stack.min + group.length;
 1270+
 1271+ }
 1272+});
 1273+
 1274+$.ui.plugin.add("draggable", "zIndex", {
 1275+ start: function(event, ui) {
 1276+ var t = $(ui.helper), o = $(this).data("draggable").options;
 1277+ if(t.css("zIndex")) o._zIndex = t.css("zIndex");
 1278+ t.css('zIndex', o.zIndex);
 1279+ },
 1280+ stop: function(event, ui) {
 1281+ var o = $(this).data("draggable").options;
 1282+ if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
 1283+ }
 1284+});
 1285+
 1286+})(jQuery);
 1287+
 1288+/*
 1289+ * jQuery UI Droppable 1.7.2
 1290+ *
 1291+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 1292+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 1293+ * and GPL (GPL-LICENSE.txt) licenses.
 1294+ *
 1295+ * http://docs.jquery.com/UI/Droppables
 1296+ *
 1297+ * Depends:
 1298+ * ui.core.js
 1299+ * ui.draggable.js
 1300+ */
 1301+(function($) {
 1302+
 1303+$.widget("ui.droppable", {
 1304+
 1305+ _init: function() {
 1306+
 1307+ var o = this.options, accept = o.accept;
 1308+ this.isover = 0; this.isout = 1;
 1309+
 1310+ this.options.accept = this.options.accept && $.isFunction(this.options.accept) ? this.options.accept : function(d) {
 1311+ return d.is(accept);
 1312+ };
 1313+
 1314+ //Store the droppable's proportions
 1315+ this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
 1316+
 1317+ // Add the reference and positions to the manager
 1318+ $.ui.ddmanager.droppables[this.options.scope] = $.ui.ddmanager.droppables[this.options.scope] || [];
 1319+ $.ui.ddmanager.droppables[this.options.scope].push(this);
 1320+
 1321+ (this.options.addClasses && this.element.addClass("ui-droppable"));
 1322+
 1323+ },
 1324+
 1325+ destroy: function() {
 1326+ var drop = $.ui.ddmanager.droppables[this.options.scope];
 1327+ for ( var i = 0; i < drop.length; i++ )
 1328+ if ( drop[i] == this )
 1329+ drop.splice(i, 1);
 1330+
 1331+ this.element
 1332+ .removeClass("ui-droppable ui-droppable-disabled")
 1333+ .removeData("droppable")
 1334+ .unbind(".droppable");
 1335+ },
 1336+
 1337+ _setData: function(key, value) {
 1338+
 1339+ if(key == 'accept') {
 1340+ this.options.accept = value && $.isFunction(value) ? value : function(d) {
 1341+ return d.is(value);
 1342+ };
 1343+ } else {
 1344+ $.widget.prototype._setData.apply(this, arguments);
 1345+ }
 1346+
 1347+ },
 1348+
 1349+ _activate: function(event) {
 1350+ var draggable = $.ui.ddmanager.current;
 1351+ if(this.options.activeClass) this.element.addClass(this.options.activeClass);
 1352+ (draggable && this._trigger('activate', event, this.ui(draggable)));
 1353+ },
 1354+
 1355+ _deactivate: function(event) {
 1356+ var draggable = $.ui.ddmanager.current;
 1357+ if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
 1358+ (draggable && this._trigger('deactivate', event, this.ui(draggable)));
 1359+ },
 1360+
 1361+ _over: function(event) {
 1362+
 1363+ var draggable = $.ui.ddmanager.current;
 1364+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
 1365+
 1366+ if (this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
 1367+ if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
 1368+ this._trigger('over', event, this.ui(draggable));
 1369+ }
 1370+
 1371+ },
 1372+
 1373+ _out: function(event) {
 1374+
 1375+ var draggable = $.ui.ddmanager.current;
 1376+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
 1377+
 1378+ if (this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
 1379+ if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
 1380+ this._trigger('out', event, this.ui(draggable));
 1381+ }
 1382+
 1383+ },
 1384+
 1385+ _drop: function(event,custom) {
 1386+
 1387+ var draggable = custom || $.ui.ddmanager.current;
 1388+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
 1389+
 1390+ var childrenIntersection = false;
 1391+ this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
 1392+ var inst = $.data(this, 'droppable');
 1393+ if(inst.options.greedy && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) {
 1394+ childrenIntersection = true; return false;
 1395+ }
 1396+ });
 1397+ if(childrenIntersection) return false;
 1398+
 1399+ if(this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
 1400+ if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
 1401+ if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
 1402+ this._trigger('drop', event, this.ui(draggable));
 1403+ return this.element;
 1404+ }
 1405+
 1406+ return false;
 1407+
 1408+ },
 1409+
 1410+ ui: function(c) {
 1411+ return {
 1412+ draggable: (c.currentItem || c.element),
 1413+ helper: c.helper,
 1414+ position: c.position,
 1415+ absolutePosition: c.positionAbs, //deprecated
 1416+ offset: c.positionAbs
 1417+ };
 1418+ }
 1419+
 1420+});
 1421+
 1422+$.extend($.ui.droppable, {
 1423+ version: "1.7.2",
 1424+ eventPrefix: 'drop',
 1425+ defaults: {
 1426+ accept: '*',
 1427+ activeClass: false,
 1428+ addClasses: true,
 1429+ greedy: false,
 1430+ hoverClass: false,
 1431+ scope: 'default',
 1432+ tolerance: 'intersect'
 1433+ }
 1434+});
 1435+
 1436+$.ui.intersect = function(draggable, droppable, toleranceMode) {
 1437+
 1438+ if (!droppable.offset) return false;
 1439+
 1440+ var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
 1441+ y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
 1442+ var l = droppable.offset.left, r = l + droppable.proportions.width,
 1443+ t = droppable.offset.top, b = t + droppable.proportions.height;
 1444+
 1445+ switch (toleranceMode) {
 1446+ case 'fit':
 1447+ return (l < x1 && x2 < r
 1448+ && t < y1 && y2 < b);
 1449+ break;
 1450+ case 'intersect':
 1451+ return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
 1452+ && x2 - (draggable.helperProportions.width / 2) < r // Left Half
 1453+ && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
 1454+ && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
 1455+ break;
 1456+ case 'pointer':
 1457+ var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
 1458+ draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
 1459+ isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
 1460+ return isOver;
 1461+ break;
 1462+ case 'touch':
 1463+ return (
 1464+ (y1 >= t && y1 <= b) || // Top edge touching
 1465+ (y2 >= t && y2 <= b) || // Bottom edge touching
 1466+ (y1 < t && y2 > b) // Surrounded vertically
 1467+ ) && (
 1468+ (x1 >= l && x1 <= r) || // Left edge touching
 1469+ (x2 >= l && x2 <= r) || // Right edge touching
 1470+ (x1 < l && x2 > r) // Surrounded horizontally
 1471+ );
 1472+ break;
 1473+ default:
 1474+ return false;
 1475+ break;
 1476+ }
 1477+
 1478+};
 1479+
 1480+/*
 1481+ This manager tracks offsets of draggables and droppables
 1482+*/
 1483+$.ui.ddmanager = {
 1484+ current: null,
 1485+ droppables: { 'default': [] },
 1486+ prepareOffsets: function(t, event) {
 1487+
 1488+ var m = $.ui.ddmanager.droppables[t.options.scope];
 1489+ var type = event ? event.type : null; // workaround for #2317
 1490+ var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
 1491+
 1492+ droppablesLoop: for (var i = 0; i < m.length; i++) {
 1493+
 1494+ if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
 1495+ for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
 1496+ m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
 1497+
 1498+ m[i].offset = m[i].element.offset();
 1499+ m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
 1500+
 1501+ if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
 1502+
 1503+ }
 1504+
 1505+ },
 1506+ drop: function(draggable, event) {
 1507+
 1508+ var dropped = false;
 1509+ $.each($.ui.ddmanager.droppables[draggable.options.scope], function() {
 1510+
 1511+ if(!this.options) return;
 1512+ if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
 1513+ dropped = this._drop.call(this, event);
 1514+
 1515+ if (!this.options.disabled && this.visible && this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
 1516+ this.isout = 1; this.isover = 0;
 1517+ this._deactivate.call(this, event);
 1518+ }
 1519+
 1520+ });
 1521+ return dropped;
 1522+
 1523+ },
 1524+ drag: function(draggable, event) {
 1525+
 1526+ //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
 1527+ if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
 1528+
 1529+ //Run through all droppables and check their positions based on specific tolerance options
 1530+
 1531+ $.each($.ui.ddmanager.droppables[draggable.options.scope], function() {
 1532+
 1533+ if(this.options.disabled || this.greedyChild || !this.visible) return;
 1534+ var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
 1535+
 1536+ var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
 1537+ if(!c) return;
 1538+
 1539+ var parentInstance;
 1540+ if (this.options.greedy) {
 1541+ var parent = this.element.parents(':data(droppable):eq(0)');
 1542+ if (parent.length) {
 1543+ parentInstance = $.data(parent[0], 'droppable');
 1544+ parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
 1545+ }
 1546+ }
 1547+
 1548+ // we just moved into a greedy child
 1549+ if (parentInstance && c == 'isover') {
 1550+ parentInstance['isover'] = 0;
 1551+ parentInstance['isout'] = 1;
 1552+ parentInstance._out.call(parentInstance, event);
 1553+ }
 1554+
 1555+ this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
 1556+ this[c == "isover" ? "_over" : "_out"].call(this, event);
 1557+
 1558+ // we just moved out of a greedy child
 1559+ if (parentInstance && c == 'isout') {
 1560+ parentInstance['isout'] = 0;
 1561+ parentInstance['isover'] = 1;
 1562+ parentInstance._over.call(parentInstance, event);
 1563+ }
 1564+ });
 1565+
 1566+ }
 1567+};
 1568+
 1569+})(jQuery);
 1570+
 1571+/*
 1572+ * jQuery UI Resizable 1.7.2
 1573+ *
 1574+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 1575+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 1576+ * and GPL (GPL-LICENSE.txt) licenses.
 1577+ *
 1578+ * http://docs.jquery.com/UI/Resizables
 1579+ *
 1580+ * Depends:
 1581+ * ui.core.js
 1582+ */
 1583+(function($) {
 1584+
 1585+$.widget("ui.resizable", $.extend({}, $.ui.mouse, {
 1586+
 1587+ _init: function() {
 1588+
 1589+ var self = this, o = this.options;
 1590+ this.element.addClass("ui-resizable");
 1591+
 1592+ $.extend(this, {
 1593+ _aspectRatio: !!(o.aspectRatio),
 1594+ aspectRatio: o.aspectRatio,
 1595+ originalElement: this.element,
 1596+ _proportionallyResizeElements: [],
 1597+ _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
 1598+ });
 1599+
 1600+ //Wrap the element if it cannot hold child nodes
 1601+ if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
 1602+
 1603+ //Opera fix for relative positioning
 1604+ if (/relative/.test(this.element.css('position')) && $.browser.opera)
 1605+ this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
 1606+
 1607+ //Create a wrapper element and set the wrapper to the new current internal element
 1608+ this.element.wrap(
 1609+ $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
 1610+ position: this.element.css('position'),
 1611+ width: this.element.outerWidth(),
 1612+ height: this.element.outerHeight(),
 1613+ top: this.element.css('top'),
 1614+ left: this.element.css('left')
 1615+ })
 1616+ );
 1617+
 1618+ //Overwrite the original this.element
 1619+ this.element = this.element.parent().data(
 1620+ "resizable", this.element.data('resizable')
 1621+ );
 1622+
 1623+ this.elementIsWrapper = true;
 1624+
 1625+ //Move margins to the wrapper
 1626+ this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
 1627+ this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
 1628+
 1629+ //Prevent Safari textarea resize
 1630+ this.originalResizeStyle = this.originalElement.css('resize');
 1631+ this.originalElement.css('resize', 'none');
 1632+
 1633+ //Push the actual element to our proportionallyResize internal array
 1634+ this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
 1635+
 1636+ // avoid IE jump (hard set the margin)
 1637+ this.originalElement.css({ margin: this.originalElement.css('margin') });
 1638+
 1639+ // fix handlers offset
 1640+ this._proportionallyResize();
 1641+
 1642+ }
 1643+
 1644+ this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
 1645+ if(this.handles.constructor == String) {
 1646+
 1647+ if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
 1648+ var n = this.handles.split(","); this.handles = {};
 1649+
 1650+ for(var i = 0; i < n.length; i++) {
 1651+
 1652+ var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
 1653+ var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
 1654+
 1655+ // increase zIndex of sw, se, ne, nw axis
 1656+ //TODO : this modifies original option
 1657+ if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
 1658+
 1659+ //TODO : What's going on here?
 1660+ if ('se' == handle) {
 1661+ axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
 1662+ };
 1663+
 1664+ //Insert into internal handles object and append to element
 1665+ this.handles[handle] = '.ui-resizable-'+handle;
 1666+ this.element.append(axis);
 1667+ }
 1668+
 1669+ }
 1670+
 1671+ this._renderAxis = function(target) {
 1672+
 1673+ target = target || this.element;
 1674+
 1675+ for(var i in this.handles) {
 1676+
 1677+ if(this.handles[i].constructor == String)
 1678+ this.handles[i] = $(this.handles[i], this.element).show();
 1679+
 1680+ //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
 1681+ if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
 1682+
 1683+ var axis = $(this.handles[i], this.element), padWrapper = 0;
 1684+
 1685+ //Checking the correct pad and border
 1686+ padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
 1687+
 1688+ //The padding type i have to apply...
 1689+ var padPos = [ 'padding',
 1690+ /ne|nw|n/.test(i) ? 'Top' :
 1691+ /se|sw|s/.test(i) ? 'Bottom' :
 1692+ /^e$/.test(i) ? 'Right' : 'Left' ].join("");
 1693+
 1694+ target.css(padPos, padWrapper);
 1695+
 1696+ this._proportionallyResize();
 1697+
 1698+ }
 1699+
 1700+ //TODO: What's that good for? There's not anything to be executed left
 1701+ if(!$(this.handles[i]).length)
 1702+ continue;
 1703+
 1704+ }
 1705+ };
 1706+
 1707+ //TODO: make renderAxis a prototype function
 1708+ this._renderAxis(this.element);
 1709+
 1710+ this._handles = $('.ui-resizable-handle', this.element)
 1711+ .disableSelection();
 1712+
 1713+ //Matching axis name
 1714+ this._handles.mouseover(function() {
 1715+ if (!self.resizing) {
 1716+ if (this.className)
 1717+ var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
 1718+ //Axis, default = se
 1719+ self.axis = axis && axis[1] ? axis[1] : 'se';
 1720+ }
 1721+ });
 1722+
 1723+ //If we want to auto hide the elements
 1724+ if (o.autoHide) {
 1725+ this._handles.hide();
 1726+ $(this.element)
 1727+ .addClass("ui-resizable-autohide")
 1728+ .hover(function() {
 1729+ $(this).removeClass("ui-resizable-autohide");
 1730+ self._handles.show();
 1731+ },
 1732+ function(){
 1733+ if (!self.resizing) {
 1734+ $(this).addClass("ui-resizable-autohide");
 1735+ self._handles.hide();
 1736+ }
 1737+ });
 1738+ }
 1739+
 1740+ //Initialize the mouse interaction
 1741+ this._mouseInit();
 1742+
 1743+ },
 1744+
 1745+ destroy: function() {
 1746+
 1747+ this._mouseDestroy();
 1748+
 1749+ var _destroy = function(exp) {
 1750+ $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
 1751+ .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
 1752+ };
 1753+
 1754+ //TODO: Unwrap at same DOM position
 1755+ if (this.elementIsWrapper) {
 1756+ _destroy(this.element);
 1757+ var wrapper = this.element;
 1758+ wrapper.parent().append(
 1759+ this.originalElement.css({
 1760+ position: wrapper.css('position'),
 1761+ width: wrapper.outerWidth(),
 1762+ height: wrapper.outerHeight(),
 1763+ top: wrapper.css('top'),
 1764+ left: wrapper.css('left')
 1765+ })
 1766+ ).end().remove();
 1767+ }
 1768+
 1769+ this.originalElement.css('resize', this.originalResizeStyle);
 1770+ _destroy(this.originalElement);
 1771+
 1772+ },
 1773+
 1774+ _mouseCapture: function(event) {
 1775+
 1776+ var handle = false;
 1777+ for(var i in this.handles) {
 1778+ if($(this.handles[i])[0] == event.target) handle = true;
 1779+ }
 1780+
 1781+ return this.options.disabled || !!handle;
 1782+
 1783+ },
 1784+
 1785+ _mouseStart: function(event) {
 1786+
 1787+ var o = this.options, iniPos = this.element.position(), el = this.element;
 1788+
 1789+ this.resizing = true;
 1790+ this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
 1791+
 1792+ // bugfix for http://dev.jquery.com/ticket/1749
 1793+ if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
 1794+ el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
 1795+ }
 1796+
 1797+ //Opera fixing relative position
 1798+ if ($.browser.opera && (/relative/).test(el.css('position')))
 1799+ el.css({ position: 'relative', top: 'auto', left: 'auto' });
 1800+
 1801+ this._renderProxy();
 1802+
 1803+ var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
 1804+
 1805+ if (o.containment) {
 1806+ curleft += $(o.containment).scrollLeft() || 0;
 1807+ curtop += $(o.containment).scrollTop() || 0;
 1808+ }
 1809+
 1810+ //Store needed variables
 1811+ this.offset = this.helper.offset();
 1812+ this.position = { left: curleft, top: curtop };
 1813+ this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
 1814+ this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
 1815+ this.originalPosition = { left: curleft, top: curtop };
 1816+ this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
 1817+ this.originalMousePosition = { left: event.pageX, top: event.pageY };
 1818+
 1819+ //Aspect Ratio
 1820+ this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
 1821+
 1822+ var cursor = $('.ui-resizable-' + this.axis).css('cursor');
 1823+ $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
 1824+
 1825+ el.addClass("ui-resizable-resizing");
 1826+ this._propagate("start", event);
 1827+ return true;
 1828+ },
 1829+
 1830+ _mouseDrag: function(event) {
 1831+
 1832+ //Increase performance, avoid regex
 1833+ var el = this.helper, o = this.options, props = {},
 1834+ self = this, smp = this.originalMousePosition, a = this.axis;
 1835+
 1836+ var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
 1837+ var trigger = this._change[a];
 1838+ if (!trigger) return false;
 1839+
 1840+ // Calculate the attrs that will be change
 1841+ var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
 1842+
 1843+ if (this._aspectRatio || event.shiftKey)
 1844+ data = this._updateRatio(data, event);
 1845+
 1846+ data = this._respectSize(data, event);
 1847+
 1848+ // plugins callbacks need to be called first
 1849+ this._propagate("resize", event);
 1850+
 1851+ el.css({
 1852+ top: this.position.top + "px", left: this.position.left + "px",
 1853+ width: this.size.width + "px", height: this.size.height + "px"
 1854+ });
 1855+
 1856+ if (!this._helper && this._proportionallyResizeElements.length)
 1857+ this._proportionallyResize();
 1858+
 1859+ this._updateCache(data);
 1860+
 1861+ // calling the user callback at the end
 1862+ this._trigger('resize', event, this.ui());
 1863+
 1864+ return false;
 1865+ },
 1866+
 1867+ _mouseStop: function(event) {
 1868+
 1869+ this.resizing = false;
 1870+ var o = this.options, self = this;
 1871+
 1872+ if(this._helper) {
 1873+ var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
 1874+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
 1875+ soffsetw = ista ? 0 : self.sizeDiff.width;
 1876+
 1877+ var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
 1878+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
 1879+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
 1880+
 1881+ if (!o.animate)
 1882+ this.element.css($.extend(s, { top: top, left: left }));
 1883+
 1884+ self.helper.height(self.size.height);
 1885+ self.helper.width(self.size.width);
 1886+
 1887+ if (this._helper && !o.animate) this._proportionallyResize();
 1888+ }
 1889+
 1890+ $('body').css('cursor', 'auto');
 1891+
 1892+ this.element.removeClass("ui-resizable-resizing");
 1893+
 1894+ this._propagate("stop", event);
 1895+
 1896+ if (this._helper) this.helper.remove();
 1897+ return false;
 1898+
 1899+ },
 1900+
 1901+ _updateCache: function(data) {
 1902+ var o = this.options;
 1903+ this.offset = this.helper.offset();
 1904+ if (isNumber(data.left)) this.position.left = data.left;
 1905+ if (isNumber(data.top)) this.position.top = data.top;
 1906+ if (isNumber(data.height)) this.size.height = data.height;
 1907+ if (isNumber(data.width)) this.size.width = data.width;
 1908+ },
 1909+
 1910+ _updateRatio: function(data, event) {
 1911+
 1912+ var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
 1913+
 1914+ if (data.height) data.width = (csize.height * this.aspectRatio);
 1915+ else if (data.width) data.height = (csize.width / this.aspectRatio);
 1916+
 1917+ if (a == 'sw') {
 1918+ data.left = cpos.left + (csize.width - data.width);
 1919+ data.top = null;
 1920+ }
 1921+ if (a == 'nw') {
 1922+ data.top = cpos.top + (csize.height - data.height);
 1923+ data.left = cpos.left + (csize.width - data.width);
 1924+ }
 1925+
 1926+ return data;
 1927+ },
 1928+
 1929+ _respectSize: function(data, event) {
 1930+
 1931+ var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
 1932+ ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
 1933+ isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
 1934+
 1935+ if (isminw) data.width = o.minWidth;
 1936+ if (isminh) data.height = o.minHeight;
 1937+ if (ismaxw) data.width = o.maxWidth;
 1938+ if (ismaxh) data.height = o.maxHeight;
 1939+
 1940+ var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
 1941+ var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
 1942+
 1943+ if (isminw && cw) data.left = dw - o.minWidth;
 1944+ if (ismaxw && cw) data.left = dw - o.maxWidth;
 1945+ if (isminh && ch) data.top = dh - o.minHeight;
 1946+ if (ismaxh && ch) data.top = dh - o.maxHeight;
 1947+
 1948+ // fixing jump error on top/left - bug #2330
 1949+ var isNotwh = !data.width && !data.height;
 1950+ if (isNotwh && !data.left && data.top) data.top = null;
 1951+ else if (isNotwh && !data.top && data.left) data.left = null;
 1952+
 1953+ return data;
 1954+ },
 1955+
 1956+ _proportionallyResize: function() {
 1957+
 1958+ var o = this.options;
 1959+ if (!this._proportionallyResizeElements.length) return;
 1960+ var element = this.helper || this.element;
 1961+
 1962+ for (var i=0; i < this._proportionallyResizeElements.length; i++) {
 1963+
 1964+ var prel = this._proportionallyResizeElements[i];
 1965+
 1966+ if (!this.borderDif) {
 1967+ var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
 1968+ p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
 1969+
 1970+ this.borderDif = $.map(b, function(v, i) {
 1971+ var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
 1972+ return border + padding;
 1973+ });
 1974+ }
 1975+
 1976+ if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
 1977+ continue;
 1978+
 1979+ prel.css({
 1980+ height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
 1981+ width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
 1982+ });
 1983+
 1984+ };
 1985+
 1986+ },
 1987+
 1988+ _renderProxy: function() {
 1989+
 1990+ var el = this.element, o = this.options;
 1991+ this.elementOffset = el.offset();
 1992+
 1993+ if(this._helper) {
 1994+
 1995+ this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
 1996+
 1997+ // fix ie6 offset TODO: This seems broken
 1998+ var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
 1999+ pxyoffset = ( ie6 ? 2 : -1 );
 2000+
 2001+ this.helper.addClass(this._helper).css({
 2002+ width: this.element.outerWidth() + pxyoffset,
 2003+ height: this.element.outerHeight() + pxyoffset,
 2004+ position: 'absolute',
 2005+ left: this.elementOffset.left - ie6offset +'px',
 2006+ top: this.elementOffset.top - ie6offset +'px',
 2007+ zIndex: ++o.zIndex //TODO: Don't modify option
 2008+ });
 2009+
 2010+ this.helper
 2011+ .appendTo("body")
 2012+ .disableSelection();
 2013+
 2014+ } else {
 2015+ this.helper = this.element;
 2016+ }
 2017+
 2018+ },
 2019+
 2020+ _change: {
 2021+ e: function(event, dx, dy) {
 2022+ return { width: this.originalSize.width + dx };
 2023+ },
 2024+ w: function(event, dx, dy) {
 2025+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
 2026+ return { left: sp.left + dx, width: cs.width - dx };
 2027+ },
 2028+ n: function(event, dx, dy) {
 2029+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
 2030+ return { top: sp.top + dy, height: cs.height - dy };
 2031+ },
 2032+ s: function(event, dx, dy) {
 2033+ return { height: this.originalSize.height + dy };
 2034+ },
 2035+ se: function(event, dx, dy) {
 2036+ return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
 2037+ },
 2038+ sw: function(event, dx, dy) {
 2039+ return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
 2040+ },
 2041+ ne: function(event, dx, dy) {
 2042+ return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
 2043+ },
 2044+ nw: function(event, dx, dy) {
 2045+ return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
 2046+ }
 2047+ },
 2048+
 2049+ _propagate: function(n, event) {
 2050+ $.ui.plugin.call(this, n, [event, this.ui()]);
 2051+ (n != "resize" && this._trigger(n, event, this.ui()));
 2052+ },
 2053+
 2054+ plugins: {},
 2055+
 2056+ ui: function() {
 2057+ return {
 2058+ originalElement: this.originalElement,
 2059+ element: this.element,
 2060+ helper: this.helper,
 2061+ position: this.position,
 2062+ size: this.size,
 2063+ originalSize: this.originalSize,
 2064+ originalPosition: this.originalPosition
 2065+ };
 2066+ }
 2067+
 2068+}));
 2069+
 2070+$.extend($.ui.resizable, {
 2071+ version: "1.7.2",
 2072+ eventPrefix: "resize",
 2073+ defaults: {
 2074+ alsoResize: false,
 2075+ animate: false,
 2076+ animateDuration: "slow",
 2077+ animateEasing: "swing",
 2078+ aspectRatio: false,
 2079+ autoHide: false,
 2080+ cancel: ":input,option",
 2081+ containment: false,
 2082+ delay: 0,
 2083+ distance: 1,
 2084+ ghost: false,
 2085+ grid: false,
 2086+ handles: "e,s,se",
 2087+ helper: false,
 2088+ maxHeight: null,
 2089+ maxWidth: null,
 2090+ minHeight: 10,
 2091+ minWidth: 10,
 2092+ zIndex: 1000
 2093+ }
 2094+});
 2095+
 2096+/*
 2097+ * Resizable Extensions
 2098+ */
 2099+
 2100+$.ui.plugin.add("resizable", "alsoResize", {
 2101+
 2102+ start: function(event, ui) {
 2103+
 2104+ var self = $(this).data("resizable"), o = self.options;
 2105+
 2106+ _store = function(exp) {
 2107+ $(exp).each(function() {
 2108+ $(this).data("resizable-alsoresize", {
 2109+ width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
 2110+ left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
 2111+ });
 2112+ });
 2113+ };
 2114+
 2115+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
 2116+ if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
 2117+ else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); }
 2118+ }else{
 2119+ _store(o.alsoResize);
 2120+ }
 2121+ },
 2122+
 2123+ resize: function(event, ui){
 2124+ var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
 2125+
 2126+ var delta = {
 2127+ height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
 2128+ top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
 2129+ },
 2130+
 2131+ _alsoResize = function(exp, c) {
 2132+ $(exp).each(function() {
 2133+ var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
 2134+
 2135+ $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
 2136+ var sum = (start[prop]||0) + (delta[prop]||0);
 2137+ if (sum && sum >= 0)
 2138+ style[prop] = sum || null;
 2139+ });
 2140+
 2141+ //Opera fixing relative position
 2142+ if (/relative/.test(el.css('position')) && $.browser.opera) {
 2143+ self._revertToRelativePosition = true;
 2144+ el.css({ position: 'absolute', top: 'auto', left: 'auto' });
 2145+ }
 2146+
 2147+ el.css(style);
 2148+ });
 2149+ };
 2150+
 2151+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
 2152+ $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });
 2153+ }else{
 2154+ _alsoResize(o.alsoResize);
 2155+ }
 2156+ },
 2157+
 2158+ stop: function(event, ui){
 2159+ var self = $(this).data("resizable");
 2160+
 2161+ //Opera fixing relative position
 2162+ if (self._revertToRelativePosition && $.browser.opera) {
 2163+ self._revertToRelativePosition = false;
 2164+ el.css({ position: 'relative' });
 2165+ }
 2166+
 2167+ $(this).removeData("resizable-alsoresize-start");
 2168+ }
 2169+});
 2170+
 2171+$.ui.plugin.add("resizable", "animate", {
 2172+
 2173+ stop: function(event, ui) {
 2174+ var self = $(this).data("resizable"), o = self.options;
 2175+
 2176+ var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
 2177+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
 2178+ soffsetw = ista ? 0 : self.sizeDiff.width;
 2179+
 2180+ var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
 2181+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
 2182+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
 2183+
 2184+ self.element.animate(
 2185+ $.extend(style, top && left ? { top: top, left: left } : {}), {
 2186+ duration: o.animateDuration,
 2187+ easing: o.animateEasing,
 2188+ step: function() {
 2189+
 2190+ var data = {
 2191+ width: parseInt(self.element.css('width'), 10),
 2192+ height: parseInt(self.element.css('height'), 10),
 2193+ top: parseInt(self.element.css('top'), 10),
 2194+ left: parseInt(self.element.css('left'), 10)
 2195+ };
 2196+
 2197+ if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
 2198+
 2199+ // propagating resize, and updating values for each animation step
 2200+ self._updateCache(data);
 2201+ self._propagate("resize", event);
 2202+
 2203+ }
 2204+ }
 2205+ );
 2206+ }
 2207+
 2208+});
 2209+
 2210+$.ui.plugin.add("resizable", "containment", {
 2211+
 2212+ start: function(event, ui) {
 2213+ var self = $(this).data("resizable"), o = self.options, el = self.element;
 2214+ var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
 2215+ if (!ce) return;
 2216+
 2217+ self.containerElement = $(ce);
 2218+
 2219+ if (/document/.test(oc) || oc == document) {
 2220+ self.containerOffset = { left: 0, top: 0 };
 2221+ self.containerPosition = { left: 0, top: 0 };
 2222+
 2223+ self.parentData = {
 2224+ element: $(document), left: 0, top: 0,
 2225+ width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
 2226+ };
 2227+ }
 2228+
 2229+ // i'm a node, so compute top, left, right, bottom
 2230+ else {
 2231+ var element = $(ce), p = [];
 2232+ $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
 2233+
 2234+ self.containerOffset = element.offset();
 2235+ self.containerPosition = element.position();
 2236+ self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
 2237+
 2238+ var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
 2239+ width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
 2240+
 2241+ self.parentData = {
 2242+ element: ce, left: co.left, top: co.top, width: width, height: height
 2243+ };
 2244+ }
 2245+ },
 2246+
 2247+ resize: function(event, ui) {
 2248+ var self = $(this).data("resizable"), o = self.options,
 2249+ ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
 2250+ pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
 2251+
 2252+ if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
 2253+
 2254+ if (cp.left < (self._helper ? co.left : 0)) {
 2255+ self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
 2256+ if (pRatio) self.size.height = self.size.width / o.aspectRatio;
 2257+ self.position.left = o.helper ? co.left : 0;
 2258+ }
 2259+
 2260+ if (cp.top < (self._helper ? co.top : 0)) {
 2261+ self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
 2262+ if (pRatio) self.size.width = self.size.height * o.aspectRatio;
 2263+ self.position.top = self._helper ? co.top : 0;
 2264+ }
 2265+
 2266+ self.offset.left = self.parentData.left+self.position.left;
 2267+ self.offset.top = self.parentData.top+self.position.top;
 2268+
 2269+ var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
 2270+ hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
 2271+
 2272+ var isParent = self.containerElement.get(0) == self.element.parent().get(0),
 2273+ isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
 2274+
 2275+ if(isParent && isOffsetRelative) woset -= self.parentData.left;
 2276+
 2277+ if (woset + self.size.width >= self.parentData.width) {
 2278+ self.size.width = self.parentData.width - woset;
 2279+ if (pRatio) self.size.height = self.size.width / self.aspectRatio;
 2280+ }
 2281+
 2282+ if (hoset + self.size.height >= self.parentData.height) {
 2283+ self.size.height = self.parentData.height - hoset;
 2284+ if (pRatio) self.size.width = self.size.height * self.aspectRatio;
 2285+ }
 2286+ },
 2287+
 2288+ stop: function(event, ui){
 2289+ var self = $(this).data("resizable"), o = self.options, cp = self.position,
 2290+ co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
 2291+
 2292+ var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
 2293+
 2294+ if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
 2295+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
 2296+
 2297+ if (self._helper && !o.animate && (/static/).test(ce.css('position')))
 2298+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
 2299+
 2300+ }
 2301+});
 2302+
 2303+$.ui.plugin.add("resizable", "ghost", {
 2304+
 2305+ start: function(event, ui) {
 2306+
 2307+ var self = $(this).data("resizable"), o = self.options, cs = self.size;
 2308+
 2309+ self.ghost = self.originalElement.clone();
 2310+ self.ghost
 2311+ .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
 2312+ .addClass('ui-resizable-ghost')
 2313+ .addClass(typeof o.ghost == 'string' ? o.ghost : '');
 2314+
 2315+ self.ghost.appendTo(self.helper);
 2316+
 2317+ },
 2318+
 2319+ resize: function(event, ui){
 2320+ var self = $(this).data("resizable"), o = self.options;
 2321+ if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
 2322+ },
 2323+
 2324+ stop: function(event, ui){
 2325+ var self = $(this).data("resizable"), o = self.options;
 2326+ if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
 2327+ }
 2328+
 2329+});
 2330+
 2331+$.ui.plugin.add("resizable", "grid", {
 2332+
 2333+ resize: function(event, ui) {
 2334+ var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
 2335+ o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
 2336+ var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
 2337+
 2338+ if (/^(se|s|e)$/.test(a)) {
 2339+ self.size.width = os.width + ox;
 2340+ self.size.height = os.height + oy;
 2341+ }
 2342+ else if (/^(ne)$/.test(a)) {
 2343+ self.size.width = os.width + ox;
 2344+ self.size.height = os.height + oy;
 2345+ self.position.top = op.top - oy;
 2346+ }
 2347+ else if (/^(sw)$/.test(a)) {
 2348+ self.size.width = os.width + ox;
 2349+ self.size.height = os.height + oy;
 2350+ self.position.left = op.left - ox;
 2351+ }
 2352+ else {
 2353+ self.size.width = os.width + ox;
 2354+ self.size.height = os.height + oy;
 2355+ self.position.top = op.top - oy;
 2356+ self.position.left = op.left - ox;
 2357+ }
 2358+ }
 2359+
 2360+});
 2361+
 2362+var num = function(v) {
 2363+ return parseInt(v, 10) || 0;
 2364+};
 2365+
 2366+var isNumber = function(value) {
 2367+ return !isNaN(parseInt(value, 10));
 2368+};
 2369+
 2370+})(jQuery);
 2371+/*
 2372+ * jQuery UI Dialog 1.7.2
 2373+ *
 2374+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 2375+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 2376+ * and GPL (GPL-LICENSE.txt) licenses.
 2377+ *
 2378+ * http://docs.jquery.com/UI/Dialog
 2379+ *
 2380+ * Depends:
 2381+ * ui.core.js
 2382+ * ui.draggable.js
 2383+ * ui.resizable.js
 2384+ */
 2385+(function($) {
 2386+
 2387+var setDataSwitch = {
 2388+ dragStart: "start.draggable",
 2389+ drag: "drag.draggable",
 2390+ dragStop: "stop.draggable",
 2391+ maxHeight: "maxHeight.resizable",
 2392+ minHeight: "minHeight.resizable",
 2393+ maxWidth: "maxWidth.resizable",
 2394+ minWidth: "minWidth.resizable",
 2395+ resizeStart: "start.resizable",
 2396+ resize: "drag.resizable",
 2397+ resizeStop: "stop.resizable"
 2398+ },
 2399+
 2400+ uiDialogClasses =
 2401+ 'ui-dialog ' +
 2402+ 'ui-widget ' +
 2403+ 'ui-widget-content ' +
 2404+ 'ui-corner-all ';
 2405+
 2406+$.widget("ui.dialog", {
 2407+
 2408+ _init: function() {
 2409+ this.originalTitle = this.element.attr('title');
 2410+
 2411+ var self = this,
 2412+ options = this.options,
 2413+
 2414+ title = options.title || this.originalTitle || '&nbsp;',
 2415+ titleId = $.ui.dialog.getTitleId(this.element),
 2416+
 2417+ uiDialog = (this.uiDialog = $('<div/>'))
 2418+ .appendTo(document.body)
 2419+ .hide()
 2420+ .addClass(uiDialogClasses + options.dialogClass)
 2421+ .css({
 2422+ position: 'absolute',
 2423+ overflow: 'hidden',
 2424+ zIndex: options.zIndex
 2425+ })
 2426+ // setting tabIndex makes the div focusable
 2427+ // setting outline to 0 prevents a border on focus in Mozilla
 2428+ .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
 2429+ (options.closeOnEscape && event.keyCode
 2430+ && event.keyCode == $.ui.keyCode.ESCAPE && self.close(event));
 2431+ })
 2432+ .attr({
 2433+ role: 'dialog',
 2434+ 'aria-labelledby': titleId
 2435+ })
 2436+ .mousedown(function(event) {
 2437+ self.moveToTop(false, event);
 2438+ }),
 2439+
 2440+ uiDialogContent = this.element
 2441+ .show()
 2442+ .removeAttr('title')
 2443+ .addClass(
 2444+ 'ui-dialog-content ' +
 2445+ 'ui-widget-content')
 2446+ .appendTo(uiDialog),
 2447+
 2448+ uiDialogTitlebar = (this.uiDialogTitlebar = $('<div></div>'))
 2449+ .addClass(
 2450+ 'ui-dialog-titlebar ' +
 2451+ 'ui-widget-header ' +
 2452+ 'ui-corner-all ' +
 2453+ 'ui-helper-clearfix'
 2454+ )
 2455+ .prependTo(uiDialog),
 2456+
 2457+ uiDialogTitlebarClose = $('<a href="#"/>')
 2458+ .addClass(
 2459+ 'ui-dialog-titlebar-close ' +
 2460+ 'ui-corner-all'
 2461+ )
 2462+ .attr('role', 'button')
 2463+ .hover(
 2464+ function() {
 2465+ uiDialogTitlebarClose.addClass('ui-state-hover');
 2466+ },
 2467+ function() {
 2468+ uiDialogTitlebarClose.removeClass('ui-state-hover');
 2469+ }
 2470+ )
 2471+ .focus(function() {
 2472+ uiDialogTitlebarClose.addClass('ui-state-focus');
 2473+ })
 2474+ .blur(function() {
 2475+ uiDialogTitlebarClose.removeClass('ui-state-focus');
 2476+ })
 2477+ .mousedown(function(ev) {
 2478+ ev.stopPropagation();
 2479+ })
 2480+ .click(function(event) {
 2481+ self.close(event);
 2482+ return false;
 2483+ })
 2484+ .appendTo(uiDialogTitlebar),
 2485+
 2486+ uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>'))
 2487+ .addClass(
 2488+ 'ui-icon ' +
 2489+ 'ui-icon-closethick'
 2490+ )
 2491+ .text(options.closeText)
 2492+ .appendTo(uiDialogTitlebarClose),
 2493+
 2494+ uiDialogTitle = $('<span/>')
 2495+ .addClass('ui-dialog-title')
 2496+ .attr('id', titleId)
 2497+ .html(title)
 2498+ .prependTo(uiDialogTitlebar);
 2499+
 2500+ uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
 2501+
 2502+ (options.draggable && $.fn.draggable && this._makeDraggable());
 2503+ (options.resizable && $.fn.resizable && this._makeResizable());
 2504+
 2505+ this._createButtons(options.buttons);
 2506+ this._isOpen = false;
 2507+
 2508+ (options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe());
 2509+ (options.autoOpen && this.open());
 2510+
 2511+ },
 2512+
 2513+ destroy: function() {
 2514+ (this.overlay && this.overlay.destroy());
 2515+ this.uiDialog.hide();
 2516+ this.element
 2517+ .unbind('.dialog')
 2518+ .removeData('dialog')
 2519+ .removeClass('ui-dialog-content ui-widget-content')
 2520+ .hide().appendTo('body');
 2521+ this.uiDialog.remove();
 2522+
 2523+ (this.originalTitle && this.element.attr('title', this.originalTitle));
 2524+ },
 2525+
 2526+ close: function(event) {
 2527+ var self = this;
 2528+
 2529+ if (false === self._trigger('beforeclose', event)) {
 2530+ return;
 2531+ }
 2532+
 2533+ (self.overlay && self.overlay.destroy());
 2534+ self.uiDialog.unbind('keypress.ui-dialog');
 2535+
 2536+ (self.options.hide
 2537+ ? self.uiDialog.hide(self.options.hide, function() {
 2538+ self._trigger('close', event);
 2539+ })
 2540+ : self.uiDialog.hide() && self._trigger('close', event));
 2541+
 2542+ $.ui.dialog.overlay.resize();
 2543+
 2544+ self._isOpen = false;
 2545+
 2546+ // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
 2547+ if (self.options.modal) {
 2548+ var maxZ = 0;
 2549+ $('.ui-dialog').each(function() {
 2550+ if (this != self.uiDialog[0]) {
 2551+ maxZ = Math.max(maxZ, $(this).css('z-index'));
 2552+ }
 2553+ });
 2554+ $.ui.dialog.maxZ = maxZ;
 2555+ }
 2556+ },
 2557+
 2558+ isOpen: function() {
 2559+ return this._isOpen;
 2560+ },
 2561+
 2562+ // the force parameter allows us to move modal dialogs to their correct
 2563+ // position on open
 2564+ moveToTop: function(force, event) {
 2565+
 2566+ if ((this.options.modal && !force)
 2567+ || (!this.options.stack && !this.options.modal)) {
 2568+ return this._trigger('focus', event);
 2569+ }
 2570+
 2571+ if (this.options.zIndex > $.ui.dialog.maxZ) {
 2572+ $.ui.dialog.maxZ = this.options.zIndex;
 2573+ }
 2574+ (this.overlay && this.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = ++$.ui.dialog.maxZ));
 2575+
 2576+ //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
 2577+ // http://ui.jquery.com/bugs/ticket/3193
 2578+ var saveScroll = { scrollTop: this.element.attr('scrollTop'), scrollLeft: this.element.attr('scrollLeft') };
 2579+ this.uiDialog.css('z-index', ++$.ui.dialog.maxZ);
 2580+ this.element.attr(saveScroll);
 2581+ this._trigger('focus', event);
 2582+ },
 2583+
 2584+ open: function() {
 2585+ if (this._isOpen) { return; }
 2586+
 2587+ var options = this.options,
 2588+ uiDialog = this.uiDialog;
 2589+
 2590+ this.overlay = options.modal ? new $.ui.dialog.overlay(this) : null;
 2591+ (uiDialog.next().length && uiDialog.appendTo('body'));
 2592+ this._size();
 2593+ this._position(options.position);
 2594+ uiDialog.show(options.show);
 2595+ this.moveToTop(true);
 2596+
 2597+ // prevent tabbing out of modal dialogs
 2598+ (options.modal && uiDialog.bind('keypress.ui-dialog', function(event) {
 2599+ if (event.keyCode != $.ui.keyCode.TAB) {
 2600+ return;
 2601+ }
 2602+
 2603+ var tabbables = $(':tabbable', this),
 2604+ first = tabbables.filter(':first')[0],
 2605+ last = tabbables.filter(':last')[0];
 2606+
 2607+ if (event.target == last && !event.shiftKey) {
 2608+ setTimeout(function() {
 2609+ first.focus();
 2610+ }, 1);
 2611+ } else if (event.target == first && event.shiftKey) {
 2612+ setTimeout(function() {
 2613+ last.focus();
 2614+ }, 1);
 2615+ }
 2616+ }));
 2617+
 2618+ // set focus to the first tabbable element in the content area or the first button
 2619+ // if there are no tabbable elements, set focus on the dialog itself
 2620+ $([])
 2621+ .add(uiDialog.find('.ui-dialog-content :tabbable:first'))
 2622+ .add(uiDialog.find('.ui-dialog-buttonpane :tabbable:first'))
 2623+ .add(uiDialog)
 2624+ .filter(':first')
 2625+ .focus();
 2626+
 2627+ this._trigger('open');
 2628+ this._isOpen = true;
 2629+ },
 2630+
 2631+ _createButtons: function(buttons) {
 2632+ var self = this,
 2633+ hasButtons = false,
 2634+ uiDialogButtonPane = $('<div></div>')
 2635+ .addClass(
 2636+ 'ui-dialog-buttonpane ' +
 2637+ 'ui-widget-content ' +
 2638+ 'ui-helper-clearfix'
 2639+ );
 2640+
 2641+ // if we already have a button pane, remove it
 2642+ this.uiDialog.find('.ui-dialog-buttonpane').remove();
 2643+
 2644+ (typeof buttons == 'object' && buttons !== null &&
 2645+ $.each(buttons, function() { return !(hasButtons = true); }));
 2646+ if (hasButtons) {
 2647+ $.each(buttons, function(name, fn) {
 2648+ $('<button type="button"></button>')
 2649+ .addClass(
 2650+ 'ui-state-default ' +
 2651+ 'ui-corner-all'
 2652+ )
 2653+ .text(name)
 2654+ .click(function() { fn.apply(self.element[0], arguments); })
 2655+ .hover(
 2656+ function() {
 2657+ $(this).addClass('ui-state-hover');
 2658+ },
 2659+ function() {
 2660+ $(this).removeClass('ui-state-hover');
 2661+ }
 2662+ )
 2663+ .focus(function() {
 2664+ $(this).addClass('ui-state-focus');
 2665+ })
 2666+ .blur(function() {
 2667+ $(this).removeClass('ui-state-focus');
 2668+ })
 2669+ .appendTo(uiDialogButtonPane);
 2670+ });
 2671+ uiDialogButtonPane.appendTo(this.uiDialog);
 2672+ }
 2673+ },
 2674+
 2675+ _makeDraggable: function() {
 2676+ var self = this,
 2677+ options = this.options,
 2678+ heightBeforeDrag;
 2679+
 2680+ this.uiDialog.draggable({
 2681+ cancel: '.ui-dialog-content',
 2682+ handle: '.ui-dialog-titlebar',
 2683+ containment: 'document',
 2684+ start: function() {
 2685+ heightBeforeDrag = options.height;
 2686+ $(this).height($(this).height()).addClass("ui-dialog-dragging");
 2687+ (options.dragStart && options.dragStart.apply(self.element[0], arguments));
 2688+ },
 2689+ drag: function() {
 2690+ (options.drag && options.drag.apply(self.element[0], arguments));
 2691+ },
 2692+ stop: function() {
 2693+ $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
 2694+ (options.dragStop && options.dragStop.apply(self.element[0], arguments));
 2695+ $.ui.dialog.overlay.resize();
 2696+ }
 2697+ });
 2698+ },
 2699+
 2700+ _makeResizable: function(handles) {
 2701+ handles = (handles === undefined ? this.options.resizable : handles);
 2702+ var self = this,
 2703+ options = this.options,
 2704+ resizeHandles = typeof handles == 'string'
 2705+ ? handles
 2706+ : 'n,e,s,w,se,sw,ne,nw';
 2707+
 2708+ this.uiDialog.resizable({
 2709+ cancel: '.ui-dialog-content',
 2710+ alsoResize: this.element,
 2711+ maxWidth: options.maxWidth,
 2712+ maxHeight: options.maxHeight,
 2713+ minWidth: options.minWidth,
 2714+ minHeight: options.minHeight,
 2715+ start: function() {
 2716+ $(this).addClass("ui-dialog-resizing");
 2717+ (options.resizeStart && options.resizeStart.apply(self.element[0], arguments));
 2718+ },
 2719+ resize: function() {
 2720+ (options.resize && options.resize.apply(self.element[0], arguments));
 2721+ },
 2722+ handles: resizeHandles,
 2723+ stop: function() {
 2724+ $(this).removeClass("ui-dialog-resizing");
 2725+ options.height = $(this).height();
 2726+ options.width = $(this).width();
 2727+ (options.resizeStop && options.resizeStop.apply(self.element[0], arguments));
 2728+ $.ui.dialog.overlay.resize();
 2729+ }
 2730+ })
 2731+ .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
 2732+ },
 2733+
 2734+ _position: function(pos) {
 2735+ var wnd = $(window), doc = $(document),
 2736+ pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
 2737+ minTop = pTop;
 2738+
 2739+ if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
 2740+ pos = [
 2741+ pos == 'right' || pos == 'left' ? pos : 'center',
 2742+ pos == 'top' || pos == 'bottom' ? pos : 'middle'
 2743+ ];
 2744+ }
 2745+ if (pos.constructor != Array) {
 2746+ pos = ['center', 'middle'];
 2747+ }
 2748+ if (pos[0].constructor == Number) {
 2749+ pLeft += pos[0];
 2750+ } else {
 2751+ switch (pos[0]) {
 2752+ case 'left':
 2753+ pLeft += 0;
 2754+ break;
 2755+ case 'right':
 2756+ pLeft += wnd.width() - this.uiDialog.outerWidth();
 2757+ break;
 2758+ default:
 2759+ case 'center':
 2760+ pLeft += (wnd.width() - this.uiDialog.outerWidth()) / 2;
 2761+ }
 2762+ }
 2763+ if (pos[1].constructor == Number) {
 2764+ pTop += pos[1];
 2765+ } else {
 2766+ switch (pos[1]) {
 2767+ case 'top':
 2768+ pTop += 0;
 2769+ break;
 2770+ case 'bottom':
 2771+ pTop += wnd.height() - this.uiDialog.outerHeight();
 2772+ break;
 2773+ default:
 2774+ case 'middle':
 2775+ pTop += (wnd.height() - this.uiDialog.outerHeight()) / 2;
 2776+ }
 2777+ }
 2778+
 2779+ // prevent the dialog from being too high (make sure the titlebar
 2780+ // is accessible)
 2781+ pTop = Math.max(pTop, minTop);
 2782+ this.uiDialog.css({top: pTop, left: pLeft});
 2783+ },
 2784+
 2785+ _setData: function(key, value){
 2786+ (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
 2787+ switch (key) {
 2788+ case "buttons":
 2789+ this._createButtons(value);
 2790+ break;
 2791+ case "closeText":
 2792+ this.uiDialogTitlebarCloseText.text(value);
 2793+ break;
 2794+ case "dialogClass":
 2795+ this.uiDialog
 2796+ .removeClass(this.options.dialogClass)
 2797+ .addClass(uiDialogClasses + value);
 2798+ break;
 2799+ case "draggable":
 2800+ (value
 2801+ ? this._makeDraggable()
 2802+ : this.uiDialog.draggable('destroy'));
 2803+ break;
 2804+ case "height":
 2805+ this.uiDialog.height(value);
 2806+ break;
 2807+ case "position":
 2808+ this._position(value);
 2809+ break;
 2810+ case "resizable":
 2811+ var uiDialog = this.uiDialog,
 2812+ isResizable = this.uiDialog.is(':data(resizable)');
 2813+
 2814+ // currently resizable, becoming non-resizable
 2815+ (isResizable && !value && uiDialog.resizable('destroy'));
 2816+
 2817+ // currently resizable, changing handles
 2818+ (isResizable && typeof value == 'string' &&
 2819+ uiDialog.resizable('option', 'handles', value));
 2820+
 2821+ // currently non-resizable, becoming resizable
 2822+ (isResizable || this._makeResizable(value));
 2823+ break;
 2824+ case "title":
 2825+ $(".ui-dialog-title", this.uiDialogTitlebar).html(value || '&nbsp;');
 2826+ break;
 2827+ case "width":
 2828+ this.uiDialog.width(value);
 2829+ break;
 2830+ }
 2831+
 2832+ $.widget.prototype._setData.apply(this, arguments);
 2833+ },
 2834+
 2835+ _size: function() {
 2836+ /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
 2837+ * divs will both have width and height set, so we need to reset them
 2838+ */
 2839+ var options = this.options;
 2840+
 2841+ // reset content sizing
 2842+ this.element.css({
 2843+ height: 0,
 2844+ minHeight: 0,
 2845+ width: 'auto'
 2846+ });
 2847+
 2848+ // reset wrapper sizing
 2849+ // determine the height of all the non-content elements
 2850+ var nonContentHeight = this.uiDialog.css({
 2851+ height: 'auto',
 2852+ width: options.width
 2853+ })
 2854+ .height();
 2855+
 2856+ this.element
 2857+ .css({
 2858+ minHeight: Math.max(options.minHeight - nonContentHeight, 0),
 2859+ height: options.height == 'auto'
 2860+ ? 'auto'
 2861+ : Math.max(options.height - nonContentHeight, 0)
 2862+ });
 2863+ }
 2864+});
 2865+
 2866+$.extend($.ui.dialog, {
 2867+ version: "1.7.2",
 2868+ defaults: {
 2869+ autoOpen: true,
 2870+ bgiframe: false,
 2871+ buttons: {},
 2872+ closeOnEscape: true,
 2873+ closeText: 'close',
 2874+ dialogClass: '',
 2875+ draggable: true,
 2876+ hide: null,
 2877+ height: 'auto',
 2878+ maxHeight: false,
 2879+ maxWidth: false,
 2880+ minHeight: 150,
 2881+ minWidth: 150,
 2882+ modal: false,
 2883+ position: 'center',
 2884+ resizable: true,
 2885+ show: null,
 2886+ stack: true,
 2887+ title: '',
 2888+ width: 300,
 2889+ zIndex: 1000
 2890+ },
 2891+
 2892+ getter: 'isOpen',
 2893+
 2894+ uuid: 0,
 2895+ maxZ: 0,
 2896+
 2897+ getTitleId: function($el) {
 2898+ return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid);
 2899+ },
 2900+
 2901+ overlay: function(dialog) {
 2902+ this.$el = $.ui.dialog.overlay.create(dialog);
 2903+ }
 2904+});
 2905+
 2906+$.extend($.ui.dialog.overlay, {
 2907+ instances: [],
 2908+ maxZ: 0,
 2909+ events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
 2910+ function(event) { return event + '.dialog-overlay'; }).join(' '),
 2911+ create: function(dialog) {
 2912+ if (this.instances.length === 0) {
 2913+ // prevent use of anchors and inputs
 2914+ // we use a setTimeout in case the overlay is created from an
 2915+ // event that we're going to be cancelling (see #2804)
 2916+ setTimeout(function() {
 2917+ // handle $(el).dialog().dialog('close') (see #4065)
 2918+ if ($.ui.dialog.overlay.instances.length) {
 2919+ $(document).bind($.ui.dialog.overlay.events, function(event) {
 2920+ var dialogZ = $(event.target).parents('.ui-dialog').css('zIndex') || 0;
 2921+ return (dialogZ > $.ui.dialog.overlay.maxZ);
 2922+ });
 2923+ }
 2924+ }, 1);
 2925+
 2926+ // allow closing by pressing the escape key
 2927+ $(document).bind('keydown.dialog-overlay', function(event) {
 2928+ (dialog.options.closeOnEscape && event.keyCode
 2929+ && event.keyCode == $.ui.keyCode.ESCAPE && dialog.close(event));
 2930+ });
 2931+
 2932+ // handle window resize
 2933+ $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
 2934+ }
 2935+
 2936+ var $el = $('<div></div>').appendTo(document.body)
 2937+ .addClass('ui-widget-overlay').css({
 2938+ width: this.width(),
 2939+ height: this.height()
 2940+ });
 2941+
 2942+ (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());
 2943+
 2944+ this.instances.push($el);
 2945+ return $el;
 2946+ },
 2947+
 2948+ destroy: function($el) {
 2949+ this.instances.splice($.inArray(this.instances, $el), 1);
 2950+
 2951+ if (this.instances.length === 0) {
 2952+ $([document, window]).unbind('.dialog-overlay');
 2953+ }
 2954+
 2955+ $el.remove();
 2956+
 2957+ // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
 2958+ var maxZ = 0;
 2959+ $.each(this.instances, function() {
 2960+ maxZ = Math.max(maxZ, this.css('z-index'));
 2961+ });
 2962+ this.maxZ = maxZ;
 2963+ },
 2964+
 2965+ height: function() {
 2966+ // handle IE 6
 2967+ if ($.browser.msie && $.browser.version < 7) {
 2968+ var scrollHeight = Math.max(
 2969+ document.documentElement.scrollHeight,
 2970+ document.body.scrollHeight
 2971+ );
 2972+ var offsetHeight = Math.max(
 2973+ document.documentElement.offsetHeight,
 2974+ document.body.offsetHeight
 2975+ );
 2976+
 2977+ if (scrollHeight < offsetHeight) {
 2978+ return $(window).height() + 'px';
 2979+ } else {
 2980+ return scrollHeight + 'px';
 2981+ }
 2982+ // handle "good" browsers
 2983+ } else {
 2984+ return $(document).height() + 'px';
 2985+ }
 2986+ },
 2987+
 2988+ width: function() {
 2989+ // handle IE 6
 2990+ if ($.browser.msie && $.browser.version < 7) {
 2991+ var scrollWidth = Math.max(
 2992+ document.documentElement.scrollWidth,
 2993+ document.body.scrollWidth
 2994+ );
 2995+ var offsetWidth = Math.max(
 2996+ document.documentElement.offsetWidth,
 2997+ document.body.offsetWidth
 2998+ );
 2999+
 3000+ if (scrollWidth < offsetWidth) {
 3001+ return $(window).width() + 'px';
 3002+ } else {
 3003+ return scrollWidth + 'px';
 3004+ }
 3005+ // handle "good" browsers
 3006+ } else {
 3007+ return $(document).width() + 'px';
 3008+ }
 3009+ },
 3010+
 3011+ resize: function() {
 3012+ /* If the dialog is draggable and the user drags it past the
 3013+ * right edge of the window, the document becomes wider so we
 3014+ * need to stretch the overlay. If the user then drags the
 3015+ * dialog back to the left, the document will become narrower,
 3016+ * so we need to shrink the overlay to the appropriate size.
 3017+ * This is handled by shrinking the overlay before setting it
 3018+ * to the full document size.
 3019+ */
 3020+ var $overlays = $([]);
 3021+ $.each($.ui.dialog.overlay.instances, function() {
 3022+ $overlays = $overlays.add(this);
 3023+ });
 3024+
 3025+ $overlays.css({
 3026+ width: 0,
 3027+ height: 0
 3028+ }).css({
 3029+ width: $.ui.dialog.overlay.width(),
 3030+ height: $.ui.dialog.overlay.height()
 3031+ });
 3032+ }
 3033+});
 3034+
 3035+$.extend($.ui.dialog.overlay.prototype, {
 3036+ destroy: function() {
 3037+ $.ui.dialog.overlay.destroy(this.$el);
 3038+ }
 3039+});
 3040+
 3041+})(jQuery);
 3042+/*
 3043+ * jQuery UI Tabs 1.7.2
 3044+ *
 3045+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 3046+ * Dual licensed under the MIT (MIT-LICENSE.txt)
 3047+ * and GPL (GPL-LICENSE.txt) licenses.
 3048+ *
 3049+ * http://docs.jquery.com/UI/Tabs
 3050+ *
 3051+ * Depends:
 3052+ * ui.core.js
 3053+ */
 3054+(function($) {
 3055+
 3056+$.widget("ui.tabs", {
 3057+
 3058+ _init: function() {
 3059+ if (this.options.deselectable !== undefined) {
 3060+ this.options.collapsible = this.options.deselectable;
 3061+ }
 3062+ this._tabify(true);
 3063+ },
 3064+
 3065+ _setData: function(key, value) {
 3066+ if (key == 'selected') {
 3067+ if (this.options.collapsible && value == this.options.selected) {
 3068+ return;
 3069+ }
 3070+ this.select(value);
 3071+ }
 3072+ else {
 3073+ this.options[key] = value;
 3074+ if (key == 'deselectable') {
 3075+ this.options.collapsible = value;
 3076+ }
 3077+ this._tabify();
 3078+ }
 3079+ },
 3080+
 3081+ _tabId: function(a) {
 3082+ return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') ||
 3083+ this.options.idPrefix + $.data(a);
 3084+ },
 3085+
 3086+ _sanitizeSelector: function(hash) {
 3087+ return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":"
 3088+ },
 3089+
 3090+ _cookie: function() {
 3091+ var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + $.data(this.list[0]));
 3092+ return $.cookie.apply(null, [cookie].concat($.makeArray(arguments)));
 3093+ },
 3094+
 3095+ _ui: function(tab, panel) {
 3096+ return {
 3097+ tab: tab,
 3098+ panel: panel,
 3099+ index: this.anchors.index(tab)
 3100+ };
 3101+ },
 3102+
 3103+ _cleanup: function() {
 3104+ // restore all former loading tabs labels
 3105+ this.lis.filter('.ui-state-processing').removeClass('ui-state-processing')
 3106+ .find('span:data(label.tabs)')
 3107+ .each(function() {
 3108+ var el = $(this);
 3109+ el.html(el.data('label.tabs')).removeData('label.tabs');
 3110+ });
 3111+ },
 3112+
 3113+ _tabify: function(init) {
 3114+
 3115+ this.list = this.element.children('ul:first');
 3116+ this.lis = $('li:has(a[href])', this.list);
 3117+ this.anchors = this.lis.map(function() { return $('a', this)[0]; });
 3118+ this.panels = $([]);
 3119+
 3120+ var self = this, o = this.options;
 3121+
 3122+ var fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
 3123+ this.anchors.each(function(i, a) {
 3124+ var href = $(a).attr('href');
 3125+
 3126+ // For dynamically created HTML that contains a hash as href IE < 8 expands
 3127+ // such href to the full page url with hash and then misinterprets tab as ajax.
 3128+ // Same consideration applies for an added tab with a fragment identifier
 3129+ // since a[href=#fragment-identifier] does unexpectedly not match.
 3130+ // Thus normalize href attribute...
 3131+ var hrefBase = href.split('#')[0], baseEl;
 3132+ if (hrefBase && (hrefBase === location.toString().split('#')[0] ||
 3133+ (baseEl = $('base')[0]) && hrefBase === baseEl.href)) {
 3134+ href = a.hash;
 3135+ a.href = href;
 3136+ }
 3137+
 3138+ // inline tab
 3139+ if (fragmentId.test(href)) {
 3140+ self.panels = self.panels.add(self._sanitizeSelector(href));
 3141+ }
 3142+
 3143+ // remote tab
 3144+ else if (href != '#') { // prevent loading the page itself if href is just "#"
 3145+ $.data(a, 'href.tabs', href); // required for restore on destroy
 3146+
 3147+ // TODO until #3808 is fixed strip fragment identifier from url
 3148+ // (IE fails to load from such url)
 3149+ $.data(a, 'load.tabs', href.replace(/#.*$/, '')); // mutable data
 3150+
 3151+ var id = self._tabId(a);
 3152+ a.href = '#' + id;
 3153+ var $panel = $('#' + id);
 3154+ if (!$panel.length) {
 3155+ $panel = $(o.panelTemplate).attr('id', id).addClass('ui-tabs-panel ui-widget-content ui-corner-bottom')
 3156+ .insertAfter(self.panels[i - 1] || self.list);
 3157+ $panel.data('destroy.tabs', true);
 3158+ }
 3159+ self.panels = self.panels.add($panel);
 3160+ }
 3161+
 3162+ // invalid tab href
 3163+ else {
 3164+ o.disabled.push(i);
 3165+ }
 3166+ });
 3167+
 3168+ // initialization from scratch
 3169+ if (init) {
 3170+
 3171+ // attach necessary classes for styling
 3172+ this.element.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all');
 3173+ this.list.addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');
 3174+ this.lis.addClass('ui-state-default ui-corner-top');
 3175+ this.panels.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom');
 3176+
 3177+ // Selected tab
 3178+ // use "selected" option or try to retrieve:
 3179+ // 1. from fragment identifier in url
 3180+ // 2. from cookie
 3181+ // 3. from selected class attribute on <li>
 3182+ if (o.selected === undefined) {
 3183+ if (location.hash) {
 3184+ this.anchors.each(function(i, a) {
 3185+ if (a.hash == location.hash) {
 3186+ o.selected = i;
 3187+ return false; // break
 3188+ }
 3189+ });
 3190+ }
 3191+ if (typeof o.selected != 'number' && o.cookie) {
 3192+ o.selected = parseInt(self._cookie(), 10);
 3193+ }
 3194+ if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) {
 3195+ o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));
 3196+ }
 3197+ o.selected = o.selected || 0;
 3198+ }
 3199+ else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release
 3200+ o.selected = -1;
 3201+ }
 3202+
 3203+ // sanity check - default to first tab...
 3204+ o.selected = ((o.selected >= 0 && this.anchors[o.selected]) || o.selected < 0) ? o.selected : 0;
 3205+
 3206+ // Take disabling tabs via class attribute from HTML
 3207+ // into account and update option properly.
 3208+ // A selected tab cannot become disabled.
 3209+ o.disabled = $.unique(o.disabled.concat(
 3210+ $.map(this.lis.filter('.ui-state-disabled'),
 3211+ function(n, i) { return self.lis.index(n); } )
 3212+ )).sort();
 3213+
 3214+ if ($.inArray(o.selected, o.disabled) != -1) {
 3215+ o.disabled.splice($.inArray(o.selected, o.disabled), 1);
 3216+ }
 3217+
 3218+ // highlight selected tab
 3219+ this.panels.addClass('ui-tabs-hide');
 3220+ this.lis.removeClass('ui-tabs-selected ui-state-active');
 3221+ if (o.selected >= 0 && this.anchors.length) { // check for length avoids error when initializing empty list
 3222+ this.panels.eq(o.selected).removeClass('ui-tabs-hide');
 3223+ this.lis.eq(o.selected).addClass('ui-tabs-selected ui-state-active');
 3224+
 3225+ // seems to be expected behavior that the show callback is fired
 3226+ self.element.queue("tabs", function() {
 3227+ self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected]));
 3228+ });
 3229+
 3230+ this.load(o.selected);
 3231+ }
 3232+
 3233+ // clean up to avoid memory leaks in certain versions of IE 6
 3234+ $(window).bind('unload', function() {
 3235+ self.lis.add(self.anchors).unbind('.tabs');
 3236+ self.lis = self.anchors = self.panels = null;
 3237+ });
 3238+
 3239+ }
 3240+ // update selected after add/remove
 3241+ else {
 3242+ o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));
 3243+ }
 3244+
 3245+ // update collapsible
 3246+ this.element[o.collapsible ? 'addClass' : 'removeClass']('ui-tabs-collapsible');
 3247+
 3248+ // set or update cookie after init and add/remove respectively
 3249+ if (o.cookie) {
 3250+ this._cookie(o.selected, o.cookie);
 3251+ }
 3252+
 3253+ // disable tabs
 3254+ for (var i = 0, li; (li = this.lis[i]); i++) {
 3255+ $(li)[$.inArray(i, o.disabled) != -1 &&
 3256+ !$(li).hasClass('ui-tabs-selected') ? 'addClass' : 'removeClass']('ui-state-disabled');
 3257+ }
 3258+
 3259+ // reset cache if switching from cached to not cached
 3260+ if (o.cache === false) {
 3261+ this.anchors.removeData('cache.tabs');
 3262+ }
 3263+
 3264+ // remove all handlers before, tabify may run on existing tabs after add or option change
 3265+ this.lis.add(this.anchors).unbind('.tabs');
 3266+
 3267+ if (o.event != 'mouseover') {
 3268+ var addState = function(state, el) {
 3269+ if (el.is(':not(.ui-state-disabled)')) {
 3270+ el.addClass('ui-state-' + state);
 3271+ }
 3272+ };
 3273+ var removeState = function(state, el) {
 3274+ el.removeClass('ui-state-' + state);
 3275+ };
 3276+ this.lis.bind('mouseover.tabs', function() {
 3277+ addState('hover', $(this));
 3278+ });
 3279+ this.lis.bind('mouseout.tabs', function() {
 3280+ removeState('hover', $(this));
 3281+ });
 3282+ this.anchors.bind('focus.tabs', function() {
 3283+ addState('focus', $(this).closest('li'));
 3284+ });
 3285+ this.anchors.bind('blur.tabs', function() {
 3286+ removeState('focus', $(this).closest('li'));
 3287+ });
 3288+ }
 3289+
 3290+ // set up animations
 3291+ var hideFx, showFx;
 3292+ if (o.fx) {
 3293+ if ($.isArray(o.fx)) {
 3294+ hideFx = o.fx[0];
 3295+ showFx = o.fx[1];
 3296+ }
 3297+ else {
 3298+ hideFx = showFx = o.fx;
 3299+ }
 3300+ }
 3301+
 3302+ // Reset certain styles left over from animation
 3303+ // and prevent IE's ClearType bug...
 3304+ function resetStyle($el, fx) {
 3305+ $el.css({ display: '' });
 3306+ if ($.browser.msie && fx.opacity) {
 3307+ $el[0].style.removeAttribute('filter');
 3308+ }
 3309+ }
 3310+
 3311+ // Show a tab...
 3312+ var showTab = showFx ?
 3313+ function(clicked, $show) {
 3314+ $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active');
 3315+ $show.hide().removeClass('ui-tabs-hide') // avoid flicker that way
 3316+ .animate(showFx, showFx.duration || 'normal', function() {
 3317+ resetStyle($show, showFx);
 3318+ self._trigger('show', null, self._ui(clicked, $show[0]));
 3319+ });
 3320+ } :
 3321+ function(clicked, $show) {
 3322+ $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active');
 3323+ $show.removeClass('ui-tabs-hide');
 3324+ self._trigger('show', null, self._ui(clicked, $show[0]));
 3325+ };
 3326+
 3327+ // Hide a tab, $show is optional...
 3328+ var hideTab = hideFx ?
 3329+ function(clicked, $hide) {
 3330+ $hide.animate(hideFx, hideFx.duration || 'normal', function() {
 3331+ self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default');
 3332+ $hide.addClass('ui-tabs-hide');
 3333+ resetStyle($hide, hideFx);
 3334+ self.element.dequeue("tabs");
 3335+ });
 3336+ } :
 3337+ function(clicked, $hide, $show) {
 3338+ self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default');
 3339+ $hide.addClass('ui-tabs-hide');
 3340+ self.element.dequeue("tabs");
 3341+ };
 3342+
 3343+ // attach tab event handler, unbind to avoid duplicates from former tabifying...
 3344+ this.anchors.bind(o.event + '.tabs', function() {
 3345+ var el = this, $li = $(this).closest('li'), $hide = self.panels.filter(':not(.ui-tabs-hide)'),
 3346+ $show = $(self._sanitizeSelector(this.hash));
 3347+
 3348+ // If tab is already selected and not collapsible or tab disabled or
 3349+ // or is already loading or click callback returns false stop here.
 3350+ // Check if click handler returns false last so that it is not executed
 3351+ // for a disabled or loading tab!
 3352+ if (($li.hasClass('ui-tabs-selected') && !o.collapsible) ||
 3353+ $li.hasClass('ui-state-disabled') ||
 3354+ $li.hasClass('ui-state-processing') ||
 3355+ self._trigger('select', null, self._ui(this, $show[0])) === false) {
 3356+ this.blur();
 3357+ return false;
 3358+ }
 3359+
 3360+ o.selected = self.anchors.index(this);
 3361+
 3362+ self.abort();
 3363+
 3364+ // if tab may be closed
 3365+ if (o.collapsible) {
 3366+ if ($li.hasClass('ui-tabs-selected')) {
 3367+ o.selected = -1;
 3368+
 3369+ if (o.cookie) {
 3370+ self._cookie(o.selected, o.cookie);
 3371+ }
 3372+
 3373+ self.element.queue("tabs", function() {
 3374+ hideTab(el, $hide);
 3375+ }).dequeue("tabs");
 3376+
 3377+ this.blur();
 3378+ return false;
 3379+ }
 3380+ else if (!$hide.length) {
 3381+ if (o.cookie) {
 3382+ self._cookie(o.selected, o.cookie);
 3383+ }
 3384+
 3385+ self.element.queue("tabs", function() {
 3386+ showTab(el, $show);
 3387+ });
 3388+
 3389+ self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
 3390+
 3391+ this.blur();
 3392+ return false;
 3393+ }
 3394+ }
 3395+
 3396+ if (o.cookie) {
 3397+ self._cookie(o.selected, o.cookie);
 3398+ }
 3399+
 3400+ // show new tab
 3401+ if ($show.length) {
 3402+ if ($hide.length) {
 3403+ self.element.queue("tabs", function() {
 3404+ hideTab(el, $hide);
 3405+ });
 3406+ }
 3407+ self.element.queue("tabs", function() {
 3408+ showTab(el, $show);
 3409+ });
 3410+
 3411+ self.load(self.anchors.index(this));
 3412+ }
 3413+ else {
 3414+ throw 'jQuery UI Tabs: Mismatching fragment identifier.';
 3415+ }
 3416+
 3417+ // Prevent IE from keeping other link focussed when using the back button
 3418+ // and remove dotted border from clicked link. This is controlled via CSS
 3419+ // in modern browsers; blur() removes focus from address bar in Firefox
 3420+ // which can become a usability and annoying problem with tabs('rotate').
 3421+ if ($.browser.msie) {
 3422+ this.blur();
 3423+ }
 3424+
 3425+ });
 3426+
 3427+ // disable click in any case
 3428+ this.anchors.bind('click.tabs', function(){return false;});
 3429+
 3430+ },
 3431+
 3432+ destroy: function() {
 3433+ var o = this.options;
 3434+
 3435+ this.abort();
 3436+
 3437+ this.element.unbind('.tabs')
 3438+ .removeClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible')
 3439+ .removeData('tabs');
 3440+
 3441+ this.list.removeClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');
 3442+
 3443+ this.anchors.each(function() {
 3444+ var href = $.data(this, 'href.tabs');
 3445+ if (href) {
 3446+ this.href = href;
 3447+ }
 3448+ var $this = $(this).unbind('.tabs');
 3449+ $.each(['href', 'load', 'cache'], function(i, prefix) {
 3450+ $this.removeData(prefix + '.tabs');
 3451+ });
 3452+ });
 3453+
 3454+ this.lis.unbind('.tabs').add(this.panels).each(function() {
 3455+ if ($.data(this, 'destroy.tabs')) {
 3456+ $(this).remove();
 3457+ }
 3458+ else {
 3459+ $(this).removeClass([
 3460+ 'ui-state-default',
 3461+ 'ui-corner-top',
 3462+ 'ui-tabs-selected',
 3463+ 'ui-state-active',
 3464+ 'ui-state-hover',
 3465+ 'ui-state-focus',
 3466+ 'ui-state-disabled',
 3467+ 'ui-tabs-panel',
 3468+ 'ui-widget-content',
 3469+ 'ui-corner-bottom',
 3470+ 'ui-tabs-hide'
 3471+ ].join(' '));
 3472+ }
 3473+ });
 3474+
 3475+ if (o.cookie) {
 3476+ this._cookie(null, o.cookie);
 3477+ }
 3478+ },
 3479+
 3480+ add: function(url, label, index) {
 3481+ if (index === undefined) {
 3482+ index = this.anchors.length; // append by default
 3483+ }
 3484+
 3485+ var self = this, o = this.options,
 3486+ $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label)),
 3487+ id = !url.indexOf('#') ? url.replace('#', '') : this._tabId($('a', $li)[0]);
 3488+
 3489+ $li.addClass('ui-state-default ui-corner-top').data('destroy.tabs', true);
 3490+
 3491+ // try to find an existing element before creating a new one
 3492+ var $panel = $('#' + id);
 3493+ if (!$panel.length) {
 3494+ $panel = $(o.panelTemplate).attr('id', id).data('destroy.tabs', true);
 3495+ }
 3496+ $panel.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide');
 3497+
 3498+ if (index >= this.lis.length) {
 3499+ $li.appendTo(this.list);
 3500+ $panel.appendTo(this.list[0].parentNode);
 3501+ }
 3502+ else {
 3503+ $li.insertBefore(this.lis[index]);
 3504+ $panel.insertBefore(this.panels[index]);
 3505+ }
 3506+
 3507+ o.disabled = $.map(o.disabled,
 3508+ function(n, i) { return n >= index ? ++n : n; });
 3509+
 3510+ this._tabify();
 3511+
 3512+ if (this.anchors.length == 1) { // after tabify
 3513+ $li.addClass('ui-tabs-selected ui-state-active');
 3514+ $panel.removeClass('ui-tabs-hide');
 3515+ this.element.queue("tabs", function() {
 3516+ self._trigger('show', null, self._ui(self.anchors[0], self.panels[0]));
 3517+ });
 3518+
 3519+ this.load(0);
 3520+ }
 3521+
 3522+ // callback
 3523+ this._trigger('add', null, this._ui(this.anchors[index], this.panels[index]));
 3524+ },
 3525+
 3526+ remove: function(index) {
 3527+ var o = this.options, $li = this.lis.eq(index).remove(),
 3528+ $panel = this.panels.eq(index).remove();
 3529+
 3530+ // If selected tab was removed focus tab to the right or
 3531+ // in case the last tab was removed the tab to the left.
 3532+ if ($li.hasClass('ui-tabs-selected') && this.anchors.length > 1) {
 3533+ this.select(index + (index + 1 < this.anchors.length ? 1 : -1));
 3534+ }
 3535+
 3536+ o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
 3537+ function(n, i) { return n >= index ? --n : n; });
 3538+
 3539+ this._tabify();
 3540+
 3541+ // callback
 3542+ this._trigger('remove', null, this._ui($li.find('a')[0], $panel[0]));
 3543+ },
 3544+
 3545+ enable: function(index) {
 3546+ var o = this.options;
 3547+ if ($.inArray(index, o.disabled) == -1) {
 3548+ return;
 3549+ }
 3550+
 3551+ this.lis.eq(index).removeClass('ui-state-disabled');
 3552+ o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });
 3553+
 3554+ // callback
 3555+ this._trigger('enable', null, this._ui(this.anchors[index], this.panels[index]));
 3556+ },
 3557+
 3558+ disable: function(index) {
 3559+ var self = this, o = this.options;
 3560+ if (index != o.selected) { // cannot disable already selected tab
 3561+ this.lis.eq(index).addClass('ui-state-disabled');
 3562+
 3563+ o.disabled.push(index);
 3564+ o.disabled.sort();
 3565+
 3566+ // callback
 3567+ this._trigger('disable', null, this._ui(this.anchors[index], this.panels[index]));
 3568+ }
 3569+ },
 3570+
 3571+ select: function(index) {
 3572+ if (typeof index == 'string') {
 3573+ index = this.anchors.index(this.anchors.filter('[href$=' + index + ']'));
 3574+ }
 3575+ else if (index === null) { // usage of null is deprecated, TODO remove in next release
 3576+ index = -1;
 3577+ }
 3578+ if (index == -1 && this.options.collapsible) {
 3579+ index = this.options.selected;
 3580+ }
 3581+
 3582+ this.anchors.eq(index).trigger(this.options.event + '.tabs');
 3583+ },
 3584+
 3585+ load: function(index) {
 3586+ var self = this, o = this.options, a = this.anchors.eq(index)[0], url = $.data(a, 'load.tabs');
 3587+
 3588+ this.abort();
 3589+
 3590+ // not remote or from cache
 3591+ if (!url || this.element.queue("tabs").length !== 0 && $.data(a, 'cache.tabs')) {
 3592+ this.element.dequeue("tabs");
 3593+ return;
 3594+ }
 3595+
 3596+ // load remote from here on
 3597+ this.lis.eq(index).addClass('ui-state-processing');
 3598+
 3599+ if (o.spinner) {
 3600+ var span = $('span', a);
 3601+ span.data('label.tabs', span.html()).html(o.spinner);
 3602+ }
 3603+
 3604+ this.xhr = $.ajax($.extend({}, o.ajaxOptions, {
 3605+ url: url,
 3606+ success: function(r, s) {
 3607+ $(self._sanitizeSelector(a.hash)).html(r);
 3608+
 3609+ // take care of tab labels
 3610+ self._cleanup();
 3611+
 3612+ if (o.cache) {
 3613+ $.data(a, 'cache.tabs', true); // if loaded once do not load them again
 3614+ }
 3615+
 3616+ // callbacks
 3617+ self._trigger('load', null, self._ui(self.anchors[index], self.panels[index]));
 3618+ try {
 3619+ o.ajaxOptions.success(r, s);
 3620+ }
 3621+ catch (e) {}
 3622+
 3623+ // last, so that load event is fired before show...
 3624+ self.element.dequeue("tabs");
 3625+ }
 3626+ }));
 3627+ },
 3628+
 3629+ abort: function() {
 3630+ // stop possibly running animations
 3631+ this.element.queue([]);
 3632+ this.panels.stop(false, true);
 3633+
 3634+ // terminate pending requests from other tabs
 3635+ if (this.xhr) {
 3636+ this.xhr.abort();
 3637+ delete this.xhr;
 3638+ }
 3639+
 3640+ // take care of tab labels
 3641+ this._cleanup();
 3642+
 3643+ },
 3644+
 3645+ url: function(index, url) {
 3646+ this.anchors.eq(index).removeData('cache.tabs').data('load.tabs', url);
 3647+ },
 3648+
 3649+ length: function() {
 3650+ return this.anchors.length;
 3651+ }
 3652+
 3653+});
 3654+
 3655+$.extend($.ui.tabs, {
 3656+ version: '1.7.2',
 3657+ getter: 'length',
 3658+ defaults: {
 3659+ ajaxOptions: null,
 3660+ cache: false,
 3661+ cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
 3662+ collapsible: false,
 3663+ disabled: [],
 3664+ event: 'click',
 3665+ fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
 3666+ idPrefix: 'ui-tabs-',
 3667+ panelTemplate: '<div></div>',
 3668+ spinner: '<em>Loading&#8230;</em>',
 3669+ tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>'
 3670+ }
 3671+});
 3672+
 3673+/*
 3674+ * Tabs Extensions
 3675+ */
 3676+
 3677+/*
 3678+ * Rotate
 3679+ */
 3680+$.extend($.ui.tabs.prototype, {
 3681+ rotation: null,
 3682+ rotate: function(ms, continuing) {
 3683+
 3684+ var self = this, o = this.options;
 3685+
 3686+ var rotate = self._rotate || (self._rotate = function(e) {
 3687+ clearTimeout(self.rotation);
 3688+ self.rotation = setTimeout(function() {
 3689+ var t = o.selected;
 3690+ self.select( ++t < self.anchors.length ? t : 0 );
 3691+ }, ms);
 3692+
 3693+ if (e) {
 3694+ e.stopPropagation();
 3695+ }
 3696+ });
 3697+
 3698+ var stop = self._unrotate || (self._unrotate = !continuing ?
 3699+ function(e) {
 3700+ if (e.clientX) { // in case of a true click
 3701+ self.rotate(null);
 3702+ }
 3703+ } :
 3704+ function(e) {
 3705+ t = o.selected;
 3706+ rotate();
 3707+ });
 3708+
 3709+ // start rotation
 3710+ if (ms) {
 3711+ this.element.bind('tabsshow', rotate);
 3712+ this.anchors.bind(o.event + '.tabs', stop);
 3713+ rotate();
 3714+ }
 3715+ // stop rotation
 3716+ else {
 3717+ clearTimeout(self.rotation);
 3718+ this.element.unbind('tabsshow', rotate);
 3719+ this.anchors.unbind(o.event + '.tabs', stop);
 3720+ delete this._rotate;
 3721+ delete this._unrotate;
 3722+ }
 3723+ }
 3724+});
 3725+
 3726+})(jQuery);
 3727+/* JavaScript for MediaWIki JS2 */
 3728+
 3729+/**
 3730+ * This is designed to be directly compatible with (and is essentially taken
 3731+ * directly from) the mv_embed code for bringing internationalized messages into
 3732+ * the JavaScript space. As such, if we get to the point of merging that stuff
 3733+ * into the main branch this code will be uneeded and probably cause issues.
 3734+ */
 3735+// Creates global message object if not already in existence
 3736+if ( !gMsg ) var gMsg = {};
 3737+if( ! mw ) var mw = { };
 3738+
 3739+/**
 3740+ * Caches a list of messages for later retrieval
 3741+ * @param {Object} msgSet Hash of key:value pairs of messages to cache
 3742+ */
 3743+if( ! mw.addMessages ){
 3744+ mw.addMessages = function( msgSet ){
 3745+ for ( var i in msgSet ){
 3746+ gMsg[ i ] = msgSet[i];
 3747+ }
 3748+ }
 3749+}
 3750+
 3751+/**
 3752+ * Retieves a message from the global message cache, performing on-the-fly
 3753+ * replacements using MediaWiki message syntax ($1, $2, etc.)
 3754+ * @param {String} key Name of message as it is in MediaWiki
 3755+ * @param {Array} args Array of replacement arguments
 3756+ */
 3757+function gM( key, args ) {
 3758+ var ms = '';
 3759+ if ( key in gMsg ) {
 3760+ ms = gMsg[ key ];
 3761+ if ( typeof args == 'object' || typeof args == 'array' ) {
 3762+ for ( var v in args ){
 3763+ var rep = '\$'+ ( parseInt(v) + 1 );
 3764+ ms = ms.replace( rep, args[v]);
 3765+ }
 3766+ } else if ( typeof args =='string' || typeof args =='number' ) {
 3767+ ms = ms.replace( /\$1/, args );
 3768+ }
 3769+ return ms;
 3770+ } else {
 3771+ return '[' + key + ']';
 3772+ }
 3773+}
 3774+/**
 3775+ * Mimics the no-conflict method used by the js2 stuff
 3776+ */
 3777+$j = jQuery.noConflict();
 3778+/**
 3779+ * Provides js2 compatible onload hook
 3780+ * @param func Function to call when ready
 3781+ */
 3782+mw.addOnloadHook = function( func ) {
 3783+ $j(document).ready( func );
 3784+}
Property changes on: trunk/extensions/MultilingualLiquidThreads/jquery/plugins.js
___________________________________________________________________
Name: svn:eol-style
37853785 + native
Property changes on: trunk/extensions/MultilingualLiquidThreads/langrid/TranslatedThread.php
___________________________________________________________________
Name: svn:eol-style
37863786 + native
Index: trunk/extensions/MultilingualLiquidThreads/langrid/SourceView.php
@@ -1,53 +1,53 @@
2 -<?php
3 -class SourceView {
4 - public $thread;
5 - public $langridAccessObject;
6 - public $request;
7 -
8 - function __construct( $thread, $request ) {
9 - $this->thread = $thread;
10 - $this->langridAccessObject = new LanguageGridAccessObject();
11 - $this->request = $request;
12 - }
13 -
14 - function methodAppliesToThread( $method ) {
15 - return $this->request->getVal( 'lqt_method' ) == $method &&
16 - $this->request->getVal( 'lqt_operand' ) == $this->thread->id();
17 - }
18 -
19 - function getMethod() {
20 - return $this->request->getVal( 'lqt_method' );
21 - }
22 -
23 - function getLang() {
24 - return $this->request->getVal( 'setlang' );
25 - }
26 -
27 - function showSource( $thread ) {
28 -
29 - $sourceBody = MultilangThreadController::getSourceSentence( $thread );
30 -
31 - $cancelUrl = LqtView::talkpageUrl( $thread->title(), null, $thread,
32 - true , $this->request );
33 - $languageCode = $this->getLang();
34 - if( !$languageCode ) {
35 - $languageCode = $this->langridAccessObject->getSourceLanguage( $thread->id() );
36 - }
37 - $hideMsg = wfMsg( 'multilang_lqt_hide_original',
38 - LanguageGridAccessObject::convertLanguageCodeIntoLanguageName( $languageCode ) );
39 - if( is_null( $hideMsg ) ) {
40 - $hideMsg = 'Hide';
41 - }
42 -
43 - $sourceBody .= Xml::tags( 'a',
44 - array( 'href' => $cancelUrl, 'id' => 'mw-source-cancel' ),
45 - $hideMsg );
46 -
47 - $tag = Xml::tags( 'div', array( 'class' => 'source-content' ),
48 - $sourceBody );
49 -
50 - return $tag;
51 - }
52 -
53 -}
54 -?>
 2+<?php
 3+class SourceView {
 4+ public $thread;
 5+ public $langridAccessObject;
 6+ public $request;
 7+
 8+ function __construct( $thread, $request ) {
 9+ $this->thread = $thread;
 10+ $this->langridAccessObject = new LanguageGridAccessObject();
 11+ $this->request = $request;
 12+ }
 13+
 14+ function methodAppliesToThread( $method ) {
 15+ return $this->request->getVal( 'lqt_method' ) == $method &&
 16+ $this->request->getVal( 'lqt_operand' ) == $this->thread->id();
 17+ }
 18+
 19+ function getMethod() {
 20+ return $this->request->getVal( 'lqt_method' );
 21+ }
 22+
 23+ function getLang() {
 24+ return $this->request->getVal( 'setlang' );
 25+ }
 26+
 27+ function showSource( $thread ) {
 28+
 29+ $sourceBody = MultilangThreadController::getSourceSentence( $thread );
 30+
 31+ $cancelUrl = LqtView::talkpageUrl( $thread->title(), null, $thread,
 32+ true , $this->request );
 33+ $languageCode = $this->getLang();
 34+ if( !$languageCode ) {
 35+ $languageCode = $this->langridAccessObject->getSourceLanguage( $thread->id() );
 36+ }
 37+ $hideMsg = wfMsg( 'multilang_lqt_hide_original',
 38+ LanguageGridAccessObject::convertLanguageCodeIntoLanguageName( $languageCode ) );
 39+ if( is_null( $hideMsg ) ) {
 40+ $hideMsg = 'Hide';
 41+ }
 42+
 43+ $sourceBody .= Xml::tags( 'a',
 44+ array( 'href' => $cancelUrl, 'id' => 'mw-source-cancel' ),
 45+ $hideMsg );
 46+
 47+ $tag = Xml::tags( 'div', array( 'class' => 'source-content' ),
 48+ $sourceBody );
 49+
 50+ return $tag;
 51+ }
 52+
 53+}
 54+?>
Property changes on: trunk/extensions/MultilingualLiquidThreads/langrid/SourceView.php
___________________________________________________________________
Name: svn:eol-style
5555 + native
Index: trunk/extensions/MultilingualLiquidThreads/langrid/MultilangLqt.php
@@ -1,36 +1,36 @@
2 -<?php
3 -$dir = dirname( __FILE__ ) . '/';
4 -
5 -$wgExtensionMessagesFiles['LiquidThreads'] = $dir . 'MultilangLqt.i18n.php'; // Added for Multilang Extension
6 -
7 -// Classes
8 -$wgAutoloadClasses['HTMLTranslator'] = $dir . 'HTMLTranslator.php';
9 -$wgAutoloadClasses['LanguageGridAccessObject'] = $dir . 'LanguageGridAccessObject.php';
10 -$wgAutoloadClasses['MetaTranslator'] = $dir . 'MetaTranslator.php';
11 -$wgAutoloadClasses['MultilangLqtHooks'] = $dir . 'MultilangLqtHooks.php';
12 -$wgAutoloadClasses['MultilangThreadController'] = $dir . 'MultilangThreadController.php';
13 -$wgAutoloadClasses['SourceView'] = $dir . 'SourceView.php';
14 -$wgAutoloadClasses['ThreadLanguage'] = $dir . 'ThreadLanguage.php';
15 -$wgAutoloadClasses['TranslatedSubject'] = $dir . 'TranslatedSubject.php';
16 -$wgAutoloadClasses['TranslatedThread'] = $dir . 'TranslatedThread.php';
17 -
18 -// Language Grid
19 -$wgAutoloadClasses['LangridAccessClient'] = $dir . '../../LanguageGrid/api/class/client/LangridAccessClient.class.php';
20 -
21 -// hook
22 -$wgHooks['LiquidThreadsSaveReply'][] = 'MultilangLqtHooks::saveReply';
23 -$wgHooks['LiquidThreadsThreadCommands'][] = 'MultilangLqtHooks::onThreadCommands';
24 -$wgHooks['LiquidThreadsThreadPermalinkView'][] = 'MultilangLqtHooks::onThreadPermalinkView';
25 -$wgHooks['LiquidThreadsEditingFormContent'][] = 'MultilangLqtHooks::translateRoot';
26 -$wgHooks['LiquidThreadsThreadSignature'][] = 'MultilangLqtHooks::onThreadSignature';
27 -$wgHooks['LiquidThreadsShowThreadHeading'][] = 'MultilangLqtHooks::translateSubject';
28 -$wgHooks['LiquidThreadsGetTOC'][] = 'MultilangLqtHooks::translateSubjectforTOC';
29 -$wgHooks['LiquidThreadsShowPostContent'][] = 'MultilangLqtHooks::translateBody';
30 -$wgHooks['LiquidThreadsThreadMajorCommands'][] = 'MultilangLqtHooks::onThreadMajorCommands';
31 -$wgHooks['LiquidThreadsShowPostThreadBody'][] = 'MultilangLqtHooks::onShowPostThreadBody';
32 -$wgHooks['LiquidThreadsDoInlineEditForm'][] = 'MultilangLqtHooks::onDoInlineEditForm';
33 -$wgHooks['LiquidThreadsAfterNewPostMetadataUpdates'][] = 'MultilangLqtHooks::saveSourceLang';
34 -$wgHooks['LiquidThreadsAfterReplyMetadataUpdates'][] = 'MultilangLqtHooks::saveSourceLang';
35 -$wgHooks['LiquidThreadsEndOfShowNewThreadForm'][] = 'MultilangLqtHooks::showLanguageSelector';
36 -$wgHooks['LiquidThreadsShowReplyForm'][] = 'MultilangLqtHooks::showLanguageSelector';
37 -
 2+<?php
 3+$dir = dirname( __FILE__ ) . '/';
 4+
 5+$wgExtensionMessagesFiles['LiquidThreads'] = $dir . 'MultilangLqt.i18n.php'; // Added for Multilang Extension
 6+
 7+// Classes
 8+$wgAutoloadClasses['HTMLTranslator'] = $dir . 'HTMLTranslator.php';
 9+$wgAutoloadClasses['LanguageGridAccessObject'] = $dir . 'LanguageGridAccessObject.php';
 10+$wgAutoloadClasses['MetaTranslator'] = $dir . 'MetaTranslator.php';
 11+$wgAutoloadClasses['MultilangLqtHooks'] = $dir . 'MultilangLqtHooks.php';
 12+$wgAutoloadClasses['MultilangThreadController'] = $dir . 'MultilangThreadController.php';
 13+$wgAutoloadClasses['SourceView'] = $dir . 'SourceView.php';
 14+$wgAutoloadClasses['ThreadLanguage'] = $dir . 'ThreadLanguage.php';
 15+$wgAutoloadClasses['TranslatedSubject'] = $dir . 'TranslatedSubject.php';
 16+$wgAutoloadClasses['TranslatedThread'] = $dir . 'TranslatedThread.php';
 17+
 18+// Language Grid
 19+$wgAutoloadClasses['LangridAccessClient'] = $dir . '../../LanguageGrid/api/class/client/LangridAccessClient.class.php';
 20+
 21+// hook
 22+$wgHooks['LiquidThreadsSaveReply'][] = 'MultilangLqtHooks::saveReply';
 23+$wgHooks['LiquidThreadsThreadCommands'][] = 'MultilangLqtHooks::onThreadCommands';
 24+$wgHooks['LiquidThreadsThreadPermalinkView'][] = 'MultilangLqtHooks::onThreadPermalinkView';
 25+$wgHooks['LiquidThreadsEditingFormContent'][] = 'MultilangLqtHooks::translateRoot';
 26+$wgHooks['LiquidThreadsThreadSignature'][] = 'MultilangLqtHooks::onThreadSignature';
 27+$wgHooks['LiquidThreadsShowThreadHeading'][] = 'MultilangLqtHooks::translateSubject';
 28+$wgHooks['LiquidThreadsGetTOC'][] = 'MultilangLqtHooks::translateSubjectforTOC';
 29+$wgHooks['LiquidThreadsShowPostContent'][] = 'MultilangLqtHooks::translateBody';
 30+$wgHooks['LiquidThreadsThreadMajorCommands'][] = 'MultilangLqtHooks::onThreadMajorCommands';
 31+$wgHooks['LiquidThreadsShowPostThreadBody'][] = 'MultilangLqtHooks::onShowPostThreadBody';
 32+$wgHooks['LiquidThreadsDoInlineEditForm'][] = 'MultilangLqtHooks::onDoInlineEditForm';
 33+$wgHooks['LiquidThreadsAfterNewPostMetadataUpdates'][] = 'MultilangLqtHooks::saveSourceLang';
 34+$wgHooks['LiquidThreadsAfterReplyMetadataUpdates'][] = 'MultilangLqtHooks::saveSourceLang';
 35+$wgHooks['LiquidThreadsEndOfShowNewThreadForm'][] = 'MultilangLqtHooks::showLanguageSelector';
 36+$wgHooks['LiquidThreadsShowReplyForm'][] = 'MultilangLqtHooks::showLanguageSelector';
 37+
Property changes on: trunk/extensions/MultilingualLiquidThreads/langrid/MultilangLqt.php
___________________________________________________________________
Name: svn:eol-style
3838 + native
Index: trunk/extensions/MultilingualLiquidThreads/langrid/HTMLTranslator.php
@@ -1,46 +1,46 @@
2 -<?php
3 -
4 -
5 -
6 -class HTMLTranslator {
7 - /**
8 - * Constructor
9 - * @param $sourceLang SourceLanguage
10 - */
11 - public function __construct() {
12 - }
13 -
14 - public function HTMLTranslate($func, $param, $order, $sourceLang, $targetLang, $source, $resultFunc, $statusFunc) {
15 - $unTag=$this->removeTags($source);
16 - $param[$order[2]]=$unTag;
17 -
18 - $result=$this->doTranslate($func, $param, $sourceLang, $targetLang, $unTag, $resultFunc, $statusFunc);
19 -
20 - return $result;
21 - }
22 -
23 - private function removeTags($source) {
24 - return preg_replace('/<[^<]+?>/', '', $source);
25 - }
26 -
27 - /**
28 - * Translate body
29 - */
30 - private function doTranslate($func, $param, $sourceLang, $targetLang, $source, $resultFunc, $statusFunc) {
31 - if($resultFunc==null) {
32 - return call_user_func_array($func, $param);
33 - }else {
34 - $response=call_user_func_array($func, $param);
35 -
36 - $status=call_user_func_array($statusFunc, array($response));
37 - if($status == 'OK') {
38 - return call_user_func_array($resultFunc, array($response));
39 - }else {
40 - return null;
41 - }
42 - }
43 - }
44 -}
45 -
46 -?>
 2+<?php
 3+
 4+
 5+
 6+class HTMLTranslator {
 7+ /**
 8+ * Constructor
 9+ * @param $sourceLang SourceLanguage
 10+ */
 11+ public function __construct() {
 12+ }
 13+
 14+ public function HTMLTranslate($func, $param, $order, $sourceLang, $targetLang, $source, $resultFunc, $statusFunc) {
 15+ $unTag=$this->removeTags($source);
 16+ $param[$order[2]]=$unTag;
 17+
 18+ $result=$this->doTranslate($func, $param, $sourceLang, $targetLang, $unTag, $resultFunc, $statusFunc);
 19+
 20+ return $result;
 21+ }
 22+
 23+ private function removeTags($source) {
 24+ return preg_replace('/<[^<]+?>/', '', $source);
 25+ }
 26+
 27+ /**
 28+ * Translate body
 29+ */
 30+ private function doTranslate($func, $param, $sourceLang, $targetLang, $source, $resultFunc, $statusFunc) {
 31+ if($resultFunc==null) {
 32+ return call_user_func_array($func, $param);
 33+ }else {
 34+ $response=call_user_func_array($func, $param);
 35+
 36+ $status=call_user_func_array($statusFunc, array($response));
 37+ if($status == 'OK') {
 38+ return call_user_func_array($resultFunc, array($response));
 39+ }else {
 40+ return null;
 41+ }
 42+ }
 43+ }
 44+}
 45+
 46+?>
4747
\ No newline at end of file
Property changes on: trunk/extensions/MultilingualLiquidThreads/langrid/HTMLTranslator.php
___________________________________________________________________
Name: svn:eol-style
4848 + native
Index: trunk/extensions/MultilingualLiquidThreads/langrid/MetaTranslator.php
@@ -1,341 +1,341 @@
2 -<?php
3 -
4 -require_once('HTMLTranslator.php');
5 -
6 -class MetaTranslator {
7 - /* Translation parameters */
8 - private $sourceLang;
9 -
10 - /* in MetaTranslation process */
11 - private $noTranslations;
12 - private $tags_begin=array();
13 - private $tags_end=array();
14 -
15 - /* Constant */
16 - private $TAG_BEGIN="<notranslate>";
17 - private $TAG_END="</notranslate>";
18 - private $TAG_RELAXED='__________';
19 - private $LANG_TAG_BEGIN='[';
20 - private $LANG_TAG_END=']';
21 -
22 -
23 -
24 - /**
25 - * Constructor
26 - * @param $sourceLang SourceLanguage
27 - */
28 - public function __construct($sourceLang) {
29 - $this->setSourceLanguage($sourceLang);
30 - }
31 -
32 - /**
33 - *
34 - */
35 - public function metaTranslate($func, $param, $order, $meta=true, $attach=true, $resultFunc, $statusFunc) {
36 - $sourceLang=$param[$order[0]];
37 - $targetLang=$param[$order[1]];
38 - $source=$param[$order[2]];
39 -
40 -
41 - $encode=$this->preTranslation($source, $meta);
42 -
43 - $trans=$this->doTranslate($func, $param, $order, $sourceLang, $targetLang, $encode, $resultFunc, $statusFunc);
44 -
45 - if($trans==null) {
46 - //error occured
47 - return null;
48 - }
49 -
50 - $newparam=$param;
51 - $newparam[$order[2]]=$trans;
52 -
53 - $decode=$this->postTranslation($func, $newparam, $order, $meta, $attach, $resultFunc, $statusFunc);
54 -
55 - return $decode;
56 - }
57 -
58 - /**
59 - * PreProcess
60 - * @param $source Translated sentence
61 - * @param $meta MetaTranslate or not
62 - * @return Encoded sentence
63 - */
64 - public function preTranslation($source, $meta=true) {
65 - $this->noTranslations=array();
66 - $escEncode='';
67 -
68 - /* no-MetaTranslate */
69 - if($meta) {
70 - $this->tags_begin[]='[relax]';
71 - $this->tags_begin[]=$this->TAG_BEGIN;
72 -
73 - $this->tags_end[]='[/relax]';
74 - $this->tags_end[]=$this->TAG_END;
75 - }
76 -
77 - /* LanguageTags */
78 -
79 -
80 - /* Encoding */
81 - $escEncode=$this->encodeEscapes_relaxed($source);
82 -
83 - return $escEncode;
84 - }
85 -
86 -
87 - /**
88 - * PostProcess
89 - * @param $func Translator
90 - * @param $param Parameters for $func
91 - * @param $order Parameter position : $param[$order[0]]=SourceLanguage, $param[$order[1]]=TargetLanguage, $param[$order[2]]=Source
92 - * @param $meta MetaTranslate or not
93 - * @param $attach Whether Description is necessary : Unnecessary->false
94 - * @param $resultFunc Such function that $resultFunc($func($param)) returns sentence
95 - * @return Sentence
96 - */
97 - public function postTranslation($func, $param, $order, $meta=true, $attach=true, $resultFunc=null, $statusFunc) {
98 - $source=$param[$order[2]];
99 -
100 - /* attach Descriptions */
101 - if($meta) {
102 - $this->attachDescriptions($func, $param, $order, $meta, $attach, $resultFunc, $statusFunc);
103 - }
104 -
105 - /* Decode */
106 - $result=$this->decodeEscapes($source);
107 -
108 -
109 - return $result;
110 - }
111 -
112 - /**
113 - * Replacing Intermediate Code into Escapes
114 - * @param $source Encoded sentence
115 - * @return Decoded sentence
116 - */
117 - private function decodeEscapes($source) {
118 - for($i=0; $i<count($this->noTranslations); $i++) {
119 - $source=str_ireplace($this->noTranslations[$i]['code'],
120 - $this->noTranslations[$i]['escape'], $source);
121 - }
122 -
123 - return $source;
124 - }
125 -
126 - /**
127 - * Attaching Descriptions
128 - */
129 - private function attachDescriptions($func, $param, $order, $meta, $attach, $resultFunc, $statusFunc) {
130 - $sourceLang=$param[$order[0]];
131 - $targetLang=$param[$order[1]];
132 -
133 -
134 - /* for all noTranslations */
135 - for($i=0; $i<count($this->noTranslations); $i++) {
136 - if($attach) {
137 - /* Recursive MetaTranslation */
138 - $meta=new MetaTranslator($sourceLang);
139 - $encode=$meta->preTranslation($this->noTranslations[$i]['escape']);
140 -
141 - $trans=$this->doTranslate($func, $param, $order, $sourceLang, $targetLang, $encode, $resultFunc, $statusFunc);
142 -
143 - $newparam=$param;
144 - $newparam[$order[2]]=$trans;
145 - $description=$meta->postTranslation($func, $newparam, $order, true, true, $resultFunc, $statusFunc);
146 -
147 - /* attaching */
148 - if($this->canAttach($this->noTranslations[$i]['escape'], $description)) {
149 - $this->noTranslations[$i]['escape'].='('.$description.')';
150 - }
151 - }
152 -
153 - $tagnum=$this->noTranslations[$i]['tag'];
154 - if($tagnum!=0) {
155 - $this->noTranslations[$i]['escape']=$this->tags_begin[$tagnum].
156 - $this->noTranslations[$i]['escape'].
157 - $this->tags_end[$tagnum];
158 - }else {
159 - $this->noTranslations[$i]['escape']=$this->TAG_RELAXED.
160 - $this->noTranslations[$i]['escape'].
161 - $this->TAG_RELAXED;
162 - }
163 - }
164 - }
165 -
166 - /**
167 - * Whether to Attach Descriptions
168 - */
169 - private function canAttach($escape, $description) {
170 - /* punctuations */
171 - $pattern='[\.| |.|,|,| |:|:|;|。|、|!|!|\?|?]';
172 - $comp1=@preg_replace($pattern, '', $escape);
173 - $comp2=@preg_replace($pattern, '', $description);
174 -
175 - return $comp1!==$comp2;
176 - }
177 -
178 - /**
179 - * Translate body
180 - */
181 - private function doTranslate($func, $param, $order, $sourceLang, $targetLang, $source, $resultFunc, $statusFunc) {
182 - $param[$order[0]]=$sourceLang;
183 - $param[$order[1]]=$targetLang;
184 - $param[$order[2]]=$source;
185 -
186 - $ht=new HTMLTranslator();
187 -
188 -
189 - $result = $ht->HTMLTranslate($func, $param, $order, $sourceLang, $targetLang, $source, $resultFunc, $statusFunc);
190 -
191 - return $result;
192 - }
193 -
194 - /**
195 - * Replacing Escapes into Intermediate Code : relaxed mode
196 - */
197 - private function encodeEscapes_relaxed($source) {
198 - $array=explode($this->TAG_RELAXED, $source);
199 -
200 - $relaxed='';
201 - for($i=0; $i<count($array)-1; $i++) {
202 - $relaxed.=$array[$i];
203 -
204 - if($i%2==0) {
205 - $relaxed.=$this->tags_begin[0];
206 - }else {
207 - $relaxed.=$this->tags_end[0];
208 - }
209 - }
210 - $relaxed.=$array[count($array)-1];
211 -
212 - return $this->encodeEscapes_strict($relaxed);
213 - }
214 -
215 - /**
216 - * Replacing Escapes into Intermediate Code : strict mode
217 - */
218 - private function encodeEscapes_strict($source) {
219 - $encode='';
220 - $escape='';
221 - $indent=0;
222 - $id=0;
223 - $tagStart=0;
224 - $tagEnd=0;
225 -
226 - $buf='';
227 - for($i=0; $i<mb_strlen($source); $i++) {
228 - $buf.=mb_substr($source, $i, 1);
229 -
230 - /* escape begins */
231 - $len=$this->startsWith($this->tags_begin, $buf);
232 - if($len!=-1) {
233 - /* before tag, do not escape */
234 - if($indent==0) {
235 - $encode.=mb_substr($buf, 0, mb_strlen($buf)-$len);
236 - $tagStart=$i;
237 - }else {
238 - $escape.=$buf;
239 - }
240 -
241 - $buf='';
242 -
243 - $indent++;
244 - continue;
245 - }
246 -
247 -
248 - /* escape ends */
249 - $len=$this->startsWith($this->tags_end, $buf, $tagNumber);
250 - if($len!=-1) {
251 - $indent--;
252 -
253 - $escape.=$buf;
254 - /* after tag, do not escape */
255 - if($indent==0) {
256 - $escape=mb_substr($escape, 0, mb_strlen($escape)-$len);
257 - $escape=$this->removeDescription($escape);
258 - $escape=trim($escape);
259 - $tagEnd=$i;
260 - $interCode=$this->getInterCode($tagStart, $tagEnd);
261 - $this->noTranslations[$id]=array('escape'=>$escape,
262 - 'code'=>$interCode,
263 - 'tag'=>$tagNumber);
264 - $id++;
265 - $encode.=' '.$interCode.' ';
266 - $escape='';
267 - }
268 -
269 - $buf='';
270 - continue;
271 - }
272 -
273 - }
274 - return $encode.$buf;
275 - }
276 -
277 - /**
278 - * if $str startsWith one of $array, return strlen($array[$i]), else -1
279 - */
280 - private function startsWith($array, $str, &$num=null) {
281 - for($i=0; $i<count($array); $i++) {
282 - if(strpos($str, $array[$i])!==false) {
283 - $num=$i;
284 - return mb_strlen($array[$i]);
285 - }
286 - }
287 -
288 - return -1;
289 - }
290 -
291 - /**
292 - * Removing Descriptions
293 - */
294 - private function removeDescription($source) {
295 - $ret='';
296 - $indent=0;
297 -
298 - for($i=0; $i<mb_strlen($source); $i++) {
299 - $buf=mb_substr($source, $i, 1);
300 -
301 - if($buf=='(') {
302 - $indent++;
303 - }
304 -
305 - if($indent==0) {
306 - $ret.=$buf;
307 - }
308 -
309 - if($buf==')') {
310 - $indent--;
311 - }
312 - }
313 -
314 - return $ret;
315 -
316 - }
317 -
318 -
319 - private function getInterCode($tagStart, $tagEnd) {
320 - $alt=dechex($tagStart).'x'.dechex($tagEnd);
321 - $search=array('0','1','2','3','4','5','6','7','8','9');
322 - $replace=array('g','h','i','j','k','l','m','n','o','p');
323 -
324 - $result=str_replace($search, $replace, $alt);
325 -
326 - return 'xxx'.$result.'xxx';
327 - }
328 -
329 - /**
330 - * Setter
331 - */
332 - public function setSourceLanguage($sourceLang) {
333 - $this->sourceLang=$sourceLang;
334 - }
335 -
336 - public function getSourceLanguage() {
337 - return $this->sourceLang;
338 - }
339 -}
340 -
341 -?>
 2+<?php
 3+
 4+require_once('HTMLTranslator.php');
 5+
 6+class MetaTranslator {
 7+ /* Translation parameters */
 8+ private $sourceLang;
 9+
 10+ /* in MetaTranslation process */
 11+ private $noTranslations;
 12+ private $tags_begin=array();
 13+ private $tags_end=array();
 14+
 15+ /* Constant */
 16+ private $TAG_BEGIN="<notranslate>";
 17+ private $TAG_END="</notranslate>";
 18+ private $TAG_RELAXED='__________';
 19+ private $LANG_TAG_BEGIN='[';
 20+ private $LANG_TAG_END=']';
 21+
 22+
 23+
 24+ /**
 25+ * Constructor
 26+ * @param $sourceLang SourceLanguage
 27+ */
 28+ public function __construct($sourceLang) {
 29+ $this->setSourceLanguage($sourceLang);
 30+ }
 31+
 32+ /**
 33+ *
 34+ */
 35+ public function metaTranslate($func, $param, $order, $meta=true, $attach=true, $resultFunc, $statusFunc) {
 36+ $sourceLang=$param[$order[0]];
 37+ $targetLang=$param[$order[1]];
 38+ $source=$param[$order[2]];
 39+
 40+
 41+ $encode=$this->preTranslation($source, $meta);
 42+
 43+ $trans=$this->doTranslate($func, $param, $order, $sourceLang, $targetLang, $encode, $resultFunc, $statusFunc);
 44+
 45+ if($trans==null) {
 46+ //error occured
 47+ return null;
 48+ }
 49+
 50+ $newparam=$param;
 51+ $newparam[$order[2]]=$trans;
 52+
 53+ $decode=$this->postTranslation($func, $newparam, $order, $meta, $attach, $resultFunc, $statusFunc);
 54+
 55+ return $decode;
 56+ }
 57+
 58+ /**
 59+ * PreProcess
 60+ * @param $source Translated sentence
 61+ * @param $meta MetaTranslate or not
 62+ * @return Encoded sentence
 63+ */
 64+ public function preTranslation($source, $meta=true) {
 65+ $this->noTranslations=array();
 66+ $escEncode='';
 67+
 68+ /* no-MetaTranslate */
 69+ if($meta) {
 70+ $this->tags_begin[]='[relax]';
 71+ $this->tags_begin[]=$this->TAG_BEGIN;
 72+
 73+ $this->tags_end[]='[/relax]';
 74+ $this->tags_end[]=$this->TAG_END;
 75+ }
 76+
 77+ /* LanguageTags */
 78+
 79+
 80+ /* Encoding */
 81+ $escEncode=$this->encodeEscapes_relaxed($source);
 82+
 83+ return $escEncode;
 84+ }
 85+
 86+
 87+ /**
 88+ * PostProcess
 89+ * @param $func Translator
 90+ * @param $param Parameters for $func
 91+ * @param $order Parameter position : $param[$order[0]]=SourceLanguage, $param[$order[1]]=TargetLanguage, $param[$order[2]]=Source
 92+ * @param $meta MetaTranslate or not
 93+ * @param $attach Whether Description is necessary : Unnecessary->false
 94+ * @param $resultFunc Such function that $resultFunc($func($param)) returns sentence
 95+ * @return Sentence
 96+ */
 97+ public function postTranslation($func, $param, $order, $meta=true, $attach=true, $resultFunc=null, $statusFunc) {
 98+ $source=$param[$order[2]];
 99+
 100+ /* attach Descriptions */
 101+ if($meta) {
 102+ $this->attachDescriptions($func, $param, $order, $meta, $attach, $resultFunc, $statusFunc);
 103+ }
 104+
 105+ /* Decode */
 106+ $result=$this->decodeEscapes($source);
 107+
 108+
 109+ return $result;
 110+ }
 111+
 112+ /**
 113+ * Replacing Intermediate Code into Escapes
 114+ * @param $source Encoded sentence
 115+ * @return Decoded sentence
 116+ */
 117+ private function decodeEscapes($source) {
 118+ for($i=0; $i<count($this->noTranslations); $i++) {
 119+ $source=str_ireplace($this->noTranslations[$i]['code'],
 120+ $this->noTranslations[$i]['escape'], $source);
 121+ }
 122+
 123+ return $source;
 124+ }
 125+
 126+ /**
 127+ * Attaching Descriptions
 128+ */
 129+ private function attachDescriptions($func, $param, $order, $meta, $attach, $resultFunc, $statusFunc) {
 130+ $sourceLang=$param[$order[0]];
 131+ $targetLang=$param[$order[1]];
 132+
 133+
 134+ /* for all noTranslations */
 135+ for($i=0; $i<count($this->noTranslations); $i++) {
 136+ if($attach) {
 137+ /* Recursive MetaTranslation */
 138+ $meta=new MetaTranslator($sourceLang);
 139+ $encode=$meta->preTranslation($this->noTranslations[$i]['escape']);
 140+
 141+ $trans=$this->doTranslate($func, $param, $order, $sourceLang, $targetLang, $encode, $resultFunc, $statusFunc);
 142+
 143+ $newparam=$param;
 144+ $newparam[$order[2]]=$trans;
 145+ $description=$meta->postTranslation($func, $newparam, $order, true, true, $resultFunc, $statusFunc);
 146+
 147+ /* attaching */
 148+ if($this->canAttach($this->noTranslations[$i]['escape'], $description)) {
 149+ $this->noTranslations[$i]['escape'].='('.$description.')';
 150+ }
 151+ }
 152+
 153+ $tagnum=$this->noTranslations[$i]['tag'];
 154+ if($tagnum!=0) {
 155+ $this->noTranslations[$i]['escape']=$this->tags_begin[$tagnum].
 156+ $this->noTranslations[$i]['escape'].
 157+ $this->tags_end[$tagnum];
 158+ }else {
 159+ $this->noTranslations[$i]['escape']=$this->TAG_RELAXED.
 160+ $this->noTranslations[$i]['escape'].
 161+ $this->TAG_RELAXED;
 162+ }
 163+ }
 164+ }
 165+
 166+ /**
 167+ * Whether to Attach Descriptions
 168+ */
 169+ private function canAttach($escape, $description) {
 170+ /* punctuations */
 171+ $pattern='[\.| |.|,|,| |:|:|;|。|、|!|!|\?|?]';
 172+ $comp1=@preg_replace($pattern, '', $escape);
 173+ $comp2=@preg_replace($pattern, '', $description);
 174+
 175+ return $comp1!==$comp2;
 176+ }
 177+
 178+ /**
 179+ * Translate body
 180+ */
 181+ private function doTranslate($func, $param, $order, $sourceLang, $targetLang, $source, $resultFunc, $statusFunc) {
 182+ $param[$order[0]]=$sourceLang;
 183+ $param[$order[1]]=$targetLang;
 184+ $param[$order[2]]=$source;
 185+
 186+ $ht=new HTMLTranslator();
 187+
 188+
 189+ $result = $ht->HTMLTranslate($func, $param, $order, $sourceLang, $targetLang, $source, $resultFunc, $statusFunc);
 190+
 191+ return $result;
 192+ }
 193+
 194+ /**
 195+ * Replacing Escapes into Intermediate Code : relaxed mode
 196+ */
 197+ private function encodeEscapes_relaxed($source) {
 198+ $array=explode($this->TAG_RELAXED, $source);
 199+
 200+ $relaxed='';
 201+ for($i=0; $i<count($array)-1; $i++) {
 202+ $relaxed.=$array[$i];
 203+
 204+ if($i%2==0) {
 205+ $relaxed.=$this->tags_begin[0];
 206+ }else {
 207+ $relaxed.=$this->tags_end[0];
 208+ }
 209+ }
 210+ $relaxed.=$array[count($array)-1];
 211+
 212+ return $this->encodeEscapes_strict($relaxed);
 213+ }
 214+
 215+ /**
 216+ * Replacing Escapes into Intermediate Code : strict mode
 217+ */
 218+ private function encodeEscapes_strict($source) {
 219+ $encode='';
 220+ $escape='';
 221+ $indent=0;
 222+ $id=0;
 223+ $tagStart=0;
 224+ $tagEnd=0;
 225+
 226+ $buf='';
 227+ for($i=0; $i<mb_strlen($source); $i++) {
 228+ $buf.=mb_substr($source, $i, 1);
 229+
 230+ /* escape begins */
 231+ $len=$this->startsWith($this->tags_begin, $buf);
 232+ if($len!=-1) {
 233+ /* before tag, do not escape */
 234+ if($indent==0) {
 235+ $encode.=mb_substr($buf, 0, mb_strlen($buf)-$len);
 236+ $tagStart=$i;
 237+ }else {
 238+ $escape.=$buf;
 239+ }
 240+
 241+ $buf='';
 242+
 243+ $indent++;
 244+ continue;
 245+ }
 246+
 247+
 248+ /* escape ends */
 249+ $len=$this->startsWith($this->tags_end, $buf, $tagNumber);
 250+ if($len!=-1) {
 251+ $indent--;
 252+
 253+ $escape.=$buf;
 254+ /* after tag, do not escape */
 255+ if($indent==0) {
 256+ $escape=mb_substr($escape, 0, mb_strlen($escape)-$len);
 257+ $escape=$this->removeDescription($escape);
 258+ $escape=trim($escape);
 259+ $tagEnd=$i;
 260+ $interCode=$this->getInterCode($tagStart, $tagEnd);
 261+ $this->noTranslations[$id]=array('escape'=>$escape,
 262+ 'code'=>$interCode,
 263+ 'tag'=>$tagNumber);
 264+ $id++;
 265+ $encode.=' '.$interCode.' ';
 266+ $escape='';
 267+ }
 268+
 269+ $buf='';
 270+ continue;
 271+ }
 272+
 273+ }
 274+ return $encode.$buf;
 275+ }
 276+
 277+ /**
 278+ * if $str startsWith one of $array, return strlen($array[$i]), else -1
 279+ */
 280+ private function startsWith($array, $str, &$num=null) {
 281+ for($i=0; $i<count($array); $i++) {
 282+ if(strpos($str, $array[$i])!==false) {
 283+ $num=$i;
 284+ return mb_strlen($array[$i]);
 285+ }
 286+ }
 287+
 288+ return -1;
 289+ }
 290+
 291+ /**
 292+ * Removing Descriptions
 293+ */
 294+ private function removeDescription($source) {
 295+ $ret='';
 296+ $indent=0;
 297+
 298+ for($i=0; $i<mb_strlen($source); $i++) {
 299+ $buf=mb_substr($source, $i, 1);
 300+
 301+ if($buf=='(') {
 302+ $indent++;
 303+ }
 304+
 305+ if($indent==0) {
 306+ $ret.=$buf;
 307+ }
 308+
 309+ if($buf==')') {
 310+ $indent--;
 311+ }
 312+ }
 313+
 314+ return $ret;
 315+
 316+ }
 317+
 318+
 319+ private function getInterCode($tagStart, $tagEnd) {
 320+ $alt=dechex($tagStart).'x'.dechex($tagEnd);
 321+ $search=array('0','1','2','3','4','5','6','7','8','9');
 322+ $replace=array('g','h','i','j','k','l','m','n','o','p');
 323+
 324+ $result=str_replace($search, $replace, $alt);
 325+
 326+ return 'xxx'.$result.'xxx';
 327+ }
 328+
 329+ /**
 330+ * Setter
 331+ */
 332+ public function setSourceLanguage($sourceLang) {
 333+ $this->sourceLang=$sourceLang;
 334+ }
 335+
 336+ public function getSourceLanguage() {
 337+ return $this->sourceLang;
 338+ }
 339+}
 340+
 341+?>
342342
\ No newline at end of file
Property changes on: trunk/extensions/MultilingualLiquidThreads/langrid/MetaTranslator.php
___________________________________________________________________
Name: svn:eol-style
343343 + native
Index: trunk/extensions/MultilingualLiquidThreads/langrid/MultilangLqtHooks.php
@@ -1,185 +1,185 @@
2 -<?php
3 -class MultilangLqtHooks {
4 -
5 - static $translatedSubject;
6 -
7 - static function saveReply( &$info, &$e, &$thread ) {
8 - $replyTo = $info['replyTo'];
9 - $subject = $replyTo->subject();
10 - $langridAccessObject = new LanguageGridAccessObject();
11 - $translatedSubject = $langridAccessObject->translateSubject($replyTo, $subject);
12 - $replyTo->setSubject( $translatedSubject );
13 - $info['replyTo'] = $replyTo;
14 - return true;
15 - }
16 -
17 - static function onThreadCommands( $thread, &$commands ) {
18 - $langridAccessObject = new LanguageGridAccessObject();
19 - if ( !$langridAccessObject->needsNoTranslation( $thread->id() ) ) {
20 - $translatedRoot = $langridAccessObject->translatedRootByThread( $thread );
21 - if ( isset( $translatedRoot ) ) {
22 - $thread->setRoot( $translatedRoot );
23 - }
24 - }
25 -
26 - $translated_history_url = LqtView::permalinkUrlWithQuery( $thread, array( 'action' => 'history' ) );
27 - $commands['history'] = array( 'label' => wfMsgExt( 'history_short', 'parseinline' ),
28 - 'href' => $translated_history_url,
29 - 'enabled' => true );
30 - return true;
31 - }
32 -
33 - static function onThreadPermalinkView( $threadParmalinkView, &$thread ) {
34 - $langridAccessObject = new LanguageGridAccessObject();
35 - $originalRoot = $langridAccessObject->originalRootbyRoot( $threadParmalinkView->article );
36 - if ( is_null( $originalRoot ) ) {
37 - $thread = Threads::withRoot( $threadParmalinkView->article );
38 - } else {
39 - $thread = Threads::withRoot( $originalRoot );
40 - }
41 -
42 - return true;
43 - }
44 -
45 - static function translateRoot( $thread, &$article, $talkpage) {
46 - $langridAccessObject = new LanguageGridAccessObject();
47 - $article = $langridAccessObject->translatedRootByRoot($thread->root());
48 - return true;
49 - }
50 -
51 - static function onThreadSignature( $thread, &$signature) {
52 - $langridAccessObject = new LanguageGridAccessObject();
53 - $languageCode = $langridAccessObject->getSourceLanguage( $thread->id() );
54 - $signature .= wfMsg( 'multilang_lqt_post_language',
55 - LanguageGridAccessObject::convertLanguageCodeIntoLanguageName($languageCode));
56 - return true;
57 - }
58 -
59 - static function translateSubject( $thread, &$html ) {
60 - $sourceSubject = $thread->subjectWithoutIncrement();
61 - $langridAccessObject = new LanguageGridAccessObject();
62 - $translatedSubject = $langridAccessObject->translateSubject( $thread, $sourceSubject );
63 - if ( is_null( $translatedSubject ) ) {
64 - $html .= ' <font color="#f00">(Translation Failed)</font> ';
65 - } else {
66 - $html = LqtView::formatSubject( $translatedSubject );
67 - }
68 - return true;
69 - }
70 -
71 - static function translateSubjectforTOC( $thread ) {
72 - $sourceSubject = $thread->subjectWithoutIncrement();
73 - $langridAccessObject = new LanguageGridAccessObject();
74 - $translatedSubject = $langridAccessObject->translateSubject( $thread, $sourceSubject );
75 - if ( is_null( $translatedSubject ) ) {
76 - $thread->setSubject( $sourceSubject );
77 - } else {
78 - $thread->setSubject( $translatedSubject );
79 - }
80 - return true;
81 - }
82 -
83 - static function translateBody( $thread, &$post ) {
84 - $langridAccessObject = new LanguageGridAccessObject();
85 - $root = $langridAccessObject->translatedRootByThread($thread);
86 - if ( !is_null( $root ) ) {
87 - $post = $root;
88 - }
89 -
90 - return true;
91 - }
92 -
93 - static function onThreadMajorCommands( $thread, &$commands ) {
94 - $langridAccessObject = new LanguageGridAccessObject();
95 - if ( !$langridAccessObject->needsNoTranslation( $thread->id() ) ) {
96 - $languageCode = $langridAccessObject->getSourceLanguage( $thread->id() );
97 - $sourceMsg = wfMsg( 'multilang_lqt_show_original',
98 - LanguageGridAccessObject::convertLanguageCodeIntoLanguageName( $languageCode ) );
99 - if ( is_null( $sourceMsg ) ) $sourceMsg = 'Original';
100 - $sourceUrl = LqtView::talkpageUrl( $thread->title() , 'source', $thread,
101 - true /* include fragment */, true );
102 - $commands['source'] =
103 - array(
104 - 'label' => $sourceMsg,
105 - 'class' => 'lqt-command-source',
106 - 'href' => $sourceUrl,
107 - 'enabled' => true
108 - );
109 - }
110 -
111 - return true;
112 - }
113 -
114 - static function onShowPostThreadBody( $thread, $request, &$html ) {
115 - $sView = new SourceView( $thread, $request );
116 -
117 - // show source
118 - if ( $sView->methodAppliesToThread( 'source' ) ) {
119 - // As with above, flush HTML to avoid refactoring EditPage.
120 - $html .= '<hr>';
121 - $html .= $sView->showSource( $thread );
122 - } else {
123 - $html .= Xml::tags( 'div',
124 - array( 'class' => 'lqt-source-form lqt-edit-form',
125 - 'style' => 'display: none;' ),
126 - '' );
127 - }
128 -
129 - return true;
130 - }
131 -
132 - static function onDoInlineEditForm( $thread, $request, &$output ) {
133 - $sView = new SourceView( $thread, $request );
134 -
135 - if ( $sView->methodAppliesToThread( 'source' ) ) {
136 - $html = $sView->showSource( $thread );
137 - $output->addHTML( $html );
138 - }
139 -
140 - return true;
141 - }
142 -
143 - static function saveSourceLang( &$thread ) {
144 - $dbw = wfGetDB( DB_MASTER );
145 - $threadId = $thread->id();
146 -
147 - $langridAccessObject = new LanguageGridAccessObject();
148 - $postlang = $langridAccessObject->getTargetLanguage();
149 -
150 - $threadlang = ThreadLanguage::create( $threadId, $postlang );
151 -
152 - return true;
153 - }
154 -
155 - static function showLanguageSelector( &$e, $t ) {
156 - $language_label = wfMsg( 'multilang_lqt_language' );
157 -
158 - $lang_select_html .= Xml::openElement('select', array('name' => 'wpPostlang', 'id' => 'wpPostlang', 'style' => $select));
159 - global $wgLanguageSelectorLanguages,$wgContLang,$wgLang;
160 -
161 - //$postlang = $this->request->getVal( 'wpPostlang' );
162 - $langridAccessObject = new LanguageGridAccessObject();
163 - $postlang = $langridAccessObject->getTargetLanguage();
164 - if($postlang) {
165 - // for preview page
166 - $code = $postlang;
167 - } else {
168 - $code = $wgLang->getCode();
169 - }
170 -
171 - foreach ($wgLanguageSelectorLanguages as $ln) {
172 - $name = $wgContLang->getLanguageName($ln);
173 - if ($showCode) $name = wfBCP47($ln) . ' - ' . $name;
174 - $lang_select_html .= Xml::option($name, $ln, $ln == $code);
175 - }
176 - $lang_select_html .= Xml::closeElement('select');
177 - $e->editFormTextBeforeContent .=
178 - Xml::Label( $language_label, 'lqt_lang_name' ) .
179 - $lang_select_html .
180 - Xml::element( 'br' );
181 -
182 - return true;
183 - }
184 -
185 -}
186 -?>
 2+<?php
 3+class MultilangLqtHooks {
 4+
 5+ static $translatedSubject;
 6+
 7+ static function saveReply( &$info, &$e, &$thread ) {
 8+ $replyTo = $info['replyTo'];
 9+ $subject = $replyTo->subject();
 10+ $langridAccessObject = new LanguageGridAccessObject();
 11+ $translatedSubject = $langridAccessObject->translateSubject($replyTo, $subject);
 12+ $replyTo->setSubject( $translatedSubject );
 13+ $info['replyTo'] = $replyTo;
 14+ return true;
 15+ }
 16+
 17+ static function onThreadCommands( $thread, &$commands ) {
 18+ $langridAccessObject = new LanguageGridAccessObject();
 19+ if ( !$langridAccessObject->needsNoTranslation( $thread->id() ) ) {
 20+ $translatedRoot = $langridAccessObject->translatedRootByThread( $thread );
 21+ if ( isset( $translatedRoot ) ) {
 22+ $thread->setRoot( $translatedRoot );
 23+ }
 24+ }
 25+
 26+ $translated_history_url = LqtView::permalinkUrlWithQuery( $thread, array( 'action' => 'history' ) );
 27+ $commands['history'] = array( 'label' => wfMsgExt( 'history_short', 'parseinline' ),
 28+ 'href' => $translated_history_url,
 29+ 'enabled' => true );
 30+ return true;
 31+ }
 32+
 33+ static function onThreadPermalinkView( $threadParmalinkView, &$thread ) {
 34+ $langridAccessObject = new LanguageGridAccessObject();
 35+ $originalRoot = $langridAccessObject->originalRootbyRoot( $threadParmalinkView->article );
 36+ if ( is_null( $originalRoot ) ) {
 37+ $thread = Threads::withRoot( $threadParmalinkView->article );
 38+ } else {
 39+ $thread = Threads::withRoot( $originalRoot );
 40+ }
 41+
 42+ return true;
 43+ }
 44+
 45+ static function translateRoot( $thread, &$article, $talkpage) {
 46+ $langridAccessObject = new LanguageGridAccessObject();
 47+ $article = $langridAccessObject->translatedRootByRoot($thread->root());
 48+ return true;
 49+ }
 50+
 51+ static function onThreadSignature( $thread, &$signature) {
 52+ $langridAccessObject = new LanguageGridAccessObject();
 53+ $languageCode = $langridAccessObject->getSourceLanguage( $thread->id() );
 54+ $signature .= wfMsg( 'multilang_lqt_post_language',
 55+ LanguageGridAccessObject::convertLanguageCodeIntoLanguageName($languageCode));
 56+ return true;
 57+ }
 58+
 59+ static function translateSubject( $thread, &$html ) {
 60+ $sourceSubject = $thread->subjectWithoutIncrement();
 61+ $langridAccessObject = new LanguageGridAccessObject();
 62+ $translatedSubject = $langridAccessObject->translateSubject( $thread, $sourceSubject );
 63+ if ( is_null( $translatedSubject ) ) {
 64+ $html .= ' <font color="#f00">(Translation Failed)</font> ';
 65+ } else {
 66+ $html = LqtView::formatSubject( $translatedSubject );
 67+ }
 68+ return true;
 69+ }
 70+
 71+ static function translateSubjectforTOC( $thread ) {
 72+ $sourceSubject = $thread->subjectWithoutIncrement();
 73+ $langridAccessObject = new LanguageGridAccessObject();
 74+ $translatedSubject = $langridAccessObject->translateSubject( $thread, $sourceSubject );
 75+ if ( is_null( $translatedSubject ) ) {
 76+ $thread->setSubject( $sourceSubject );
 77+ } else {
 78+ $thread->setSubject( $translatedSubject );
 79+ }
 80+ return true;
 81+ }
 82+
 83+ static function translateBody( $thread, &$post ) {
 84+ $langridAccessObject = new LanguageGridAccessObject();
 85+ $root = $langridAccessObject->translatedRootByThread($thread);
 86+ if ( !is_null( $root ) ) {
 87+ $post = $root;
 88+ }
 89+
 90+ return true;
 91+ }
 92+
 93+ static function onThreadMajorCommands( $thread, &$commands ) {
 94+ $langridAccessObject = new LanguageGridAccessObject();
 95+ if ( !$langridAccessObject->needsNoTranslation( $thread->id() ) ) {
 96+ $languageCode = $langridAccessObject->getSourceLanguage( $thread->id() );
 97+ $sourceMsg = wfMsg( 'multilang_lqt_show_original',
 98+ LanguageGridAccessObject::convertLanguageCodeIntoLanguageName( $languageCode ) );
 99+ if ( is_null( $sourceMsg ) ) $sourceMsg = 'Original';
 100+ $sourceUrl = LqtView::talkpageUrl( $thread->title() , 'source', $thread,
 101+ true /* include fragment */, true );
 102+ $commands['source'] =
 103+ array(
 104+ 'label' => $sourceMsg,
 105+ 'class' => 'lqt-command-source',
 106+ 'href' => $sourceUrl,
 107+ 'enabled' => true
 108+ );
 109+ }
 110+
 111+ return true;
 112+ }
 113+
 114+ static function onShowPostThreadBody( $thread, $request, &$html ) {
 115+ $sView = new SourceView( $thread, $request );
 116+
 117+ // show source
 118+ if ( $sView->methodAppliesToThread( 'source' ) ) {
 119+ // As with above, flush HTML to avoid refactoring EditPage.
 120+ $html .= '<hr>';
 121+ $html .= $sView->showSource( $thread );
 122+ } else {
 123+ $html .= Xml::tags( 'div',
 124+ array( 'class' => 'lqt-source-form lqt-edit-form',
 125+ 'style' => 'display: none;' ),
 126+ '' );
 127+ }
 128+
 129+ return true;
 130+ }
 131+
 132+ static function onDoInlineEditForm( $thread, $request, &$output ) {
 133+ $sView = new SourceView( $thread, $request );
 134+
 135+ if ( $sView->methodAppliesToThread( 'source' ) ) {
 136+ $html = $sView->showSource( $thread );
 137+ $output->addHTML( $html );
 138+ }
 139+
 140+ return true;
 141+ }
 142+
 143+ static function saveSourceLang( &$thread ) {
 144+ $dbw = wfGetDB( DB_MASTER );
 145+ $threadId = $thread->id();
 146+
 147+ $langridAccessObject = new LanguageGridAccessObject();
 148+ $postlang = $langridAccessObject->getTargetLanguage();
 149+
 150+ $threadlang = ThreadLanguage::create( $threadId, $postlang );
 151+
 152+ return true;
 153+ }
 154+
 155+ static function showLanguageSelector( &$e, $t ) {
 156+ $language_label = wfMsg( 'multilang_lqt_language' );
 157+
 158+ $lang_select_html .= Xml::openElement('select', array('name' => 'wpPostlang', 'id' => 'wpPostlang', 'style' => $select));
 159+ global $wgLanguageSelectorLanguages,$wgContLang,$wgLang;
 160+
 161+ //$postlang = $this->request->getVal( 'wpPostlang' );
 162+ $langridAccessObject = new LanguageGridAccessObject();
 163+ $postlang = $langridAccessObject->getTargetLanguage();
 164+ if($postlang) {
 165+ // for preview page
 166+ $code = $postlang;
 167+ } else {
 168+ $code = $wgLang->getCode();
 169+ }
 170+
 171+ foreach ($wgLanguageSelectorLanguages as $ln) {
 172+ $name = $wgContLang->getLanguageName($ln);
 173+ if ($showCode) $name = wfBCP47($ln) . ' - ' . $name;
 174+ $lang_select_html .= Xml::option($name, $ln, $ln == $code);
 175+ }
 176+ $lang_select_html .= Xml::closeElement('select');
 177+ $e->editFormTextBeforeContent .=
 178+ Xml::Label( $language_label, 'lqt_lang_name' ) .
 179+ $lang_select_html .
 180+ Xml::element( 'br' );
 181+
 182+ return true;
 183+ }
 184+
 185+}
 186+?>
Property changes on: trunk/extensions/MultilingualLiquidThreads/langrid/MultilangLqtHooks.php
___________________________________________________________________
Name: svn:eol-style
187187 + native
Index: trunk/extensions/MultilingualLiquidThreads/langrid/MultilangThreadController.php
@@ -1,62 +1,62 @@
2 -<?php
3 -class MultilangThreadController {
4 - public $thread;
5 - public $langridAccessObject;
6 -
7 - //もしかして、これって$threadを上書きできない?
8 - //getThreadメソッドが必要? by嶋田
9 - function __construct ( $thread ) {
10 - $this->thread = $thread;
11 - $this->langridAccessObject = new LanguageGridAccessObject();
12 - }
13 -
14 - function getRootId( $thread ) {
15 -
16 - }
17 -
18 - function rootById( $rootId ) {
19 - $article_cache = Thread::$articleCacheById[$rootId];
20 - if ( isset( $article_cache ) ) {
21 - return $article_cache;
22 - }
23 - $title_cache = Thread::$titleCacheById[$rootId];
24 - $title = isset( $title_cache ) ? $title_cache : Title::newFromID( $rootId );
25 - return $title ? new Article_LQT_Compat( $title ) : null;
26 - }
27 -
28 - function editMonolingualSubject( $subject ) {
29 - $threadId = $this->thread->id();
30 - if ( $this->langridAccessObject->needsNoTranslation( $threadId ) ) {
31 - $this->thread->setThisSubject( $subject );
32 - } else {
33 - $targetLang = $this->langridAccessObject->getTargetLanguage();
34 - $translatedThread = TranslatedThread::loadTranslatedThread( $threadId, $targetLang );
35 - $translatedThread->setTtSubject( $subject );
36 - $translatedThread->save();
37 - }
38 -
39 - foreach( $this->thread->replies() as $reply ) {
40 - $multilangThreadController = new MultilangThreadController( $reply );
41 - $multilangThreadController->editMonolingualSubject( $subject );
42 - }
43 - }
44 -
45 - function getSourceSentence( $thread ) {
46 - global $wgOut;
47 -
48 - $post = $thread->root();
49 - $oldid = $thread->isHistorical() ? $thread->rootRevision() : null;
50 -
51 - // Load compatibility layer for older versions
52 - if ( !( $post instanceof Article_LQT_Compat ) ) {
53 - wfWarn( "No article compatibility layer loaded, inefficiently duplicating information." );
54 - $post = new Article_LQT_Compat( $post->getTitle() );
55 - }
56 -
57 - $parserOutput = $post->getParserOutput( $oldid );
58 - $wgOut->addParserOutputNoText( $parserOutput );
59 -
60 - return $parserOutput->getText();
61 - }
62 -}
63 -?>
 2+<?php
 3+class MultilangThreadController {
 4+ public $thread;
 5+ public $langridAccessObject;
 6+
 7+ //もしかして、これって$threadを上書きできない?
 8+ //getThreadメソッドが必要? by嶋田
 9+ function __construct ( $thread ) {
 10+ $this->thread = $thread;
 11+ $this->langridAccessObject = new LanguageGridAccessObject();
 12+ }
 13+
 14+ function getRootId( $thread ) {
 15+
 16+ }
 17+
 18+ function rootById( $rootId ) {
 19+ $article_cache = Thread::$articleCacheById[$rootId];
 20+ if ( isset( $article_cache ) ) {
 21+ return $article_cache;
 22+ }
 23+ $title_cache = Thread::$titleCacheById[$rootId];
 24+ $title = isset( $title_cache ) ? $title_cache : Title::newFromID( $rootId );
 25+ return $title ? new Article_LQT_Compat( $title ) : null;
 26+ }
 27+
 28+ function editMonolingualSubject( $subject ) {
 29+ $threadId = $this->thread->id();
 30+ if ( $this->langridAccessObject->needsNoTranslation( $threadId ) ) {
 31+ $this->thread->setThisSubject( $subject );
 32+ } else {
 33+ $targetLang = $this->langridAccessObject->getTargetLanguage();
 34+ $translatedThread = TranslatedThread::loadTranslatedThread( $threadId, $targetLang );
 35+ $translatedThread->setTtSubject( $subject );
 36+ $translatedThread->save();
 37+ }
 38+
 39+ foreach( $this->thread->replies() as $reply ) {
 40+ $multilangThreadController = new MultilangThreadController( $reply );
 41+ $multilangThreadController->editMonolingualSubject( $subject );
 42+ }
 43+ }
 44+
 45+ function getSourceSentence( $thread ) {
 46+ global $wgOut;
 47+
 48+ $post = $thread->root();
 49+ $oldid = $thread->isHistorical() ? $thread->rootRevision() : null;
 50+
 51+ // Load compatibility layer for older versions
 52+ if ( !( $post instanceof Article_LQT_Compat ) ) {
 53+ wfWarn( "No article compatibility layer loaded, inefficiently duplicating information." );
 54+ $post = new Article_LQT_Compat( $post->getTitle() );
 55+ }
 56+
 57+ $parserOutput = $post->getParserOutput( $oldid );
 58+ $wgOut->addParserOutputNoText( $parserOutput );
 59+
 60+ return $parserOutput->getText();
 61+ }
 62+}
 63+?>
Property changes on: trunk/extensions/MultilingualLiquidThreads/langrid/MultilangThreadController.php
___________________________________________________________________
Name: svn:eol-style
6464 + native
Index: trunk/extensions/MultilingualLiquidThreads/.project
@@ -1,11 +1,11 @@
2 -<?xml version="1.0" encoding="UTF-8"?>
3 -<projectDescription>
4 - <name>MultilingualLiquidThreads</name>
5 - <comment></comment>
6 - <projects>
7 - </projects>
8 - <buildSpec>
9 - </buildSpec>
10 - <natures>
11 - </natures>
12 -</projectDescription>
 2+<?xml version="1.0" encoding="UTF-8"?>
 3+<projectDescription>
 4+ <name>MultilingualLiquidThreads</name>
 5+ <comment></comment>
 6+ <projects>
 7+ </projects>
 8+ <buildSpec>
 9+ </buildSpec>
 10+ <natures>
 11+ </natures>
 12+</projectDescription>
Property changes on: trunk/extensions/MultilingualLiquidThreads/.project
___________________________________________________________________
Name: svn:eol-style
1313 + native
Index: trunk/extensions/MultilingualLiquidThreads/LiquidThreads.php
@@ -1,227 +1,227 @@
2 -<?php
3 -if ( !defined( 'MEDIAWIKI' ) )
4 - die();
5 -
6 -$wgExtensionCredits['other'][] = array(
7 - 'path' => __FILE__,
8 - 'name' => 'Liquid Threads',
9 - 'version' => '2.0-alpha',
10 - 'url' => 'http://www.mediawiki.org/wiki/Extension:LiquidThreads',
11 - 'author' => array( 'David McCabe', 'Andrew Garrett' ),
12 - 'descriptionmsg' => 'lqt-desc',
13 -);
14 -
15 -require( 'LqtFunctions.php' );
16 -
17 -define( 'NS_LQT_THREAD', efArrayDefault( 'egLqtNamespaceNumbers', 'Thread', 90 ) );
18 -define( 'NS_LQT_THREAD_TALK', efArrayDefault( 'egLqtNamespaceNumbers', 'Thread_talk', 91 ) );
19 -define( 'NS_LQT_SUMMARY', efArrayDefault( 'egLqtNamespaceNumbers', 'Summary', 92 ) );
20 -define( 'NS_LQT_SUMMARY_TALK', efArrayDefault( 'egLqtNamespaceNumbers', 'Summary_talk', 93 ) );
21 -define( 'LQT_NEWEST_CHANGES', 'nc' );
22 -define( 'LQT_NEWEST_THREADS', 'nt' );
23 -define( 'LQT_OLDEST_THREADS', 'ot' );
24 -
25 -// FIXME: would be neat if it was possible to somehow localise this.
26 -$wgCanonicalNamespaceNames[NS_LQT_THREAD] = 'Thread';
27 -$wgCanonicalNamespaceNames[NS_LQT_THREAD_TALK] = 'Thread_talk';
28 -$wgCanonicalNamespaceNames[NS_LQT_SUMMARY] = 'Summary';
29 -$wgCanonicalNamespaceNames[NS_LQT_SUMMARY_TALK] = 'Summary_talk';
30 -
31 -// FIXME: would be neat if it was possible to somehow localise this.
32 -$wgExtraNamespaces[NS_LQT_THREAD] = 'Thread';
33 -$wgExtraNamespaces[NS_LQT_THREAD_TALK] = 'Thread_talk';
34 -$wgExtraNamespaces[NS_LQT_SUMMARY] = 'Summary';
35 -$wgExtraNamespaces[NS_LQT_SUMMARY_TALK] = 'Summary_talk';
36 -
37 -// Localisation
38 -$dir = dirname( __FILE__ ) . '/';
39 -$wgExtensionMessagesFiles['LiquidThreads'] = $dir . 'i18n/Lqt.i18n.php';
40 -$wgExtensionMessagesFiles['LiquidThreadsMagic'] = $dir . 'i18n/LiquidThreads.magic.php';
41 -$wgExtensionAliasesFiles['LiquidThreads'] = $dir . 'i18n/Lqt.alias.php';
42 -
43 -// Parser Function Setup
44 -$wgHooks['ParserFirstCallInit'][] = 'lqtSetupParserFunctions';
45 -
46 -// Hooks
47 -// Main dispatch hook
48 -$wgHooks['MediaWikiPerformAction'][] = 'LqtDispatch::tryPage';
49 -$wgHooks['SkinTemplateTabs'][] = 'LqtDispatch::onSkinTemplateTabs';
50 -$wgHooks['SkinTemplateNavigation'][] = 'LqtDispatch::onSkinTemplateNavigation';
51 -
52 -// Customisation of recentchanges
53 -$wgHooks['OldChangesListRecentChangesLine'][] = 'LqtHooks::customizeOldChangesList';
54 -
55 -// Notification (watchlist, newtalk)
56 -$wgHooks['SkinTemplateOutputPageBeforeExec'][] = 'LqtHooks::setNewtalkHTML';
57 -$wgHooks['SpecialWatchlistQuery'][] = 'LqtHooks::beforeWatchlist';
58 -$wgHooks['ArticleEditUpdateNewTalk'][] = 'LqtHooks::updateNewtalkOnEdit';
59 -$wgHooks['PersonalUrls'][] = 'LqtHooks::onPersonalUrls';
60 -
61 -// Preferences
62 -$wgHooks['GetPreferences'][] = 'LqtHooks::getPreferences';
63 -
64 -// Export-related
65 -$wgHooks['XmlDumpWriterOpenPage'][] = 'LqtHooks::dumpThreadData';
66 -$wgHooks['ModifyExportQuery'][] = 'LqtHooks::modifyExportQuery';
67 -$wgHooks['OAIFetchRowsQuery'][] = 'LqtHooks::modifyOAIQuery';
68 -$wgHooks['OAIFetchRecordQuery'][] = 'LqtHooks::modifyOAIQuery';
69 -
70 -// Deletion
71 -$wgHooks['ArticleDeleteComplete'][] = 'LqtDeletionController::onArticleDeleteComplete';
72 -$wgHooks['ArticleRevisionUndeleted'][] = 'LqtDeletionController::onArticleRevisionUndeleted';
73 -$wgHooks['ArticleUndelete'][] = 'LqtDeletionController::onArticleUndelete';
74 -$wgHooks['ArticleConfirmDelete'][] = 'LqtDeletionController::onArticleConfirmDelete';
75 -$wgHooks['ArticleDelete'][] = 'LqtDeletionController::onArticleDelete';
76 -
77 -// Moving
78 -$wgHooks['SpecialMovepageAfterMove'][] = 'LqtHooks::onArticleMoveComplete';
79 -$wgHooks['AbortMove'][] = 'LqtHooks::onArticleMove';
80 -
81 -// Search
82 -$wgHooks['ShowSearchHitTitle'][] = 'LqtHooks::customiseSearchResultTitle';
83 -$wgHooks['SpecialSearchProfiles'][] = 'LqtHooks::customiseSearchProfiles';
84 -
85 -// Updates
86 -$wgHooks['LoadExtensionSchemaUpdates'][] = 'LqtHooks::onLoadExtensionSchemaUpdates';
87 -
88 -// Rename
89 -$wgHooks['RenameUserSQL'][] = 'LqtHooks::onUserRename';
90 -
91 -// Edit-related
92 -$wgHooks['EditPageBeforeEditChecks'][] = 'LqtHooks::editCheckBoxes';
93 -$wgHooks['ArticleSaveComplete'][] = 'LqtHooks::onArticleSaveComplete';
94 -
95 -// Blocking
96 -$wgHooks['UserIsBlockedFrom'][] = 'LqtHooks::userIsBlockedFrom';
97 -
98 -// Protection
99 -$wgHooks['TitleGetRestrictionTypes'][] = 'LqtHooks::getProtectionTypes';
100 -
101 -// Special pages
102 -$wgSpecialPages['MoveThread'] = 'SpecialMoveThread';
103 -$wgSpecialPages['NewMessages'] = 'SpecialNewMessages';
104 -$wgSpecialPages['SplitThread'] = 'SpecialSplitThread';
105 -$wgSpecialPages['MergeThread'] = 'SpecialMergeThread';
106 -// $wgSpecialPages['HotTopics'] = 'SpecialHotTopics';
107 -$wgSpecialPageGroups['NewMessages'] = 'wiki';
108 -
109 -// Classes
110 -$wgAutoloadClasses['LqtDispatch'] = $dir . 'classes/Dispatch.php';
111 -$wgAutoloadClasses['LqtView'] = $dir . 'classes/View.php';
112 -$wgAutoloadClasses['HistoricalThread'] = $dir . 'classes/HistoricalThread.php';
113 -$wgAutoloadClasses['Thread'] = $dir . 'classes/Thread.php';
114 -$wgAutoloadClasses['Threads'] = $dir . 'classes/Threads.php';
115 -$wgAutoloadClasses['NewMessages'] = $dir . 'classes/NewMessagesController.php';
116 -$wgAutoloadClasses['LqtParserFunctions'] = $dir . 'classes/ParserFunctions.php';
117 -$wgAutoloadClasses['LqtDeletionController'] = $dir . 'classes/DeletionController.php';
118 -$wgAutoloadClasses['LqtHooks'] = $dir . 'classes/Hooks.php';
119 -$wgAutoloadClasses['ThreadRevision'] = $dir . "/classes/ThreadRevision.php";
120 -$wgAutoloadClasses['SynchroniseThreadArticleDataJob'] = "$dir/classes/SynchroniseThreadArticleDataJob.php";
121 -$wgAutoloadClasses['ThreadHistoryPager'] = "$dir/classes/ThreadHistoryPager.php";
122 -$wgAutoloadClasses['TalkpageHistoryView'] = "$dir/pages/TalkpageHistoryView.php";
123 -$wgAutoloadClasses['LqtHotTopicsController'] = "$dir/classes/HotTopics.php";
124 -$wgAutoloadClasses['LqtLogFormatter'] = "$dir/classes/LogFormatter.php";
125 -
126 -// View classes
127 -$wgAutoloadClasses['TalkpageView'] = $dir . 'pages/TalkpageView.php';
128 -$wgAutoloadClasses['ThreadPermalinkView'] = $dir . 'pages/ThreadPermalinkView.php';
129 -$wgAutoloadClasses['TalkpageHeaderView'] = $dir . 'pages/TalkpageHeaderView.php';
130 -$wgAutoloadClasses['IndividualThreadHistoryView'] = $dir . 'pages/IndividualThreadHistoryView.php';
131 -$wgAutoloadClasses['ThreadDiffView'] = $dir . 'pages/ThreadDiffView.php';
132 -$wgAutoloadClasses['ThreadWatchView'] = $dir . 'pages/ThreadWatchView.php';
133 -$wgAutoloadClasses['ThreadProtectionFormView'] = $dir . 'pages/ThreadProtectionFormView.php';
134 -$wgAutoloadClasses['ThreadHistoryListingView'] = $dir . 'pages/ThreadHistoryListingView.php';
135 -$wgAutoloadClasses['ThreadHistoricalRevisionView'] = $dir . 'pages/ThreadHistoricalRevisionView.php';
136 -$wgAutoloadClasses['SummaryPageView'] = $dir . 'pages/SummaryPageView.php';
137 -$wgAutoloadClasses['NewUserMessagesView'] = $dir . 'pages/NewUserMessagesView.php';
138 -
139 -// Special pages
140 -$wgAutoloadClasses['ThreadActionPage'] = $dir . 'pages/ThreadActionPage.php';
141 -$wgAutoloadClasses['SpecialMoveThread'] = $dir . 'pages/SpecialMoveThread.php';
142 -$wgAutoloadClasses['SpecialNewMessages'] = $dir . 'pages/SpecialNewMessages.php';
143 -$wgAutoloadClasses['SpecialSplitThread'] = $dir . 'pages/SpecialSplitThread.php';
144 -$wgAutoloadClasses['SpecialMergeThread'] = $dir . 'pages/SpecialMergeThread.php';
145 -$wgAutoloadClasses['SpecialHotTopics'] = "$dir/pages/SpecialHotTopics.php";
146 -
147 -// Job queue
148 -$wgJobClasses['synchroniseThreadArticleData'] = 'SynchroniseThreadArticleDataJob';
149 -
150 -// Backwards-compatibility
151 -$wgAutoloadClasses['Article_LQT_Compat'] = $dir . 'compat/LqtCompatArticle.php';
152 -if ( version_compare( $wgVersion, '1.16', '<' ) ) {
153 - $wgAutoloadClasses['HTMLForm'] = "$dir/compat/HTMLForm.php";
154 - $wgExtensionMessagesFiles['Lqt-Compat'] = "$dir/compat/Lqt-compat.i18n.php";
155 -}
156 -
157 -// Logging
158 -$wgLogTypes[] = 'liquidthreads';
159 -$wgLogNames['liquidthreads'] = 'lqt-log-name';
160 -$wgLogHeaders['liquidthreads'] = 'lqt-log-header';
161 -
162 -foreach ( array( 'move', 'split', 'merge', 'subjectedit', 'resort' ) as $action ) {
163 - $wgLogActionsHandlers["liquidthreads/$action"] = 'LqtLogFormatter::formatLogEntry';
164 -}
165 -
166 -// Preferences
167 -$wgDefaultUserOptions['lqtnotifytalk'] = false;
168 -$wgDefaultUserOptions['lqtdisplaydepth'] = 5;
169 -$wgDefaultUserOptions['lqtdisplaycount'] = 25;
170 -$wgDefaultUserOptions['lqtcustomsignatures'] = true;
171 -
172 -// API
173 -$wgAutoloadClasses['ApiQueryLQTThreads'] = "$dir/api/ApiQueryLQTThreads.php";
174 -$wgAPIListModules['threads'] = 'ApiQueryLQTThreads';
175 -$wgAutoloadClasses['ApiFeedLQTThreads'] = "$dir/api/ApiFeedLQTThreads.php";
176 -$wgAPIModules['feedthreads'] = 'ApiFeedLQTThreads';
177 -$wgAutoloadClasses['ApiThreadAction'] = "$dir/api/ApiThreadAction.php";
178 -$wgAPIModules['threadaction'] = 'ApiThreadAction';
179 -
180 -// Name of the extension (wmf-specific, for splitting to versions)
181 -$wgLiquidThreadsExtensionName = 'LiquidThreads';
182 -
183 -/** CONFIGURATION SECTION */
184 -
185 -$wgDefaultUserOptions['lqt-watch-threads'] = true;
186 -
187 -$wgGroupPermissions['user']['lqt-split'] = true;
188 -$wgGroupPermissions['user']['lqt-merge'] = true;
189 -
190 -$wgAvailableRights[] = 'lqt-split';
191 -$wgAvailableRights[] = 'lqt-merge';
192 -
193 -/* Allows activation of LiquidThreads on individual pages */
194 -$wgLqtPages = array();
195 -
196 -/* Allows switching LiquidThreads off for regular talk pages
197 - (intended for testing and transition) */
198 -$wgLqtTalkPages = true;
199 -
200 -/* Whether or not to activate LiquidThreads email notifications */
201 -$wgLqtEnotif = true;
202 -
203 -/* Thread actions which do *not* cause threads to be "bumped" to the top */
204 -/* Using numbers because the change type constants are defined in Threads.php, don't
205 - want to have to parse it on every page view */
206 -$wgThreadActionsNoBump = array(
207 - 3 /* Edited summary */,
208 - 10 /* Merged from */,
209 - 12 /* Split from */,
210 - 2 /* Edited root */,
211 - 14 /* Adjusted sortkey */
212 -);
213 -
214 -/** Switch this on if you've migrated from a version before around May 2009 */
215 -$wgLiquidThreadsMigrate = false;
216 -
217 -/** The default number of threads per page */
218 -$wgLiquidThreadsDefaultPageLimit = 20;
219 -
220 -/** Whether or not to allow users to activate/deactivate LiquidThreads per-page */
221 -$wgLiquidThreadsAllowUserControl = true;
222 -
223 -/** Whether or not to allow users to activate/deactivate LiquidThreads in specific namespaces.
224 - NULL means either all or none, depending on the above. */
225 -$wgLiquidThreadsAllowUserControlNamespaces = null;
226 -
227 -// Multilingal LQT
228 -require_once( $dir . 'langrid/MultilangLqt.php' );
 2+<?php
 3+if ( !defined( 'MEDIAWIKI' ) )
 4+ die();
 5+
 6+$wgExtensionCredits['other'][] = array(
 7+ 'path' => __FILE__,
 8+ 'name' => 'Liquid Threads',
 9+ 'version' => '2.0-alpha',
 10+ 'url' => 'http://www.mediawiki.org/wiki/Extension:LiquidThreads',
 11+ 'author' => array( 'David McCabe', 'Andrew Garrett' ),
 12+ 'descriptionmsg' => 'lqt-desc',
 13+);
 14+
 15+require( 'LqtFunctions.php' );
 16+
 17+define( 'NS_LQT_THREAD', efArrayDefault( 'egLqtNamespaceNumbers', 'Thread', 90 ) );
 18+define( 'NS_LQT_THREAD_TALK', efArrayDefault( 'egLqtNamespaceNumbers', 'Thread_talk', 91 ) );
 19+define( 'NS_LQT_SUMMARY', efArrayDefault( 'egLqtNamespaceNumbers', 'Summary', 92 ) );
 20+define( 'NS_LQT_SUMMARY_TALK', efArrayDefault( 'egLqtNamespaceNumbers', 'Summary_talk', 93 ) );
 21+define( 'LQT_NEWEST_CHANGES', 'nc' );
 22+define( 'LQT_NEWEST_THREADS', 'nt' );
 23+define( 'LQT_OLDEST_THREADS', 'ot' );
 24+
 25+// FIXME: would be neat if it was possible to somehow localise this.
 26+$wgCanonicalNamespaceNames[NS_LQT_THREAD] = 'Thread';
 27+$wgCanonicalNamespaceNames[NS_LQT_THREAD_TALK] = 'Thread_talk';
 28+$wgCanonicalNamespaceNames[NS_LQT_SUMMARY] = 'Summary';
 29+$wgCanonicalNamespaceNames[NS_LQT_SUMMARY_TALK] = 'Summary_talk';
 30+
 31+// FIXME: would be neat if it was possible to somehow localise this.
 32+$wgExtraNamespaces[NS_LQT_THREAD] = 'Thread';
 33+$wgExtraNamespaces[NS_LQT_THREAD_TALK] = 'Thread_talk';
 34+$wgExtraNamespaces[NS_LQT_SUMMARY] = 'Summary';
 35+$wgExtraNamespaces[NS_LQT_SUMMARY_TALK] = 'Summary_talk';
 36+
 37+// Localisation
 38+$dir = dirname( __FILE__ ) . '/';
 39+$wgExtensionMessagesFiles['LiquidThreads'] = $dir . 'i18n/Lqt.i18n.php';
 40+$wgExtensionMessagesFiles['LiquidThreadsMagic'] = $dir . 'i18n/LiquidThreads.magic.php';
 41+$wgExtensionAliasesFiles['LiquidThreads'] = $dir . 'i18n/Lqt.alias.php';
 42+
 43+// Parser Function Setup
 44+$wgHooks['ParserFirstCallInit'][] = 'lqtSetupParserFunctions';
 45+
 46+// Hooks
 47+// Main dispatch hook
 48+$wgHooks['MediaWikiPerformAction'][] = 'LqtDispatch::tryPage';
 49+$wgHooks['SkinTemplateTabs'][] = 'LqtDispatch::onSkinTemplateTabs';
 50+$wgHooks['SkinTemplateNavigation'][] = 'LqtDispatch::onSkinTemplateNavigation';
 51+
 52+// Customisation of recentchanges
 53+$wgHooks['OldChangesListRecentChangesLine'][] = 'LqtHooks::customizeOldChangesList';
 54+
 55+// Notification (watchlist, newtalk)
 56+$wgHooks['SkinTemplateOutputPageBeforeExec'][] = 'LqtHooks::setNewtalkHTML';
 57+$wgHooks['SpecialWatchlistQuery'][] = 'LqtHooks::beforeWatchlist';
 58+$wgHooks['ArticleEditUpdateNewTalk'][] = 'LqtHooks::updateNewtalkOnEdit';
 59+$wgHooks['PersonalUrls'][] = 'LqtHooks::onPersonalUrls';
 60+
 61+// Preferences
 62+$wgHooks['GetPreferences'][] = 'LqtHooks::getPreferences';
 63+
 64+// Export-related
 65+$wgHooks['XmlDumpWriterOpenPage'][] = 'LqtHooks::dumpThreadData';
 66+$wgHooks['ModifyExportQuery'][] = 'LqtHooks::modifyExportQuery';
 67+$wgHooks['OAIFetchRowsQuery'][] = 'LqtHooks::modifyOAIQuery';
 68+$wgHooks['OAIFetchRecordQuery'][] = 'LqtHooks::modifyOAIQuery';
 69+
 70+// Deletion
 71+$wgHooks['ArticleDeleteComplete'][] = 'LqtDeletionController::onArticleDeleteComplete';
 72+$wgHooks['ArticleRevisionUndeleted'][] = 'LqtDeletionController::onArticleRevisionUndeleted';
 73+$wgHooks['ArticleUndelete'][] = 'LqtDeletionController::onArticleUndelete';
 74+$wgHooks['ArticleConfirmDelete'][] = 'LqtDeletionController::onArticleConfirmDelete';
 75+$wgHooks['ArticleDelete'][] = 'LqtDeletionController::onArticleDelete';
 76+
 77+// Moving
 78+$wgHooks['SpecialMovepageAfterMove'][] = 'LqtHooks::onArticleMoveComplete';
 79+$wgHooks['AbortMove'][] = 'LqtHooks::onArticleMove';
 80+
 81+// Search
 82+$wgHooks['ShowSearchHitTitle'][] = 'LqtHooks::customiseSearchResultTitle';
 83+$wgHooks['SpecialSearchProfiles'][] = 'LqtHooks::customiseSearchProfiles';
 84+
 85+// Updates
 86+$wgHooks['LoadExtensionSchemaUpdates'][] = 'LqtHooks::onLoadExtensionSchemaUpdates';
 87+
 88+// Rename
 89+$wgHooks['RenameUserSQL'][] = 'LqtHooks::onUserRename';
 90+
 91+// Edit-related
 92+$wgHooks['EditPageBeforeEditChecks'][] = 'LqtHooks::editCheckBoxes';
 93+$wgHooks['ArticleSaveComplete'][] = 'LqtHooks::onArticleSaveComplete';
 94+
 95+// Blocking
 96+$wgHooks['UserIsBlockedFrom'][] = 'LqtHooks::userIsBlockedFrom';
 97+
 98+// Protection
 99+$wgHooks['TitleGetRestrictionTypes'][] = 'LqtHooks::getProtectionTypes';
 100+
 101+// Special pages
 102+$wgSpecialPages['MoveThread'] = 'SpecialMoveThread';
 103+$wgSpecialPages['NewMessages'] = 'SpecialNewMessages';
 104+$wgSpecialPages['SplitThread'] = 'SpecialSplitThread';
 105+$wgSpecialPages['MergeThread'] = 'SpecialMergeThread';
 106+// $wgSpecialPages['HotTopics'] = 'SpecialHotTopics';
 107+$wgSpecialPageGroups['NewMessages'] = 'wiki';
 108+
 109+// Classes
 110+$wgAutoloadClasses['LqtDispatch'] = $dir . 'classes/Dispatch.php';
 111+$wgAutoloadClasses['LqtView'] = $dir . 'classes/View.php';
 112+$wgAutoloadClasses['HistoricalThread'] = $dir . 'classes/HistoricalThread.php';
 113+$wgAutoloadClasses['Thread'] = $dir . 'classes/Thread.php';
 114+$wgAutoloadClasses['Threads'] = $dir . 'classes/Threads.php';
 115+$wgAutoloadClasses['NewMessages'] = $dir . 'classes/NewMessagesController.php';
 116+$wgAutoloadClasses['LqtParserFunctions'] = $dir . 'classes/ParserFunctions.php';
 117+$wgAutoloadClasses['LqtDeletionController'] = $dir . 'classes/DeletionController.php';
 118+$wgAutoloadClasses['LqtHooks'] = $dir . 'classes/Hooks.php';
 119+$wgAutoloadClasses['ThreadRevision'] = $dir . "/classes/ThreadRevision.php";
 120+$wgAutoloadClasses['SynchroniseThreadArticleDataJob'] = "$dir/classes/SynchroniseThreadArticleDataJob.php";
 121+$wgAutoloadClasses['ThreadHistoryPager'] = "$dir/classes/ThreadHistoryPager.php";
 122+$wgAutoloadClasses['TalkpageHistoryView'] = "$dir/pages/TalkpageHistoryView.php";
 123+$wgAutoloadClasses['LqtHotTopicsController'] = "$dir/classes/HotTopics.php";
 124+$wgAutoloadClasses['LqtLogFormatter'] = "$dir/classes/LogFormatter.php";
 125+
 126+// View classes
 127+$wgAutoloadClasses['TalkpageView'] = $dir . 'pages/TalkpageView.php';
 128+$wgAutoloadClasses['ThreadPermalinkView'] = $dir . 'pages/ThreadPermalinkView.php';
 129+$wgAutoloadClasses['TalkpageHeaderView'] = $dir . 'pages/TalkpageHeaderView.php';
 130+$wgAutoloadClasses['IndividualThreadHistoryView'] = $dir . 'pages/IndividualThreadHistoryView.php';
 131+$wgAutoloadClasses['ThreadDiffView'] = $dir . 'pages/ThreadDiffView.php';
 132+$wgAutoloadClasses['ThreadWatchView'] = $dir . 'pages/ThreadWatchView.php';
 133+$wgAutoloadClasses['ThreadProtectionFormView'] = $dir . 'pages/ThreadProtectionFormView.php';
 134+$wgAutoloadClasses['ThreadHistoryListingView'] = $dir . 'pages/ThreadHistoryListingView.php';
 135+$wgAutoloadClasses['ThreadHistoricalRevisionView'] = $dir . 'pages/ThreadHistoricalRevisionView.php';
 136+$wgAutoloadClasses['SummaryPageView'] = $dir . 'pages/SummaryPageView.php';
 137+$wgAutoloadClasses['NewUserMessagesView'] = $dir . 'pages/NewUserMessagesView.php';
 138+
 139+// Special pages
 140+$wgAutoloadClasses['ThreadActionPage'] = $dir . 'pages/ThreadActionPage.php';
 141+$wgAutoloadClasses['SpecialMoveThread'] = $dir . 'pages/SpecialMoveThread.php';
 142+$wgAutoloadClasses['SpecialNewMessages'] = $dir . 'pages/SpecialNewMessages.php';
 143+$wgAutoloadClasses['SpecialSplitThread'] = $dir . 'pages/SpecialSplitThread.php';
 144+$wgAutoloadClasses['SpecialMergeThread'] = $dir . 'pages/SpecialMergeThread.php';
 145+$wgAutoloadClasses['SpecialHotTopics'] = "$dir/pages/SpecialHotTopics.php";
 146+
 147+// Job queue
 148+$wgJobClasses['synchroniseThreadArticleData'] = 'SynchroniseThreadArticleDataJob';
 149+
 150+// Backwards-compatibility
 151+$wgAutoloadClasses['Article_LQT_Compat'] = $dir . 'compat/LqtCompatArticle.php';
 152+if ( version_compare( $wgVersion, '1.16', '<' ) ) {
 153+ $wgAutoloadClasses['HTMLForm'] = "$dir/compat/HTMLForm.php";
 154+ $wgExtensionMessagesFiles['Lqt-Compat'] = "$dir/compat/Lqt-compat.i18n.php";
 155+}
 156+
 157+// Logging
 158+$wgLogTypes[] = 'liquidthreads';
 159+$wgLogNames['liquidthreads'] = 'lqt-log-name';
 160+$wgLogHeaders['liquidthreads'] = 'lqt-log-header';
 161+
 162+foreach ( array( 'move', 'split', 'merge', 'subjectedit', 'resort' ) as $action ) {
 163+ $wgLogActionsHandlers["liquidthreads/$action"] = 'LqtLogFormatter::formatLogEntry';
 164+}
 165+
 166+// Preferences
 167+$wgDefaultUserOptions['lqtnotifytalk'] = false;
 168+$wgDefaultUserOptions['lqtdisplaydepth'] = 5;
 169+$wgDefaultUserOptions['lqtdisplaycount'] = 25;
 170+$wgDefaultUserOptions['lqtcustomsignatures'] = true;
 171+
 172+// API
 173+$wgAutoloadClasses['ApiQueryLQTThreads'] = "$dir/api/ApiQueryLQTThreads.php";
 174+$wgAPIListModules['threads'] = 'ApiQueryLQTThreads';
 175+$wgAutoloadClasses['ApiFeedLQTThreads'] = "$dir/api/ApiFeedLQTThreads.php";
 176+$wgAPIModules['feedthreads'] = 'ApiFeedLQTThreads';
 177+$wgAutoloadClasses['ApiThreadAction'] = "$dir/api/ApiThreadAction.php";
 178+$wgAPIModules['threadaction'] = 'ApiThreadAction';
 179+
 180+// Name of the extension (wmf-specific, for splitting to versions)
 181+$wgLiquidThreadsExtensionName = 'LiquidThreads';
 182+
 183+/** CONFIGURATION SECTION */
 184+
 185+$wgDefaultUserOptions['lqt-watch-threads'] = true;
 186+
 187+$wgGroupPermissions['user']['lqt-split'] = true;
 188+$wgGroupPermissions['user']['lqt-merge'] = true;
 189+
 190+$wgAvailableRights[] = 'lqt-split';
 191+$wgAvailableRights[] = 'lqt-merge';
 192+
 193+/* Allows activation of LiquidThreads on individual pages */
 194+$wgLqtPages = array();
 195+
 196+/* Allows switching LiquidThreads off for regular talk pages
 197+ (intended for testing and transition) */
 198+$wgLqtTalkPages = true;
 199+
 200+/* Whether or not to activate LiquidThreads email notifications */
 201+$wgLqtEnotif = true;
 202+
 203+/* Thread actions which do *not* cause threads to be "bumped" to the top */
 204+/* Using numbers because the change type constants are defined in Threads.php, don't
 205+ want to have to parse it on every page view */
 206+$wgThreadActionsNoBump = array(
 207+ 3 /* Edited summary */,
 208+ 10 /* Merged from */,
 209+ 12 /* Split from */,
 210+ 2 /* Edited root */,
 211+ 14 /* Adjusted sortkey */
 212+);
 213+
 214+/** Switch this on if you've migrated from a version before around May 2009 */
 215+$wgLiquidThreadsMigrate = false;
 216+
 217+/** The default number of threads per page */
 218+$wgLiquidThreadsDefaultPageLimit = 20;
 219+
 220+/** Whether or not to allow users to activate/deactivate LiquidThreads per-page */
 221+$wgLiquidThreadsAllowUserControl = true;
 222+
 223+/** Whether or not to allow users to activate/deactivate LiquidThreads in specific namespaces.
 224+ NULL means either all or none, depending on the above. */
 225+$wgLiquidThreadsAllowUserControlNamespaces = null;
 226+
 227+// Multilingal LQT
 228+require_once( $dir . 'langrid/MultilangLqt.php' );
Property changes on: trunk/extensions/MultilingualLiquidThreads/LiquidThreads.php
___________________________________________________________________
Name: svn:eol-style
229229 + native
Index: trunk/extensions/MultilingualLiquidThreads/classes/.copy.5083af11-2801-0010-9c4b-5d124da4a9ce.tmp
@@ -1,26 +1,26 @@
2 -<?php
3 -class LqtParserFunctions {
4 - static function useLiquidThreads( &$parser, $param = '1' ) {
5 - $offParams = array( 'no', 'off', 'disable' );
6 - // Figure out if they want to turn it off or on.
7 - $param = trim( strtolower( $param ) );
8 -
9 - if ( in_array( $param, $offParams ) || !$param ) {
10 - $param = 0;
11 - } else {
12 - $param = 1;
13 - }
14 -
15 - $parser->mOutput->setProperty( 'use-liquid-threads', $param );
16 - }
17 -
18 - static function lqtPageLimit( &$parser, $param = null ) {
19 - if ( $param && $param > 0 ) {
20 - $parser->mOutput->setProperty( 'lqt-page-limit', $param );
21 - }
22 - }
23 -
24 - static function efMetaTranslation( $input, $args, $parser ) {
25 - return '<notranslate><u>'.htmlspecialchars( $input ).'</u></notranslate>';
26 - }
27 -}
 2+<?php
 3+class LqtParserFunctions {
 4+ static function useLiquidThreads( &$parser, $param = '1' ) {
 5+ $offParams = array( 'no', 'off', 'disable' );
 6+ // Figure out if they want to turn it off or on.
 7+ $param = trim( strtolower( $param ) );
 8+
 9+ if ( in_array( $param, $offParams ) || !$param ) {
 10+ $param = 0;
 11+ } else {
 12+ $param = 1;
 13+ }
 14+
 15+ $parser->mOutput->setProperty( 'use-liquid-threads', $param );
 16+ }
 17+
 18+ static function lqtPageLimit( &$parser, $param = null ) {
 19+ if ( $param && $param > 0 ) {
 20+ $parser->mOutput->setProperty( 'lqt-page-limit', $param );
 21+ }
 22+ }
 23+
 24+ static function efMetaTranslation( $input, $args, $parser ) {
 25+ return '<notranslate><u>'.htmlspecialchars( $input ).'</u></notranslate>';
 26+ }
 27+}
Property changes on: trunk/extensions/MultilingualLiquidThreads/classes/.copy.5083af11-2801-0010-9c4b-5d124da4a9ce.tmp
___________________________________________________________________
Name: svn:eol-style
2828 + native
Index: trunk/extensions/MultilingualLiquidThreads/classes/LogFormatter.php
@@ -1,44 +1,44 @@
2 -<?php
3 -
4 -// Contains formatter functions for all log entry types.
5 -class LqtLogFormatter {
6 - protected static function isForIRC( ) {
7 - // FIXME this is a horrific hack, but it's better than spewing HTML in the wrong
8 - // language to IRC.
9 - return in_string( '/LogPage::addEntry/', wfGetAllCallers() );
10 - }
11 -
12 - static function formatLogEntry( $type, $action, $title, $sk, $parameters ) {
13 - switch( $action ) {
14 - case 'merge':
15 - if ( $parameters[0] ) {
16 - $msg = 'lqt-log-action-merge-across';
17 - } else {
18 - $msg = 'lqt-log-action-merge-down';
19 - }
20 - break;
21 - default:
22 - $msg = 'lqt-log-action-' . $action;
23 - break;
24 - }
25 -
26 - $options = array( 'parseinline' );
27 -
28 - $forIRC = self::isForIRC();
29 -
30 - if ( $forIRC ) {
31 - global $wgContLang;
32 - $options['language'] = $wgContLang->getCode();
33 - }
34 -
35 - $replacements = array_merge( array( $title->getPrefixedText() ), $parameters );
36 -
37 - $html = wfMsgExt( $msg, $options, $replacements );
38 -
39 - if ( $forIRC ) {
40 - $html = StringUtils::delimiterReplace( '<', '>', '', $html );
41 - }
42 -
43 - return $html;
44 - }
45 -}
 2+<?php
 3+
 4+// Contains formatter functions for all log entry types.
 5+class LqtLogFormatter {
 6+ protected static function isForIRC( ) {
 7+ // FIXME this is a horrific hack, but it's better than spewing HTML in the wrong
 8+ // language to IRC.
 9+ return in_string( '/LogPage::addEntry/', wfGetAllCallers() );
 10+ }
 11+
 12+ static function formatLogEntry( $type, $action, $title, $sk, $parameters ) {
 13+ switch( $action ) {
 14+ case 'merge':
 15+ if ( $parameters[0] ) {
 16+ $msg = 'lqt-log-action-merge-across';
 17+ } else {
 18+ $msg = 'lqt-log-action-merge-down';
 19+ }
 20+ break;
 21+ default:
 22+ $msg = 'lqt-log-action-' . $action;
 23+ break;
 24+ }
 25+
 26+ $options = array( 'parseinline' );
 27+
 28+ $forIRC = self::isForIRC();
 29+
 30+ if ( $forIRC ) {
 31+ global $wgContLang;
 32+ $options['language'] = $wgContLang->getCode();
 33+ }
 34+
 35+ $replacements = array_merge( array( $title->getPrefixedText() ), $parameters );
 36+
 37+ $html = wfMsgExt( $msg, $options, $replacements );
 38+
 39+ if ( $forIRC ) {
 40+ $html = StringUtils::delimiterReplace( '<', '>', '', $html );
 41+ }
 42+
 43+ return $html;
 44+ }
 45+}
Property changes on: trunk/extensions/MultilingualLiquidThreads/classes/LogFormatter.php
___________________________________________________________________
Name: svn:eol-style
4646 + native
Index: trunk/extensions/MultilingualLiquidThreads/classes/.copy.33c5ae11-2801-0010-9c4b-5d124da4a9ce.tmp
@@ -1,26 +1,26 @@
2 -<?php
3 -class LqtParserFunctions {
4 - static function useLiquidThreads( &$parser, $param = '1' ) {
5 - $offParams = array( 'no', 'off', 'disable' );
6 - // Figure out if they want to turn it off or on.
7 - $param = trim( strtolower( $param ) );
8 -
9 - if ( in_array( $param, $offParams ) || !$param ) {
10 - $param = 0;
11 - } else {
12 - $param = 1;
13 - }
14 -
15 - $parser->mOutput->setProperty( 'use-liquid-threads', $param );
16 - }
17 -
18 - static function lqtPageLimit( &$parser, $param = null ) {
19 - if ( $param && $param > 0 ) {
20 - $parser->mOutput->setProperty( 'lqt-page-limit', $param );
21 - }
22 - }
23 -
24 - static function efMetaTranslation( $input, $args, $parser ) {
25 - return '<notranslate><u>'.htmlspecialchars( $input ).'</u></notranslate>';
26 - }
27 -}
 2+<?php
 3+class LqtParserFunctions {
 4+ static function useLiquidThreads( &$parser, $param = '1' ) {
 5+ $offParams = array( 'no', 'off', 'disable' );
 6+ // Figure out if they want to turn it off or on.
 7+ $param = trim( strtolower( $param ) );
 8+
 9+ if ( in_array( $param, $offParams ) || !$param ) {
 10+ $param = 0;
 11+ } else {
 12+ $param = 1;
 13+ }
 14+
 15+ $parser->mOutput->setProperty( 'use-liquid-threads', $param );
 16+ }
 17+
 18+ static function lqtPageLimit( &$parser, $param = null ) {
 19+ if ( $param && $param > 0 ) {
 20+ $parser->mOutput->setProperty( 'lqt-page-limit', $param );
 21+ }
 22+ }
 23+
 24+ static function efMetaTranslation( $input, $args, $parser ) {
 25+ return '<notranslate><u>'.htmlspecialchars( $input ).'</u></notranslate>';
 26+ }
 27+}
Property changes on: trunk/extensions/MultilingualLiquidThreads/classes/.copy.33c5ae11-2801-0010-9c4b-5d124da4a9ce.tmp
___________________________________________________________________
Name: svn:eol-style
2828 + native
Index: trunk/extensions/MultilingualLiquidThreads/lqt.pg.sql
@@ -1,67 +1,67 @@
2 -
3 -BEGIN;
4 -
5 -CREATE SEQUENCE thread_thread_id_seq;
6 -CREATE TABLE thread (
7 - thread_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('thread_thread_id_seq'),
8 - thread_root INTEGER NOT NULL,
9 - thread_ancestor INTEGER NOT NULL,
10 - thread_parent INTEGER NOT NULL,
11 - thread_summary_page INTEGER NOT NULL,
12 - thread_subject TEXT NULL,
13 - thread_author_id INTEGER NULL,
14 - thread_author_name TEXT NULL,
15 - thread_modified TIMESTAMPTZ NULL DEFAULT now(),
16 - thread_created TIMESTAMPTZ NULL DEFAULT now(),
17 - thread_editedness SMALLINT NOT NULL DEFAULT 0,
18 - thread_article_namespace SMALLINT NOT NULL,
19 - thread_article_title TEXT NOT NULL,
20 - thread_article_id INTEGER NOT NULL,
21 - thread_type SMALLINT NOT NULL DEFAULT 0,
22 - thread_sortkey TEXT NOT NULL DEFAULT '',
23 - thread_replies INTEGER NOT NULL DEFAULT -1
24 -);
25 -
26 -CREATE UNIQUE INDEX thread_root_page ON thread(thread_root);
27 -CREATE INDEX thread_ancestor ON thread(thread_ancestor, thread_parent);
28 -CREATE INDEX thread_article_title ON thread(thread_article_namespace, thread_article_title, thread_sortkey);
29 -CREATE INDEX thread_article ON thread(thread_article_id, thread_sortkey);
30 -CREATE INDEX thread_modified ON thread(thread_modified);
31 -CREATE INDEX thread_created ON thread(thread_created);
32 -CREATE INDEX thread_summary_page ON thread(thread_summary_page);
33 -CREATE INDEX thread_author ON thread(thread_author_id,thread_author_name);
34 -CREATE INDEX thread_sortkey ON thread(thread_sortkey);
35 -
36 -CREATE TABLE historical_thread (
37 - hthread_id INTEGER NOT NULL,
38 - hthread_revision INTEGER NOT NULL,
39 - hthread_contents TEXT NOT NULL,
40 - hthread_change_type INTEGER NOT NULL,
41 - hthread_change_object INTEGER NOT NULL
42 -);
43 -CREATE UNIQUE INDEX historical_thread_unique ON historical_thread(hthread_id, hthread_revision);
44 -
45 -CREATE TABLE user_message_state (
46 - ums_user INTEGER NOT NULL,
47 - ums_thread INTEGER NOT NULL,
48 - ums_read_timestamp TIMESTAMPTZ
49 -);
50 -CREATE UNIQUE INDEX user_message_state_unique ON user_message_state(ums_user, ums_thread);
51 -
52 -CREATE SEQUENCE thread_history_th_id_seq;
53 -CREATE TABLE thread_history (
54 - th_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('thread_history_th_id_seq'),
55 - th_thread INTEGER NOT NULL,
56 - th_timestamp TEXT NOT NULL,
57 - th_user INTEGER NOT NULL,
58 - th_user_text TEXT NOT NULL,
59 - th_change_type INTEGER NOT NULL,
60 - th_change_object INTEGER NOT NULL,
61 - th_change_comment TEXT NOT NULL,
62 - th_content TEXT NOT NULL
63 -);
64 -CREATE INDEX thread_history_thread ON thread_history(th_thread,th_timestamp);
65 -CREATE INDEX thread_history_user ON thread_history(th_user,th_user_text);
66 -
67 -COMMIT;
 2+-- Postgres version of the schema for the LiquidThreads extension
 3+
 4+BEGIN;
 5+
 6+CREATE SEQUENCE thread_thread_id_seq;
 7+CREATE TABLE thread (
 8+ thread_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('thread_thread_id_seq'),
 9+ thread_root INTEGER NOT NULL,
 10+ thread_ancestor INTEGER NOT NULL,
 11+ thread_parent INTEGER NOT NULL,
 12+ thread_summary_page INTEGER NOT NULL,
 13+ thread_subject TEXT NULL,
 14+ thread_author_id INTEGER NULL,
 15+ thread_author_name TEXT NULL,
 16+ thread_modified TIMESTAMPTZ NULL DEFAULT now(),
 17+ thread_created TIMESTAMPTZ NULL DEFAULT now(),
 18+ thread_editedness SMALLINT NOT NULL DEFAULT 0,
 19+ thread_article_namespace SMALLINT NOT NULL,
 20+ thread_article_title TEXT NOT NULL,
 21+ thread_article_id INTEGER NOT NULL,
 22+ thread_type SMALLINT NOT NULL DEFAULT 0,
 23+ thread_sortkey TEXT NOT NULL DEFAULT '',
 24+ thread_replies INTEGER NOT NULL DEFAULT -1
 25+);
 26+
 27+CREATE UNIQUE INDEX thread_root_page ON thread(thread_root);
 28+CREATE INDEX thread_ancestor ON thread(thread_ancestor, thread_parent);
 29+CREATE INDEX thread_article_title ON thread(thread_article_namespace, thread_article_title, thread_sortkey);
 30+CREATE INDEX thread_article ON thread(thread_article_id, thread_sortkey);
 31+CREATE INDEX thread_modified ON thread(thread_modified);
 32+CREATE INDEX thread_created ON thread(thread_created);
 33+CREATE INDEX thread_summary_page ON thread(thread_summary_page);
 34+CREATE INDEX thread_author ON thread(thread_author_id,thread_author_name);
 35+CREATE INDEX thread_sortkey ON thread(thread_sortkey);
 36+
 37+CREATE TABLE historical_thread (
 38+ hthread_id INTEGER NOT NULL,
 39+ hthread_revision INTEGER NOT NULL,
 40+ hthread_contents TEXT NOT NULL,
 41+ hthread_change_type INTEGER NOT NULL,
 42+ hthread_change_object INTEGER NOT NULL
 43+);
 44+CREATE UNIQUE INDEX historical_thread_unique ON historical_thread(hthread_id, hthread_revision);
 45+
 46+CREATE TABLE user_message_state (
 47+ ums_user INTEGER NOT NULL,
 48+ ums_thread INTEGER NOT NULL,
 49+ ums_read_timestamp TIMESTAMPTZ
 50+);
 51+CREATE UNIQUE INDEX user_message_state_unique ON user_message_state(ums_user, ums_thread);
 52+
 53+CREATE SEQUENCE thread_history_th_id_seq;
 54+CREATE TABLE thread_history (
 55+ th_id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('thread_history_th_id_seq'),
 56+ th_thread INTEGER NOT NULL,
 57+ th_timestamp TEXT NOT NULL,
 58+ th_user INTEGER NOT NULL,
 59+ th_user_text TEXT NOT NULL,
 60+ th_change_type INTEGER NOT NULL,
 61+ th_change_object INTEGER NOT NULL,
 62+ th_change_comment TEXT NOT NULL,
 63+ th_content TEXT NOT NULL
 64+);
 65+CREATE INDEX thread_history_thread ON thread_history(th_thread,th_timestamp);
 66+CREATE INDEX thread_history_user ON thread_history(th_user,th_user_text);
 67+
 68+COMMIT;
Property changes on: trunk/extensions/MultilingualLiquidThreads/lqt.pg.sql
___________________________________________________________________
Name: svn:eol-style
6869 + native
Index: trunk/extensions/MultilingualLiquidThreads/schema-changes/thread_signature.sql
@@ -1,2 +1,2 @@
2 -ALTER TABLE /*_*/thread ADD COLUMN thread_signature TINYBLOB NULL;
 2+-- Add thread_signature field
 3+ALTER TABLE /*_*/thread ADD COLUMN thread_signature TINYBLOB NULL;
Property changes on: trunk/extensions/MultilingualLiquidThreads/schema-changes/thread_signature.sql
___________________________________________________________________
Name: svn:eol-style
34 + native

Status & tagging log