1 /*--------------------------------------------------------
  2  * Copyright (c) 2011, The Dojo Foundation
  3  * This software is distributed under the "Simplified BSD license",
  4  * the text of which is available at http://www.winktoolkit.org/licence.txt
  5  * or see the "license.txt" file for more details.
  6  *--------------------------------------------------------*/
  7 
  8 /**
  9  * @fileOverview Wink main object and core methods
 10  * 
 11  * @compatibility iOS2, iOS3, iOS4, iOS5, iOS6, Android 1.1, Android 1.5, Android 2.1, Android 2.2, Android 2.3, Android 3.0, Android 3.1, Android 4.0, BlackBerry 6, BlackBerry 7, Bada 1.0, Windows Phone 7.5, Windows Phone 8
 12  * @author Jerome GIRAUD
 13  */
 14 
 15 define(['../../_kernel/js/kernel'], function(wink)
 16 {
 17 	/**
 18 	 * The version of Wink currently in use
 19 	 * 
 20 	 * @property
 21 	 * @type string
 22 	 */
 23 	wink.version = '1.4.3';
 24 	
 25 	/**
 26 	 * @namespace Gathers all the HTML5 APIs related components
 27 	 */
 28 	wink.api = {};
 29 	
 30 	/**
 31 	 * @namespace Gathers all things related to CSS effects
 32 	 * 
 33 	 * @compatibility 
 34 	 * 
 35 	 * <b>2D fx</b> iOS2, iOS3, iOS4, iOS5, iOS6, Android 1.5, Android 2.1, Android 2.2, Android 2.3, Android 3.0, Android 3.1, Android 4.0, Bada 1.0, Windows Phone 7.5, Windows Phone 8
 36 	 * <br />
 37 	 * <b>3D fx</b> iOS2, iOS3, iOS4, iOS5, iOS6, Android 3.0, Android 3.1, Android 4.0, BlackBerry 7, Windows Phone 8
 38 	 * 
 39 	 * @see <a href="WINK_ROOT_URL/fx/_xy/test/test_xy_1.html" target="_blank">Test page</a>
 40 	 * @see <a href="WINK_ROOT_URL/fx/_xy/test/test_xy_2.html" target="_blank">Test page (transition)</a>
 41 	 * @see <a href="WINK_ROOT_URL/fx/_xyz/test/test_xyz.html" target="_blank">Test page (3d)</a>
 42 	 */
 43 	wink.fx = {};
 44 	
 45 	/**
 46 	 * @namespace A set a of mathematical libraries and methods
 47 	 * 
 48 	 * @compatibility
 49 	 * 
 50 	 * <b>basics</b> iOS2, iOS3, iOS4, iOS5, iOS6, Android 1.1, Android 1.5, Android 2.1, Android 2.2, Android 2.3, Android 3.0, Android 3.1, Android 4.0, BlackBerry 6, BlackBerry 7, Bada 1.0, Windows Phone 7.5, Windows Phone 8
 51 	 * <br />
 52 	 * <b>geometrics</b> iOS2, iOS3, iOS4, iOS5, iOS6, Android 1.1, Android 1.5, Android 2.1, Android 2.2, Android 2.3, Android 3.0, Android 3.1, Android 4.0, BlackBerry 6, BlackBerry 7, Bada 1.0, Windows Phone 7.5, Windows Phone 8
 53 	 * <br />
 54 	 * <b>matrix</b> iOS2, iOS3, iOS4, iOS5, iOS6, Android 2.1, Android 2.2, Android 2.3, Android 3.0, Android 3.1, Android 4.0, BlackBerry 6, BlackBerry 7, Bada 1.0, Windows Phone 8
 55 	 * 
 56 	 * @see <a href="WINK_ROOT_URL/math/_basics/test/test_basics.html" target="_blank">Test page (basics)</a>
 57 	 * @see <a href="WINK_ROOT_URL/math/_geometric/test/test_geometric.html" target="_blank">Test page (geometric)</a>
 58 	 * @see <a href="WINK_ROOT_URL/math/_matrix/test/test_matrix.html" target="_blank">Test page (matrix)</a>
 59 	 */
 60 	wink.math = {};
 61 	
 62 	/**
 63 	 * @namespace Gathers all the multimedia components
 64 	 */
 65 	wink.mm = {};
 66 	
 67 	/**
 68 	 * @namespace Gathers all the network related components
 69 	 */
 70 	wink.net = {};
 71 	
 72 	/**
 73 	 * @namespace Gathers all the wink plugins
 74 	 */
 75 	wink.plugins = {};
 76 	
 77 	/**
 78 	 * @namespace Gathers all the UI components
 79 	 */
 80 	wink.ui = 
 81 	{
 82 		/**
 83 		 * @namespace Gathers all the form components
 84 		 */
 85 		form: {},
 86 		/**
 87 		 * @namespace Gathers all the layout components
 88 		 */
 89 		layout: {},
 90 		/**
 91 		 * @namespace Gathers all the 2D components
 92 		 */
 93 		xy: {},
 94 		/**
 95 		 * @namespace Gathers all the 3D components
 96 		 */
 97 		xyz: {}
 98 	};
 99 	
100 	/**
101 	 * @namespace Gathers all the interactions components
102 	 */
103 	wink.ux = {};
104 	
105 	var slice = Array.prototype.slice;
106 	var wd = window;
107 	
108 	/**
109 	 * Returns a DOM element
110 	 * 
111 	 * @param {string} id The identifier of the DOM element to return
112 	 * @returns {HTMLElement} Returns the DOM ellement if it has been found or the id otherwise
113 	 * 
114 	 * @example
115 	 * 
116 	 * var test = wink.byId('myComponent');
117 	 * 
118 	 */
119 	wink.byId = function(id)
120 	{
121 		if (wink.isString(id)) 
122 		{
123 			return document.getElementById(id);
124 		} else 
125 		{
126 			return id;
127 		}
128 	};
129 	
130 	/**
131 	 * Execute a query and returns the corresponding DOM elements
132 	 * 
133 	 * @param {string} selector The query selector you want to use
134 	 * @param {HTMLElement} [element] The element where you want to search
135 	 * 
136 	 * @returns {object} Returns a wrapper containing an array of the DOM elements corresponding to the query
137 	 * 
138 	 * @example
139 	 * 
140 	 * var test = wink.query('.MyClass');
141 	 * var test2 = $$('input[type=radio]');
142 	 * 
143 	 * $$(".MyClass").removeClass("hidden").addClass("active");
144 
145 	 * $$(".MyClass").translate(20, 20).rotate(2);
146 	 * var positions = $$(".MyClass").getPosition();
147 	 * 
148 	 * if ($$("#box").hasClass("visible")) {
149 	 *   $$("#box").applyTransition("background-color", "1s", "1ms", "linear").apply({ "background-color": "blue" });
150 	 *   $$("#box").listenTo("rotation", function(gestureInfos) {
151 	 *     console.log("rotation [" + gestureInfos.rotation + "deg]");
152 	 *   });
153 	 * }
154 	 * 
155 	 */
156 	wink.query = function(selector, element)
157 	{
158 		return new QueryWrapper(selector, element);
159 	};
160 	
161 	/**
162 	 * The QueryWrapper wraps the result of a query selection, allowing to chain some wink calls for each element
163 	 */
164 	var QueryWrapper = (function() {
165 		var wrapper = function(selector, element) {
166 			if (wink.isUndefined(wrapper.prototype.initialized)) {
167 				this.init();
168 			}
169 			
170 			var r;
171 			try {
172 				r = slice.call((element||document).querySelectorAll(selector));
173 			} catch (e) {
174 				r = [];
175 			}
176 			var l = this.length = r.length;
177 			
178 			for (var i = 0; i < l; i++) {
179 				this[i] = r[i];
180 			}
181 			this.selector = selector;
182 			
183 			return this;
184 		};
185 		
186 		var wp = wrapper.prototype = {
187 			/**
188 			 * Initialize the wrapper prototype's methods
189 			 * @ignore
190 			 */
191 			init: function() {
192 				wp.each([
193 					"pop", "push", "reverse", "shift", "sort", "splice", "unshift", "slice", "indexOf", "lastIndexOf", "forEach"
194 				], function(i, name) {
195 					wp[name] = [][name];
196 				});
197 				
198 				wink.query.extend(wink, [ "getPosition", "getTopPosition", "getLeftPosition" ], true);
199 				wink.query.extend(wink.fx, [ "getTransformPosition", "hasClass" ], true);
200 				wink.query.extend(wink.fx, [ "translate", "rotate", "scale", "addClass", "removeClass", 
201 				                             "apply", "applyTransition", "applyTransformTransition", "onTransitionEnd" ], false);
202 				wink.query.extend(wink.ux.gesture, [ "listenTo", "unlistenTo" ], false);
203 				
204 				wp.each([
205 					"start", "move", "end"
206 				], function(i, name) {
207 					wp[name] = function() {
208 						var l = this.size();
209 						if (l == 0) {
210 							return;
211 						}
212 						var i, nodes = this.toArray(), argus = this.splice.call(arguments, 0), t = wink.ux.touch;
213 						for (i = 0; i < l; i++) {
214 							t.addListener.apply(t, [ nodes[i], name ].concat(argus));
215 						}
216 					}
217 				});
218 				
219 				wp.initialized = true;
220 			},
221 			/**
222 			 * Extends the wrapper. The user can extend another wrapper by giving it as a parameter.
223 			 * @ignore
224 			 */
225 			extend: function(context, methods, withResult, wrapper) {
226 				var thewp = wrapper || wp,
227 					map = {};
228 				
229 				var l = methods.length;
230 				for (var i = 0; i < l; i++) {
231 					var mi = methods[i],
232 						f = context ? context[mi] : null;
233 					if (wink.isFunction(f)) {
234 						map[mi] = { c: context, f: f, r: withResult };
235 					}
236 				}
237 				
238 				wp.each(map, function(method, props) {
239 					var f = props.f,
240 						ctx = props.c,
241 						withResult = props.r;
242 					thewp[method] = function() {
243 						var l = this.size();
244 						if (l == 0) {
245 							return;
246 						}
247 						var i, nodes = this.toArray(), res = [], argus = this.splice.call(arguments, 0);
248 						for (i = 0; i < l; i++) {
249 							res.push(f.apply(ctx, [ nodes[i] ].concat(argus)));
250 						}
251 						if (!withResult) {
252 							return this;
253 						}
254 						if (res.length == 1) {
255 							return res[0];
256 						}
257 						return res;
258 					};
259 				});
260 			},
261 			/**
262 			 * @ignore
263 			 */
264 			size: function() {
265 				return this.length;
266 			},
267 			/**
268 			 * Gets an array of selected elements
269 			 * @ignore
270 			 */
271 			toArray: function() {
272 				return slice.call(this, 0);
273 			},
274 			/**
275 			 * Call the callback for each element of the list
276 			 * @ignore
277 			 */
278 			each: function(list, callback) {
279 				for (var i in list) {
280 					var li = list[i];
281 					callback.call(li, i, li);
282 				}
283 			}
284 		};
285 		
286 		return wrapper;
287 	})();
288 	
289 	/**
290 	 * Extends the wrapper
291 	 */
292 	wink.query.extend = QueryWrapper.prototype.extend;
293 	
294 	
295 	var _winklocale = "en_EN";
296 	/**
297 	 * Set wink locale used for translation
298 	 * 
299 	 * @param {string} locale The lang you want to set
300 	 */
301 	wink.setLocale = function(locale)
302 	{
303 		_winklocale = locale;
304 	};
305 	
306 	/**
307 	 * Returns the translated value of a key
308 	 * 
309 	 * @param {String} key The key identifying a ressource
310 	 * @param {Object} [object] The component that holds the resource list (within an i18n object)
311 	 * 
312 	 * @returns {string} The translated value of the key
313 	 * 
314 	 * @example
315 	 * 
316 	 * var test = wink.translate('myText')
317 	 * var test2 = _('myText');
318 	 * 
319 	 */
320 	wink.translate = function(key, object)
321 	{
322 		var result = key;
323 		var i18n = window.i18n || {};
324 		if (wink.isSet(object) && wink.isSet(object.i18n))
325 		{
326 			i18n = object.i18n;
327 		}
328 		var resourceList = i18n[_winklocale];
329 		if (wink.isUndefined(resourceList)) {
330 			resourceList = i18n;
331 		}
332 		var value = resourceList[key];
333 		if (!wink.isUndefined(value))
334 		{
335 			result = value;
336 		}
337 		return result;
338 	};
339 	
340 	/**
341 	 * Returns true if the given parameter is undefined, false otherwise.
342 	 * 
343 	 * @param {object} object The object to test
344 	 *  
345 	 * @returns {boolean} True if the object is undefined false otherwise
346 	 */
347 	wink.isUndefined = function(object) 
348 	{
349 		return (object === undefined);
350 	};
351 	
352 	/**
353 	 * Returns true if the given parameter is null, false otherwise.
354 	 * 
355 	 * @param {object} object The object to test
356 	 *  
357 	 * @returns {boolean} True if the object is null false otherwise
358 	 */
359 	wink.isNull = function(object)
360 	{
361 		return (object === null);
362 	};
363 	
364 	/**
365 	 * Returns true if the given parameter is set, false otherwise.
366 	 * 
367 	 * @param {object} object The object to test
368 	 * 
369 	 * @returns {boolean} True if the object is set false otherwise
370 	 */
371 	wink.isSet = function(object) 
372 	{
373 		return ((!wink.isUndefined(object)) && (!wink.isNull(object)));
374 	};
375 	
376 	/**
377 	 * Returns true if the given callback object is valid (contains at least a method. It can also contain a context)
378 	 * A callback can be also a function.
379 	 * 
380 	 * @param {object|function} callback The object to test
381 	 * 
382 	 * @returns {boolean} True if the object is a valid callback false otherwise
383 	 */
384 	wink.isCallback = function(callback) 
385 	{
386 		return !!((callback && callback.method) || wink.isFunction(callback));
387 	};
388 	
389 	/**
390 	 * Returns true if the given parameter is a string, false otherwise.
391 	 * 
392 	 * @param {object} object The object to test
393 	 *  
394 	 * @returns {boolean} True if the object is a string false otherwise
395 	 */
396 	wink.isString = function(object) 
397 	{
398 		return (typeof object == "string" || object instanceof String);
399 	};
400 	
401 	/**
402 	 * Returns true if the given parameter is an integer
403 	 * 
404 	 * @param {object} object The object to test
405 	 * 
406 	 * @returns {boolean} True if the object is an integer false otherwise
407 	 */
408 	wink.isInteger = function(object)
409 	{
410 		return (parseInt(object)===object);
411 	};
412 	
413 	/**
414 	 * Returns true if the given parameter is a number
415 	 * 
416 	 * @param {object} object The object to test
417 	 * 
418 	 * @returns {boolean} True if the object is a number false otherwise
419 	 */
420 	wink.isNumber = function(object)
421 	{
422 		return (typeof object == "number" || object instanceof Number);
423 	};
424 	
425 	/**
426 	 * Returns true if the given parameter is an array
427 	 * 
428 	 * @param {object} object The object to test
429 	 * 
430 	 * @returns {boolean} True if the object is an array false otherwise
431 	 */
432 	wink.isArray = function(object)
433 	{
434 		return (typeof object == "array" || object instanceof Array);
435 	};
436 	
437 	/**
438 	 * Returns true if the given parameter is a boolean
439 	 * 
440 	 * @param {object} object The object to test
441 	 * 
442 	 * @returns {boolean} True if the object is a boolean false otherwise
443 	 */
444 	wink.isBoolean = function(object)
445 	{
446 		return (typeof object == "boolean" || object instanceof Boolean);
447 	};
448 	
449 	/**
450 	 * Returns true if the given parameter is a function
451 	 * 
452 	 * @param {object} object The object to test
453 	 * 
454 	 * @returns {boolean} True if the object is a function false otherwise
455 	 */
456 	wink.isFunction = function(object)
457 	{
458 		return Object.prototype.toString.call(object) === "[object Function]";
459 	};
460 	
461 	/**
462 	 * Returns the given string parameter trimed.
463 	 * 
464 	 * @param {string} str The string to trim
465 	 *  
466 	 * @returns {string} The trimmed string
467 	 */
468 	wink.trim = function(str) 
469 	{
470 		return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
471 	};
472 	
473 	/**
474 	 * Binds a method to a given context
475 	 * 
476 	 * @param {string} method The method to bind
477 	 * @param {object} context The scope with which the method will be executed
478 	 * @param {object} [arguments] Arguments to pass to the binded function
479 	 * 
480 	 * @returns {function} The binded function
481 	 */
482 	wink.bind = function(method, context /*[, arg1 [, arg2 ... ] ]*/)
483 	{
484 		var args = slice.call(arguments, 2);
485 		return function()
486 		{
487 			var finalArgs = args.concat(slice.call(arguments, 0));
488 			return method.apply(context, finalArgs);
489 		};
490 	};
491 	
492 	/**
493 	 * Invokes the given callback
494 	 * 
495 	 * @param {object|function} callback The callback to invoke
496 	 * @param {object} [parameters] Parameters to pass to the callback
497 	 * 
498 	 * @returns {function} The called function
499 	 * 
500 	 * @example
501 	 * 
502 	 * var ctx = {
503 	 *   fn: function(params, message) {
504 	 *     console.log("fn: ", params.property, message);
505 	 *   }
506 	 * };
507 	 * var fn2 = function(message, params) {
508 	 *   console.log("fn2: ", params.property, message);
509 	 * };
510 	 * wink.call({ context: ctx, method: 'fn', arguments: "message" }, { property: "value" });
511 	 * wink.call(wink.bind(fn2, this, "message"), { property: "value" });
512 	 * 
513 	 */
514 	wink.call = function(callback, parameters)
515 	{
516 		if (wink.isFunction(callback))
517 		{
518 			return callback.apply(wd, wink.isArray(parameters) ? parameters : [parameters]);
519 		}
520 		
521 		var context = wd;
522 		var method = callback.method;
523 		var args = [];
524 		
525 		if (wink.isSet(callback.context))
526 		{
527 			context = callback.context;
528 		}
529 	
530 		if (arguments.length == 2)
531 		{
532 			args = [parameters];
533 		}
534 		if (wink.isSet(callback.arguments))
535 		{
536 			var additional = callback.arguments;
537 			if (!wink.isArray(additional)) {
538 				additional = [callback.arguments];
539 			}
540 			args = args.concat(additional);
541 		}
542 		return context[method].apply(context, args);
543 	};
544 	
545 	/**
546 	 * Connect a method to another method
547 	 * 
548 	 * @param {object} source The source context
549 	 * @param {string} method The source method
550 	 * @param {object|function} callback A callback that will be called once the source method will be invoked
551 	 */
552 	wink.connect = function(source, method, callback)
553 	{
554 		var isFn = wink.isFunction(callback);
555 		if (!isFn && !wink.isSet(callback.context))
556 		{
557 			callback.context = wd;
558 		}
559 		
560 		var f = source[method];
561 		
562 		if ( wink.isNull(f) || wink.isUndefined(f.cbs) )
563 		{
564 			var _source = function()
565 			{
566 				var target = _source.target,
567 					args = [].splice.call(arguments, 0);
568 				
569 				var result = target && target.apply(source, args);
570 
571 				var i, cbs = _source.cbs.slice(0), l = cbs.length;
572 				for (i = 0; i < l; i++)
573 				{
574 					var cb = cbs[i];
575 					if (wink.isFunction(cb))
576 					{
577 						wink.call(cb, args);
578 					}
579 					else
580 					{
581 						wink.call({ context: cb.context, method: cb.method, arguments: args.concat(cb.arguments) });
582 					}
583 				}
584 				
585 				return result;
586 			};
587 			
588 			_source.target = f;
589 			_source.cbs = [];
590 			
591 			f = source[method] = _source;
592 		}
593 
594 		var i, cbs = f.cbs, l = cbs.length;
595 		for (i = 0; i < l; i++)
596 		{
597 			var cb = cbs[i];
598 			if ((isFn && callback == cb) || (!isFn && cb.context == callback.context && cb.method == callback.method))
599 			{
600 				return
601 			}
602 		}
603 
604 		cbs.push(callback);
605 	};
606 	
607 	/**
608 	 * Disconnect two methods
609 	 * 
610 	 * @param {object} source The source context that was previously connected
611 	 * @param {string} method The source method that was previously connected
612 	 * @param {object|function} callback The callback that was previously connected
613 	 */
614 	wink.disconnect = function(source, method, callback)
615 	{
616 		var isFn = wink.isFunction(callback);
617 		if (!isFn && !wink.isSet(callback.context))
618 		{
619 			callback.context = wd;
620 		}
621 		
622 		var f = source[method];
623 		
624 		if ( !wink.isUndefined(f.cbs) )
625 		{
626 			var i, cbs = f.cbs, l = cbs.length;
627 			for (i = 0; i < l; i++)
628 			{
629 				var cb = cbs[i];
630 				if ((isFn && callback == cb) || (!isFn && cb.context == callback.context && cb.method == callback.method))
631 				{
632 					cbs.splice(i, 1);
633 					break;
634 				}
635 			}
636 		}
637 	};
638 	
639 	/**
640 	 * Calls a deferred method.
641 	 * 
642 	 * @param {object} context The execution context of the method to call 
643 	 * @param {string} method The method to call
644 	 * @param {integer} delay Time (in milliseconds) to wait before calling method
645 	 * @param {object} [arguments] A list of caller arguments
646 	 * 
647 	 * @returns {object} The timeout object
648 	 */
649 	wink.setTimeout = function(context, method, delay /*[, arg1 [, arg2 ... ] ]*/)
650 	{
651 		var args = slice.call(arguments, 3);
652 		var toExecute = function()
653 		{
654 			context[method].apply(context, args);
655 		};
656 		return setTimeout(toExecute, delay);
657 	};
658 	
659 	/**
660 	 * Calls a method periodically at the provided frequency
661 	 * 
662 	 * @param {object} context The execution context of the method to call 
663 	 * @param {string} method The method to call
664 	 * @param {integer} delay Time (in milliseconds) to wait before calling method again
665 	 * @param {object} [arguments] A list of caller arguments
666 	 * 
667 	 * @returns {object} The interval object
668 	 */
669 	wink.setInterval = function(context, method, delay /*[, arg1 [, arg2 ... ] ]*/)
670 	{
671 		var args = slice.call(arguments, 3);
672 		var toExecute = function()
673 		{
674 			context[method].apply(context, args);
675 		};
676 		return setInterval(toExecute, delay);
677 	};
678 	
679 	/**
680 	 * Retrieve the position of a node (top, left and transform if specified)
681 	 * 
682 	 * @param {HTMLElement} node The node
683 	 * @param {HTMLElement} [parentNode] If specified, the returned value is relative to the parentNode node. If parentNode is not a parent node of the current HTML element or if not specified, the returned value will be an absolute position
684 	 * @param {boolean} [transform] Take CSS transforms into account while calculating the position
685 	 * 
686 	 * @returns {object} the x and y position of the element
687 	 */
688 	wink.getPosition = function(node, parentNode, transform)
689 	{
690 		var position = {x: 0, y: 0};
691 		var obj = node;
692 
693 		while (obj && obj != parentNode) 
694 		{
695 			position.x += obj.offsetLeft;
696 			position.y += obj.offsetTop;
697 
698 			if ( transform )
699 			{
700 				position.x += wink.fx.getTransformPosition(obj).x;
701 				position.y += wink.fx.getTransformPosition(obj).y;
702 			}
703 			
704 			obj = obj.offsetParent;
705 		}
706 		
707 		return position;
708 	};
709 		
710 	/**
711 	 * Retrieve the top position of a node (top and transform if specified)
712 	 * 
713 	 * @param {HTMLElement} node The node
714 	 * @param {HTMLElement} [parentNode] If specified, the returned value is relative to the parentNode node. If parentNode is not a parent node of the current HTML element or if not specified, the returned value will be an absolute top position
715 	 * @param {boolean} [transform] Take CSS transforms into account while calculating the position
716 	 * 
717 	 * @returns {integer} the y position of the element
718 	 */
719 	wink.getTopPosition = function(node, parentNode, transform)
720 	{
721 		return (wink.getPosition(node, parentNode, transform).y);
722 	};
723 	
724 	/**
725 	 * Retrieve the top position of a node (left and transform if specified)
726 	 * 
727 	 * @param {HTMLElement} node The node
728 	 * @param {HTMLElement} [parentNode] If specified, the returned value is relative to the parentNode node. If parentNode is not a parent node of the current HTML element or if not specified, the returned value will be an absolute left position
729 	 * @param {boolean} [transform] Take CSS transforms into account while calculating the position
730 	 * 
731 	 * @returns {integer} The x position of the element
732 	 */
733 	wink.getLeftPosition = function(node, parentNode, transform)
734 	{
735 		return (wink.getPosition(node, parentNode, transform).x);
736 	};
737 
738 	var _uidSequence = 100;
739 	/**
740 	 * Generates a unique identifier
741 	 * 
742 	 * @returns {integer} The unique id
743 	 */
744 	wink.getUId = function()
745 	{
746 		return (_uidSequence += 1);
747 	};
748 	
749 	
750 	if (wink.isUndefined(wd._))
751 	{
752 		/**
753 		 * @function
754 		 * @see wink.translate
755 		 */
756 		_ = wink.bind(wink.translate, wink);
757 	}
758 	
759 	if (wink.isUndefined(wd.$))
760 	{
761 		/**
762 		 * @function
763 		 * @see wink.query
764 		 */
765 		$ = function() {
766 			if ( console )
767 			{
768 				console.log("$ is deprecated: the use of wink.query or $$ methods is recommanded");
769 			}
770 			return wink.query.apply(wink, arguments);
771 		};
772 	}
773 	
774 	if (wink.isUndefined(wd.$$))
775 	{
776 		/**
777 		 * @function
778 		 * @see wink.query
779 		 */
780 		$$ = wink.bind(wink.query, wink);
781 	}
782 	
783 	return wink;
784 });
785