'
1154 | , trigger: 'hover'
1155 | , title: ''
1156 | , delay: 0
1157 | }
1158 |
1159 | }(window.jQuery);/* ===========================================================
1160 | * bootstrap-popover.js v2.0.3
1161 | * http://twitter.github.com/bootstrap/javascript.html#popovers
1162 | * ===========================================================
1163 | * Copyright 2012 Twitter, Inc.
1164 | *
1165 | * Licensed under the Apache License, Version 2.0 (the "License");
1166 | * you may not use this file except in compliance with the License.
1167 | * You may obtain a copy of the License at
1168 | *
1169 | * http://www.apache.org/licenses/LICENSE-2.0
1170 | *
1171 | * Unless required by applicable law or agreed to in writing, software
1172 | * distributed under the License is distributed on an "AS IS" BASIS,
1173 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1174 | * See the License for the specific language governing permissions and
1175 | * limitations under the License.
1176 | * =========================================================== */
1177 |
1178 |
1179 | !function ($) {
1180 |
1181 | "use strict"; // jshint ;_;
1182 |
1183 |
1184 | /* POPOVER PUBLIC CLASS DEFINITION
1185 | * =============================== */
1186 |
1187 | var Popover = function ( element, options ) {
1188 | this.init('popover', element, options)
1189 | }
1190 |
1191 |
1192 | /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
1193 | ========================================== */
1194 |
1195 | Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
1196 |
1197 | constructor: Popover
1198 |
1199 | , setContent: function () {
1200 | var $tip = this.tip()
1201 | , title = this.getTitle()
1202 | , content = this.getContent()
1203 |
1204 | $tip.find('.popover-title')[this.isHTML(title) ? 'html' : 'text'](title)
1205 | $tip.find('.popover-content > *')[this.isHTML(content) ? 'html' : 'text'](content)
1206 |
1207 | $tip.removeClass('fade top bottom left right in')
1208 | }
1209 |
1210 | , hasContent: function () {
1211 | return this.getTitle() || this.getContent()
1212 | }
1213 |
1214 | , getContent: function () {
1215 | var content
1216 | , $e = this.$element
1217 | , o = this.options
1218 |
1219 | content = $e.attr('data-content')
1220 | || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
1221 |
1222 | return content
1223 | }
1224 |
1225 | , tip: function () {
1226 | if (!this.$tip) {
1227 | this.$tip = $(this.options.template)
1228 | }
1229 | return this.$tip
1230 | }
1231 |
1232 | })
1233 |
1234 |
1235 | /* POPOVER PLUGIN DEFINITION
1236 | * ======================= */
1237 |
1238 | $.fn.popover = function (option) {
1239 | return this.each(function () {
1240 | var $this = $(this)
1241 | , data = $this.data('popover')
1242 | , options = typeof option == 'object' && option
1243 | if (!data) $this.data('popover', (data = new Popover(this, options)))
1244 | if (typeof option == 'string') data[option]()
1245 | })
1246 | }
1247 |
1248 | $.fn.popover.Constructor = Popover
1249 |
1250 | $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
1251 | placement: 'right'
1252 | , content: ''
1253 | , template: '
'
1254 | })
1255 |
1256 | }(window.jQuery);/* =============================================================
1257 | * bootstrap-scrollspy.js v2.0.3
1258 | * http://twitter.github.com/bootstrap/javascript.html#scrollspy
1259 | * =============================================================
1260 | * Copyright 2012 Twitter, Inc.
1261 | *
1262 | * Licensed under the Apache License, Version 2.0 (the "License");
1263 | * you may not use this file except in compliance with the License.
1264 | * You may obtain a copy of the License at
1265 | *
1266 | * http://www.apache.org/licenses/LICENSE-2.0
1267 | *
1268 | * Unless required by applicable law or agreed to in writing, software
1269 | * distributed under the License is distributed on an "AS IS" BASIS,
1270 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1271 | * See the License for the specific language governing permissions and
1272 | * limitations under the License.
1273 | * ============================================================== */
1274 |
1275 |
1276 | !function ($) {
1277 |
1278 | "use strict"; // jshint ;_;
1279 |
1280 |
1281 | /* SCROLLSPY CLASS DEFINITION
1282 | * ========================== */
1283 |
1284 | function ScrollSpy( element, options) {
1285 | var process = $.proxy(this.process, this)
1286 | , $element = $(element).is('body') ? $(window) : $(element)
1287 | , href
1288 | this.options = $.extend({}, $.fn.scrollspy.defaults, options)
1289 | this.$scrollElement = $element.on('scroll.scroll.data-api', process)
1290 | this.selector = (this.options.target
1291 | || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1292 | || '') + ' .nav li > a'
1293 | this.$body = $('body').on('click.scroll.data-api', this.selector, process)
1294 | this.refresh()
1295 | this.process()
1296 | }
1297 |
1298 | ScrollSpy.prototype = {
1299 |
1300 | constructor: ScrollSpy
1301 |
1302 | , refresh: function () {
1303 | var self = this
1304 | , $targets
1305 |
1306 | this.offsets = $([])
1307 | this.targets = $([])
1308 |
1309 | $targets = this.$body
1310 | .find(this.selector)
1311 | .map(function () {
1312 | var $el = $(this)
1313 | , href = $el.data('target') || $el.attr('href')
1314 | , $href = /^#\w/.test(href) && $(href)
1315 | return ( $href
1316 | && href.length
1317 | && [[ $href.position().top, href ]] ) || null
1318 | })
1319 | .sort(function (a, b) { return a[0] - b[0] })
1320 | .each(function () {
1321 | self.offsets.push(this[0])
1322 | self.targets.push(this[1])
1323 | })
1324 | }
1325 |
1326 | , process: function () {
1327 | var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
1328 | , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
1329 | , maxScroll = scrollHeight - this.$scrollElement.height()
1330 | , offsets = this.offsets
1331 | , targets = this.targets
1332 | , activeTarget = this.activeTarget
1333 | , i
1334 |
1335 | if (scrollTop >= maxScroll) {
1336 | return activeTarget != (i = targets.last()[0])
1337 | && this.activate ( i )
1338 | }
1339 |
1340 | for (i = offsets.length; i--;) {
1341 | activeTarget != targets[i]
1342 | && scrollTop >= offsets[i]
1343 | && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
1344 | && this.activate( targets[i] )
1345 | }
1346 | }
1347 |
1348 | , activate: function (target) {
1349 | var active
1350 | , selector
1351 |
1352 | this.activeTarget = target
1353 |
1354 | $(this.selector)
1355 | .parent('.active')
1356 | .removeClass('active')
1357 |
1358 | selector = this.selector
1359 | + '[data-target="' + target + '"],'
1360 | + this.selector + '[href="' + target + '"]'
1361 |
1362 | active = $(selector)
1363 | .parent('li')
1364 | .addClass('active')
1365 |
1366 | if (active.parent('.dropdown-menu')) {
1367 | active = active.closest('li.dropdown').addClass('active')
1368 | }
1369 |
1370 | active.trigger('activate')
1371 | }
1372 |
1373 | }
1374 |
1375 |
1376 | /* SCROLLSPY PLUGIN DEFINITION
1377 | * =========================== */
1378 |
1379 | $.fn.scrollspy = function ( option ) {
1380 | return this.each(function () {
1381 | var $this = $(this)
1382 | , data = $this.data('scrollspy')
1383 | , options = typeof option == 'object' && option
1384 | if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
1385 | if (typeof option == 'string') data[option]()
1386 | })
1387 | }
1388 |
1389 | $.fn.scrollspy.Constructor = ScrollSpy
1390 |
1391 | $.fn.scrollspy.defaults = {
1392 | offset: 10
1393 | }
1394 |
1395 |
1396 | /* SCROLLSPY DATA-API
1397 | * ================== */
1398 |
1399 | $(function () {
1400 | $('[data-spy="scroll"]').each(function () {
1401 | var $spy = $(this)
1402 | $spy.scrollspy($spy.data())
1403 | })
1404 | })
1405 |
1406 | }(window.jQuery);/* ========================================================
1407 | * bootstrap-tab.js v2.0.3
1408 | * http://twitter.github.com/bootstrap/javascript.html#tabs
1409 | * ========================================================
1410 | * Copyright 2012 Twitter, Inc.
1411 | *
1412 | * Licensed under the Apache License, Version 2.0 (the "License");
1413 | * you may not use this file except in compliance with the License.
1414 | * You may obtain a copy of the License at
1415 | *
1416 | * http://www.apache.org/licenses/LICENSE-2.0
1417 | *
1418 | * Unless required by applicable law or agreed to in writing, software
1419 | * distributed under the License is distributed on an "AS IS" BASIS,
1420 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1421 | * See the License for the specific language governing permissions and
1422 | * limitations under the License.
1423 | * ======================================================== */
1424 |
1425 |
1426 | !function ($) {
1427 |
1428 | "use strict"; // jshint ;_;
1429 |
1430 |
1431 | /* TAB CLASS DEFINITION
1432 | * ==================== */
1433 |
1434 | var Tab = function ( element ) {
1435 | this.element = $(element)
1436 | }
1437 |
1438 | Tab.prototype = {
1439 |
1440 | constructor: Tab
1441 |
1442 | , show: function () {
1443 | var $this = this.element
1444 | , $ul = $this.closest('ul:not(.dropdown-menu)')
1445 | , selector = $this.attr('data-target')
1446 | , previous
1447 | , $target
1448 | , e
1449 |
1450 | if (!selector) {
1451 | selector = $this.attr('href')
1452 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1453 | }
1454 |
1455 | if ( $this.parent('li').hasClass('active') ) return
1456 |
1457 | previous = $ul.find('.active a').last()[0]
1458 |
1459 | e = $.Event('show', {
1460 | relatedTarget: previous
1461 | })
1462 |
1463 | $this.trigger(e)
1464 |
1465 | if (e.isDefaultPrevented()) return
1466 |
1467 | $target = $(selector)
1468 |
1469 | this.activate($this.parent('li'), $ul)
1470 | this.activate($target, $target.parent(), function () {
1471 | $this.trigger({
1472 | type: 'shown'
1473 | , relatedTarget: previous
1474 | })
1475 | })
1476 | }
1477 |
1478 | , activate: function ( element, container, callback) {
1479 | var $active = container.find('> .active')
1480 | , transition = callback
1481 | && $.support.transition
1482 | && $active.hasClass('fade')
1483 |
1484 | function next() {
1485 | $active
1486 | .removeClass('active')
1487 | .find('> .dropdown-menu > .active')
1488 | .removeClass('active')
1489 |
1490 | element.addClass('active')
1491 |
1492 | if (transition) {
1493 | element[0].offsetWidth // reflow for transition
1494 | element.addClass('in')
1495 | } else {
1496 | element.removeClass('fade')
1497 | }
1498 |
1499 | if ( element.parent('.dropdown-menu') ) {
1500 | element.closest('li.dropdown').addClass('active')
1501 | }
1502 |
1503 | callback && callback()
1504 | }
1505 |
1506 | transition ?
1507 | $active.one($.support.transition.end, next) :
1508 | next()
1509 |
1510 | $active.removeClass('in')
1511 | }
1512 | }
1513 |
1514 |
1515 | /* TAB PLUGIN DEFINITION
1516 | * ===================== */
1517 |
1518 | $.fn.tab = function ( option ) {
1519 | return this.each(function () {
1520 | var $this = $(this)
1521 | , data = $this.data('tab')
1522 | if (!data) $this.data('tab', (data = new Tab(this)))
1523 | if (typeof option == 'string') data[option]()
1524 | })
1525 | }
1526 |
1527 | $.fn.tab.Constructor = Tab
1528 |
1529 |
1530 | /* TAB DATA-API
1531 | * ============ */
1532 |
1533 | $(function () {
1534 | $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1535 | e.preventDefault()
1536 | $(this).tab('show')
1537 | })
1538 | })
1539 |
1540 | }(window.jQuery);/* =============================================================
1541 | * bootstrap-typeahead.js v2.0.3
1542 | * http://twitter.github.com/bootstrap/javascript.html#typeahead
1543 | * =============================================================
1544 | * Copyright 2012 Twitter, Inc.
1545 | *
1546 | * Licensed under the Apache License, Version 2.0 (the "License");
1547 | * you may not use this file except in compliance with the License.
1548 | * You may obtain a copy of the License at
1549 | *
1550 | * http://www.apache.org/licenses/LICENSE-2.0
1551 | *
1552 | * Unless required by applicable law or agreed to in writing, software
1553 | * distributed under the License is distributed on an "AS IS" BASIS,
1554 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1555 | * See the License for the specific language governing permissions and
1556 | * limitations under the License.
1557 | * ============================================================ */
1558 |
1559 |
1560 | !function($){
1561 |
1562 | "use strict"; // jshint ;_;
1563 |
1564 |
1565 | /* TYPEAHEAD PUBLIC CLASS DEFINITION
1566 | * ================================= */
1567 |
1568 | var Typeahead = function (element, options) {
1569 | this.$element = $(element)
1570 | this.options = $.extend({}, $.fn.typeahead.defaults, options)
1571 | this.matcher = this.options.matcher || this.matcher
1572 | this.sorter = this.options.sorter || this.sorter
1573 | this.highlighter = this.options.highlighter || this.highlighter
1574 | this.updater = this.options.updater || this.updater
1575 | this.$menu = $(this.options.menu).appendTo('body')
1576 | this.source = this.options.source
1577 | this.shown = false
1578 | this.listen()
1579 | }
1580 |
1581 | Typeahead.prototype = {
1582 |
1583 | constructor: Typeahead
1584 |
1585 | , select: function () {
1586 | var val = this.$menu.find('.active').attr('data-value')
1587 | this.$element
1588 | .val(this.updater(val))
1589 | .change()
1590 | return this.hide()
1591 | }
1592 |
1593 | , updater: function (item) {
1594 | return item
1595 | }
1596 |
1597 | , show: function () {
1598 | var pos = $.extend({}, this.$element.position(), {
1599 | height: this.$element[0].offsetHeight
1600 | })
1601 |
1602 | this.$menu.css({
1603 | top: pos.top + pos.height
1604 | , left: pos.left
1605 | })
1606 |
1607 | this.$menu.show()
1608 | this.shown = true
1609 | return this
1610 | }
1611 |
1612 | , hide: function () {
1613 | this.$menu.hide()
1614 | this.shown = false
1615 | return this
1616 | }
1617 |
1618 | , lookup: function (event) {
1619 | var that = this
1620 | , items
1621 | , q
1622 |
1623 | this.query = this.$element.val()
1624 |
1625 | if (!this.query) {
1626 | return this.shown ? this.hide() : this
1627 | }
1628 |
1629 | items = $.grep(this.source, function (item) {
1630 | return that.matcher(item)
1631 | })
1632 |
1633 | items = this.sorter(items)
1634 |
1635 | if (!items.length) {
1636 | return this.shown ? this.hide() : this
1637 | }
1638 |
1639 | return this.render(items.slice(0, this.options.items)).show()
1640 | }
1641 |
1642 | , matcher: function (item) {
1643 | return ~item.toLowerCase().indexOf(this.query.toLowerCase())
1644 | }
1645 |
1646 | , sorter: function (items) {
1647 | var beginswith = []
1648 | , caseSensitive = []
1649 | , caseInsensitive = []
1650 | , item
1651 |
1652 | while (item = items.shift()) {
1653 | if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
1654 | else if (~item.indexOf(this.query)) caseSensitive.push(item)
1655 | else caseInsensitive.push(item)
1656 | }
1657 |
1658 | return beginswith.concat(caseSensitive, caseInsensitive)
1659 | }
1660 |
1661 | , highlighter: function (item) {
1662 | var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
1663 | return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
1664 | return '' + match + ''
1665 | })
1666 | }
1667 |
1668 | , render: function (items) {
1669 | var that = this
1670 |
1671 | items = $(items).map(function (i, item) {
1672 | i = $(that.options.item).attr('data-value', item)
1673 | i.find('a').html(that.highlighter(item))
1674 | return i[0]
1675 | })
1676 |
1677 | items.first().addClass('active')
1678 | this.$menu.html(items)
1679 | return this
1680 | }
1681 |
1682 | , next: function (event) {
1683 | var active = this.$menu.find('.active').removeClass('active')
1684 | , next = active.next()
1685 |
1686 | if (!next.length) {
1687 | next = $(this.$menu.find('li')[0])
1688 | }
1689 |
1690 | next.addClass('active')
1691 | }
1692 |
1693 | , prev: function (event) {
1694 | var active = this.$menu.find('.active').removeClass('active')
1695 | , prev = active.prev()
1696 |
1697 | if (!prev.length) {
1698 | prev = this.$menu.find('li').last()
1699 | }
1700 |
1701 | prev.addClass('active')
1702 | }
1703 |
1704 | , listen: function () {
1705 | this.$element
1706 | .on('blur', $.proxy(this.blur, this))
1707 | .on('keypress', $.proxy(this.keypress, this))
1708 | .on('keyup', $.proxy(this.keyup, this))
1709 |
1710 | if ($.browser.webkit || $.browser.msie) {
1711 | this.$element.on('keydown', $.proxy(this.keypress, this))
1712 | }
1713 |
1714 | this.$menu
1715 | .on('click', $.proxy(this.click, this))
1716 | .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
1717 | }
1718 |
1719 | , keyup: function (e) {
1720 | switch(e.keyCode) {
1721 | case 40: // down arrow
1722 | case 38: // up arrow
1723 | break
1724 |
1725 | case 9: // tab
1726 | case 13: // enter
1727 | if (!this.shown) return
1728 | this.select()
1729 | break
1730 |
1731 | case 27: // escape
1732 | if (!this.shown) return
1733 | this.hide()
1734 | break
1735 |
1736 | default:
1737 | this.lookup()
1738 | }
1739 |
1740 | e.stopPropagation()
1741 | e.preventDefault()
1742 | }
1743 |
1744 | , keypress: function (e) {
1745 | if (!this.shown) return
1746 |
1747 | switch(e.keyCode) {
1748 | case 9: // tab
1749 | case 13: // enter
1750 | case 27: // escape
1751 | e.preventDefault()
1752 | break
1753 |
1754 | case 38: // up arrow
1755 | if (e.type != 'keydown') break
1756 | e.preventDefault()
1757 | this.prev()
1758 | break
1759 |
1760 | case 40: // down arrow
1761 | if (e.type != 'keydown') break
1762 | e.preventDefault()
1763 | this.next()
1764 | break
1765 | }
1766 |
1767 | e.stopPropagation()
1768 | }
1769 |
1770 | , blur: function (e) {
1771 | var that = this
1772 | setTimeout(function () { that.hide() }, 150)
1773 | }
1774 |
1775 | , click: function (e) {
1776 | e.stopPropagation()
1777 | e.preventDefault()
1778 | this.select()
1779 | }
1780 |
1781 | , mouseenter: function (e) {
1782 | this.$menu.find('.active').removeClass('active')
1783 | $(e.currentTarget).addClass('active')
1784 | }
1785 |
1786 | }
1787 |
1788 |
1789 | /* TYPEAHEAD PLUGIN DEFINITION
1790 | * =========================== */
1791 |
1792 | $.fn.typeahead = function (option) {
1793 | return this.each(function () {
1794 | var $this = $(this)
1795 | , data = $this.data('typeahead')
1796 | , options = typeof option == 'object' && option
1797 | if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
1798 | if (typeof option == 'string') data[option]()
1799 | })
1800 | }
1801 |
1802 | $.fn.typeahead.defaults = {
1803 | source: []
1804 | , items: 8
1805 | , menu: '
'
1806 | , item: '
'
1807 | }
1808 |
1809 | $.fn.typeahead.Constructor = Typeahead
1810 |
1811 |
1812 | /* TYPEAHEAD DATA-API
1813 | * ================== */
1814 |
1815 | $(function () {
1816 | $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
1817 | var $this = $(this)
1818 | if ($this.data('typeahead')) return
1819 | e.preventDefault()
1820 | $this.typeahead($this.data())
1821 | })
1822 | })
1823 |
1824 | }(window.jQuery);
--------------------------------------------------------------------------------
/client/lib/emberjs/load.js:
--------------------------------------------------------------------------------
1 | define([
2 | 'lib/requirejs/plugins/order!lib/jquery/jquery',
3 | 'lib/requirejs/plugins/order!lib/bootstrap/bootstrap',
4 | 'lib/requirejs/plugins/order!lib/emberjs/ember-0.9.8.1.js'
5 | ],function() {
6 | return Ember;
7 | });
8 |
--------------------------------------------------------------------------------
/client/lib/requirejs/plugins/order.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license RequireJS order 1.0.5 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
3 | * Available via the MIT or new BSD license.
4 | * see: http://github.com/jrburke/requirejs for details
5 | */
6 | /*jslint nomen: false, plusplus: false, strict: false */
7 | /*global require: false, define: false, window: false, document: false,
8 | setTimeout: false */
9 |
10 | //Specify that requirejs optimizer should wrap this code in a closure that
11 | //maps the namespaced requirejs API to non-namespaced local variables.
12 | /*requirejs namespace: true */
13 |
14 | (function () {
15 |
16 | //Sadly necessary browser inference due to differences in the way
17 | //that browsers load and execute dynamically inserted javascript
18 | //and whether the script/cache method works when ordered execution is
19 | //desired. Currently, Gecko and Opera do not load/fire onload for scripts with
20 | //type="script/cache" but they execute injected scripts in order
21 | //unless the 'async' flag is present.
22 | //However, this is all changing in latest browsers implementing HTML5
23 | //spec. With compliant browsers .async true by default, and
24 | //if false, then it will execute in order. Favor that test first for forward
25 | //compatibility.
26 | var testScript = typeof document !== "undefined" &&
27 | typeof window !== "undefined" &&
28 | document.createElement("script"),
29 |
30 | supportsInOrderExecution = testScript && (testScript.async ||
31 | ((window.opera &&
32 | Object.prototype.toString.call(window.opera) === "[object Opera]") ||
33 | //If Firefox 2 does not have to be supported, then
34 | //a better check may be:
35 | //('mozIsLocallyAvailable' in window.navigator)
36 | ("MozAppearance" in document.documentElement.style))),
37 |
38 | //This test is true for IE browsers, which will load scripts but only
39 | //execute them once the script is added to the DOM.
40 | supportsLoadSeparateFromExecute = testScript &&
41 | testScript.readyState === 'uninitialized',
42 |
43 | readyRegExp = /^(complete|loaded)$/,
44 | cacheWaiting = [],
45 | cached = {},
46 | scriptNodes = {},
47 | scriptWaiting = [];
48 |
49 | //Done with the test script.
50 | testScript = null;
51 |
52 | //Callback used by the type="script/cache" callback that indicates a script
53 | //has finished downloading.
54 | function scriptCacheCallback(evt) {
55 | var node = evt.currentTarget || evt.srcElement, i,
56 | moduleName, resource;
57 |
58 | if (evt.type === "load" || readyRegExp.test(node.readyState)) {
59 | //Pull out the name of the module and the context.
60 | moduleName = node.getAttribute("data-requiremodule");
61 |
62 | //Mark this cache request as loaded
63 | cached[moduleName] = true;
64 |
65 | //Find out how many ordered modules have loaded
66 | for (i = 0; (resource = cacheWaiting[i]); i++) {
67 | if (cached[resource.name]) {
68 | resource.req([resource.name], resource.onLoad);
69 | } else {
70 | //Something in the ordered list is not loaded,
71 | //so wait.
72 | break;
73 | }
74 | }
75 |
76 | //If just loaded some items, remove them from cacheWaiting.
77 | if (i > 0) {
78 | cacheWaiting.splice(0, i);
79 | }
80 |
81 | //Remove this script tag from the DOM
82 | //Use a setTimeout for cleanup because some older IE versions vomit
83 | //if removing a script node while it is being evaluated.
84 | setTimeout(function () {
85 | node.parentNode.removeChild(node);
86 | }, 15);
87 | }
88 | }
89 |
90 | /**
91 | * Used for the IE case, where fetching is done by creating script element
92 | * but not attaching it to the DOM. This function will be called when that
93 | * happens so it can be determined when the node can be attached to the
94 | * DOM to trigger its execution.
95 | */
96 | function onFetchOnly(node) {
97 | var i, loadedNode, resourceName;
98 |
99 | //Mark this script as loaded.
100 | node.setAttribute('data-orderloaded', 'loaded');
101 |
102 | //Cycle through waiting scripts. If the matching node for them
103 | //is loaded, and is in the right order, add it to the DOM
104 | //to execute the script.
105 | for (i = 0; (resourceName = scriptWaiting[i]); i++) {
106 | loadedNode = scriptNodes[resourceName];
107 | if (loadedNode &&
108 | loadedNode.getAttribute('data-orderloaded') === 'loaded') {
109 | delete scriptNodes[resourceName];
110 | require.addScriptToDom(loadedNode);
111 | } else {
112 | break;
113 | }
114 | }
115 |
116 | //If just loaded some items, remove them from waiting.
117 | if (i > 0) {
118 | scriptWaiting.splice(0, i);
119 | }
120 | }
121 |
122 | define({
123 | version: '1.0.5',
124 |
125 | load: function (name, req, onLoad, config) {
126 | var hasToUrl = !!req.nameToUrl,
127 | url, node, context;
128 |
129 | //If no nameToUrl, then probably a build with a loader that
130 | //does not support it, and all modules are inlined.
131 | if (!hasToUrl) {
132 | req([name], onLoad);
133 | return;
134 | }
135 |
136 | url = req.nameToUrl(name, null);
137 |
138 | //Make sure the async attribute is not set for any pathway involving
139 | //this script.
140 | require.s.skipAsync[url] = true;
141 | if (supportsInOrderExecution || config.isBuild) {
142 | //Just a normal script tag append, but without async attribute
143 | //on the script.
144 | req([name], onLoad);
145 | } else if (supportsLoadSeparateFromExecute) {
146 | //Just fetch the URL, but do not execute it yet. The
147 | //non-standards IE case. Really not so nice because it is
148 | //assuming and touching requrejs internals. OK though since
149 | //ordered execution should go away after a long while.
150 | context = require.s.contexts._;
151 |
152 | if (!context.urlFetched[url] && !context.loaded[name]) {
153 | //Indicate the script is being fetched.
154 | context.urlFetched[url] = true;
155 |
156 | //Stuff from require.load
157 | require.resourcesReady(false);
158 | context.scriptCount += 1;
159 |
160 | //Fetch the script now, remember it.
161 | node = require.attach(url, context, name, null, null, onFetchOnly);
162 | scriptNodes[name] = node;
163 | scriptWaiting.push(name);
164 | }
165 |
166 | //Do a normal require for it, once it loads, use it as return
167 | //value.
168 | req([name], onLoad);
169 | } else {
170 | //Credit to LABjs author Kyle Simpson for finding that scripts
171 | //with type="script/cache" allow scripts to be downloaded into
172 | //browser cache but not executed. Use that
173 | //so that subsequent addition of a real type="text/javascript"
174 | //tag will cause the scripts to be executed immediately in the
175 | //correct order.
176 | if (req.specified(name)) {
177 | req([name], onLoad);
178 | } else {
179 | cacheWaiting.push({
180 | name: name,
181 | req: req,
182 | onLoad: onLoad
183 | });
184 | require.attach(url, null, name, scriptCacheCallback, "script/cache");
185 | }
186 | }
187 | }
188 | });
189 | }());
190 |
--------------------------------------------------------------------------------
/client/lib/requirejs/plugins/text.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license RequireJS text 1.0.8 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
3 | * Available via the MIT or new BSD license.
4 | * see: http://github.com/jrburke/requirejs for details
5 | */
6 | /*jslint regexp: true, plusplus: true, sloppy: true */
7 | /*global require: false, XMLHttpRequest: false, ActiveXObject: false,
8 | define: false, window: false, process: false, Packages: false,
9 | java: false, location: false */
10 |
11 | (function () {
12 | var progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
13 | xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
14 | bodyRegExp = /]*>\s*([\s\S]+)\s*<\/body>/im,
15 | hasLocation = typeof location !== 'undefined' && location.href,
16 | defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
17 | defaultHostName = hasLocation && location.hostname,
18 | defaultPort = hasLocation && (location.port || undefined),
19 | buildMap = [];
20 |
21 | define(function () {
22 | var text, fs;
23 |
24 | text = {
25 | version: '1.0.8',
26 |
27 | strip: function (content) {
28 | //Strips declarations so that external SVG and XML
29 | //documents can be added to a document without worry. Also, if the string
30 | //is an HTML document, only the part inside the body tag is returned.
31 | if (content) {
32 | content = content.replace(xmlRegExp, "");
33 | var matches = content.match(bodyRegExp);
34 | if (matches) {
35 | content = matches[1];
36 | }
37 | } else {
38 | content = "";
39 | }
40 | return content;
41 | },
42 |
43 | jsEscape: function (content) {
44 | return content.replace(/(['\\])/g, '\\$1')
45 | .replace(/[\f]/g, "\\f")
46 | .replace(/[\b]/g, "\\b")
47 | .replace(/[\n]/g, "\\n")
48 | .replace(/[\t]/g, "\\t")
49 | .replace(/[\r]/g, "\\r");
50 | },
51 |
52 | createXhr: function () {
53 | //Would love to dump the ActiveX crap in here. Need IE 6 to die first.
54 | var xhr, i, progId;
55 | if (typeof XMLHttpRequest !== "undefined") {
56 | return new XMLHttpRequest();
57 | } else if (typeof ActiveXObject !== "undefined") {
58 | for (i = 0; i < 3; i++) {
59 | progId = progIds[i];
60 | try {
61 | xhr = new ActiveXObject(progId);
62 | } catch (e) {}
63 |
64 | if (xhr) {
65 | progIds = [progId]; // so faster next time
66 | break;
67 | }
68 | }
69 | }
70 |
71 | return xhr;
72 | },
73 |
74 | /**
75 | * Parses a resource name into its component parts. Resource names
76 | * look like: module/name.ext!strip, where the !strip part is
77 | * optional.
78 | * @param {String} name the resource name
79 | * @returns {Object} with properties "moduleName", "ext" and "strip"
80 | * where strip is a boolean.
81 | */
82 | parseName: function (name) {
83 | var strip = false, index = name.indexOf("."),
84 | modName = name.substring(0, index),
85 | ext = name.substring(index + 1, name.length);
86 |
87 | index = ext.indexOf("!");
88 | if (index !== -1) {
89 | //Pull off the strip arg.
90 | strip = ext.substring(index + 1, ext.length);
91 | strip = strip === "strip";
92 | ext = ext.substring(0, index);
93 | }
94 |
95 | return {
96 | moduleName: modName,
97 | ext: ext,
98 | strip: strip
99 | };
100 | },
101 |
102 | xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
103 |
104 | /**
105 | * Is an URL on another domain. Only works for browser use, returns
106 | * false in non-browser environments. Only used to know if an
107 | * optimized .js version of a text resource should be loaded
108 | * instead.
109 | * @param {String} url
110 | * @returns Boolean
111 | */
112 | useXhr: function (url, protocol, hostname, port) {
113 | var match = text.xdRegExp.exec(url),
114 | uProtocol, uHostName, uPort;
115 | if (!match) {
116 | return true;
117 | }
118 | uProtocol = match[2];
119 | uHostName = match[3];
120 |
121 | uHostName = uHostName.split(':');
122 | uPort = uHostName[1];
123 | uHostName = uHostName[0];
124 |
125 | return (!uProtocol || uProtocol === protocol) &&
126 | (!uHostName || uHostName === hostname) &&
127 | ((!uPort && !uHostName) || uPort === port);
128 | },
129 |
130 | finishLoad: function (name, strip, content, onLoad, config) {
131 | content = strip ? text.strip(content) : content;
132 | if (config.isBuild) {
133 | buildMap[name] = content;
134 | }
135 | onLoad(content);
136 | },
137 |
138 | load: function (name, req, onLoad, config) {
139 | //Name has format: some.module.filext!strip
140 | //The strip part is optional.
141 | //if strip is present, then that means only get the string contents
142 | //inside a body tag in an HTML string. For XML/SVG content it means
143 | //removing the declarations so the content can be inserted
144 | //into the current doc without problems.
145 |
146 | // Do not bother with the work if a build and text will
147 | // not be inlined.
148 | if (config.isBuild && !config.inlineText) {
149 | onLoad();
150 | return;
151 | }
152 |
153 | var parsed = text.parseName(name),
154 | nonStripName = parsed.moduleName + '.' + parsed.ext,
155 | url = req.toUrl(nonStripName),
156 | useXhr = (config && config.text && config.text.useXhr) ||
157 | text.useXhr;
158 |
159 | //Load the text. Use XHR if possible and in a browser.
160 | if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
161 | text.get(url, function (content) {
162 | text.finishLoad(name, parsed.strip, content, onLoad, config);
163 | });
164 | } else {
165 | //Need to fetch the resource across domains. Assume
166 | //the resource has been optimized into a JS module. Fetch
167 | //by the module name + extension, but do not include the
168 | //!strip part to avoid file system issues.
169 | req([nonStripName], function (content) {
170 | text.finishLoad(parsed.moduleName + '.' + parsed.ext,
171 | parsed.strip, content, onLoad, config);
172 | });
173 | }
174 | },
175 |
176 | write: function (pluginName, moduleName, write, config) {
177 | if (buildMap.hasOwnProperty(moduleName)) {
178 | var content = text.jsEscape(buildMap[moduleName]);
179 | write.asModule(pluginName + "!" + moduleName,
180 | "define(function () { return '" +
181 | content +
182 | "';});\n");
183 | }
184 | },
185 |
186 | writeFile: function (pluginName, moduleName, req, write, config) {
187 | var parsed = text.parseName(moduleName),
188 | nonStripName = parsed.moduleName + '.' + parsed.ext,
189 | //Use a '.js' file name so that it indicates it is a
190 | //script that can be loaded across domains.
191 | fileName = req.toUrl(parsed.moduleName + '.' +
192 | parsed.ext) + '.js';
193 |
194 | //Leverage own load() method to load plugin value, but only
195 | //write out values that do not have the strip argument,
196 | //to avoid any potential issues with ! in file names.
197 | text.load(nonStripName, req, function (value) {
198 | //Use own write() method to construct full module value.
199 | //But need to create shell that translates writeFile's
200 | //write() to the right interface.
201 | var textWrite = function (contents) {
202 | return write(fileName, contents);
203 | };
204 | textWrite.asModule = function (moduleName, contents) {
205 | return write.asModule(moduleName, fileName, contents);
206 | };
207 |
208 | text.write(pluginName, nonStripName, textWrite, config);
209 | }, config);
210 | }
211 | };
212 |
213 | if (text.createXhr()) {
214 | text.get = function (url, callback) {
215 | var xhr = text.createXhr();
216 | xhr.open('GET', url, true);
217 | xhr.onreadystatechange = function (evt) {
218 | //Do not explicitly handle errors, those should be
219 | //visible via console output in the browser.
220 | if (xhr.readyState === 4) {
221 | callback(xhr.responseText);
222 | }
223 | };
224 | xhr.send(null);
225 | };
226 | } else if (typeof process !== "undefined" &&
227 | process.versions &&
228 | !!process.versions.node) {
229 | //Using special require.nodeRequire, something added by r.js.
230 | fs = require.nodeRequire('fs');
231 |
232 | text.get = function (url, callback) {
233 | var file = fs.readFileSync(url, 'utf8');
234 | //Remove BOM (Byte Mark Order) from utf8 files if it is there.
235 | if (file.indexOf('\uFEFF') === 0) {
236 | file = file.substring(1);
237 | }
238 | callback(file);
239 | };
240 | } else if (typeof Packages !== 'undefined') {
241 | //Why Java, why is this so awkward?
242 | text.get = function (url, callback) {
243 | var encoding = "utf-8",
244 | file = new java.io.File(url),
245 | lineSeparator = java.lang.System.getProperty("line.separator"),
246 | input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
247 | stringBuffer, line,
248 | content = '';
249 | try {
250 | stringBuffer = new java.lang.StringBuffer();
251 | line = input.readLine();
252 |
253 | // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
254 | // http://www.unicode.org/faq/utf_bom.html
255 |
256 | // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
257 | // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
258 | if (line && line.length() && line.charAt(0) === 0xfeff) {
259 | // Eat the BOM, since we've already found the encoding on this file,
260 | // and we plan to concatenating this buffer with others; the BOM should
261 | // only appear at the top of a file.
262 | line = line.substring(1);
263 | }
264 |
265 | stringBuffer.append(line);
266 |
267 | while ((line = input.readLine()) !== null) {
268 | stringBuffer.append(lineSeparator);
269 | stringBuffer.append(line);
270 | }
271 | //Make sure we return a JavaScript string and not a Java string.
272 | content = String(stringBuffer.toString()); //String
273 | } finally {
274 | input.close();
275 | }
276 | callback(content);
277 | };
278 | }
279 |
280 | return text;
281 | });
282 | }());
283 |
--------------------------------------------------------------------------------
/client/lib/requirejs/require.js:
--------------------------------------------------------------------------------
1 | /** vim: et:ts=4:sw=4:sts=4
2 | * @license RequireJS 1.0.8 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
3 | * Available via the MIT or new BSD license.
4 | * see: http://github.com/jrburke/requirejs for details
5 | */
6 | /*jslint strict: false, plusplus: false, sub: true */
7 | /*global window, navigator, document, importScripts, jQuery, setTimeout, opera */
8 |
9 | var requirejs, require, define;
10 | (function (undefined) {
11 | //Change this version number for each release.
12 | var version = "1.0.8",
13 | commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
14 | cjsRequireRegExp = /require\(\s*["']([^'"\s]+)["']\s*\)/g,
15 | currDirRegExp = /^\.\//,
16 | jsSuffixRegExp = /\.js$/,
17 | ostring = Object.prototype.toString,
18 | ap = Array.prototype,
19 | aps = ap.slice,
20 | apsp = ap.splice,
21 | isBrowser = !!(typeof window !== "undefined" && navigator && document),
22 | isWebWorker = !isBrowser && typeof importScripts !== "undefined",
23 | //PS3 indicates loaded and complete, but need to wait for complete
24 | //specifically. Sequence is "loading", "loaded", execution,
25 | // then "complete". The UA check is unfortunate, but not sure how
26 | //to feature test w/o causing perf issues.
27 | readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
28 | /^complete$/ : /^(complete|loaded)$/,
29 | defContextName = "_",
30 | //Oh the tragedy, detecting opera. See the usage of isOpera for reason.
31 | isOpera = typeof opera !== "undefined" && opera.toString() === "[object Opera]",
32 | empty = {},
33 | contexts = {},
34 | globalDefQueue = [],
35 | interactiveScript = null,
36 | checkLoadedDepth = 0,
37 | useInteractive = false,
38 | reservedDependencies = {
39 | require: true,
40 | module: true,
41 | exports: true
42 | },
43 | req, cfg = {}, currentlyAddingScript, s, head, baseElement, scripts, script,
44 | src, subPath, mainScript, dataMain, globalI, ctx, jQueryCheck, checkLoadedTimeoutId;
45 |
46 | function isFunction(it) {
47 | return ostring.call(it) === "[object Function]";
48 | }
49 |
50 | function isArray(it) {
51 | return ostring.call(it) === "[object Array]";
52 | }
53 |
54 | /**
55 | * Simple function to mix in properties from source into target,
56 | * but only if target does not already have a property of the same name.
57 | * This is not robust in IE for transferring methods that match
58 | * Object.prototype names, but the uses of mixin here seem unlikely to
59 | * trigger a problem related to that.
60 | */
61 | function mixin(target, source, force) {
62 | for (var prop in source) {
63 | if (!(prop in empty) && (!(prop in target) || force)) {
64 | target[prop] = source[prop];
65 | }
66 | }
67 | return req;
68 | }
69 |
70 | /**
71 | * Constructs an error with a pointer to an URL with more information.
72 | * @param {String} id the error ID that maps to an ID on a web page.
73 | * @param {String} message human readable error.
74 | * @param {Error} [err] the original error, if there is one.
75 | *
76 | * @returns {Error}
77 | */
78 | function makeError(id, msg, err) {
79 | var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
80 | if (err) {
81 | e.originalError = err;
82 | }
83 | return e;
84 | }
85 |
86 | /**
87 | * Used to set up package paths from a packagePaths or packages config object.
88 | * @param {Object} pkgs the object to store the new package config
89 | * @param {Array} currentPackages an array of packages to configure
90 | * @param {String} [dir] a prefix dir to use.
91 | */
92 | function configurePackageDir(pkgs, currentPackages, dir) {
93 | var i, location, pkgObj;
94 |
95 | for (i = 0; (pkgObj = currentPackages[i]); i++) {
96 | pkgObj = typeof pkgObj === "string" ? { name: pkgObj } : pkgObj;
97 | location = pkgObj.location;
98 |
99 | //Add dir to the path, but avoid paths that start with a slash
100 | //or have a colon (indicates a protocol)
101 | if (dir && (!location || (location.indexOf("/") !== 0 && location.indexOf(":") === -1))) {
102 | location = dir + "/" + (location || pkgObj.name);
103 | }
104 |
105 | //Create a brand new object on pkgs, since currentPackages can
106 | //be passed in again, and config.pkgs is the internal transformed
107 | //state for all package configs.
108 | pkgs[pkgObj.name] = {
109 | name: pkgObj.name,
110 | location: location || pkgObj.name,
111 | //Remove leading dot in main, so main paths are normalized,
112 | //and remove any trailing .js, since different package
113 | //envs have different conventions: some use a module name,
114 | //some use a file name.
115 | main: (pkgObj.main || "main")
116 | .replace(currDirRegExp, '')
117 | .replace(jsSuffixRegExp, '')
118 | };
119 | }
120 | }
121 |
122 | /**
123 | * jQuery 1.4.3-1.5.x use a readyWait/ready() pairing to hold DOM
124 | * ready callbacks, but jQuery 1.6 supports a holdReady() API instead.
125 | * At some point remove the readyWait/ready() support and just stick
126 | * with using holdReady.
127 | */
128 | function jQueryHoldReady($, shouldHold) {
129 | if ($.holdReady) {
130 | $.holdReady(shouldHold);
131 | } else if (shouldHold) {
132 | $.readyWait += 1;
133 | } else {
134 | $.ready(true);
135 | }
136 | }
137 |
138 | if (typeof define !== "undefined") {
139 | //If a define is already in play via another AMD loader,
140 | //do not overwrite.
141 | return;
142 | }
143 |
144 | if (typeof requirejs !== "undefined") {
145 | if (isFunction(requirejs)) {
146 | //Do not overwrite and existing requirejs instance.
147 | return;
148 | } else {
149 | cfg = requirejs;
150 | requirejs = undefined;
151 | }
152 | }
153 |
154 | //Allow for a require config object
155 | if (typeof require !== "undefined" && !isFunction(require)) {
156 | //assume it is a config object.
157 | cfg = require;
158 | require = undefined;
159 | }
160 |
161 | /**
162 | * Creates a new context for use in require and define calls.
163 | * Handle most of the heavy lifting. Do not want to use an object
164 | * with prototype here to avoid using "this" in require, in case it
165 | * needs to be used in more super secure envs that do not want this.
166 | * Also there should not be that many contexts in the page. Usually just
167 | * one for the default context, but could be extra for multiversion cases
168 | * or if a package needs a special context for a dependency that conflicts
169 | * with the standard context.
170 | */
171 | function newContext(contextName) {
172 | var context, resume,
173 | config = {
174 | waitSeconds: 7,
175 | baseUrl: "./",
176 | paths: {},
177 | pkgs: {},
178 | catchError: {}
179 | },
180 | defQueue = [],
181 | specified = {
182 | "require": true,
183 | "exports": true,
184 | "module": true
185 | },
186 | urlMap = {},
187 | defined = {},
188 | loaded = {},
189 | waiting = {},
190 | waitAry = [],
191 | urlFetched = {},
192 | managerCounter = 0,
193 | managerCallbacks = {},
194 | plugins = {},
195 | //Used to indicate which modules in a build scenario
196 | //need to be full executed.
197 | needFullExec = {},
198 | fullExec = {},
199 | resumeDepth = 0;
200 |
201 | /**
202 | * Trims the . and .. from an array of path segments.
203 | * It will keep a leading path segment if a .. will become
204 | * the first path segment, to help with module name lookups,
205 | * which act like paths, but can be remapped. But the end result,
206 | * all paths that use this function should look normalized.
207 | * NOTE: this method MODIFIES the input array.
208 | * @param {Array} ary the array of path segments.
209 | */
210 | function trimDots(ary) {
211 | var i, part;
212 | for (i = 0; (part = ary[i]); i++) {
213 | if (part === ".") {
214 | ary.splice(i, 1);
215 | i -= 1;
216 | } else if (part === "..") {
217 | if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
218 | //End of the line. Keep at least one non-dot
219 | //path segment at the front so it can be mapped
220 | //correctly to disk. Otherwise, there is likely
221 | //no path mapping for a path starting with '..'.
222 | //This can still fail, but catches the most reasonable
223 | //uses of ..
224 | break;
225 | } else if (i > 0) {
226 | ary.splice(i - 1, 2);
227 | i -= 2;
228 | }
229 | }
230 | }
231 | }
232 |
233 | /**
234 | * Given a relative module name, like ./something, normalize it to
235 | * a real name that can be mapped to a path.
236 | * @param {String} name the relative name
237 | * @param {String} baseName a real name that the name arg is relative
238 | * to.
239 | * @returns {String} normalized name
240 | */
241 | function normalize(name, baseName) {
242 | var pkgName, pkgConfig;
243 |
244 | //Adjust any relative paths.
245 | if (name && name.charAt(0) === ".") {
246 | //If have a base name, try to normalize against it,
247 | //otherwise, assume it is a top-level require that will
248 | //be relative to baseUrl in the end.
249 | if (baseName) {
250 | if (config.pkgs[baseName]) {
251 | //If the baseName is a package name, then just treat it as one
252 | //name to concat the name with.
253 | baseName = [baseName];
254 | } else {
255 | //Convert baseName to array, and lop off the last part,
256 | //so that . matches that "directory" and not name of the baseName's
257 | //module. For instance, baseName of "one/two/three", maps to
258 | //"one/two/three.js", but we want the directory, "one/two" for
259 | //this normalization.
260 | baseName = baseName.split("/");
261 | baseName = baseName.slice(0, baseName.length - 1);
262 | }
263 |
264 | name = baseName.concat(name.split("/"));
265 | trimDots(name);
266 |
267 | //Some use of packages may use a . path to reference the
268 | //"main" module name, so normalize for that.
269 | pkgConfig = config.pkgs[(pkgName = name[0])];
270 | name = name.join("/");
271 | if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {
272 | name = pkgName;
273 | }
274 | } else if (name.indexOf("./") === 0) {
275 | // No baseName, so this is ID is resolved relative
276 | // to baseUrl, pull off the leading dot.
277 | name = name.substring(2);
278 | }
279 | }
280 | return name;
281 | }
282 |
283 | /**
284 | * Creates a module mapping that includes plugin prefix, module
285 | * name, and path. If parentModuleMap is provided it will
286 | * also normalize the name via require.normalize()
287 | *
288 | * @param {String} name the module name
289 | * @param {String} [parentModuleMap] parent module map
290 | * for the module name, used to resolve relative names.
291 | *
292 | * @returns {Object}
293 | */
294 | function makeModuleMap(name, parentModuleMap) {
295 | var index = name ? name.indexOf("!") : -1,
296 | prefix = null,
297 | parentName = parentModuleMap ? parentModuleMap.name : null,
298 | originalName = name,
299 | normalizedName, url, pluginModule;
300 |
301 | if (index !== -1) {
302 | prefix = name.substring(0, index);
303 | name = name.substring(index + 1, name.length);
304 | }
305 |
306 | if (prefix) {
307 | prefix = normalize(prefix, parentName);
308 | }
309 |
310 | //Account for relative paths if there is a base name.
311 | if (name) {
312 | if (prefix) {
313 | pluginModule = defined[prefix];
314 | if (pluginModule && pluginModule.normalize) {
315 | //Plugin is loaded, use its normalize method.
316 | normalizedName = pluginModule.normalize(name, function (name) {
317 | return normalize(name, parentName);
318 | });
319 | } else {
320 | normalizedName = normalize(name, parentName);
321 | }
322 | } else {
323 | //A regular module.
324 | normalizedName = normalize(name, parentName);
325 |
326 | url = urlMap[normalizedName];
327 | if (!url) {
328 | //Calculate url for the module, if it has a name.
329 | //Use name here since nameToUrl also calls normalize,
330 | //and for relative names that are outside the baseUrl
331 | //this causes havoc. Was thinking of just removing
332 | //parentModuleMap to avoid extra normalization, but
333 | //normalize() still does a dot removal because of
334 | //issue #142, so just pass in name here and redo
335 | //the normalization. Paths outside baseUrl are just
336 | //messy to support.
337 | url = context.nameToUrl(name, null, parentModuleMap);
338 |
339 | //Store the URL mapping for later.
340 | urlMap[normalizedName] = url;
341 | }
342 | }
343 | }
344 |
345 | return {
346 | prefix: prefix,
347 | name: normalizedName,
348 | parentMap: parentModuleMap,
349 | url: url,
350 | originalName: originalName,
351 | fullName: prefix ? prefix + "!" + (normalizedName || '') : normalizedName
352 | };
353 | }
354 |
355 | /**
356 | * Determine if priority loading is done. If so clear the priorityWait
357 | */
358 | function isPriorityDone() {
359 | var priorityDone = true,
360 | priorityWait = config.priorityWait,
361 | priorityName, i;
362 | if (priorityWait) {
363 | for (i = 0; (priorityName = priorityWait[i]); i++) {
364 | if (!loaded[priorityName]) {
365 | priorityDone = false;
366 | break;
367 | }
368 | }
369 | if (priorityDone) {
370 | delete config.priorityWait;
371 | }
372 | }
373 | return priorityDone;
374 | }
375 |
376 | function makeContextModuleFunc(func, relModuleMap, enableBuildCallback) {
377 | return function () {
378 | //A version of a require function that passes a moduleName
379 | //value for items that may need to
380 | //look up paths relative to the moduleName
381 | var args = aps.call(arguments, 0), lastArg;
382 | if (enableBuildCallback &&
383 | isFunction((lastArg = args[args.length - 1]))) {
384 | lastArg.__requireJsBuild = true;
385 | }
386 | args.push(relModuleMap);
387 | return func.apply(null, args);
388 | };
389 | }
390 |
391 | /**
392 | * Helper function that creates a require function object to give to
393 | * modules that ask for it as a dependency. It needs to be specific
394 | * per module because of the implication of path mappings that may
395 | * need to be relative to the module name.
396 | */
397 | function makeRequire(relModuleMap, enableBuildCallback, altRequire) {
398 | var modRequire = makeContextModuleFunc(altRequire || context.require, relModuleMap, enableBuildCallback);
399 |
400 | mixin(modRequire, {
401 | nameToUrl: makeContextModuleFunc(context.nameToUrl, relModuleMap),
402 | toUrl: makeContextModuleFunc(context.toUrl, relModuleMap),
403 | defined: makeContextModuleFunc(context.requireDefined, relModuleMap),
404 | specified: makeContextModuleFunc(context.requireSpecified, relModuleMap),
405 | isBrowser: req.isBrowser
406 | });
407 | return modRequire;
408 | }
409 |
410 | /*
411 | * Queues a dependency for checking after the loader is out of a
412 | * "paused" state, for example while a script file is being loaded
413 | * in the browser, where it may have many modules defined in it.
414 | */
415 | function queueDependency(manager) {
416 | context.paused.push(manager);
417 | }
418 |
419 | function execManager(manager) {
420 | var i, ret, err, errFile, errModuleTree,
421 | cb = manager.callback,
422 | map = manager.map,
423 | fullName = map.fullName,
424 | args = manager.deps,
425 | listeners = manager.listeners,
426 | execCb = config.requireExecCb || req.execCb,
427 | cjsModule;
428 |
429 | //Call the callback to define the module, if necessary.
430 | if (cb && isFunction(cb)) {
431 | if (config.catchError.define) {
432 | try {
433 | ret = execCb(fullName, manager.callback, args, defined[fullName]);
434 | } catch (e) {
435 | err = e;
436 | }
437 | } else {
438 | ret = execCb(fullName, manager.callback, args, defined[fullName]);
439 | }
440 |
441 | if (fullName) {
442 | //If setting exports via "module" is in play,
443 | //favor that over return value and exports. After that,
444 | //favor a non-undefined return value over exports use.
445 | cjsModule = manager.cjsModule;
446 | if (cjsModule &&
447 | cjsModule.exports !== undefined &&
448 | //Make sure it is not already the exports value
449 | cjsModule.exports !== defined[fullName]) {
450 | ret = defined[fullName] = manager.cjsModule.exports;
451 | } else if (ret === undefined && manager.usingExports) {
452 | //exports already set the defined value.
453 | ret = defined[fullName];
454 | } else {
455 | //Use the return value from the function.
456 | defined[fullName] = ret;
457 | //If this module needed full execution in a build
458 | //environment, mark that now.
459 | if (needFullExec[fullName]) {
460 | fullExec[fullName] = true;
461 | }
462 | }
463 | }
464 | } else if (fullName) {
465 | //May just be an object definition for the module. Only
466 | //worry about defining if have a module name.
467 | ret = defined[fullName] = cb;
468 |
469 | //If this module needed full execution in a build
470 | //environment, mark that now.
471 | if (needFullExec[fullName]) {
472 | fullExec[fullName] = true;
473 | }
474 | }
475 |
476 | //Clean up waiting. Do this before error calls, and before
477 | //calling back listeners, so that bookkeeping is correct
478 | //in the event of an error and error is reported in correct order,
479 | //since the listeners will likely have errors if the
480 | //onError function does not throw.
481 | if (waiting[manager.id]) {
482 | delete waiting[manager.id];
483 | manager.isDone = true;
484 | context.waitCount -= 1;
485 | if (context.waitCount === 0) {
486 | //Clear the wait array used for cycles.
487 | waitAry = [];
488 | }
489 | }
490 |
491 | //Do not need to track manager callback now that it is defined.
492 | delete managerCallbacks[fullName];
493 |
494 | //Allow instrumentation like the optimizer to know the order
495 | //of modules executed and their dependencies.
496 | if (req.onResourceLoad && !manager.placeholder) {
497 | req.onResourceLoad(context, map, manager.depArray);
498 | }
499 |
500 | if (err) {
501 | errFile = (fullName ? makeModuleMap(fullName).url : '') ||
502 | err.fileName || err.sourceURL;
503 | errModuleTree = err.moduleTree;
504 | err = makeError('defineerror', 'Error evaluating ' +
505 | 'module "' + fullName + '" at location "' +
506 | errFile + '":\n' +
507 | err + '\nfileName:' + errFile +
508 | '\nlineNumber: ' + (err.lineNumber || err.line), err);
509 | err.moduleName = fullName;
510 | err.moduleTree = errModuleTree;
511 | return req.onError(err);
512 | }
513 |
514 | //Let listeners know of this manager's value.
515 | for (i = 0; (cb = listeners[i]); i++) {
516 | cb(ret);
517 | }
518 |
519 | return undefined;
520 | }
521 |
522 | /**
523 | * Helper that creates a callack function that is called when a dependency
524 | * is ready, and sets the i-th dependency for the manager as the
525 | * value passed to the callback generated by this function.
526 | */
527 | function makeArgCallback(manager, i) {
528 | return function (value) {
529 | //Only do the work if it has not been done
530 | //already for a dependency. Cycle breaking
531 | //logic in forceExec could mean this function
532 | //is called more than once for a given dependency.
533 | if (!manager.depDone[i]) {
534 | manager.depDone[i] = true;
535 | manager.deps[i] = value;
536 | manager.depCount -= 1;
537 | if (!manager.depCount) {
538 | //All done, execute!
539 | execManager(manager);
540 | }
541 | }
542 | };
543 | }
544 |
545 | function callPlugin(pluginName, depManager) {
546 | var map = depManager.map,
547 | fullName = map.fullName,
548 | name = map.name,
549 | plugin = plugins[pluginName] ||
550 | (plugins[pluginName] = defined[pluginName]),
551 | load;
552 |
553 | //No need to continue if the manager is already
554 | //in the process of loading.
555 | if (depManager.loading) {
556 | return;
557 | }
558 | depManager.loading = true;
559 |
560 | load = function (ret) {
561 | depManager.callback = function () {
562 | return ret;
563 | };
564 | execManager(depManager);
565 |
566 | loaded[depManager.id] = true;
567 |
568 | //The loading of this plugin
569 | //might have placed other things
570 | //in the paused queue. In particular,
571 | //a loader plugin that depends on
572 | //a different plugin loaded resource.
573 | resume();
574 | };
575 |
576 | //Allow plugins to load other code without having to know the
577 | //context or how to "complete" the load.
578 | load.fromText = function (moduleName, text) {
579 | /*jslint evil: true */
580 | var hasInteractive = useInteractive;
581 |
582 | //Indicate a the module is in process of loading.
583 | loaded[moduleName] = false;
584 | context.scriptCount += 1;
585 |
586 | //Indicate this is not a "real" module, so do not track it
587 | //for builds, it does not map to a real file.
588 | context.fake[moduleName] = true;
589 |
590 | //Turn off interactive script matching for IE for any define
591 | //calls in the text, then turn it back on at the end.
592 | if (hasInteractive) {
593 | useInteractive = false;
594 | }
595 |
596 | req.exec(text);
597 |
598 | if (hasInteractive) {
599 | useInteractive = true;
600 | }
601 |
602 | //Support anonymous modules.
603 | context.completeLoad(moduleName);
604 | };
605 |
606 | //No need to continue if the plugin value has already been
607 | //defined by a build.
608 | if (fullName in defined) {
609 | load(defined[fullName]);
610 | } else {
611 | //Use parentName here since the plugin's name is not reliable,
612 | //could be some weird string with no path that actually wants to
613 | //reference the parentName's path.
614 | plugin.load(name, makeRequire(map.parentMap, true, function (deps, cb) {
615 | var moduleDeps = [],
616 | i, dep, depMap;
617 | //Convert deps to full names and hold on to them
618 | //for reference later, when figuring out if they
619 | //are blocked by a circular dependency.
620 | for (i = 0; (dep = deps[i]); i++) {
621 | depMap = makeModuleMap(dep, map.parentMap);
622 | deps[i] = depMap.fullName;
623 | if (!depMap.prefix) {
624 | moduleDeps.push(deps[i]);
625 | }
626 | }
627 | depManager.moduleDeps = (depManager.moduleDeps || []).concat(moduleDeps);
628 | return context.require(deps, cb);
629 | }), load, config);
630 | }
631 | }
632 |
633 | /**
634 | * Adds the manager to the waiting queue. Only fully
635 | * resolved items should be in the waiting queue.
636 | */
637 | function addWait(manager) {
638 | if (!waiting[manager.id]) {
639 | waiting[manager.id] = manager;
640 | waitAry.push(manager);
641 | context.waitCount += 1;
642 | }
643 | }
644 |
645 | /**
646 | * Function added to every manager object. Created out here
647 | * to avoid new function creation for each manager instance.
648 | */
649 | function managerAdd(cb) {
650 | this.listeners.push(cb);
651 | }
652 |
653 | function getManager(map, shouldQueue) {
654 | var fullName = map.fullName,
655 | prefix = map.prefix,
656 | plugin = prefix ? plugins[prefix] ||
657 | (plugins[prefix] = defined[prefix]) : null,
658 | manager, created, pluginManager, prefixMap;
659 |
660 | if (fullName) {
661 | manager = managerCallbacks[fullName];
662 | }
663 |
664 | if (!manager) {
665 | created = true;
666 | manager = {
667 | //ID is just the full name, but if it is a plugin resource
668 | //for a plugin that has not been loaded,
669 | //then add an ID counter to it.
670 | id: (prefix && !plugin ?
671 | (managerCounter++) + '__p@:' : '') +
672 | (fullName || '__r@' + (managerCounter++)),
673 | map: map,
674 | depCount: 0,
675 | depDone: [],
676 | depCallbacks: [],
677 | deps: [],
678 | listeners: [],
679 | add: managerAdd
680 | };
681 |
682 | specified[manager.id] = true;
683 |
684 | //Only track the manager/reuse it if this is a non-plugin
685 | //resource. Also only track plugin resources once
686 | //the plugin has been loaded, and so the fullName is the
687 | //true normalized value.
688 | if (fullName && (!prefix || plugins[prefix])) {
689 | managerCallbacks[fullName] = manager;
690 | }
691 | }
692 |
693 | //If there is a plugin needed, but it is not loaded,
694 | //first load the plugin, then continue on.
695 | if (prefix && !plugin) {
696 | prefixMap = makeModuleMap(prefix);
697 |
698 | //Clear out defined and urlFetched if the plugin was previously
699 | //loaded/defined, but not as full module (as in a build
700 | //situation). However, only do this work if the plugin is in
701 | //defined but does not have a module export value.
702 | if (prefix in defined && !defined[prefix]) {
703 | delete defined[prefix];
704 | delete urlFetched[prefixMap.url];
705 | }
706 |
707 | pluginManager = getManager(prefixMap, true);
708 | pluginManager.add(function (plugin) {
709 | //Create a new manager for the normalized
710 | //resource ID and have it call this manager when
711 | //done.
712 | var newMap = makeModuleMap(map.originalName, map.parentMap),
713 | normalizedManager = getManager(newMap, true);
714 |
715 | //Indicate this manager is a placeholder for the real,
716 | //normalized thing. Important for when trying to map
717 | //modules and dependencies, for instance, in a build.
718 | manager.placeholder = true;
719 |
720 | normalizedManager.add(function (resource) {
721 | manager.callback = function () {
722 | return resource;
723 | };
724 | execManager(manager);
725 | });
726 | });
727 | } else if (created && shouldQueue) {
728 | //Indicate the resource is not loaded yet if it is to be
729 | //queued.
730 | loaded[manager.id] = false;
731 | queueDependency(manager);
732 | addWait(manager);
733 | }
734 |
735 | return manager;
736 | }
737 |
738 | function main(inName, depArray, callback, relModuleMap) {
739 | var moduleMap = makeModuleMap(inName, relModuleMap),
740 | name = moduleMap.name,
741 | fullName = moduleMap.fullName,
742 | manager = getManager(moduleMap),
743 | id = manager.id,
744 | deps = manager.deps,
745 | i, depArg, depName, depPrefix, cjsMod;
746 |
747 | if (fullName) {
748 | //If module already defined for context, or already loaded,
749 | //then leave. Also leave if jQuery is registering but it does
750 | //not match the desired version number in the config.
751 | if (fullName in defined || loaded[id] === true ||
752 | (fullName === "jquery" && config.jQuery &&
753 | config.jQuery !== callback().fn.jquery)) {
754 | return;
755 | }
756 |
757 | //Set specified/loaded here for modules that are also loaded
758 | //as part of a layer, where onScriptLoad is not fired
759 | //for those cases. Do this after the inline define and
760 | //dependency tracing is done.
761 | specified[id] = true;
762 | loaded[id] = true;
763 |
764 | //If module is jQuery set up delaying its dom ready listeners.
765 | if (fullName === "jquery" && callback) {
766 | jQueryCheck(callback());
767 | }
768 | }
769 |
770 | //Attach real depArray and callback to the manager. Do this
771 | //only if the module has not been defined already, so do this after
772 | //the fullName checks above. IE can call main() more than once
773 | //for a module.
774 | manager.depArray = depArray;
775 | manager.callback = callback;
776 |
777 | //Add the dependencies to the deps field, and register for callbacks
778 | //on the dependencies.
779 | for (i = 0; i < depArray.length; i++) {
780 | depArg = depArray[i];
781 | //There could be cases like in IE, where a trailing comma will
782 | //introduce a null dependency, so only treat a real dependency
783 | //value as a dependency.
784 | if (depArg) {
785 | //Split the dependency name into plugin and name parts
786 | depArg = makeModuleMap(depArg, (name ? moduleMap : relModuleMap));
787 | depName = depArg.fullName;
788 | depPrefix = depArg.prefix;
789 |
790 | //Fix the name in depArray to be just the name, since
791 | //that is how it will be called back later.
792 | depArray[i] = depName;
793 |
794 | //Fast path CommonJS standard dependencies.
795 | if (depName === "require") {
796 | deps[i] = makeRequire(moduleMap);
797 | } else if (depName === "exports") {
798 | //CommonJS module spec 1.1
799 | deps[i] = defined[fullName] = {};
800 | manager.usingExports = true;
801 | } else if (depName === "module") {
802 | //CommonJS module spec 1.1
803 | manager.cjsModule = cjsMod = deps[i] = {
804 | id: name,
805 | uri: name ? context.nameToUrl(name, null, relModuleMap) : undefined,
806 | exports: defined[fullName]
807 | };
808 | } else if (depName in defined && !(depName in waiting) &&
809 | (!(fullName in needFullExec) ||
810 | (fullName in needFullExec && fullExec[depName]))) {
811 | //Module already defined, and not in a build situation
812 | //where the module is a something that needs full
813 | //execution and this dependency has not been fully
814 | //executed. See r.js's requirePatch.js for more info
815 | //on fullExec.
816 | deps[i] = defined[depName];
817 | } else {
818 | //Mark this dependency as needing full exec if
819 | //the current module needs full exec.
820 | if (fullName in needFullExec) {
821 | needFullExec[depName] = true;
822 | //Reset state so fully executed code will get
823 | //picked up correctly.
824 | delete defined[depName];
825 | urlFetched[depArg.url] = false;
826 | }
827 |
828 | //Either a resource that is not loaded yet, or a plugin
829 | //resource for either a plugin that has not
830 | //loaded yet.
831 | manager.depCount += 1;
832 | manager.depCallbacks[i] = makeArgCallback(manager, i);
833 | getManager(depArg, true).add(manager.depCallbacks[i]);
834 | }
835 | }
836 | }
837 |
838 | //Do not bother tracking the manager if it is all done.
839 | if (!manager.depCount) {
840 | //All done, execute!
841 | execManager(manager);
842 | } else {
843 | addWait(manager);
844 | }
845 | }
846 |
847 | /**
848 | * Convenience method to call main for a define call that was put on
849 | * hold in the defQueue.
850 | */
851 | function callDefMain(args) {
852 | main.apply(null, args);
853 | }
854 |
855 | /**
856 | * jQuery 1.4.3+ supports ways to hold off calling
857 | * calling jQuery ready callbacks until all scripts are loaded. Be sure
858 | * to track it if the capability exists.. Also, since jQuery 1.4.3 does
859 | * not register as a module, need to do some global inference checking.
860 | * Even if it does register as a module, not guaranteed to be the precise
861 | * name of the global. If a jQuery is tracked for this context, then go
862 | * ahead and register it as a module too, if not already in process.
863 | */
864 | jQueryCheck = function (jqCandidate) {
865 | if (!context.jQuery) {
866 | var $ = jqCandidate || (typeof jQuery !== "undefined" ? jQuery : null);
867 |
868 | if ($) {
869 | //If a specific version of jQuery is wanted, make sure to only
870 | //use this jQuery if it matches.
871 | if (config.jQuery && $.fn.jquery !== config.jQuery) {
872 | return;
873 | }
874 |
875 | if ("holdReady" in $ || "readyWait" in $) {
876 | context.jQuery = $;
877 |
878 | //Manually create a "jquery" module entry if not one already
879 | //or in process. Note this could trigger an attempt at
880 | //a second jQuery registration, but does no harm since
881 | //the first one wins, and it is the same value anyway.
882 | callDefMain(["jquery", [], function () {
883 | return jQuery;
884 | }]);
885 |
886 | //Ask jQuery to hold DOM ready callbacks.
887 | if (context.scriptCount) {
888 | jQueryHoldReady($, true);
889 | context.jQueryIncremented = true;
890 | }
891 | }
892 | }
893 | }
894 | };
895 |
896 | function findCycle(manager, traced) {
897 | var fullName = manager.map.fullName,
898 | depArray = manager.depArray,
899 | fullyLoaded = true,
900 | i, depName, depManager, result;
901 |
902 | if (manager.isDone || !fullName || !loaded[fullName]) {
903 | return result;
904 | }
905 |
906 | //Found the cycle.
907 | if (traced[fullName]) {
908 | return manager;
909 | }
910 |
911 | traced[fullName] = true;
912 |
913 | //Trace through the dependencies.
914 | if (depArray) {
915 | for (i = 0; i < depArray.length; i++) {
916 | //Some array members may be null, like if a trailing comma
917 | //IE, so do the explicit [i] access and check if it has a value.
918 | depName = depArray[i];
919 | if (!loaded[depName] && !reservedDependencies[depName]) {
920 | fullyLoaded = false;
921 | break;
922 | }
923 | depManager = waiting[depName];
924 | if (depManager && !depManager.isDone && loaded[depName]) {
925 | result = findCycle(depManager, traced);
926 | if (result) {
927 | break;
928 | }
929 | }
930 | }
931 | if (!fullyLoaded) {
932 | //Discard the cycle that was found, since it cannot
933 | //be forced yet. Also clear this module from traced.
934 | result = undefined;
935 | delete traced[fullName];
936 | }
937 | }
938 |
939 | return result;
940 | }
941 |
942 | function forceExec(manager, traced) {
943 | var fullName = manager.map.fullName,
944 | depArray = manager.depArray,
945 | i, depName, depManager, prefix, prefixManager, value;
946 |
947 |
948 | if (manager.isDone || !fullName || !loaded[fullName]) {
949 | return undefined;
950 | }
951 |
952 | if (fullName) {
953 | if (traced[fullName]) {
954 | return defined[fullName];
955 | }
956 |
957 | traced[fullName] = true;
958 | }
959 |
960 | //Trace through the dependencies.
961 | if (depArray) {
962 | for (i = 0; i < depArray.length; i++) {
963 | //Some array members may be null, like if a trailing comma
964 | //IE, so do the explicit [i] access and check if it has a value.
965 | depName = depArray[i];
966 | if (depName) {
967 | //First, make sure if it is a plugin resource that the
968 | //plugin is not blocked.
969 | prefix = makeModuleMap(depName).prefix;
970 | if (prefix && (prefixManager = waiting[prefix])) {
971 | forceExec(prefixManager, traced);
972 | }
973 | depManager = waiting[depName];
974 | if (depManager && !depManager.isDone && loaded[depName]) {
975 | value = forceExec(depManager, traced);
976 | manager.depCallbacks[i](value);
977 | }
978 | }
979 | }
980 | }
981 |
982 | return defined[fullName];
983 | }
984 |
985 | /**
986 | * Checks if all modules for a context are loaded, and if so, evaluates the
987 | * new ones in right dependency order.
988 | *
989 | * @private
990 | */
991 | function checkLoaded() {
992 | var waitInterval = config.waitSeconds * 1000,
993 | //It is possible to disable the wait interval by using waitSeconds of 0.
994 | expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
995 | noLoads = "", hasLoadedProp = false, stillLoading = false,
996 | cycleDeps = [],
997 | i, prop, err, manager, cycleManager, moduleDeps;
998 |
999 | //If there are items still in the paused queue processing wait.
1000 | //This is particularly important in the sync case where each paused
1001 | //item is processed right away but there may be more waiting.
1002 | if (context.pausedCount > 0) {
1003 | return undefined;
1004 | }
1005 |
1006 | //Determine if priority loading is done. If so clear the priority. If
1007 | //not, then do not check
1008 | if (config.priorityWait) {
1009 | if (isPriorityDone()) {
1010 | //Call resume, since it could have
1011 | //some waiting dependencies to trace.
1012 | resume();
1013 | } else {
1014 | return undefined;
1015 | }
1016 | }
1017 |
1018 | //See if anything is still in flight.
1019 | for (prop in loaded) {
1020 | if (!(prop in empty)) {
1021 | hasLoadedProp = true;
1022 | if (!loaded[prop]) {
1023 | if (expired) {
1024 | noLoads += prop + " ";
1025 | } else {
1026 | stillLoading = true;
1027 | if (prop.indexOf('!') === -1) {
1028 | //No reason to keep looking for unfinished
1029 | //loading. If the only stillLoading is a
1030 | //plugin resource though, keep going,
1031 | //because it may be that a plugin resource
1032 | //is waiting on a non-plugin cycle.
1033 | cycleDeps = [];
1034 | break;
1035 | } else {
1036 | moduleDeps = managerCallbacks[prop] && managerCallbacks[prop].moduleDeps;
1037 | if (moduleDeps) {
1038 | cycleDeps.push.apply(cycleDeps, moduleDeps);
1039 | }
1040 | }
1041 | }
1042 | }
1043 | }
1044 | }
1045 |
1046 | //Check for exit conditions.
1047 | if (!hasLoadedProp && !context.waitCount) {
1048 | //If the loaded object had no items, then the rest of
1049 | //the work below does not need to be done.
1050 | return undefined;
1051 | }
1052 | if (expired && noLoads) {
1053 | //If wait time expired, throw error of unloaded modules.
1054 | err = makeError("timeout", "Load timeout for modules: " + noLoads);
1055 | err.requireType = "timeout";
1056 | err.requireModules = noLoads;
1057 | err.contextName = context.contextName;
1058 | return req.onError(err);
1059 | }
1060 |
1061 | //If still loading but a plugin is waiting on a regular module cycle
1062 | //break the cycle.
1063 | if (stillLoading && cycleDeps.length) {
1064 | for (i = 0; (manager = waiting[cycleDeps[i]]); i++) {
1065 | if ((cycleManager = findCycle(manager, {}))) {
1066 | forceExec(cycleManager, {});
1067 | break;
1068 | }
1069 | }
1070 |
1071 | }
1072 |
1073 | //If still waiting on loads, and the waiting load is something
1074 | //other than a plugin resource, or there are still outstanding
1075 | //scripts, then just try back later.
1076 | if (!expired && (stillLoading || context.scriptCount)) {
1077 | //Something is still waiting to load. Wait for it, but only
1078 | //if a timeout is not already in effect.
1079 | if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
1080 | checkLoadedTimeoutId = setTimeout(function () {
1081 | checkLoadedTimeoutId = 0;
1082 | checkLoaded();
1083 | }, 50);
1084 | }
1085 | return undefined;
1086 | }
1087 |
1088 | //If still have items in the waiting cue, but all modules have
1089 | //been loaded, then it means there are some circular dependencies
1090 | //that need to be broken.
1091 | //However, as a waiting thing is fired, then it can add items to
1092 | //the waiting cue, and those items should not be fired yet, so
1093 | //make sure to redo the checkLoaded call after breaking a single
1094 | //cycle, if nothing else loaded then this logic will pick it up
1095 | //again.
1096 | if (context.waitCount) {
1097 | //Cycle through the waitAry, and call items in sequence.
1098 | for (i = 0; (manager = waitAry[i]); i++) {
1099 | forceExec(manager, {});
1100 | }
1101 |
1102 | //If anything got placed in the paused queue, run it down.
1103 | if (context.paused.length) {
1104 | resume();
1105 | }
1106 |
1107 | //Only allow this recursion to a certain depth. Only
1108 | //triggered by errors in calling a module in which its
1109 | //modules waiting on it cannot finish loading, or some circular
1110 | //dependencies that then may add more dependencies.
1111 | //The value of 5 is a bit arbitrary. Hopefully just one extra
1112 | //pass, or two for the case of circular dependencies generating
1113 | //more work that gets resolved in the sync node case.
1114 | if (checkLoadedDepth < 5) {
1115 | checkLoadedDepth += 1;
1116 | checkLoaded();
1117 | }
1118 | }
1119 |
1120 | checkLoadedDepth = 0;
1121 |
1122 | //Check for DOM ready, and nothing is waiting across contexts.
1123 | req.checkReadyState();
1124 |
1125 | return undefined;
1126 | }
1127 |
1128 | /**
1129 | * Resumes tracing of dependencies and then checks if everything is loaded.
1130 | */
1131 | resume = function () {
1132 | var manager, map, url, i, p, args, fullName;
1133 |
1134 | //Any defined modules in the global queue, intake them now.
1135 | context.takeGlobalQueue();
1136 |
1137 | resumeDepth += 1;
1138 |
1139 | if (context.scriptCount <= 0) {
1140 | //Synchronous envs will push the number below zero with the
1141 | //decrement above, be sure to set it back to zero for good measure.
1142 | //require() calls that also do not end up loading scripts could
1143 | //push the number negative too.
1144 | context.scriptCount = 0;
1145 | }
1146 |
1147 | //Make sure any remaining defQueue items get properly processed.
1148 | while (defQueue.length) {
1149 | args = defQueue.shift();
1150 | if (args[0] === null) {
1151 | return req.onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
1152 | } else {
1153 | callDefMain(args);
1154 | }
1155 | }
1156 |
1157 | //Skip the resume of paused dependencies
1158 | //if current context is in priority wait.
1159 | if (!config.priorityWait || isPriorityDone()) {
1160 | while (context.paused.length) {
1161 | p = context.paused;
1162 | context.pausedCount += p.length;
1163 | //Reset paused list
1164 | context.paused = [];
1165 |
1166 | for (i = 0; (manager = p[i]); i++) {
1167 | map = manager.map;
1168 | url = map.url;
1169 | fullName = map.fullName;
1170 |
1171 | //If the manager is for a plugin managed resource,
1172 | //ask the plugin to load it now.
1173 | if (map.prefix) {
1174 | callPlugin(map.prefix, manager);
1175 | } else {
1176 | //Regular dependency.
1177 | if (!urlFetched[url] && !loaded[fullName]) {
1178 | (config.requireLoad || req.load)(context, fullName, url);
1179 |
1180 | //Mark the URL as fetched, but only if it is
1181 | //not an empty: URL, used by the optimizer.
1182 | //In that case we need to be sure to call
1183 | //load() for each module that is mapped to
1184 | //empty: so that dependencies are satisfied
1185 | //correctly.
1186 | if (url.indexOf('empty:') !== 0) {
1187 | urlFetched[url] = true;
1188 | }
1189 | }
1190 | }
1191 | }
1192 |
1193 | //Move the start time for timeout forward.
1194 | context.startTime = (new Date()).getTime();
1195 | context.pausedCount -= p.length;
1196 | }
1197 | }
1198 |
1199 | //Only check if loaded when resume depth is 1. It is likely that
1200 | //it is only greater than 1 in sync environments where a factory
1201 | //function also then calls the callback-style require. In those
1202 | //cases, the checkLoaded should not occur until the resume
1203 | //depth is back at the top level.
1204 | if (resumeDepth === 1) {
1205 | checkLoaded();
1206 | }
1207 |
1208 | resumeDepth -= 1;
1209 |
1210 | return undefined;
1211 | };
1212 |
1213 | //Define the context object. Many of these fields are on here
1214 | //just to make debugging easier.
1215 | context = {
1216 | contextName: contextName,
1217 | config: config,
1218 | defQueue: defQueue,
1219 | waiting: waiting,
1220 | waitCount: 0,
1221 | specified: specified,
1222 | loaded: loaded,
1223 | urlMap: urlMap,
1224 | urlFetched: urlFetched,
1225 | scriptCount: 0,
1226 | defined: defined,
1227 | paused: [],
1228 | pausedCount: 0,
1229 | plugins: plugins,
1230 | needFullExec: needFullExec,
1231 | fake: {},
1232 | fullExec: fullExec,
1233 | managerCallbacks: managerCallbacks,
1234 | makeModuleMap: makeModuleMap,
1235 | normalize: normalize,
1236 | /**
1237 | * Set a configuration for the context.
1238 | * @param {Object} cfg config object to integrate.
1239 | */
1240 | configure: function (cfg) {
1241 | var paths, prop, packages, pkgs, packagePaths, requireWait;
1242 |
1243 | //Make sure the baseUrl ends in a slash.
1244 | if (cfg.baseUrl) {
1245 | if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== "/") {
1246 | cfg.baseUrl += "/";
1247 | }
1248 | }
1249 |
1250 | //Save off the paths and packages since they require special processing,
1251 | //they are additive.
1252 | paths = config.paths;
1253 | packages = config.packages;
1254 | pkgs = config.pkgs;
1255 |
1256 | //Mix in the config values, favoring the new values over
1257 | //existing ones in context.config.
1258 | mixin(config, cfg, true);
1259 |
1260 | //Adjust paths if necessary.
1261 | if (cfg.paths) {
1262 | for (prop in cfg.paths) {
1263 | if (!(prop in empty)) {
1264 | paths[prop] = cfg.paths[prop];
1265 | }
1266 | }
1267 | config.paths = paths;
1268 | }
1269 |
1270 | packagePaths = cfg.packagePaths;
1271 | if (packagePaths || cfg.packages) {
1272 | //Convert packagePaths into a packages config.
1273 | if (packagePaths) {
1274 | for (prop in packagePaths) {
1275 | if (!(prop in empty)) {
1276 | configurePackageDir(pkgs, packagePaths[prop], prop);
1277 | }
1278 | }
1279 | }
1280 |
1281 | //Adjust packages if necessary.
1282 | if (cfg.packages) {
1283 | configurePackageDir(pkgs, cfg.packages);
1284 | }
1285 |
1286 | //Done with modifications, assing packages back to context config
1287 | config.pkgs = pkgs;
1288 | }
1289 |
1290 | //If priority loading is in effect, trigger the loads now
1291 | if (cfg.priority) {
1292 | //Hold on to requireWait value, and reset it after done
1293 | requireWait = context.requireWait;
1294 |
1295 | //Allow tracing some require calls to allow the fetching
1296 | //of the priority config.
1297 | context.requireWait = false;
1298 | //But first, call resume to register any defined modules that may
1299 | //be in a data-main built file before the priority config
1300 | //call.
1301 | resume();
1302 |
1303 | context.require(cfg.priority);
1304 |
1305 | //Trigger a resume right away, for the case when
1306 | //the script with the priority load is done as part
1307 | //of a data-main call. In that case the normal resume
1308 | //call will not happen because the scriptCount will be
1309 | //at 1, since the script for data-main is being processed.
1310 | resume();
1311 |
1312 | //Restore previous state.
1313 | context.requireWait = requireWait;
1314 | config.priorityWait = cfg.priority;
1315 | }
1316 |
1317 | //If a deps array or a config callback is specified, then call
1318 | //require with those args. This is useful when require is defined as a
1319 | //config object before require.js is loaded.
1320 | if (cfg.deps || cfg.callback) {
1321 | context.require(cfg.deps || [], cfg.callback);
1322 | }
1323 | },
1324 |
1325 | requireDefined: function (moduleName, relModuleMap) {
1326 | return makeModuleMap(moduleName, relModuleMap).fullName in defined;
1327 | },
1328 |
1329 | requireSpecified: function (moduleName, relModuleMap) {
1330 | return makeModuleMap(moduleName, relModuleMap).fullName in specified;
1331 | },
1332 |
1333 | require: function (deps, callback, relModuleMap) {
1334 | var moduleName, fullName, moduleMap;
1335 | if (typeof deps === "string") {
1336 | if (isFunction(callback)) {
1337 | //Invalid call
1338 | return req.onError(makeError("requireargs", "Invalid require call"));
1339 | }
1340 |
1341 | //Synchronous access to one module. If require.get is
1342 | //available (as in the Node adapter), prefer that.
1343 | //In this case deps is the moduleName and callback is
1344 | //the relModuleMap
1345 | if (req.get) {
1346 | return req.get(context, deps, callback);
1347 | }
1348 |
1349 | //Just return the module wanted. In this scenario, the
1350 | //second arg (if passed) is just the relModuleMap.
1351 | moduleName = deps;
1352 | relModuleMap = callback;
1353 |
1354 | //Normalize module name, if it contains . or ..
1355 | moduleMap = makeModuleMap(moduleName, relModuleMap);
1356 | fullName = moduleMap.fullName;
1357 |
1358 | if (!(fullName in defined)) {
1359 | return req.onError(makeError("notloaded", "Module name '" +
1360 | moduleMap.fullName +
1361 | "' has not been loaded yet for context: " +
1362 | contextName));
1363 | }
1364 | return defined[fullName];
1365 | }
1366 |
1367 | //Call main but only if there are dependencies or
1368 | //a callback to call.
1369 | if (deps && deps.length || callback) {
1370 | main(null, deps, callback, relModuleMap);
1371 | }
1372 |
1373 | //If the require call does not trigger anything new to load,
1374 | //then resume the dependency processing.
1375 | if (!context.requireWait) {
1376 | while (!context.scriptCount && context.paused.length) {
1377 | resume();
1378 | }
1379 | }
1380 | return context.require;
1381 | },
1382 |
1383 | /**
1384 | * Internal method to transfer globalQueue items to this context's
1385 | * defQueue.
1386 | */
1387 | takeGlobalQueue: function () {
1388 | //Push all the globalDefQueue items into the context's defQueue
1389 | if (globalDefQueue.length) {
1390 | //Array splice in the values since the context code has a
1391 | //local var ref to defQueue, so cannot just reassign the one
1392 | //on context.
1393 | apsp.apply(context.defQueue,
1394 | [context.defQueue.length - 1, 0].concat(globalDefQueue));
1395 | globalDefQueue = [];
1396 | }
1397 | },
1398 |
1399 | /**
1400 | * Internal method used by environment adapters to complete a load event.
1401 | * A load event could be a script load or just a load pass from a synchronous
1402 | * load call.
1403 | * @param {String} moduleName the name of the module to potentially complete.
1404 | */
1405 | completeLoad: function (moduleName) {
1406 | var args;
1407 |
1408 | context.takeGlobalQueue();
1409 |
1410 | while (defQueue.length) {
1411 | args = defQueue.shift();
1412 |
1413 | if (args[0] === null) {
1414 | args[0] = moduleName;
1415 | break;
1416 | } else if (args[0] === moduleName) {
1417 | //Found matching define call for this script!
1418 | break;
1419 | } else {
1420 | //Some other named define call, most likely the result
1421 | //of a build layer that included many define calls.
1422 | callDefMain(args);
1423 | args = null;
1424 | }
1425 | }
1426 | if (args) {
1427 | callDefMain(args);
1428 | } else {
1429 | //A script that does not call define(), so just simulate
1430 | //the call for it. Special exception for jQuery dynamic load.
1431 | callDefMain([moduleName, [],
1432 | moduleName === "jquery" && typeof jQuery !== "undefined" ?
1433 | function () {
1434 | return jQuery;
1435 | } : null]);
1436 | }
1437 |
1438 | //Doing this scriptCount decrement branching because sync envs
1439 | //need to decrement after resume, otherwise it looks like
1440 | //loading is complete after the first dependency is fetched.
1441 | //For browsers, it works fine to decrement after, but it means
1442 | //the checkLoaded setTimeout 50 ms cost is taken. To avoid
1443 | //that cost, decrement beforehand.
1444 | if (req.isAsync) {
1445 | context.scriptCount -= 1;
1446 | }
1447 | resume();
1448 | if (!req.isAsync) {
1449 | context.scriptCount -= 1;
1450 | }
1451 | },
1452 |
1453 | /**
1454 | * Converts a module name + .extension into an URL path.
1455 | * *Requires* the use of a module name. It does not support using
1456 | * plain URLs like nameToUrl.
1457 | */
1458 | toUrl: function (moduleNamePlusExt, relModuleMap) {
1459 | var index = moduleNamePlusExt.lastIndexOf("."),
1460 | ext = null;
1461 |
1462 | if (index !== -1) {
1463 | ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
1464 | moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
1465 | }
1466 |
1467 | return context.nameToUrl(moduleNamePlusExt, ext, relModuleMap);
1468 | },
1469 |
1470 | /**
1471 | * Converts a module name to a file path. Supports cases where
1472 | * moduleName may actually be just an URL.
1473 | */
1474 | nameToUrl: function (moduleName, ext, relModuleMap) {
1475 | var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url,
1476 | config = context.config;
1477 |
1478 | //Normalize module name if have a base relative module name to work from.
1479 | moduleName = normalize(moduleName, relModuleMap && relModuleMap.fullName);
1480 |
1481 | //If a colon is in the URL, it indicates a protocol is used and it is just
1482 | //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
1483 | //or ends with .js, then assume the user meant to use an url and not a module id.
1484 | //The slash is important for protocol-less URLs as well as full paths.
1485 | if (req.jsExtRegExp.test(moduleName)) {
1486 | //Just a plain path, not module name lookup, so just return it.
1487 | //Add extension if it is included. This is a bit wonky, only non-.js things pass
1488 | //an extension, this method probably needs to be reworked.
1489 | url = moduleName + (ext ? ext : "");
1490 | } else {
1491 | //A module that needs to be converted to a path.
1492 | paths = config.paths;
1493 | pkgs = config.pkgs;
1494 |
1495 | syms = moduleName.split("/");
1496 | //For each module name segment, see if there is a path
1497 | //registered for it. Start with most specific name
1498 | //and work up from it.
1499 | for (i = syms.length; i > 0; i--) {
1500 | parentModule = syms.slice(0, i).join("/");
1501 | if (paths[parentModule]) {
1502 | syms.splice(0, i, paths[parentModule]);
1503 | break;
1504 | } else if ((pkg = pkgs[parentModule])) {
1505 | //If module name is just the package name, then looking
1506 | //for the main module.
1507 | if (moduleName === pkg.name) {
1508 | pkgPath = pkg.location + '/' + pkg.main;
1509 | } else {
1510 | pkgPath = pkg.location;
1511 | }
1512 | syms.splice(0, i, pkgPath);
1513 | break;
1514 | }
1515 | }
1516 |
1517 | //Join the path parts together, then figure out if baseUrl is needed.
1518 | url = syms.join("/") + (ext || ".js");
1519 | url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? "" : config.baseUrl) + url;
1520 | }
1521 |
1522 | return config.urlArgs ? url +
1523 | ((url.indexOf('?') === -1 ? '?' : '&') +
1524 | config.urlArgs) : url;
1525 | }
1526 | };
1527 |
1528 | //Make these visible on the context so can be called at the very
1529 | //end of the file to bootstrap
1530 | context.jQueryCheck = jQueryCheck;
1531 | context.resume = resume;
1532 |
1533 | return context;
1534 | }
1535 |
1536 | /**
1537 | * Main entry point.
1538 | *
1539 | * If the only argument to require is a string, then the module that
1540 | * is represented by that string is fetched for the appropriate context.
1541 | *
1542 | * If the first argument is an array, then it will be treated as an array
1543 | * of dependency string names to fetch. An optional function callback can
1544 | * be specified to execute when all of those dependencies are available.
1545 | *
1546 | * Make a local req variable to help Caja compliance (it assumes things
1547 | * on a require that are not standardized), and to give a short
1548 | * name for minification/local scope use.
1549 | */
1550 | req = requirejs = function (deps, callback) {
1551 |
1552 | //Find the right context, use default
1553 | var contextName = defContextName,
1554 | context, config;
1555 |
1556 | // Determine if have config object in the call.
1557 | if (!isArray(deps) && typeof deps !== "string") {
1558 | // deps is a config object
1559 | config = deps;
1560 | if (isArray(callback)) {
1561 | // Adjust args if there are dependencies
1562 | deps = callback;
1563 | callback = arguments[2];
1564 | } else {
1565 | deps = [];
1566 | }
1567 | }
1568 |
1569 | if (config && config.context) {
1570 | contextName = config.context;
1571 | }
1572 |
1573 | context = contexts[contextName] ||
1574 | (contexts[contextName] = newContext(contextName));
1575 |
1576 | if (config) {
1577 | context.configure(config);
1578 | }
1579 |
1580 | return context.require(deps, callback);
1581 | };
1582 |
1583 | /**
1584 | * Support require.config() to make it easier to cooperate with other
1585 | * AMD loaders on globally agreed names.
1586 | */
1587 | req.config = function (config) {
1588 | return req(config);
1589 | };
1590 |
1591 | /**
1592 | * Export require as a global, but only if it does not already exist.
1593 | */
1594 | if (!require) {
1595 | require = req;
1596 | }
1597 |
1598 | /**
1599 | * Global require.toUrl(), to match global require, mostly useful
1600 | * for debugging/work in the global space.
1601 | */
1602 | req.toUrl = function (moduleNamePlusExt) {
1603 | return contexts[defContextName].toUrl(moduleNamePlusExt);
1604 | };
1605 |
1606 | req.version = version;
1607 |
1608 | //Used to filter out dependencies that are already paths.
1609 | req.jsExtRegExp = /^\/|:|\?|\.js$/;
1610 | s = req.s = {
1611 | contexts: contexts,
1612 | //Stores a list of URLs that should not get async script tag treatment.
1613 | skipAsync: {}
1614 | };
1615 |
1616 | req.isAsync = req.isBrowser = isBrowser;
1617 | if (isBrowser) {
1618 | head = s.head = document.getElementsByTagName("head")[0];
1619 | //If BASE tag is in play, using appendChild is a problem for IE6.
1620 | //When that browser dies, this can be removed. Details in this jQuery bug:
1621 | //http://dev.jquery.com/ticket/2709
1622 | baseElement = document.getElementsByTagName("base")[0];
1623 | if (baseElement) {
1624 | head = s.head = baseElement.parentNode;
1625 | }
1626 | }
1627 |
1628 | /**
1629 | * Any errors that require explicitly generates will be passed to this
1630 | * function. Intercept/override it if you want custom error handling.
1631 | * @param {Error} err the error object.
1632 | */
1633 | req.onError = function (err) {
1634 | throw err;
1635 | };
1636 |
1637 | /**
1638 | * Does the request to load a module for the browser case.
1639 | * Make this a separate function to allow other environments
1640 | * to override it.
1641 | *
1642 | * @param {Object} context the require context to find state.
1643 | * @param {String} moduleName the name of the module.
1644 | * @param {Object} url the URL to the module.
1645 | */
1646 | req.load = function (context, moduleName, url) {
1647 | req.resourcesReady(false);
1648 |
1649 | context.scriptCount += 1;
1650 | req.attach(url, context, moduleName);
1651 |
1652 | //If tracking a jQuery, then make sure its ready callbacks
1653 | //are put on hold to prevent its ready callbacks from
1654 | //triggering too soon.
1655 | if (context.jQuery && !context.jQueryIncremented) {
1656 | jQueryHoldReady(context.jQuery, true);
1657 | context.jQueryIncremented = true;
1658 | }
1659 | };
1660 |
1661 | function getInteractiveScript() {
1662 | var scripts, i, script;
1663 | if (interactiveScript && interactiveScript.readyState === 'interactive') {
1664 | return interactiveScript;
1665 | }
1666 |
1667 | scripts = document.getElementsByTagName('script');
1668 | for (i = scripts.length - 1; i > -1 && (script = scripts[i]); i--) {
1669 | if (script.readyState === 'interactive') {
1670 | return (interactiveScript = script);
1671 | }
1672 | }
1673 |
1674 | return null;
1675 | }
1676 |
1677 | /**
1678 | * The function that handles definitions of modules. Differs from
1679 | * require() in that a string for the module should be the first argument,
1680 | * and the function to execute after dependencies are loaded should
1681 | * return a value to define the module corresponding to the first argument's
1682 | * name.
1683 | */
1684 | define = function (name, deps, callback) {
1685 | var node, context;
1686 |
1687 | //Allow for anonymous functions
1688 | if (typeof name !== 'string') {
1689 | //Adjust args appropriately
1690 | callback = deps;
1691 | deps = name;
1692 | name = null;
1693 | }
1694 |
1695 | //This module may not have dependencies
1696 | if (!isArray(deps)) {
1697 | callback = deps;
1698 | deps = [];
1699 | }
1700 |
1701 | //If no name, and callback is a function, then figure out if it a
1702 | //CommonJS thing with dependencies.
1703 | if (!deps.length && isFunction(callback)) {
1704 | //Remove comments from the callback string,
1705 | //look for require calls, and pull them into the dependencies,
1706 | //but only if there are function args.
1707 | if (callback.length) {
1708 | callback
1709 | .toString()
1710 | .replace(commentRegExp, "")
1711 | .replace(cjsRequireRegExp, function (match, dep) {
1712 | deps.push(dep);
1713 | });
1714 |
1715 | //May be a CommonJS thing even without require calls, but still
1716 | //could use exports, and module. Avoid doing exports and module
1717 | //work though if it just needs require.
1718 | //REQUIRES the function to expect the CommonJS variables in the
1719 | //order listed below.
1720 | deps = (callback.length === 1 ? ["require"] : ["require", "exports", "module"]).concat(deps);
1721 | }
1722 | }
1723 |
1724 | //If in IE 6-8 and hit an anonymous define() call, do the interactive
1725 | //work.
1726 | if (useInteractive) {
1727 | node = currentlyAddingScript || getInteractiveScript();
1728 | if (node) {
1729 | if (!name) {
1730 | name = node.getAttribute("data-requiremodule");
1731 | }
1732 | context = contexts[node.getAttribute("data-requirecontext")];
1733 | }
1734 | }
1735 |
1736 | //Always save off evaluating the def call until the script onload handler.
1737 | //This allows multiple modules to be in a file without prematurely
1738 | //tracing dependencies, and allows for anonymous module support,
1739 | //where the module name is not known until the script onload event
1740 | //occurs. If no context, use the global queue, and get it processed
1741 | //in the onscript load callback.
1742 | (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
1743 |
1744 | return undefined;
1745 | };
1746 |
1747 | define.amd = {
1748 | multiversion: true,
1749 | plugins: true,
1750 | jQuery: true
1751 | };
1752 |
1753 | /**
1754 | * Executes the text. Normally just uses eval, but can be modified
1755 | * to use a more environment specific call.
1756 | * @param {String} text the text to execute/evaluate.
1757 | */
1758 | req.exec = function (text) {
1759 | return eval(text);
1760 | };
1761 |
1762 | /**
1763 | * Executes a module callack function. Broken out as a separate function
1764 | * solely to allow the build system to sequence the files in the built
1765 | * layer in the right sequence.
1766 | *
1767 | * @private
1768 | */
1769 | req.execCb = function (name, callback, args, exports) {
1770 | return callback.apply(exports, args);
1771 | };
1772 |
1773 |
1774 | /**
1775 | * Adds a node to the DOM. Public function since used by the order plugin.
1776 | * This method should not normally be called by outside code.
1777 | */
1778 | req.addScriptToDom = function (node) {
1779 | //For some cache cases in IE 6-8, the script executes before the end
1780 | //of the appendChild execution, so to tie an anonymous define
1781 | //call to the module name (which is stored on the node), hold on
1782 | //to a reference to this node, but clear after the DOM insertion.
1783 | currentlyAddingScript = node;
1784 | if (baseElement) {
1785 | head.insertBefore(node, baseElement);
1786 | } else {
1787 | head.appendChild(node);
1788 | }
1789 | currentlyAddingScript = null;
1790 | };
1791 |
1792 | /**
1793 | * callback for script loads, used to check status of loading.
1794 | *
1795 | * @param {Event} evt the event from the browser for the script
1796 | * that was loaded.
1797 | *
1798 | * @private
1799 | */
1800 | req.onScriptLoad = function (evt) {
1801 | //Using currentTarget instead of target for Firefox 2.0's sake. Not
1802 | //all old browsers will be supported, but this one was easy enough
1803 | //to support and still makes sense.
1804 | var node = evt.currentTarget || evt.srcElement, contextName, moduleName,
1805 | context;
1806 |
1807 | if (evt.type === "load" || (node && readyRegExp.test(node.readyState))) {
1808 | //Reset interactive script so a script node is not held onto for
1809 | //to long.
1810 | interactiveScript = null;
1811 |
1812 | //Pull out the name of the module and the context.
1813 | contextName = node.getAttribute("data-requirecontext");
1814 | moduleName = node.getAttribute("data-requiremodule");
1815 | context = contexts[contextName];
1816 |
1817 | contexts[contextName].completeLoad(moduleName);
1818 |
1819 | //Clean up script binding. Favor detachEvent because of IE9
1820 | //issue, see attachEvent/addEventListener comment elsewhere
1821 | //in this file.
1822 | if (node.detachEvent && !isOpera) {
1823 | //Probably IE. If not it will throw an error, which will be
1824 | //useful to know.
1825 | node.detachEvent("onreadystatechange", req.onScriptLoad);
1826 | } else {
1827 | node.removeEventListener("load", req.onScriptLoad, false);
1828 | }
1829 | }
1830 | };
1831 |
1832 | /**
1833 | * Attaches the script represented by the URL to the current
1834 | * environment. Right now only supports browser loading,
1835 | * but can be redefined in other environments to do the right thing.
1836 | * @param {String} url the url of the script to attach.
1837 | * @param {Object} context the context that wants the script.
1838 | * @param {moduleName} the name of the module that is associated with the script.
1839 | * @param {Function} [callback] optional callback, defaults to require.onScriptLoad
1840 | * @param {String} [type] optional type, defaults to text/javascript
1841 | * @param {Function} [fetchOnlyFunction] optional function to indicate the script node
1842 | * should be set up to fetch the script but do not attach it to the DOM
1843 | * so that it can later be attached to execute it. This is a way for the
1844 | * order plugin to support ordered loading in IE. Once the script is fetched,
1845 | * but not executed, the fetchOnlyFunction will be called.
1846 | */
1847 | req.attach = function (url, context, moduleName, callback, type, fetchOnlyFunction) {
1848 | var node;
1849 | if (isBrowser) {
1850 | //In the browser so use a script tag
1851 | callback = callback || req.onScriptLoad;
1852 | node = context && context.config && context.config.xhtml ?
1853 | document.createElementNS("http://www.w3.org/1999/xhtml", "html:script") :
1854 | document.createElement("script");
1855 | node.type = type || (context && context.config.scriptType) ||
1856 | "text/javascript";
1857 | node.charset = "utf-8";
1858 | //Use async so Gecko does not block on executing the script if something
1859 | //like a long-polling comet tag is being run first. Gecko likes
1860 | //to evaluate scripts in DOM order, even for dynamic scripts.
1861 | //It will fetch them async, but only evaluate the contents in DOM
1862 | //order, so a long-polling script tag can delay execution of scripts
1863 | //after it. But telling Gecko we expect async gets us the behavior
1864 | //we want -- execute it whenever it is finished downloading. Only
1865 | //Helps Firefox 3.6+
1866 | //Allow some URLs to not be fetched async. Mostly helps the order!
1867 | //plugin
1868 | node.async = !s.skipAsync[url];
1869 |
1870 | if (context) {
1871 | node.setAttribute("data-requirecontext", context.contextName);
1872 | }
1873 | node.setAttribute("data-requiremodule", moduleName);
1874 |
1875 | //Set up load listener. Test attachEvent first because IE9 has
1876 | //a subtle issue in its addEventListener and script onload firings
1877 | //that do not match the behavior of all other browsers with
1878 | //addEventListener support, which fire the onload event for a
1879 | //script right after the script execution. See:
1880 | //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
1881 | //UNFORTUNATELY Opera implements attachEvent but does not follow the script
1882 | //script execution mode.
1883 | if (node.attachEvent &&
1884 | // check if node.attachEvent is artificially added by custom script or
1885 | // natively supported by browser
1886 | // read https://github.com/jrburke/requirejs/issues/187
1887 | // if we can NOT find [native code] then it must NOT natively supported.
1888 | // in IE8, node.attachEvent does not have toString()
1889 | // TODO: a better way to check interactive mode
1890 | !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code]') < 0) &&
1891 | !isOpera) {
1892 | //Probably IE. IE (at least 6-8) do not fire
1893 | //script onload right after executing the script, so
1894 | //we cannot tie the anonymous define call to a name.
1895 | //However, IE reports the script as being in "interactive"
1896 | //readyState at the time of the define call.
1897 | useInteractive = true;
1898 |
1899 |
1900 | if (fetchOnlyFunction) {
1901 | //Need to use old school onreadystate here since
1902 | //when the event fires and the node is not attached
1903 | //to the DOM, the evt.srcElement is null, so use
1904 | //a closure to remember the node.
1905 | node.onreadystatechange = function (evt) {
1906 | //Script loaded but not executed.
1907 | //Clear loaded handler, set the real one that
1908 | //waits for script execution.
1909 | if (node.readyState === 'loaded') {
1910 | node.onreadystatechange = null;
1911 | node.attachEvent("onreadystatechange", callback);
1912 | fetchOnlyFunction(node);
1913 | }
1914 | };
1915 | } else {
1916 | node.attachEvent("onreadystatechange", callback);
1917 | }
1918 | } else {
1919 | node.addEventListener("load", callback, false);
1920 | }
1921 | node.src = url;
1922 |
1923 | //Fetch only means waiting to attach to DOM after loaded.
1924 | if (!fetchOnlyFunction) {
1925 | req.addScriptToDom(node);
1926 | }
1927 |
1928 | return node;
1929 | } else if (isWebWorker) {
1930 | //In a web worker, use importScripts. This is not a very
1931 | //efficient use of importScripts, importScripts will block until
1932 | //its script is downloaded and evaluated. However, if web workers
1933 | //are in play, the expectation that a build has been done so that
1934 | //only one script needs to be loaded anyway. This may need to be
1935 | //reevaluated if other use cases become common.
1936 | importScripts(url);
1937 |
1938 | //Account for anonymous modules
1939 | context.completeLoad(moduleName);
1940 | }
1941 | return null;
1942 | };
1943 |
1944 | //Look for a data-main script attribute, which could also adjust the baseUrl.
1945 | if (isBrowser) {
1946 | //Figure out baseUrl. Get it from the script tag with require.js in it.
1947 | scripts = document.getElementsByTagName("script");
1948 |
1949 | for (globalI = scripts.length - 1; globalI > -1 && (script = scripts[globalI]); globalI--) {
1950 | //Set the "head" where we can append children by
1951 | //using the script's parent.
1952 | if (!head) {
1953 | head = script.parentNode;
1954 | }
1955 |
1956 | //Look for a data-main attribute to set main script for the page
1957 | //to load. If it is there, the path to data main becomes the
1958 | //baseUrl, if it is not already set.
1959 | if ((dataMain = script.getAttribute('data-main'))) {
1960 | if (!cfg.baseUrl) {
1961 | //Pull off the directory of data-main for use as the
1962 | //baseUrl.
1963 | src = dataMain.split('/');
1964 | mainScript = src.pop();
1965 | subPath = src.length ? src.join('/') + '/' : './';
1966 |
1967 | //Set final config.
1968 | cfg.baseUrl = subPath;
1969 | //Strip off any trailing .js since dataMain is now
1970 | //like a module name.
1971 | dataMain = mainScript.replace(jsSuffixRegExp, '');
1972 | }
1973 |
1974 | //Put the data-main script in the files to load.
1975 | cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain];
1976 |
1977 | break;
1978 | }
1979 | }
1980 | }
1981 |
1982 | //See if there is nothing waiting across contexts, and if not, trigger
1983 | //resourcesReady.
1984 | req.checkReadyState = function () {
1985 | var contexts = s.contexts, prop;
1986 | for (prop in contexts) {
1987 | if (!(prop in empty)) {
1988 | if (contexts[prop].waitCount) {
1989 | return;
1990 | }
1991 | }
1992 | }
1993 | req.resourcesReady(true);
1994 | };
1995 |
1996 | /**
1997 | * Internal function that is triggered whenever all scripts/resources
1998 | * have been loaded by the loader. Can be overridden by other, for
1999 | * instance the domReady plugin, which wants to know when all resources
2000 | * are loaded.
2001 | */
2002 | req.resourcesReady = function (isReady) {
2003 | var contexts, context, prop;
2004 |
2005 | //First, set the public variable indicating that resources are loading.
2006 | req.resourcesDone = isReady;
2007 |
2008 | if (req.resourcesDone) {
2009 | //If jQuery with DOM ready delayed, release it now.
2010 | contexts = s.contexts;
2011 | for (prop in contexts) {
2012 | if (!(prop in empty)) {
2013 | context = contexts[prop];
2014 | if (context.jQueryIncremented) {
2015 | jQueryHoldReady(context.jQuery, false);
2016 | context.jQueryIncremented = false;
2017 | }
2018 | }
2019 | }
2020 | }
2021 | };
2022 |
2023 | //FF < 3.6 readyState fix. Needed so that domReady plugin
2024 | //works well in that environment, since require.js is normally
2025 | //loaded via an HTML script tag so it will be there before window load,
2026 | //where the domReady plugin is more likely to be loaded after window load.
2027 | req.pageLoaded = function () {
2028 | if (document.readyState !== "complete") {
2029 | document.readyState = "complete";
2030 | }
2031 | };
2032 | if (isBrowser) {
2033 | if (document.addEventListener) {
2034 | if (!document.readyState) {
2035 | document.readyState = "loading";
2036 | window.addEventListener("load", req.pageLoaded, false);
2037 | }
2038 | }
2039 | }
2040 |
2041 | //Set up default context. If require was a configuration object, use that as base config.
2042 | req(cfg);
2043 |
2044 | //If modules are built into require.js, then need to make sure dependencies are
2045 | //traced. Use a setTimeout in the browser world, to allow all the modules to register
2046 | //themselves. In a non-browser env, assume that modules are not built into require.js,
2047 | //which seems odd to do on the server.
2048 | if (req.isAsync && typeof setTimeout !== "undefined") {
2049 | ctx = s.contexts[(cfg.context || defContextName)];
2050 | //Indicate that the script that includes require() is still loading,
2051 | //so that require()'d dependencies are not traced until the end of the
2052 | //file is parsed (approximated via the setTimeout call).
2053 | ctx.requireWait = true;
2054 | setTimeout(function () {
2055 | ctx.requireWait = false;
2056 |
2057 | if (!ctx.scriptCount) {
2058 | ctx.resume();
2059 | }
2060 | req.checkReadyState();
2061 | }, 0);
2062 | }
2063 | }());
2064 |
--------------------------------------------------------------------------------
/client/main.js:
--------------------------------------------------------------------------------
1 | /*global console:false */
2 |
3 | require([
4 | "app/core"
5 | ],function(){
6 | "use strict";
7 |
8 | console.log('Client application started');
9 | });
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nodejs-emberjs-mongodb",
3 | "version": "0.0.2",
4 | "private": true,
5 | "scripts": {
6 | "start": "NODE_ENV=development node app"
7 | },
8 | "dependencies": {
9 | "express": "3.0.x",
10 | "mongoose": "2.5.x",
11 | "requirejs": "1.0.x"
12 | }
13 | }
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | Node.js + Ember.js + MongoDB
2 | =============================
3 |
4 | Proof of concept application.
5 |
6 | ### Dependencies:
7 |
8 | * [http://nodejs.org](http://nodejs.org) 0.6.x
9 | * [http://requirejs.org](http://requirejs.org) 1.0.x
10 | * [http://expressjs.com](http://expressjs.com) 3.0.x
11 | * [http://mongoosejs.com](http://mongoosejs.com) 2.5.x
12 | * [http://www.mongodb.org](http://www.mongodb.org) 2.0.x
13 | * [http://jquery.com](http://jquery.com) 1.7.2
14 | * [http://emberjs.com](http://emberjs.com) 0.9.8.1
15 | * [http://twitter.github.com/bootstrap](http://twitter.github.com/bootstrap) 2.0.3
16 |
17 | ### How to run in development environment
18 |
19 | 1. You have to start local MongoDB instance
20 | 2. Go to the project directory
21 |
22 | $ cd nodejs-emberjs-mongodb
23 |
24 | 3. Install required Node.js modules
25 |
26 | $ npm install
27 |
28 | 4. Start Node.js HTTP server
29 |
30 | $ npm start
31 |
32 | 5. Visit address [http://localhost:3000](http://localhost:3000)
33 | 6. Enjoy!
34 |
35 | ### Build and run production version
36 |
37 | 1. You have to start local MongoDB instance
38 | 2. Go to the project directory
39 |
40 | $ cd nodejs-emberjs-mongodb
41 |
42 | 3. Install required Node.js modules
43 |
44 | $ npm install
45 |
46 | 4. Start Node.js HTTP server in production environment, client javascript and css files will be automatically optimized
47 |
48 | $ NODE_ENV=production node app
49 |
50 | ### Manual client build
51 |
52 | 1. Go to the project directory
53 |
54 | $ cd nodejs-emberjs-mongodb
55 |
56 | 2. Build client
57 |
58 | $ node build
59 |
--------------------------------------------------------------------------------
/server/api/authors.js:
--------------------------------------------------------------------------------
1 | /*global console:false */
2 |
3 | define([
4 | 'server/model/Author'
5 | ],function(
6 | Author
7 | ){
8 | "use strict";
9 |
10 | return {
11 | remove: function(req, res) {
12 | Author.findById(req.params.id, function (err, author) {
13 | if (err) {
14 | res.json(500,{
15 | error: err
16 | });
17 | console.log('Failed to get author id ' + req.params.id + ', ' + err);
18 | } else {
19 | if (author === null) {
20 | res.send(404,'');
21 | console.log('Author ' + req.params.id + ' not found');
22 | } else {
23 | author.remove(function (err) {
24 | if (err) {
25 | res.json(500,{
26 | error: err
27 | });
28 | console.log('Failed to remove author id ' + req.params.id + ', ' + err);
29 | } else {
30 | res.json(200,'');
31 | console.log('Deleted author ' + JSON.stringify(author));
32 | }
33 | });
34 | }
35 | }
36 | });
37 | },
38 |
39 | getAll: function(req, res) {
40 | Author.find({}, function (err, authors) {
41 | if (err) {
42 | res.json(500,{
43 | error: err
44 | });
45 | console.log('Failed to get authors, ' + err);
46 | } else {
47 | res.json(200, authors);
48 | console.log('Found authors ' + JSON.stringify(authors));
49 | }
50 | });
51 | },
52 |
53 | create: function(req, res) {
54 | var author = new Author({
55 | name: req.body.name
56 | });
57 | author.save(function (err) {
58 | if (err) {
59 | res.json(500,{
60 | error: err
61 | });
62 | console.log('Failed to create author ' + JSON.stringify(req.body) + ', ' + err);
63 | } else {
64 | res.json(200,{
65 | id : author.id
66 | });
67 | console.log('Created author ' + JSON.stringify(req.body));
68 | }
69 | });
70 | }
71 | };
72 | });
73 |
--------------------------------------------------------------------------------
/server/model/Author.js:
--------------------------------------------------------------------------------
1 | define([
2 | 'mongoose'
3 | ],function(
4 | mongoose
5 | ){
6 | "use strict";
7 |
8 | var Schema = mongoose.Schema;
9 |
10 | var Author = new Schema({
11 | name : String
12 | });
13 |
14 | return mongoose.model('Author', Author);
15 | });
16 |
--------------------------------------------------------------------------------
/test/create-author.sh:
--------------------------------------------------------------------------------
1 | curl -v -X POST \
2 | -H "content-type: application/json" \
3 | -H "accept: application/json" \
4 | -d '{"name":"My Name"}' http://localhost:3000/api/authors
5 |
6 |
--------------------------------------------------------------------------------
/test/db/start-db.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | [ ! -d data ] && mkdir data
4 | mongodb-linux-*/bin/mongod --dbpath data --rest
5 |
--------------------------------------------------------------------------------
/test/delete-author.sh:
--------------------------------------------------------------------------------
1 | curl -v -X DELETE \
2 | -H "accept: application/json" \
3 | http://localhost:3000/api/authors/4f97d9b0e816a79121000001
4 |
5 |
--------------------------------------------------------------------------------
/test/get-authors.sh:
--------------------------------------------------------------------------------
1 | curl -v -X GET \
2 | -H "accept: application/json" \
3 | http://localhost:3000/api/authors
4 |
5 |
--------------------------------------------------------------------------------
/test/jshint/jshint-check.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | for file in `find ../.. -name "*.js" | grep -v "client/lib" | grep -v "node_modules" | grep -v "client.build"`; do
4 | echo ===Linting $file...===
5 | jshint $file;
6 | done
7 | echo
8 |
--------------------------------------------------------------------------------